Dmitry-Borodin / pdfview-android

Small Android library to show PDF files
Apache License 2.0
294 stars 48 forks source link

Pages are cut when document have pages of different size #10

Open mlecoq opened 4 years ago

mlecoq commented 4 years ago

Hi,

When I try to display a document with pages that have different sizes (last pages have a bigger width), the bigger ones are cut.

Here is a document to reproduce the issue: document

Dmitry-Borodin commented 4 years ago

com/pdfview/PDFRegionDecoder.kt:28 - currently we taking width for the first page always. So this library doesn't support documents with various width. Would be nice to fix it, without opening all the pages during initialization.... Thank you for reporting

Dmitry-Borodin commented 4 years ago

I expect this to not be difficult. Just need to test edge cases carefully... Not sure when I"ll have time to work on it. Will mention this issue in commit if I will.

KnIfER commented 3 years ago

Hi, It's fast to get their size during initialization asynchronously, even there are hundreds of pages. I choose to scan all of them because it's the simplest way.

While google pdf viewer seems to choose to always scan from 0 to current page, as a result lt's a bit slow to jump across pages randomly.

in my logic I treat the entire pdf as a huge image of height=sum of all page's height, width=maximum page width, and pages of smaller widths would have a horizontal offset.

mpnihad commented 3 years ago

Hi Found a simple way to solve the issue


  override fun decodeRegion(rect: Rect, sampleSize: Int): Bitmap {
        val numPageAtStart = Math.floor(rect.top.toDouble() / pageHeight).toInt()
        val numPageAtEnd = Math.ceil(rect.bottom.toDouble() / pageHeight).toInt() - 1
        val bitmap = Bitmap.createBitmap(
            rect.width() / sampleSize,
            rect.height() / sampleSize,
            Bitmap.Config.ARGB_8888
        )
        val canvas = Canvas(bitmap)
        canvas.drawColor(backgroundColorPdf)
        canvas.drawBitmap(bitmap, 0f, 0f, null)
        for ((iteration, pageIndex) in (numPageAtStart..numPageAtEnd).withIndex()) {
            synchronized(renderer) {
                val page = renderer.openPage(pageIndex)
                val pageWidth = page.width
                val pageHeight = page.height
                val matrix = Matrix()
                val scale =
                    Math.min(this.pageWidth.toFloat() / pageWidth, this.pageHeight.toFloat() / pageHeight)

                matrix.setScale(scale / sampleSize, scale / sampleSize)

                matrix.postTranslate(
                    (-rect.left / sampleSize).toFloat(),
                    -((rect.top - this.pageHeight * numPageAtStart) / sampleSize).toFloat() + (this.pageHeight.toFloat() / sampleSize) * iteration
                )
                page.render(bitmap, null, matrix, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
                page.close()
            }
        }
        return bitmap
    }