Skip to content

Commit

Permalink
fix(android): resolve crash on large displays
Browse files Browse the repository at this point in the history
  • Loading branch information
alpha0010 committed Jul 13, 2022
1 parent 92030e0 commit 9266620
Showing 1 changed file with 41 additions and 11 deletions.
52 changes: 41 additions & 11 deletions android/src/main/java/com/alpha0010/pdf/PdfView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,28 @@ import java.io.FileNotFoundException
import java.util.concurrent.locks.Lock
import kotlin.concurrent.withLock
import kotlin.math.abs
import kotlin.math.floor
import kotlin.math.hypot

enum class ResizeMode(val jsName: String) {
CONTAIN("contain"),
FIT_WIDTH("fitWidth")
}

// Canvas passed to onDraw() crashes if passed too large a bitmap. Divide
// rendered bitmap into slices to draw in sequence.
// Logic assumes PdfView is at least `SLICES` pixels tall.
const val SLICES = 8

@SuppressLint("ViewConstructor")
class PdfView(context: Context, private val pdfMutex: Lock) : View(context) {
private var mAnnotation = emptyList<AnnotationPage>()
private var mBitmap: Bitmap
private val mBitmaps = MutableList(SLICES) { Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888) }
private var mDirty = false
private var mPage = 0
private var mResizeMode = ResizeMode.CONTAIN
private var mSource = ""
private val mViewRect = Rect()

init {
mBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)
}
private val mViewRects = List(SLICES) { Rect() }

fun setAnnotation(source: String) {
if (source.isEmpty()) {
Expand Down Expand Up @@ -258,10 +260,24 @@ class PdfView(context: Context, private val pdfMutex: Lock) : View(context) {

withContext(Dispatchers.Main) {
// Post new bitmap for display.
mBitmap.recycle()
mBitmap = bitmap
val sliceHeight = floor(bitmap.height.toFloat() / SLICES).toInt()
if (sliceHeight < 1) {
return@withContext
}
for (i in mBitmaps.indices) {
mBitmaps[i].recycle()
val remainingHeight = bitmap.height - i * sliceHeight
if (remainingHeight < 2 * sliceHeight) {
// Last slice.
mBitmaps[i] =
Bitmap.createBitmap(bitmap, 0, i * sliceHeight, bitmap.width, remainingHeight)
} else {
mBitmaps[i] = Bitmap.createBitmap(bitmap, 0, i * sliceHeight, bitmap.width, sliceHeight)
}
}
invalidate()
}
// TODO: Is `bitmap.recycle()` safe here?

onLoadComplete(pdfPageWidth, pdfPageHeight)
}
Expand Down Expand Up @@ -302,13 +318,27 @@ class PdfView(context: Context, private val pdfMutex: Lock) : View(context) {
}

override fun onDraw(canvas: Canvas) {
if (!mViewRect.isEmpty) {
canvas.drawBitmap(mBitmap, null, mViewRect, null)
mBitmaps.zip(mViewRects) { bitmap, viewRect ->
if (!viewRect.isEmpty) {
canvas.drawBitmap(bitmap, null, viewRect, null)
}
}
}

override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
mViewRect.set(0, 0, w, h)
val sliceHeight = floor(h.toFloat() / SLICES).toInt()
if (sliceHeight < 1) {
return
}
for (i in mViewRects.indices) {
val remainingHeight = h - i * sliceHeight
if (remainingHeight < 2 * sliceHeight) {
// Last slice.
mViewRects[i].set(0, i * sliceHeight, w, i * sliceHeight + remainingHeight)
} else {
mViewRects[i].set(0, i * sliceHeight, w, (i + 1) * sliceHeight)
}
}
mDirty = true
renderPdf()
}
Expand Down

0 comments on commit 9266620

Please sign in to comment.