react-native-pdf-jsi 1.0.1
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.
- package/DoubleTapView.js +125 -0
- package/INTEGRATION_GUIDE.md +419 -0
- package/LICENSE +21 -0
- package/PdfManager.js +26 -0
- package/PdfPageView.js +53 -0
- package/PdfView.js +421 -0
- package/PdfViewFlatList.js +30 -0
- package/PinchZoomView.js +125 -0
- package/README.md +693 -0
- package/README_JSI.md +348 -0
- package/android/.gradle/5.6.1/fileChanges/last-build.bin +0 -0
- package/android/.gradle/5.6.1/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/5.6.1/gc.properties +0 -0
- package/android/.gradle/8.5/checksums/checksums.lock +0 -0
- package/android/.gradle/8.5/checksums/md5-checksums.bin +0 -0
- package/android/.gradle/8.5/checksums/sha1-checksums.bin +0 -0
- package/android/.gradle/8.5/dependencies-accessors/dependencies-accessors.lock +0 -0
- package/android/.gradle/8.5/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.5/executionHistory/executionHistory.lock +0 -0
- package/android/.gradle/8.5/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.5/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.5/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/build.gradle +198 -0
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/android/gradle.properties +2 -0
- package/android/gradlew +249 -0
- package/android/gradlew.bat +92 -0
- package/android/project.properties +12 -0
- package/android/src/main/AndroidManifest.xml +4 -0
- package/android/src/main/cpp/Android.mk +50 -0
- package/android/src/main/cpp/CMakeLists.txt +76 -0
- package/android/src/main/cpp/PDFJSI.cpp +190 -0
- package/android/src/main/cpp/PDFJSI.h +95 -0
- package/android/src/main/cpp/PDFJSIBridge.cpp +32 -0
- package/android/src/main/cpp/PDFJSIModule.cpp +31 -0
- package/android/src/main/java/org/wonday/pdf/EnhancedPdfJSIBridge.java +281 -0
- package/android/src/main/java/org/wonday/pdf/PDFJSIManager.java +317 -0
- package/android/src/main/java/org/wonday/pdf/PDFJSIModule.java +189 -0
- package/android/src/main/java/org/wonday/pdf/PdfManager.java +180 -0
- package/android/src/main/java/org/wonday/pdf/PdfView.java +505 -0
- package/android/src/main/java/org/wonday/pdf/RNPDFPackage.java +43 -0
- package/android/src/main/java/org/wonday/pdf/events/TopChangeEvent.java +26 -0
- package/android/src/main/jniLibs/arm64-v8a/libpdfjsi.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libpdfjsi.so +0 -0
- package/android/src/main/jniLibs/x86/libpdfjsi.so +0 -0
- package/android/src/main/jniLibs/x86_64/libpdfjsi.so +0 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNPDFPdfViewManagerDelegate.java +92 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNPDFPdfViewManagerInterface.java +35 -0
- package/fabric/RNPDFPdfNativeComponent.js +48 -0
- package/index.d.ts +72 -0
- package/index.js +603 -0
- package/index.js.flow +67 -0
- package/ios/RNPDFPdf/PdfManager.h +23 -0
- package/ios/RNPDFPdf/PdfManager.mm +152 -0
- package/ios/RNPDFPdf/RNPDFPdfPageView.h +21 -0
- package/ios/RNPDFPdf/RNPDFPdfPageView.mm +185 -0
- package/ios/RNPDFPdf/RNPDFPdfPageViewManager.h +18 -0
- package/ios/RNPDFPdf/RNPDFPdfPageViewManager.mm +30 -0
- package/ios/RNPDFPdf/RNPDFPdfView.h +63 -0
- package/ios/RNPDFPdf/RNPDFPdfView.mm +1092 -0
- package/ios/RNPDFPdf/RNPDFPdfViewManager.h +18 -0
- package/ios/RNPDFPdf/RNPDFPdfViewManager.mm +68 -0
- package/ios/RNPDFPdf.xcodeproj/project.pbxproj +321 -0
- package/package.json +78 -0
- package/react-native-pdf.podspec +31 -0
- package/src/EnhancedPdfView.js +362 -0
- package/src/PDFJSI.js +519 -0
- package/src/examples/PDFJSIExample.js +296 -0
- package/src/hooks/usePDFJSI.js +346 -0
- package/src/index.js +32 -0
- package/windows/RCTPdf/PropertySheet.props +16 -0
- package/windows/RCTPdf/RCTPdf.def +3 -0
- package/windows/RCTPdf/RCTPdf.vcxproj +180 -0
- package/windows/RCTPdf/RCTPdf.vcxproj.filters +38 -0
- package/windows/RCTPdf/RCTPdfControl.cpp +667 -0
- package/windows/RCTPdf/RCTPdfControl.h +119 -0
- package/windows/RCTPdf/RCTPdfControl.idl +10 -0
- package/windows/RCTPdf/RCTPdfControl.xaml +33 -0
- package/windows/RCTPdf/RCTPdfViewManager.cpp +69 -0
- package/windows/RCTPdf/RCTPdfViewManager.h +51 -0
- package/windows/RCTPdf/ReactPackageProvider.cpp +15 -0
- package/windows/RCTPdf/ReactPackageProvider.h +16 -0
- package/windows/RCTPdf/ReactPackageProvider.idl +9 -0
- package/windows/RCTPdf/packages.config +4 -0
- package/windows/RCTPdf/pch.cpp +1 -0
- package/windows/RCTPdf/pch.h +31 -0
- package/windows/README.md +21 -0
|
@@ -0,0 +1,505 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2017-present, Wonday (@wonday.org)
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT-style license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
package org.wonday.pdf;
|
|
10
|
+
|
|
11
|
+
import java.io.File;
|
|
12
|
+
|
|
13
|
+
import android.content.ContentResolver;
|
|
14
|
+
import android.content.Context;
|
|
15
|
+
import android.util.SizeF;
|
|
16
|
+
import android.view.View;
|
|
17
|
+
import android.view.ViewGroup;
|
|
18
|
+
import android.util.Log;
|
|
19
|
+
import android.net.Uri;
|
|
20
|
+
import android.util.AttributeSet;
|
|
21
|
+
import android.view.MotionEvent;
|
|
22
|
+
import android.graphics.Canvas;
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
import com.facebook.react.uimanager.ThemedReactContext;
|
|
26
|
+
import com.facebook.react.uimanager.UIManagerHelper;
|
|
27
|
+
import com.github.barteksc.pdfviewer.PDFView;
|
|
28
|
+
import com.github.barteksc.pdfviewer.listener.OnPageChangeListener;
|
|
29
|
+
import com.github.barteksc.pdfviewer.listener.OnLoadCompleteListener;
|
|
30
|
+
import com.github.barteksc.pdfviewer.listener.OnErrorListener;
|
|
31
|
+
import com.github.barteksc.pdfviewer.listener.OnTapListener;
|
|
32
|
+
import com.github.barteksc.pdfviewer.listener.OnDrawListener;
|
|
33
|
+
import com.github.barteksc.pdfviewer.listener.OnPageScrollListener;
|
|
34
|
+
import com.github.barteksc.pdfviewer.util.FitPolicy;
|
|
35
|
+
import com.github.barteksc.pdfviewer.util.Constants;
|
|
36
|
+
import com.github.barteksc.pdfviewer.link.LinkHandler;
|
|
37
|
+
import com.github.barteksc.pdfviewer.model.LinkTapEvent;
|
|
38
|
+
|
|
39
|
+
import com.facebook.react.bridge.ReactContext;
|
|
40
|
+
import com.facebook.react.bridge.Arguments;
|
|
41
|
+
import com.facebook.react.bridge.WritableMap;
|
|
42
|
+
import com.facebook.react.bridge.ReactContext;
|
|
43
|
+
import com.facebook.react.uimanager.UIManagerModule;
|
|
44
|
+
import com.facebook.react.uimanager.events.EventDispatcher;
|
|
45
|
+
import com.facebook.react.uimanager.events.Event;
|
|
46
|
+
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
import static java.lang.String.format;
|
|
50
|
+
|
|
51
|
+
import java.io.FileNotFoundException;
|
|
52
|
+
import java.io.InputStream;
|
|
53
|
+
|
|
54
|
+
import com.google.gson.Gson;
|
|
55
|
+
|
|
56
|
+
import org.wonday.pdf.events.TopChangeEvent;
|
|
57
|
+
|
|
58
|
+
public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompleteListener,OnErrorListener,OnTapListener,OnDrawListener,OnPageScrollListener, LinkHandler {
|
|
59
|
+
private int page = 1; // start from 1
|
|
60
|
+
private boolean horizontal = false;
|
|
61
|
+
private float scale = 1;
|
|
62
|
+
private float minScale = 1;
|
|
63
|
+
private float maxScale = 3;
|
|
64
|
+
private String path;
|
|
65
|
+
private int spacing = 10;
|
|
66
|
+
private String password = "";
|
|
67
|
+
private boolean enableAntialiasing = true;
|
|
68
|
+
private boolean enableAnnotationRendering = true;
|
|
69
|
+
private boolean enableDoubleTapZoom = true;
|
|
70
|
+
|
|
71
|
+
private boolean enablePaging = false;
|
|
72
|
+
private boolean autoSpacing = false;
|
|
73
|
+
private boolean pageFling = false;
|
|
74
|
+
private boolean pageSnap = false;
|
|
75
|
+
private FitPolicy fitPolicy = FitPolicy.WIDTH;
|
|
76
|
+
private boolean singlePage = false;
|
|
77
|
+
private boolean scrollEnabled = true;
|
|
78
|
+
|
|
79
|
+
private float originalWidth = 0;
|
|
80
|
+
private float lastPageWidth = 0;
|
|
81
|
+
private float lastPageHeight = 0;
|
|
82
|
+
|
|
83
|
+
// used to store the parameters for `super.onSizeChanged`
|
|
84
|
+
private int oldW = 0;
|
|
85
|
+
private int oldH = 0;
|
|
86
|
+
|
|
87
|
+
public PdfView(Context context, AttributeSet set){
|
|
88
|
+
super(context, set);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@Override
|
|
92
|
+
public void onPageChanged(int page, int numberOfPages) {
|
|
93
|
+
// pdf lib page start from 0, convert it to our page (start from 1)
|
|
94
|
+
page = page+1;
|
|
95
|
+
this.page = page;
|
|
96
|
+
showLog(format("%s %s / %s", path, page, numberOfPages));
|
|
97
|
+
|
|
98
|
+
WritableMap event = Arguments.createMap();
|
|
99
|
+
event.putString("message", "pageChanged|"+page+"|"+numberOfPages);
|
|
100
|
+
|
|
101
|
+
ThemedReactContext context = (ThemedReactContext) getContext();
|
|
102
|
+
EventDispatcher dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, getId());
|
|
103
|
+
int surfaceId = UIManagerHelper.getSurfaceId(this);
|
|
104
|
+
|
|
105
|
+
TopChangeEvent tce = new TopChangeEvent(surfaceId, getId(), event);
|
|
106
|
+
|
|
107
|
+
if (dispatcher != null) {
|
|
108
|
+
dispatcher.dispatchEvent(tce);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ReactContext reactContext = (ReactContext)this.getContext();
|
|
112
|
+
// reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
|
|
113
|
+
// this.getId(),
|
|
114
|
+
// "topChange",
|
|
115
|
+
// event
|
|
116
|
+
// );
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// In some cases Yoga (I think) will measure the view only along one axis first, resulting in
|
|
120
|
+
// onSizeChanged being called with either w or h set to zero. This in turn starts the rendering
|
|
121
|
+
// of the pdf under the hood with one dimension being set to zero and the follow-up call to
|
|
122
|
+
// onSizeChanged with the correct dimensions doesn't have any effect on the already started process.
|
|
123
|
+
// The offending class is DecodingAsyncTask, which tries to get width and height of the pdfView
|
|
124
|
+
// in the constructor, and is created as soon as the measurement is complete, which in some cases
|
|
125
|
+
// may be incomplete as described above.
|
|
126
|
+
// By delaying calling super.onSizeChanged until the size in both dimensions is correct we are able
|
|
127
|
+
// to prevent this from happening.
|
|
128
|
+
//
|
|
129
|
+
// I'm not sure whether the second condition is necessary, but without it, it would be impossible
|
|
130
|
+
// to set the dimensions to zero after first measurement.
|
|
131
|
+
@Override
|
|
132
|
+
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
|
133
|
+
if ((w > 0 && h > 0) || this.oldW > 0 || this.oldH > 0) {
|
|
134
|
+
super.onSizeChanged(w, h, this.oldW, this.oldH);
|
|
135
|
+
this.oldW = w;
|
|
136
|
+
this.oldH = h;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@Override
|
|
141
|
+
public void loadComplete(int numberOfPages) {
|
|
142
|
+
SizeF pageSize = getPageSize(0);
|
|
143
|
+
float width = pageSize.getWidth();
|
|
144
|
+
float height = pageSize.getHeight();
|
|
145
|
+
|
|
146
|
+
this.zoomTo(this.scale);
|
|
147
|
+
WritableMap event = Arguments.createMap();
|
|
148
|
+
|
|
149
|
+
//create a new json Object for the TableOfContents
|
|
150
|
+
Gson gson = new Gson();
|
|
151
|
+
event.putString("message", "loadComplete|"+numberOfPages+"|"+width+"|"+height+"|"+gson.toJson(this.getTableOfContents()));
|
|
152
|
+
|
|
153
|
+
ThemedReactContext context = (ThemedReactContext) getContext();
|
|
154
|
+
EventDispatcher dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, getId());
|
|
155
|
+
int surfaceId = UIManagerHelper.getSurfaceId(this);
|
|
156
|
+
|
|
157
|
+
TopChangeEvent tce = new TopChangeEvent(surfaceId, getId(), event);
|
|
158
|
+
|
|
159
|
+
if (dispatcher != null) {
|
|
160
|
+
dispatcher.dispatchEvent(tce);
|
|
161
|
+
}
|
|
162
|
+
// ReactContext reactContext = (ReactContext)this.getContext();
|
|
163
|
+
// reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
|
|
164
|
+
// this.getId(),
|
|
165
|
+
// "topChange",
|
|
166
|
+
// event
|
|
167
|
+
// );
|
|
168
|
+
|
|
169
|
+
//Log.e("ReactNative", gson.toJson(this.getTableOfContents()));
|
|
170
|
+
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
@Override
|
|
174
|
+
public void onError(Throwable t){
|
|
175
|
+
WritableMap event = Arguments.createMap();
|
|
176
|
+
if (t.getMessage().contains("Password required or incorrect password")) {
|
|
177
|
+
event.putString("message", "error|Password required or incorrect password.");
|
|
178
|
+
} else {
|
|
179
|
+
event.putString("message", "error|"+t.getMessage());
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
ThemedReactContext context = (ThemedReactContext) getContext();
|
|
183
|
+
EventDispatcher dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, getId());
|
|
184
|
+
int surfaceId = UIManagerHelper.getSurfaceId(this);
|
|
185
|
+
|
|
186
|
+
TopChangeEvent tce = new TopChangeEvent(surfaceId, getId(), event);
|
|
187
|
+
|
|
188
|
+
if (dispatcher != null) {
|
|
189
|
+
dispatcher.dispatchEvent(tce);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// ReactContext reactContext = (ReactContext)this.getContext();
|
|
193
|
+
// reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
|
|
194
|
+
// this.getId(),
|
|
195
|
+
// "topChange",
|
|
196
|
+
// event
|
|
197
|
+
// );
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
@Override
|
|
201
|
+
public void onPageScrolled(int page, float positionOffset){
|
|
202
|
+
|
|
203
|
+
// maybe change by other instance, restore zoom setting
|
|
204
|
+
Constants.Pinch.MINIMUM_ZOOM = this.minScale;
|
|
205
|
+
Constants.Pinch.MAXIMUM_ZOOM = this.maxScale;
|
|
206
|
+
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
@Override
|
|
210
|
+
public boolean onTap(MotionEvent e){
|
|
211
|
+
|
|
212
|
+
// maybe change by other instance, restore zoom setting
|
|
213
|
+
//Constants.Pinch.MINIMUM_ZOOM = this.minScale;
|
|
214
|
+
//Constants.Pinch.MAXIMUM_ZOOM = this.maxScale;
|
|
215
|
+
|
|
216
|
+
WritableMap event = Arguments.createMap();
|
|
217
|
+
event.putString("message", "pageSingleTap|"+page+"|"+e.getX()+"|"+e.getY());
|
|
218
|
+
|
|
219
|
+
ThemedReactContext context = (ThemedReactContext) getContext();
|
|
220
|
+
EventDispatcher dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, getId());
|
|
221
|
+
int surfaceId = UIManagerHelper.getSurfaceId(this);
|
|
222
|
+
|
|
223
|
+
TopChangeEvent tce = new TopChangeEvent(surfaceId, getId(), event);
|
|
224
|
+
|
|
225
|
+
if (dispatcher != null) {
|
|
226
|
+
dispatcher.dispatchEvent(tce);
|
|
227
|
+
}
|
|
228
|
+
// ReactContext reactContext = (ReactContext)this.getContext();
|
|
229
|
+
// reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
|
|
230
|
+
// this.getId(),
|
|
231
|
+
// "topChange",
|
|
232
|
+
// event
|
|
233
|
+
// );
|
|
234
|
+
|
|
235
|
+
// process as tap
|
|
236
|
+
return true;
|
|
237
|
+
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
@Override
|
|
241
|
+
public void onLayerDrawn(Canvas canvas, float pageWidth, float pageHeight, int displayedPage){
|
|
242
|
+
if (originalWidth == 0) {
|
|
243
|
+
originalWidth = pageWidth;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (lastPageWidth>0 && lastPageHeight>0 && (pageWidth!=lastPageWidth || pageHeight!=lastPageHeight)) {
|
|
247
|
+
// maybe change by other instance, restore zoom setting
|
|
248
|
+
Constants.Pinch.MINIMUM_ZOOM = this.minScale;
|
|
249
|
+
Constants.Pinch.MAXIMUM_ZOOM = this.maxScale;
|
|
250
|
+
|
|
251
|
+
WritableMap event = Arguments.createMap();
|
|
252
|
+
event.putString("message", "scaleChanged|"+(pageWidth/originalWidth));
|
|
253
|
+
ThemedReactContext context = (ThemedReactContext) getContext();
|
|
254
|
+
EventDispatcher dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, getId());
|
|
255
|
+
int surfaceId = UIManagerHelper.getSurfaceId(this);
|
|
256
|
+
|
|
257
|
+
TopChangeEvent tce = new TopChangeEvent(surfaceId, getId(), event);
|
|
258
|
+
|
|
259
|
+
if (dispatcher != null) {
|
|
260
|
+
dispatcher.dispatchEvent(tce);
|
|
261
|
+
}
|
|
262
|
+
// ReactContext reactContext = (ReactContext)this.getContext();
|
|
263
|
+
// reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
|
|
264
|
+
// this.getId(),
|
|
265
|
+
// "topChange",
|
|
266
|
+
// event
|
|
267
|
+
// );
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
lastPageWidth = pageWidth;
|
|
271
|
+
lastPageHeight = pageHeight;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
@Override
|
|
275
|
+
protected void onAttachedToWindow() {
|
|
276
|
+
super.onAttachedToWindow();
|
|
277
|
+
if (this.isRecycled())
|
|
278
|
+
this.drawPdf();
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
public void drawPdf() {
|
|
282
|
+
showLog(format("drawPdf path:%s %s", this.path, this.page));
|
|
283
|
+
|
|
284
|
+
if (this.path != null){
|
|
285
|
+
|
|
286
|
+
// set scale
|
|
287
|
+
this.setMinZoom(this.minScale);
|
|
288
|
+
this.setMaxZoom(this.maxScale);
|
|
289
|
+
this.setMidZoom((this.maxScale+this.minScale)/2);
|
|
290
|
+
Constants.Pinch.MINIMUM_ZOOM = this.minScale;
|
|
291
|
+
Constants.Pinch.MAXIMUM_ZOOM = this.maxScale;
|
|
292
|
+
|
|
293
|
+
Configurator configurator;
|
|
294
|
+
|
|
295
|
+
if (this.path.startsWith("content://")) {
|
|
296
|
+
ContentResolver contentResolver = getContext().getContentResolver();
|
|
297
|
+
InputStream inputStream = null;
|
|
298
|
+
Uri uri = Uri.parse(this.path);
|
|
299
|
+
try {
|
|
300
|
+
inputStream = contentResolver.openInputStream(uri);
|
|
301
|
+
} catch (FileNotFoundException e) {
|
|
302
|
+
throw new RuntimeException(e.getMessage());
|
|
303
|
+
}
|
|
304
|
+
configurator = this.fromStream(inputStream);
|
|
305
|
+
} else {
|
|
306
|
+
configurator = this.fromUri(getURI(this.path));
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
configurator.defaultPage(this.page-1)
|
|
310
|
+
.swipeHorizontal(this.horizontal)
|
|
311
|
+
.onPageChange(this)
|
|
312
|
+
.onLoad(this)
|
|
313
|
+
.onError(this)
|
|
314
|
+
.onDraw(this)
|
|
315
|
+
.onPageScroll(this)
|
|
316
|
+
.spacing(this.spacing)
|
|
317
|
+
.password(this.password)
|
|
318
|
+
.enableAntialiasing(this.enableAntialiasing)
|
|
319
|
+
.pageFitPolicy(this.fitPolicy)
|
|
320
|
+
.pageSnap(this.pageSnap)
|
|
321
|
+
.autoSpacing(this.autoSpacing)
|
|
322
|
+
.pageFling(this.pageFling)
|
|
323
|
+
.enableSwipe(!this.singlePage && this.scrollEnabled)
|
|
324
|
+
.enableDoubletap(!this.singlePage && this.enableDoubleTapZoom)
|
|
325
|
+
.enableAnnotationRendering(this.enableAnnotationRendering)
|
|
326
|
+
.linkHandler(this);
|
|
327
|
+
|
|
328
|
+
if (this.singlePage) {
|
|
329
|
+
configurator.pages(this.page-1);
|
|
330
|
+
setTouchesEnabled(false);
|
|
331
|
+
} else {
|
|
332
|
+
configurator.onTap(this);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
configurator.load();
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
public void setEnableDoubleTapZoom(boolean enableDoubleTapZoom) {
|
|
340
|
+
this.enableDoubleTapZoom = enableDoubleTapZoom;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
public void setPath(String path) {
|
|
344
|
+
this.path = path;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// page start from 1
|
|
348
|
+
public void setPage(int page) {
|
|
349
|
+
this.page = page>1?page:1;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
public void setScale(float scale) {
|
|
353
|
+
this.scale = scale;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
public void setMinScale(float minScale) {
|
|
357
|
+
this.minScale = minScale;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
public void setMaxScale(float maxScale) {
|
|
361
|
+
this.maxScale = maxScale;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
public void setHorizontal(boolean horizontal) {
|
|
365
|
+
this.horizontal = horizontal;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
public void setScrollEnabled(boolean scrollEnabled) {
|
|
369
|
+
this.scrollEnabled = scrollEnabled;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
public void setSpacing(int spacing) {
|
|
373
|
+
this.spacing = spacing;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
public void setPassword(String password) {
|
|
377
|
+
this.password = password;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
public void setEnableAntialiasing(boolean enableAntialiasing) {
|
|
381
|
+
this.enableAntialiasing = enableAntialiasing;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
public void setEnableAnnotationRendering(boolean enableAnnotationRendering) {
|
|
385
|
+
this.enableAnnotationRendering = enableAnnotationRendering;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
public void setEnablePaging(boolean enablePaging) {
|
|
389
|
+
this.enablePaging = enablePaging;
|
|
390
|
+
if (this.enablePaging) {
|
|
391
|
+
this.autoSpacing = true;
|
|
392
|
+
this.pageFling = true;
|
|
393
|
+
this.pageSnap = true;
|
|
394
|
+
} else {
|
|
395
|
+
this.autoSpacing = false;
|
|
396
|
+
this.pageFling = false;
|
|
397
|
+
this.pageSnap = false;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
public void setFitPolicy(int fitPolicy) {
|
|
402
|
+
switch(fitPolicy){
|
|
403
|
+
case 0:
|
|
404
|
+
this.fitPolicy = FitPolicy.WIDTH;
|
|
405
|
+
break;
|
|
406
|
+
case 1:
|
|
407
|
+
this.fitPolicy = FitPolicy.HEIGHT;
|
|
408
|
+
break;
|
|
409
|
+
case 2:
|
|
410
|
+
default:
|
|
411
|
+
{
|
|
412
|
+
this.fitPolicy = FitPolicy.BOTH;
|
|
413
|
+
break;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
public void setSinglePage(boolean singlePage) {
|
|
420
|
+
this.singlePage = singlePage;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* @see https://github.com/barteksc/AndroidPdfViewer/blob/master/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/DefaultLinkHandler.java
|
|
425
|
+
*/
|
|
426
|
+
public void handleLinkEvent(LinkTapEvent event) {
|
|
427
|
+
String uri = event.getLink().getUri();
|
|
428
|
+
Integer page = event.getLink().getDestPageIdx();
|
|
429
|
+
if (uri != null && !uri.isEmpty()) {
|
|
430
|
+
handleUri(uri);
|
|
431
|
+
} else if (page != null) {
|
|
432
|
+
handlePage(page);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* @see https://github.com/barteksc/AndroidPdfViewer/blob/master/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/DefaultLinkHandler.java
|
|
438
|
+
*/
|
|
439
|
+
private void handleUri(String uri) {
|
|
440
|
+
WritableMap event = Arguments.createMap();
|
|
441
|
+
event.putString("message", "linkPressed|"+uri);
|
|
442
|
+
|
|
443
|
+
ThemedReactContext context = (ThemedReactContext) getContext();
|
|
444
|
+
EventDispatcher dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, getId());
|
|
445
|
+
int surfaceId = UIManagerHelper.getSurfaceId(this);
|
|
446
|
+
|
|
447
|
+
TopChangeEvent tce = new TopChangeEvent(surfaceId, getId(), event);
|
|
448
|
+
|
|
449
|
+
if (dispatcher != null) {
|
|
450
|
+
dispatcher.dispatchEvent(tce);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// ReactContext reactContext = (ReactContext)this.getContext();
|
|
454
|
+
// reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
|
|
455
|
+
// this.getId(),
|
|
456
|
+
// "topChange",
|
|
457
|
+
// event
|
|
458
|
+
// );
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* @see https://github.com/barteksc/AndroidPdfViewer/blob/master/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/DefaultLinkHandler.java
|
|
463
|
+
*/
|
|
464
|
+
private void handlePage(int page) {
|
|
465
|
+
this.jumpTo(page);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
private void showLog(final String str) {
|
|
469
|
+
Log.d("PdfView", str);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
private Uri getURI(final String uri) {
|
|
473
|
+
Uri parsed = Uri.parse(uri);
|
|
474
|
+
|
|
475
|
+
if (parsed.getScheme() == null || parsed.getScheme().isEmpty()) {
|
|
476
|
+
return Uri.fromFile(new File(uri));
|
|
477
|
+
}
|
|
478
|
+
return parsed;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
private void setTouchesEnabled(final boolean enabled) {
|
|
482
|
+
setTouchesEnabled(this, enabled);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
private static void setTouchesEnabled(View v, final boolean enabled) {
|
|
486
|
+
if (enabled) {
|
|
487
|
+
v.setOnTouchListener(null);
|
|
488
|
+
} else {
|
|
489
|
+
v.setOnTouchListener(new View.OnTouchListener() {
|
|
490
|
+
@Override
|
|
491
|
+
public boolean onTouch(View v, MotionEvent event) {
|
|
492
|
+
return true;
|
|
493
|
+
}
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
if (v instanceof ViewGroup) {
|
|
498
|
+
ViewGroup vg = (ViewGroup) v;
|
|
499
|
+
for (int i = 0; i < vg.getChildCount(); i++) {
|
|
500
|
+
View child = vg.getChildAt(i);
|
|
501
|
+
setTouchesEnabled(child, enabled);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2017-present, Wonday (@wonday.org)
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT-style license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
package org.wonday.pdf;
|
|
10
|
+
|
|
11
|
+
import java.util.Collections;
|
|
12
|
+
import java.util.List;
|
|
13
|
+
import java.util.ArrayList;
|
|
14
|
+
|
|
15
|
+
import com.facebook.react.ReactPackage;
|
|
16
|
+
import com.facebook.react.bridge.JavaScriptModule;
|
|
17
|
+
import com.facebook.react.bridge.NativeModule;
|
|
18
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
19
|
+
import com.facebook.react.uimanager.ViewManager;
|
|
20
|
+
|
|
21
|
+
public class RNPDFPackage implements ReactPackage {
|
|
22
|
+
|
|
23
|
+
@Override
|
|
24
|
+
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
|
25
|
+
List<NativeModule> modules = new ArrayList<>();
|
|
26
|
+
// Add JSI modules for enhanced PDF performance
|
|
27
|
+
modules.add(new PDFJSIManager(reactContext));
|
|
28
|
+
modules.add(new EnhancedPdfJSIBridge(reactContext));
|
|
29
|
+
return modules;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Deprecated as of RN 0.47.0
|
|
33
|
+
public List<Class<? extends JavaScriptModule>> createJSModules() {
|
|
34
|
+
return Collections.emptyList();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@Override
|
|
38
|
+
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
|
39
|
+
List<ViewManager> modules = new ArrayList<>();
|
|
40
|
+
modules.add(new PdfManager(reactContext));
|
|
41
|
+
return modules;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
package org.wonday.pdf.events;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.Nullable;
|
|
4
|
+
|
|
5
|
+
import com.facebook.react.bridge.WritableMap;
|
|
6
|
+
import com.facebook.react.uimanager.events.Event;
|
|
7
|
+
|
|
8
|
+
public class TopChangeEvent extends Event<TopChangeEvent> {
|
|
9
|
+
private WritableMap eventData;
|
|
10
|
+
|
|
11
|
+
public TopChangeEvent(int surfaceId, int viewTag, WritableMap data) {
|
|
12
|
+
super(surfaceId, viewTag);
|
|
13
|
+
eventData = data;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@Override
|
|
17
|
+
public String getEventName() {
|
|
18
|
+
return "topChange";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@Nullable
|
|
22
|
+
@Override
|
|
23
|
+
protected WritableMap getEventData() {
|
|
24
|
+
return eventData;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/src/paper/java/com/facebook/react/viewmanagers/RNPDFPdfViewManagerDelegate.java
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
|
3
|
+
*
|
|
4
|
+
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
|
5
|
+
* once the code is regenerated.
|
|
6
|
+
*
|
|
7
|
+
* @generated by codegen project: GeneratePropsJavaDelegate.js
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
package com.facebook.react.viewmanagers;
|
|
11
|
+
|
|
12
|
+
import android.view.View;
|
|
13
|
+
import androidx.annotation.Nullable;
|
|
14
|
+
import com.facebook.react.bridge.ReadableArray;
|
|
15
|
+
import com.facebook.react.uimanager.BaseViewManagerDelegate;
|
|
16
|
+
import com.facebook.react.uimanager.BaseViewManager;
|
|
17
|
+
import com.facebook.react.uimanager.LayoutShadowNode;
|
|
18
|
+
|
|
19
|
+
public class RNPDFPdfViewManagerDelegate<T extends View, U extends BaseViewManager<T, ? extends LayoutShadowNode> & RNPDFPdfViewManagerInterface<T>> extends BaseViewManagerDelegate<T, U> {
|
|
20
|
+
public RNPDFPdfViewManagerDelegate(U viewManager) {
|
|
21
|
+
super(viewManager);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public void setProperty(T view, String propName, @Nullable Object value) {
|
|
25
|
+
switch (propName) {
|
|
26
|
+
case "path":
|
|
27
|
+
mViewManager.setPath(view, value == null ? null : (String) value);
|
|
28
|
+
break;
|
|
29
|
+
case "page":
|
|
30
|
+
mViewManager.setPage(view, value == null ? 0 : ((Double) value).intValue());
|
|
31
|
+
break;
|
|
32
|
+
case "scale":
|
|
33
|
+
mViewManager.setScale(view, value == null ? 0f : ((Double) value).floatValue());
|
|
34
|
+
break;
|
|
35
|
+
case "minScale":
|
|
36
|
+
mViewManager.setMinScale(view, value == null ? 0f : ((Double) value).floatValue());
|
|
37
|
+
break;
|
|
38
|
+
case "maxScale":
|
|
39
|
+
mViewManager.setMaxScale(view, value == null ? 0f : ((Double) value).floatValue());
|
|
40
|
+
break;
|
|
41
|
+
case "horizontal":
|
|
42
|
+
mViewManager.setHorizontal(view, value == null ? false : (boolean) value);
|
|
43
|
+
break;
|
|
44
|
+
case "showsHorizontalScrollIndicator":
|
|
45
|
+
mViewManager.setShowsHorizontalScrollIndicator(view, value == null ? false : (boolean) value);
|
|
46
|
+
break;
|
|
47
|
+
case "showsVerticalScrollIndicator":
|
|
48
|
+
mViewManager.setShowsVerticalScrollIndicator(view, value == null ? false : (boolean) value);
|
|
49
|
+
break;
|
|
50
|
+
case "scrollEnabled":
|
|
51
|
+
mViewManager.setScrollEnabled(view, value == null ? false : (boolean) value);
|
|
52
|
+
break;
|
|
53
|
+
case "enablePaging":
|
|
54
|
+
mViewManager.setEnablePaging(view, value == null ? false : (boolean) value);
|
|
55
|
+
break;
|
|
56
|
+
case "enableRTL":
|
|
57
|
+
mViewManager.setEnableRTL(view, value == null ? false : (boolean) value);
|
|
58
|
+
break;
|
|
59
|
+
case "enableAnnotationRendering":
|
|
60
|
+
mViewManager.setEnableAnnotationRendering(view, value == null ? false : (boolean) value);
|
|
61
|
+
break;
|
|
62
|
+
case "enableDoubleTapZoom":
|
|
63
|
+
mViewManager.setEnableDoubleTapZoom(view, value == null ? false : (boolean) value);
|
|
64
|
+
break;
|
|
65
|
+
case "enableAntialiasing":
|
|
66
|
+
mViewManager.setEnableAntialiasing(view, value == null ? false : (boolean) value);
|
|
67
|
+
break;
|
|
68
|
+
case "fitPolicy":
|
|
69
|
+
mViewManager.setFitPolicy(view, value == null ? 0 : ((Double) value).intValue());
|
|
70
|
+
break;
|
|
71
|
+
case "spacing":
|
|
72
|
+
mViewManager.setSpacing(view, value == null ? 0 : ((Double) value).intValue());
|
|
73
|
+
break;
|
|
74
|
+
case "password":
|
|
75
|
+
mViewManager.setPassword(view, value == null ? null : (String) value);
|
|
76
|
+
break;
|
|
77
|
+
case "singlePage":
|
|
78
|
+
mViewManager.setSinglePage(view, value == null ? false : (boolean) value);
|
|
79
|
+
break;
|
|
80
|
+
default:
|
|
81
|
+
super.setProperty(view, propName, value);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
public void receiveCommand(T view, String commandName, ReadableArray args) {
|
|
86
|
+
switch (commandName) {
|
|
87
|
+
case "setNativePage":
|
|
88
|
+
mViewManager.setNativePage(view, args.getInt(0));
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|