Skip to content

Commit f2e1a70

Browse files
committed
Add Android resolution limit to prevent crash on reder large bitmaps
1 parent 85e5478 commit f2e1a70

5 files changed

Lines changed: 43 additions & 9 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ For more details, see the [Sample Project](https://github.com/douglasjunior/reac
7878
|source|`string`||Path to a file stored on the device.|
7979
|distanceBetweenPages|`number`|`16`|Distance in `DPI` between pages.|
8080
|maxZoom|`number`|`5`|Max zoom scale.|
81+
|maxPageResolution|`number`|`2048`|(Android only) Max page resolution (width/height) when zooming. Defined to prevent Android crash when zooming too much: https://github.com/douglasjunior/react-native-pdf-renderer/issues/26 . |
8182
|singlePage|`boolean`|`false`|(Experimental) Renders only the first page without scroll. (useful for display thumbnail)|
8283
|onPageChange|`(current: number, total: number) => void`||Invoked on pages scroll.|
8384
|style|`StyleProp<ViewStyle>`||Styles to be applied to the native [view](https://reactnative.dev/docs/view-style-props).|

Sample/App.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ function App(): JSX.Element {
8282
style={{backgroundColor: 'red'}}
8383
source={source}
8484
distanceBetweenPages={16}
85-
maxZoom={5}
85+
maxZoom={20}
86+
maxPageResolution={2048}
8687
singlePage={singlePage}
8788
onPageChange={(current, total) => {
8889
console.log('onPageChange', {current, total});

android/src/main/java/com/github/douglasjunior/reactNativePdfRenderer/modules/PdfRendererRecyclerView.java

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public class PdfRendererRecyclerView extends RecyclerView {
6464
private final LayoutManager mLayoutManager;
6565
private boolean mRequestedLayout = false;
6666
private float mMaxZoom = 5;
67+
private float mMaxPageResolution;
6768
private float mDistanceBetweenPages = 0;
6869
private int mWidth;
6970
private int mHeight;
@@ -104,6 +105,10 @@ public void setDistanceBetweenPages(float distanceBetweenPages) {
104105
);
105106
}
106107

108+
public void setMaxPageResolution(float maxPageResolution) {
109+
this.mMaxPageResolution = maxPageResolution;
110+
}
111+
107112
public void setMaxZoom(float maxZoom) {
108113
this.mMaxZoom = maxZoom;
109114
}
@@ -153,7 +158,11 @@ private void dispatchPageChangeEvent() {
153158
protected void dispatchDraw(@NonNull Canvas canvas) {
154159
canvas.save();
155160
canvas.concat(mMatrix);
156-
super.dispatchDraw(canvas);
161+
try {
162+
super.dispatchDraw(canvas);
163+
} catch (Exception ex) {
164+
Log.e("PdfRendererRecyclerView", "Error dispatching draw", ex);
165+
}
157166
canvas.restore();
158167
}
159168

@@ -409,13 +418,30 @@ public ImageView getImageView() {
409418
return (ImageView) this.itemView;
410419
}
411420

412-
public void update(int position, float newZoom) {
413-
var page = mPdfRenderer.openPage(position);
414-
var bitmap = Bitmap.createBitmap(
415-
Math.round(page.getWidth() * newZoom),
416-
Math.round(page.getHeight() * newZoom),
421+
private @NonNull Bitmap createBitmap(float newZoom, int pageWidth, int pageHeight) {
422+
var scaledPageWidth = Math.round(pageWidth * newZoom);
423+
var scaledPageHeight = Math.round(pageHeight * newZoom);
424+
425+
float scalingFactor = Math.min(
426+
mMaxPageResolution / scaledPageWidth,
427+
mMaxPageResolution / scaledPageHeight
428+
);
429+
430+
float zoomFactor = Math.min(newZoom, scalingFactor);
431+
432+
return Bitmap.createBitmap(
433+
Math.round(scaledPageWidth * zoomFactor),
434+
Math.round(scaledPageHeight * zoomFactor),
417435
Bitmap.Config.ARGB_4444
418436
);
437+
}
438+
439+
public void update(int position, float newZoom) {
440+
var page = mPdfRenderer.openPage(position);
441+
var pageWidth = page.getWidth();
442+
var pageHeight = page.getHeight();
443+
var bitmap = createBitmap(newZoom, pageWidth, pageHeight);
444+
419445
page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
420446

421447
var imageView = getImageView();
@@ -428,7 +454,7 @@ public void update(int position, float newZoom) {
428454
lp.height = LayoutParams.MATCH_PARENT;
429455
lp.setMargins(0, 0, 0, 0);
430456
} else {
431-
lp.height = Math.round(((float) mWidth / (float) page.getWidth()) * (float) page.getHeight());
457+
lp.height = Math.round(((float) mWidth / (float) pageWidth) * (float) pageHeight);
432458
lp.setMargins(0, 0, 0, (int) mDistanceBetweenPages);
433459
}
434460
imageView.setLayoutParams(lp);

android/src/main/java/com/github/douglasjunior/reactNativePdfRenderer/modules/PdfRendererViewManager.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,10 @@ public void setDistanceBetweenPages(ViewGroup layout, @Nullable float distanceBe
109109
var recyclerView = (PdfRendererRecyclerView) layout.getChildAt(0);
110110
recyclerView.setDistanceBetweenPages(distanceBetweenPages);
111111
}
112+
113+
@ReactProp(name = "maxPageResolution")
114+
public void setMaxPageResolution(ViewGroup layout, @Nullable float maxPageResolution) {
115+
var recyclerView = (PdfRendererRecyclerView) layout.getChildAt(0);
116+
recyclerView.setMaxPageResolution(maxPageResolution);
117+
}
112118
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "react-native-pdf-renderer",
33
"displayName": "React-Native Pdf Renderer",
4-
"version": "1.3.2",
4+
"version": "1.4.0",
55
"description": "⚛ A zoomable, blazing fast, zero dependencies, pure native, typed PDF Renderer for Android and iOS.",
66
"main": "src",
77
"license": "MIT",

0 commit comments

Comments
 (0)