@june24/expo-pdf-reader 0.1.20 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -89,6 +89,7 @@ class ExpoPdfReaderView(context: Context, appContext: AppContext) : ExpoView(con
|
|
|
89
89
|
private val onTextPress = ViewEvent<Map<String, Any>>("onTextPress", this, null)
|
|
90
90
|
|
|
91
91
|
private var pageHeights = mutableListOf<Int>()
|
|
92
|
+
private var rowHeights = mutableListOf<Int>()
|
|
92
93
|
private var pageWidthsPdf = mutableListOf<Float>()
|
|
93
94
|
private var pageHeightsPdf = mutableListOf<Float>()
|
|
94
95
|
private var pageViews = mutableListOf<ImageView?>()
|
|
@@ -552,13 +553,38 @@ class ExpoPdfReaderView(context: Context, appContext: AppContext) : ExpoView(con
|
|
|
552
553
|
notifyAnnotationChange()
|
|
553
554
|
}
|
|
554
555
|
|
|
556
|
+
private fun isTwoUpMode(): Boolean = displayMode == "twoUp" || displayMode == "twoUpContinuous"
|
|
557
|
+
|
|
555
558
|
private fun marginBetweenPages(): Int = if (displayMode == "single") 0 else 16
|
|
556
559
|
|
|
560
|
+
private fun getFrameForPage(pageIndex: Int): FrameLayout? {
|
|
561
|
+
if (pageIndex !in pageHeights.indices) return null
|
|
562
|
+
return if (isTwoUpMode()) {
|
|
563
|
+
val row = pageIndex / 2
|
|
564
|
+
val col = pageIndex % 2
|
|
565
|
+
if (row >= container.childCount) null
|
|
566
|
+
else (container.getChildAt(row) as? LinearLayout)?.getChildAt(col) as? FrameLayout
|
|
567
|
+
} else {
|
|
568
|
+
container.getChildAt(pageIndex) as? FrameLayout
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
557
572
|
private fun scrollToPage(pageIndex: Int) {
|
|
558
573
|
if (pageHeights.isEmpty()) return
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
574
|
+
val idx = pageIndex.coerceIn(0, pageHeights.size - 1)
|
|
575
|
+
val gap = marginBetweenPages()
|
|
576
|
+
val offset = if (isTwoUpMode() && rowHeights.isNotEmpty()) {
|
|
577
|
+
var sum = 0
|
|
578
|
+
for (r in 0 until idx / 2) {
|
|
579
|
+
sum += rowHeights[r] + gap
|
|
580
|
+
}
|
|
581
|
+
sum
|
|
582
|
+
} else {
|
|
583
|
+
var sum = 0
|
|
584
|
+
for (i in 0 until idx) {
|
|
585
|
+
sum += pageHeights[i] + gap
|
|
586
|
+
}
|
|
587
|
+
sum
|
|
562
588
|
}
|
|
563
589
|
scrollView.post { scrollView.smoothScrollTo(0, offset) }
|
|
564
590
|
}
|
|
@@ -598,6 +624,7 @@ class ExpoPdfReaderView(context: Context, appContext: AppContext) : ExpoView(con
|
|
|
598
624
|
fileDescriptor?.close()
|
|
599
625
|
fileDescriptor = null
|
|
600
626
|
pageHeights.clear()
|
|
627
|
+
rowHeights.clear()
|
|
601
628
|
pageWidthsPdf.clear()
|
|
602
629
|
pageHeightsPdf.clear()
|
|
603
630
|
pageViews.clear()
|
|
@@ -632,20 +659,16 @@ class ExpoPdfReaderView(context: Context, appContext: AppContext) : ExpoView(con
|
|
|
632
659
|
updateVisiblePages()
|
|
633
660
|
return
|
|
634
661
|
}
|
|
635
|
-
val viewHeight = height.coerceAtLeast(1)
|
|
636
662
|
val viewWidth = width.coerceAtLeast(1)
|
|
637
|
-
val
|
|
663
|
+
val isTwoUp = displayMode == "twoUp" || displayMode == "twoUpContinuous"
|
|
664
|
+
val effectiveWidth = if (isTwoUp) viewWidth / 2 else viewWidth
|
|
638
665
|
scope.launch {
|
|
639
|
-
val w =
|
|
666
|
+
val w = effectiveWidth
|
|
640
667
|
val result = withContext(Dispatchers.Default) {
|
|
641
668
|
(0 until renderer.pageCount).map { i ->
|
|
642
669
|
val page = renderer.openPage(i)
|
|
643
670
|
try {
|
|
644
|
-
val pageH =
|
|
645
|
-
viewHeight
|
|
646
|
-
} else {
|
|
647
|
-
(w.toFloat() * page.height / page.width).toInt()
|
|
648
|
-
}
|
|
671
|
+
val pageH = (w.toFloat() * page.height / page.width).toInt()
|
|
649
672
|
Triple(
|
|
650
673
|
i,
|
|
651
674
|
pageH,
|
|
@@ -659,6 +682,7 @@ class ExpoPdfReaderView(context: Context, appContext: AppContext) : ExpoView(con
|
|
|
659
682
|
if (!isActive) return@launch
|
|
660
683
|
withContext(Dispatchers.Main) {
|
|
661
684
|
pageHeights.clear()
|
|
685
|
+
rowHeights.clear()
|
|
662
686
|
pageWidthsPdf.clear()
|
|
663
687
|
pageHeightsPdf.clear()
|
|
664
688
|
for ((_, h, pdfSize) in result) {
|
|
@@ -666,6 +690,14 @@ class ExpoPdfReaderView(context: Context, appContext: AppContext) : ExpoView(con
|
|
|
666
690
|
pageWidthsPdf.add(pdfSize.first)
|
|
667
691
|
pageHeightsPdf.add(pdfSize.second)
|
|
668
692
|
}
|
|
693
|
+
if (isTwoUp) {
|
|
694
|
+
val rowCount = (renderer.pageCount + 1) / 2
|
|
695
|
+
for (r in 0 until rowCount) {
|
|
696
|
+
val h0 = pageHeights.getOrElse(2 * r) { 0 }
|
|
697
|
+
val h1 = pageHeights.getOrElse(2 * r + 1) { 0 }
|
|
698
|
+
rowHeights.add(maxOf(h0, h1))
|
|
699
|
+
}
|
|
700
|
+
}
|
|
669
701
|
ensurePlaceholders(renderer)
|
|
670
702
|
scrollToPage(initialPage.coerceIn(0, (renderer.pageCount - 1).coerceAtLeast(0)))
|
|
671
703
|
updateVisiblePages()
|
|
@@ -682,31 +714,76 @@ class ExpoPdfReaderView(context: Context, appContext: AppContext) : ExpoView(con
|
|
|
682
714
|
while (pageAnnotations.size < pageCount) {
|
|
683
715
|
pageAnnotations.add(mutableListOf())
|
|
684
716
|
}
|
|
685
|
-
|
|
686
|
-
val
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
717
|
+
if (isTwoUpMode() && rowHeights.isNotEmpty()) {
|
|
718
|
+
val rowCount = rowHeights.size
|
|
719
|
+
for (r in 0 until rowCount) {
|
|
720
|
+
val rowLayout = LinearLayout(context).apply {
|
|
721
|
+
orientation = LinearLayout.HORIZONTAL
|
|
722
|
+
layoutParams = LinearLayout.LayoutParams(
|
|
723
|
+
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
724
|
+
rowHeights[r]
|
|
725
|
+
).apply { setMargins(0, 0, 0, marginBetween) }
|
|
726
|
+
}
|
|
727
|
+
for (col in 0..1) {
|
|
728
|
+
val i = 2 * r + col
|
|
729
|
+
if (i >= pageCount) break
|
|
730
|
+
val frame = FrameLayout(context).apply {
|
|
731
|
+
layoutParams = LinearLayout.LayoutParams(
|
|
732
|
+
0,
|
|
733
|
+
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
734
|
+
1f
|
|
735
|
+
).apply { setMargins(0, 0, if (col == 0) 8 else 0, 0) }
|
|
736
|
+
setBackgroundColor(Color.LTGRAY)
|
|
737
|
+
}
|
|
738
|
+
val overlay = AnnotationOverlayView(context, i).apply {
|
|
739
|
+
layoutParams = FrameLayout.LayoutParams(
|
|
740
|
+
FrameLayout.LayoutParams.MATCH_PARENT,
|
|
741
|
+
FrameLayout.LayoutParams.MATCH_PARENT
|
|
742
|
+
)
|
|
743
|
+
}
|
|
744
|
+
frame.addView(overlay)
|
|
745
|
+
rowLayout.addView(frame)
|
|
746
|
+
overlayViews[i] = overlay
|
|
747
|
+
}
|
|
748
|
+
container.addView(rowLayout)
|
|
692
749
|
}
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
750
|
+
} else {
|
|
751
|
+
for (i in 0 until pageCount) {
|
|
752
|
+
val frame = FrameLayout(context).apply {
|
|
753
|
+
layoutParams = LinearLayout.LayoutParams(
|
|
754
|
+
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
755
|
+
pageHeights[i]
|
|
756
|
+
).apply { setMargins(0, 0, 0, marginBetween) }
|
|
757
|
+
setBackgroundColor(Color.LTGRAY)
|
|
758
|
+
}
|
|
759
|
+
val overlay = AnnotationOverlayView(context, i).apply {
|
|
760
|
+
layoutParams = FrameLayout.LayoutParams(
|
|
761
|
+
FrameLayout.LayoutParams.MATCH_PARENT,
|
|
762
|
+
FrameLayout.LayoutParams.MATCH_PARENT
|
|
763
|
+
)
|
|
764
|
+
}
|
|
765
|
+
frame.addView(overlay)
|
|
766
|
+
container.addView(frame)
|
|
767
|
+
overlayViews[i] = overlay
|
|
698
768
|
}
|
|
699
|
-
frame.addView(overlay)
|
|
700
|
-
container.addView(frame)
|
|
701
|
-
overlayViews[i] = overlay
|
|
702
769
|
}
|
|
703
770
|
}
|
|
704
771
|
|
|
705
772
|
private fun currentPageFromScroll(): Int {
|
|
706
773
|
if (pageHeights.isEmpty()) return 0
|
|
707
774
|
val scrollY = scrollView.scrollY
|
|
708
|
-
var offset = 0
|
|
709
775
|
val gap = marginBetweenPages()
|
|
776
|
+
if (isTwoUpMode() && rowHeights.isNotEmpty()) {
|
|
777
|
+
var offset = 0
|
|
778
|
+
for (r in rowHeights.indices) {
|
|
779
|
+
val rowH = rowHeights[r]
|
|
780
|
+
if (scrollY < offset + rowH / 2) return (2 * r).coerceAtMost(pageHeights.size - 1)
|
|
781
|
+
if (scrollY < offset + rowH) return (2 * r + 1).coerceAtMost(pageHeights.size - 1)
|
|
782
|
+
offset += rowH + gap
|
|
783
|
+
}
|
|
784
|
+
return (pageHeights.size - 1).coerceAtLeast(0)
|
|
785
|
+
}
|
|
786
|
+
var offset = 0
|
|
710
787
|
for (i in pageHeights.indices) {
|
|
711
788
|
if (scrollY < offset + pageHeights[i] / 2) return i
|
|
712
789
|
offset += pageHeights[i] + gap
|
|
@@ -723,7 +800,7 @@ class ExpoPdfReaderView(context: Context, appContext: AppContext) : ExpoView(con
|
|
|
723
800
|
for (i in pageViews.indices) {
|
|
724
801
|
if (i in from..to) continue
|
|
725
802
|
val iv = pageViews.getOrNull(i) ?: continue
|
|
726
|
-
val frame =
|
|
803
|
+
val frame = getFrameForPage(i) ?: continue
|
|
727
804
|
val bmp = (iv.drawable as? BitmapDrawable)?.bitmap
|
|
728
805
|
iv.setImageBitmap(null)
|
|
729
806
|
bmp?.recycle()
|
|
@@ -740,11 +817,10 @@ class ExpoPdfReaderView(context: Context, appContext: AppContext) : ExpoView(con
|
|
|
740
817
|
|
|
741
818
|
private fun renderPageToView(pageIndex: Int) {
|
|
742
819
|
val renderer = pdfRenderer ?: return
|
|
743
|
-
val frame =
|
|
744
|
-
// Frame always has overlay; only skip if we already have an ImageView for this page
|
|
820
|
+
val frame = getFrameForPage(pageIndex) ?: return
|
|
745
821
|
if (pageViews.getOrNull(pageIndex) != null) return
|
|
746
822
|
val page = renderer.openPage(pageIndex)
|
|
747
|
-
val w = width.coerceAtLeast(1)
|
|
823
|
+
val w = if (isTwoUpMode()) (width / 2).coerceAtLeast(1) else width.coerceAtLeast(1)
|
|
748
824
|
val h = pageHeights[pageIndex]
|
|
749
825
|
val bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
|
|
750
826
|
page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
|
|
@@ -766,18 +842,7 @@ class ExpoPdfReaderView(context: Context, appContext: AppContext) : ExpoView(con
|
|
|
766
842
|
|
|
767
843
|
private fun notifyPageChange() {
|
|
768
844
|
if (pageHeights.isEmpty()) return
|
|
769
|
-
val
|
|
770
|
-
var offset = 0
|
|
771
|
-
var detectedPage = 0
|
|
772
|
-
val gap = marginBetweenPages()
|
|
773
|
-
for (i in pageHeights.indices) {
|
|
774
|
-
if (scrollY < offset + pageHeights[i] / 2) {
|
|
775
|
-
detectedPage = i
|
|
776
|
-
break
|
|
777
|
-
}
|
|
778
|
-
offset += pageHeights[i] + gap
|
|
779
|
-
detectedPage = i
|
|
780
|
-
}
|
|
845
|
+
val detectedPage = currentPageFromScroll()
|
|
781
846
|
if (detectedPage != lastEmittedPageIndex) {
|
|
782
847
|
lastEmittedPageIndex = detectedPage
|
|
783
848
|
onPageChange(mapOf(
|
package/package.json
CHANGED