Pdf annotations fix (#99)

* Optimized high-res scale logic in PdfVerticalReader and adjusted layout padding in PdfViewerScreen

* Fixed position sync between both PDF reading modes

* Enabled annotation rendering in PDF tiles and improved scrolling state detection in `PdfVerticalReader` by introducing an `isDragging` flag.
This commit is contained in:
Aryan 2026-03-20 16:37:24 +05:30 committed by GitHub
parent a9c791120d
commit 9842aea9b1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 31 additions and 28 deletions

View file

@ -67,8 +67,8 @@ fun AnnotationDock(
canUndo: Boolean,
canRedo: Boolean,
lastPenTool: InkType,
lastHighlighterTool: InkType = InkType.HIGHLIGHTER,
modifier: Modifier = Modifier,
lastHighlighterTool: InkType = InkType.HIGHLIGHTER,
isSticky: Boolean = false,
isMinimized: Boolean,
onToggleMinimize: () -> Unit,

View file

@ -1195,7 +1195,7 @@ internal fun PdfPageComposable(
startY = -tileRenderY,
drawSizeX = fullPageRenderWidth,
drawSizeY = fullPageRenderHeight,
renderAnnot = false
renderAnnot = true
)
val newTile = PdfTile(tileBitmap, tileRect, tileId)

View file

@ -60,6 +60,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.Stable
@ -234,6 +235,13 @@ internal fun PdfVerticalReader(
activeToolThickness: Float = 0f
) {
SideEffect { Timber.tag("PdfDrawPerf").v("LIST: PdfVerticalReader Recomposing.") }
DisposableEffect(state) {
onDispose {
state.scrollToPageHandler = null
state.snapToPageHandler = null
state.scrollByHandler = null
}
}
var globalEraserPosition by remember { mutableStateOf<Offset?>(null) }
BoxWithConstraints(modifier = modifier.fillMaxSize(), contentAlignment = Alignment.TopStart) {
val imeInsets = WindowInsets.ime
@ -399,6 +407,7 @@ internal fun PdfVerticalReader(
var isFlinging by remember { mutableStateOf(false) }
var isFastFlinging by remember { mutableStateOf(false) }
var isInteracting by remember { mutableStateOf(false) }
var isDragging by remember { mutableStateOf(false) }
LaunchedEffect(
totalDocHeight, screenHeight, headerHeightPx, footerHeightPx, zoomAnimatable.value, isInteracting, isFlinging
@ -596,19 +605,16 @@ internal fun PdfVerticalReader(
"VerticalReader Interaction State: isBusy=$isBusy (Interacting=$isInteracting, Flinging=$isFlinging, Fast=$isFastFlinging)"
)
if (isBusy) {
highResScale = 1f
} else {
delay(20)
if (!isBusy) {
delay(50)
val target = zoomAnimatable.value
if (highResScale != target) {
Timber.tag("PdfDrawPerf")
.v("VerticalReader: Updating highResScale to $target")
}
Timber.tag("PdfDrawPerf").v("VerticalReader: Updating highResScale to $target")
highResScale = target
}
}
}
}
LaunchedEffect(highResScale, zoomAnimatable.value) {
Timber.tag("PdfDrawPerf")
@ -616,17 +622,8 @@ internal fun PdfVerticalReader(
}
LaunchedEffect(zoomAnimatable.value) {
if (!isInteracting && !isFlinging && zoomAnimatable.value != highResScale) {
highResScale = zoomAnimatable.value
}
}
LaunchedEffect(Unit) {
snapshotFlow { isInteracting }.collectLatest { interacting ->
if (interacting) {
highResScale = 1f
} else {
delay(350)
if (!isInteracting && !(isFlinging && isFastFlinging)) {
if (highResScale != zoomAnimatable.value) {
highResScale = zoomAnimatable.value
}
}
@ -938,6 +935,7 @@ internal fun PdfVerticalReader(
val down = awaitFirstDown(requireUnconsumed = false)
isInteracting = true
isDragging = false
Timber.tag("PointerTypeDebug").d("VerticalReader: Input Type detected: ${down.type}")
@ -1057,6 +1055,7 @@ internal fun PdfVerticalReader(
if (shouldScroll) {
panLocked = true
isDragging = true
if (zoomChange != 1f || panChange != Offset.Zero) {
var effectiveZoomChange = zoomChange
@ -1114,6 +1113,7 @@ internal fun PdfVerticalReader(
Timber.tag("PdfTouchDebug").v("VerticalReader: Interaction ended")
isInteracting = false
}
isDragging = false
val validFlingCondition = panLocked
@ -1519,7 +1519,7 @@ internal fun PdfVerticalReader(
onOcrStateChange = onOcrStateChange,
onBookmarkClick = { onBookmarkClick(page.index) },
isZoomEnabled = false,
isScrolling = isInteracting || (isFlinging && isFastFlinging),
isScrolling = isDragging || (isFlinging && isFastFlinging),
isVerticalScroll = true,
visualScaleProvider = currentScaleProvider,
onDoubleTap = onDoubleTapLambda,

View file

@ -2196,10 +2196,16 @@ fun PdfViewerScreen(
}
LaunchedEffect(displayMode) {
coroutineScope.launch {
if (initialScrollDone) {
if (displayMode == DisplayMode.VERTICAL_SCROLL) {
val pageToScroll = pagerState.currentPage
verticalReaderState.scrollToPage(pageToScroll)
var attempts = 0
while (verticalReaderState.snapToPageHandler == null && attempts < 50) {
delay(16)
attempts++
}
verticalReaderState.snapToPage(pageToScroll)
} else {
val pageToScroll = verticalReaderState.currentPage
pagerState.scrollToPage(pageToScroll)
@ -4124,9 +4130,6 @@ fun PdfViewerScreen(
Box(
modifier = Modifier
.fillMaxSize()
.padding(
top = verticalHeaderHeight, bottom = verticalFooterHeight
)
) {
when {
isLoadingDocument -> {
@ -4605,8 +4608,8 @@ fun PdfViewerScreen(
}
DisplayMode.VERTICAL_SCROLL -> {
val headerHeight = 0.dp
val footerHeight = 0.dp
val headerHeight = verticalHeaderHeight
val footerHeight = verticalFooterHeight
val currentSelectedTool by rememberUpdatedState(selectedTool)
val currentStrokeColorState by rememberUpdatedState(