General fixes (#102)

* Improved PDF embedded annotation hit detection logic

* Updated EPUB and PDF reader logic to improve position tracking and TTS stability.

Key changes:
- Refined CFI and locator handling in `EpubReaderScreen` with improved initialization.
- Updated `BookPaginator` to more accurately calculate text offsets in chunks and improve CFI matching logic.
- Modified `TtsPlaybackManager` to insert media items at the correct index, ensuring proper playback order.
- Simplified `EpubReaderTts` page scrolling by removing conditional checks for backward jumps.
- Disabled OCR fallback in `PdfViewerScreen` during text extraction for TTS.

* Updated extractTextWithCfiFromTop to use getBoundingClientRect for identifying the starting block
This commit is contained in:
Aryan 2026-03-21 11:49:27 +05:30 committed by GitHub
parent ddcd253c7b
commit fbe8e7aa56
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 95 additions and 184 deletions

View file

@ -2792,93 +2792,14 @@ fun PdfViewerScreen(
withContext(Dispatchers.IO) { tempTextPage?.close() }
}
ocrUsedForCurrentPageTts = false
withContext(Dispatchers.IO) {
tempPage?.close()
}
if (rawPageText.isNullOrBlank()) {
Timber.i(
"TTS: Pdfium text is blank or extraction failed. Attempting OCR for page $pageToRead."
)
ocrAttempted = true
ocrUsedForCurrentPageTts = true
var ocrBitmap: Bitmap? = null
try {
if (tempPage == null) {
withContext(Dispatchers.IO) {
tempPage?.close()
Timber.d("TTS/OCR: Re-opening page $pageToRead for bitmap rendering.")
tempPage = pdfDocument!!.openPage(pageToRead)
}
}
val pageForOcr = tempPage ?: throw IllegalStateException(
"TTS/OCR: PDF page couldn't be opened for OCR."
)
val ocrBitmapWidth = 1080
val ocrBitmapHeight: Int
withContext(Dispatchers.IO) {
val originalWidthPoints = pageForOcr.getPageWidthPoint()
val originalHeightPoints = pageForOcr.getPageHeightPoint()
if (originalWidthPoints <= 0 || originalHeightPoints <= 0) {
throw IllegalStateException(
"TTS/OCR: Invalid page dimensions (points) from Pdfium for page $pageToRead."
)
}
val aspectRatio =
originalWidthPoints.toFloat() / originalHeightPoints.toFloat()
ocrBitmapHeight = (ocrBitmapWidth / aspectRatio).toInt()
if (ocrBitmapHeight <= 0) {
throw IllegalStateException(
"TTS/OCR: Calculated invalid bitmap dimensions for OCR ($ocrBitmapWidth x $ocrBitmapHeight) for page $pageToRead."
)
}
Timber.d(
"TTS/OCR: Rendering page $pageToRead to bitmap of size ${ocrBitmapWidth}x$ocrBitmapHeight."
)
ocrBitmap = createBitmap(ocrBitmapWidth, ocrBitmapHeight)
pageForOcr.renderPageBitmap(
bitmap = ocrBitmap,
startX = 0,
startY = 0,
drawSizeX = ocrBitmapWidth,
drawSizeY = ocrBitmapHeight,
renderAnnot = false
)
}
Timber.d("TTS/OCR: Bitmap rendered for page $pageToRead. Attempting OCR.")
rawPageText = OcrHelper.extractTextFromBitmap(ocrBitmap!!) {
isOcrModelDownloading = true
}?.text
if (!rawPageText.isNullOrBlank()) {
Timber.i(
"TTS: Text extracted via OCR for page $pageToRead (length: ${rawPageText?.length})."
)
} else {
Timber.w(
"TTS: OCR process completed for page $pageToRead but returned no text or blank text."
)
}
} catch (e: Exception) {
Timber.e(e, "TTS: Error during OCR process for page $pageToRead")
} finally {
ocrBitmap?.recycle()
withContext(Dispatchers.IO) {
tempPage?.close()
Timber.d("TTS/OCR: Closed page $pageToRead after OCR attempt.")
}
}
Timber.i("TTS: Pdfium text is blank or extraction failed. OCR fallback is temporarily disabled.")
} else {
ocrUsedForCurrentPageTts = false
withContext(Dispatchers.IO) {
tempPage?.close()
Timber.d(
"TTS: Closed page $pageToRead after successful Pdfium text extraction."
)
}
Timber.d("TTS: Closed page $pageToRead after successful Pdfium text extraction.")
}
if (rawPageText != null && rawPageText!!.isNotBlank()) {