diff --git a/README.md b/README.md index 3ca9b74..3a30f15 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,10 @@ Minimum Viable Goals: - [x] Continuous Horizontal Scroll - unreasonably rare feature - [x] Presentation View - i.e. show on an external monitor - haven't seen another app do this yet! - [x] Immersive View - no system status bar etc. +- [x] Autocrop margins - [ ] Open files the Android way - currently just a bundled test file - [ ] Delete+Reorder Pages - doesn't have to save the source file, but does need to save a change journal - [ ] Text Annotations - as above -- [ ] Autocrop margins Stretch Goals: - [ ] Networked View: diff --git a/app/src/main/java/com/lhw/pdf/PdfDocument.kt b/app/src/main/java/com/lhw/pdf/PdfDocument.kt new file mode 100644 index 0000000..d0a776f --- /dev/null +++ b/app/src/main/java/com/lhw/pdf/PdfDocument.kt @@ -0,0 +1,144 @@ +package com.lhw.pdf + +import android.graphics.Bitmap +import android.graphics.Color +import android.graphics.Matrix +import android.graphics.Rect +import android.graphics.RectF +import android.graphics.pdf.PdfRenderer +import android.os.ParcelFileDescriptor +import androidx.core.graphics.times +import java.io.File +import kotlin.math.max +import kotlin.math.min + +class PdfDocument(private val fileCached: File, private val autoCrop: Boolean = false) { + private val pfd = ParcelFileDescriptor.open(fileCached, ParcelFileDescriptor.MODE_READ_ONLY) + private val renderer = PdfRenderer(pfd) + val bitmapThumbnails = mutableMapOf() + val bitmapPagesMain = mutableMapOf() + val bitmapPagesPresentation = mutableMapOf() + private val pagePtWidths = mutableListOf() + private val pagePtHeights = mutableListOf() + private val pageAutoCropRects = mutableListOf() + // Due to the way thumbnails render, the bottom right is more likely to be cut off + private val autoCropSafetyMarginUpper = 2 + private val autoCropSafetyMarginLower = 16 + + init { + val numPages = renderer.pageCount + for (i in 0.. maxWidth) Pair(maxWidth, heightFromMaxWidth) else Pair(widthFromMaxHeight, maxHeight) + + val page = renderer.openPage(index) + println("Creating page $index bitmap with width $width and height $height from cropRect $cropRect") + val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) + val ptToPixel = height/ptHeight + val transform = Matrix() + val transposePtX = -cropRect.left * ptWidth + val transposePtY = -cropRect.top * ptHeight + transform.setValues(floatArrayOf(ptToPixel, 0F, transposePtX*ptToPixel, 0F, ptToPixel, transposePtY*ptToPixel, 0F, 0F, 1F)) + page.render(bitmap, null, transform, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY) + page.close() + return bitmap + } + + private fun renderPagesToMap(map: MutableMap, width: Int, height: Int, crop: Boolean = false) { + map.clear() + val numPages = renderer.pageCount + for (i in 0.. 0) && (color.luminance() < 0.9F) + } + fun renderThumbnails(width: Int, height: Int) { + renderPagesToMap(bitmapThumbnails, width, height) + println("Thumbnails rendered") + if (autoCrop) { + println("Auto cropping from thumbnails") + val numPages = renderer.pageCount + pageAutoCropRects.clear() + for (i in 0..