@amafil/react-native-pdf-toolkit 1.1.3 → 1.1.17

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.
Files changed (52) hide show
  1. package/README.md +0 -57
  2. package/android/.gradle/8.5/executionHistory/executionHistory.bin +0 -0
  3. package/android/.gradle/8.5/executionHistory/executionHistory.lock +0 -0
  4. package/android/.gradle/8.5/fileHashes/fileHashes.bin +0 -0
  5. package/android/.gradle/8.5/fileHashes/fileHashes.lock +0 -0
  6. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  7. package/android/.gradle/file-system.probe +0 -0
  8. package/android/build/.transforms/2892d280277a194daf04e3af971b529e/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/facebook/react/viewmanagers/RNPDFPdfViewManagerDelegate.dex +0 -0
  9. package/android/build/.transforms/2892d280277a194daf04e3af971b529e/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/facebook/react/viewmanagers/RNPDFPdfViewManagerInterface.dex +0 -0
  10. package/android/build/.transforms/2892d280277a194daf04e3af971b529e/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/org/wonday/pdf/PdfManager.dex +0 -0
  11. package/android/build/.transforms/2892d280277a194daf04e3af971b529e/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/org/wonday/pdf/PdfView$1.dex +0 -0
  12. package/android/build/.transforms/2892d280277a194daf04e3af971b529e/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/org/wonday/pdf/PdfView$2.dex +0 -0
  13. package/android/build/.transforms/2892d280277a194daf04e3af971b529e/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/org/wonday/pdf/PdfView$3.dex +0 -0
  14. package/android/build/.transforms/2892d280277a194daf04e3af971b529e/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/org/wonday/pdf/PdfView.dex +0 -0
  15. package/android/build/.transforms/2892d280277a194daf04e3af971b529e/transformed/bundleLibRuntimeToDirDebug/desugar_graph.bin +0 -0
  16. package/android/build/.transforms/e40f3b884607647e8beb6dabe8165962/transformed/classes/classes_dex/classes.dex +0 -0
  17. package/android/build/generated/source/codegen/java/com/facebook/react/viewmanagers/RNPDFPdfViewManagerDelegate.java +0 -30
  18. package/android/build/generated/source/codegen/java/com/facebook/react/viewmanagers/RNPDFPdfViewManagerInterface.java +0 -10
  19. package/android/build/generated/source/codegen/jni/react/renderer/components/rnpdf/Props.cpp +0 -35
  20. package/android/build/generated/source/codegen/jni/react/renderer/components/rnpdf/Props.h +0 -7
  21. package/android/build/generated/source/codegen/schema.json +1 -1
  22. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  23. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
  24. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/facebook/react/viewmanagers/RNPDFPdfViewManagerDelegate.class +0 -0
  25. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/facebook/react/viewmanagers/RNPDFPdfViewManagerInterface.class +0 -0
  26. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/org/wonday/pdf/PdfManager.class +0 -0
  27. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/org/wonday/pdf/PdfView$1.class +0 -0
  28. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/org/wonday/pdf/PdfView$2.class +0 -0
  29. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/org/wonday/pdf/PdfView$3.class +0 -0
  30. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/org/wonday/pdf/PdfView.class +0 -0
  31. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/facebook/react/viewmanagers/RNPDFPdfViewManagerDelegate.class +0 -0
  32. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/facebook/react/viewmanagers/RNPDFPdfViewManagerInterface.class +0 -0
  33. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/org/wonday/pdf/PdfManager.class +0 -0
  34. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/org/wonday/pdf/PdfView$1.class +0 -0
  35. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/org/wonday/pdf/PdfView$2.class +0 -0
  36. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/org/wonday/pdf/PdfView$3.class +0 -0
  37. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/org/wonday/pdf/PdfView.class +0 -0
  38. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  39. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  40. package/android/src/main/java/org/wonday/pdf/PdfManager.java +6 -63
  41. package/android/src/main/java/org/wonday/pdf/PdfView.java +4 -1189
  42. package/android/src/paper/java/com/facebook/react/viewmanagers/RNPDFPdfViewManagerDelegate.java +0 -30
  43. package/android/src/paper/java/com/facebook/react/viewmanagers/RNPDFPdfViewManagerInterface.java +0 -10
  44. package/fabric/RNPDFPdfNativeComponent.js +3 -18
  45. package/index.d.ts +1 -102
  46. package/index.js +0 -110
  47. package/index.js.flow +0 -72
  48. package/ios/RNPDFPdf/RNPDFPdfView.h +0 -11
  49. package/ios/RNPDFPdf/RNPDFPdfView.mm +0 -1243
  50. package/ios/RNPDFPdf/RNPDFPdfViewManager.mm +0 -37
  51. package/package.json +5 -6
  52. package/annotationDocumentUtils.js +0 -74
@@ -54,42 +54,6 @@
54
54
  const float MAX_SCALE = 3.0f;
55
55
  const float MIN_SCALE = 1.0f;
56
56
 
57
- @class RNPDFAnnotationOverlay;
58
-
59
- @interface RNPDFAnnotationOverlay : UIView <UITextViewDelegate>
60
- @property(nonatomic, weak) PDFView *pdfView;
61
- @property(nonatomic, weak) PDFDocument *pdfDocument;
62
- @property(nonatomic, assign) BOOL annotationMode;
63
- @property(nonatomic, assign) BOOL annotationEditable;
64
- @property(nonatomic, copy) NSString *annotationTool;
65
- @property(nonatomic, copy) NSString *annotationIdMode;
66
- @property(nonatomic, copy) NSString *annotationInkColor;
67
- @property(nonatomic, assign) CGFloat annotationInkThickness;
68
-
69
- - (void)replaceAnnotationsJSONString:(NSString *)json editable:(BOOL)editable idMode:(NSString *)idMode;
70
- - (void)setAnnotationMode:(BOOL)annotationMode tool:(NSString *)tool editable:(BOOL)editable idMode:(NSString *)idMode;
71
- - (void)setInkDefaultsColor:(NSString *)color thickness:(CGFloat)thickness;
72
- - (void)beginInkAtViewPoint:(CGPoint)viewPoint page:(PDFPage *)page;
73
- - (void)appendInkPointAtViewPoint:(CGPoint)viewPoint page:(PDFPage *)page;
74
- - (void)endInk;
75
- - (void)beginMarkupAtViewPoint:(CGPoint)viewPoint page:(PDFPage *)page type:(NSString *)type;
76
- - (void)updateMarkupAtViewPoint:(CGPoint)viewPoint page:(PDFPage *)page;
77
- - (void)endMarkup;
78
- - (void)createTextAnnotationAtViewPoint:(CGPoint)viewPoint page:(PDFPage *)page;
79
- - (NSDictionary *)annotationSelectionHitAtPoint:(CGPoint)point includeHandles:(BOOL)includeHandles;
80
- - (void)selectAnnotation:(NSDictionary *)annotation;
81
- - (void)clearSelection;
82
- - (void)deleteAnnotation:(NSDictionary *)annotation;
83
- - (void)deleteSelectedAnnotation;
84
- - (void)deleteAllAnnotations;
85
- - (void)refreshDisplay;
86
- - (void)beginSelectionInteractionAtPoint:(CGPoint)point hit:(NSDictionary *)hit;
87
- - (void)updateSelectionInteractionAtPoint:(CGPoint)point;
88
- - (void)endSelectionInteraction;
89
- - (void)commitTextEditingIfNeeded;
90
- - (NSString *)serializedDocumentJSONStringWithEditable:(BOOL)editable idMode:(NSString *)idMode;
91
- @end
92
-
93
57
  @interface RNPDFPdfView() <PDFDocumentDelegate, PDFViewDelegate
94
58
  #ifdef RCT_NEW_ARCH_ENABLED
95
59
  , RCTRNPDFPdfViewViewProtocol
@@ -111,8 +75,6 @@ const float MIN_SCALE = 1.0f;
111
75
  UIPinchGestureRecognizer *_pinchRecognizer;
112
76
  UILongPressGestureRecognizer *_longPressRecognizer;
113
77
  UITapGestureRecognizer *_doubleTapEmptyRecognizer;
114
- UIPanGestureRecognizer *_annotationPanRecognizer;
115
- RNPDFAnnotationOverlay *_annotationOverlay;
116
78
 
117
79
  // Autoscroll
118
80
  CADisplayLink *_displayLink;
@@ -195,34 +157,6 @@ using namespace facebook::react;
195
157
  _enableDoubleTapZoom = newProps.enableDoubleTapZoom;
196
158
  [updatedPropNames addObject:@"enableDoubleTapZoom"];
197
159
  }
198
- if (_annotations != RCTNSStringFromStringNilIfEmpty(newProps.annotations)) {
199
- _annotations = RCTNSStringFromStringNilIfEmpty(newProps.annotations);
200
- [updatedPropNames addObject:@"annotations"];
201
- }
202
- if (_annotationMode != newProps.annotationMode) {
203
- _annotationMode = newProps.annotationMode;
204
- [updatedPropNames addObject:@"annotationMode"];
205
- }
206
- if (_annotationTool != RCTNSStringFromStringNilIfEmpty(newProps.annotationTool)) {
207
- _annotationTool = RCTNSStringFromStringNilIfEmpty(newProps.annotationTool);
208
- [updatedPropNames addObject:@"annotationTool"];
209
- }
210
- if (_annotationEditable != newProps.annotationEditable) {
211
- _annotationEditable = newProps.annotationEditable;
212
- [updatedPropNames addObject:@"annotationEditable"];
213
- }
214
- if (_annotationIdMode != RCTNSStringFromStringNilIfEmpty(newProps.annotationIdMode)) {
215
- _annotationIdMode = RCTNSStringFromStringNilIfEmpty(newProps.annotationIdMode);
216
- [updatedPropNames addObject:@"annotationIdMode"];
217
- }
218
- if (_annotationInkColor != RCTNSStringFromStringNilIfEmpty(newProps.annotationInkColor)) {
219
- _annotationInkColor = RCTNSStringFromStringNilIfEmpty(newProps.annotationInkColor);
220
- [updatedPropNames addObject:@"annotationInkColor"];
221
- }
222
- if (_annotationInkThickness != newProps.annotationInkThickness) {
223
- _annotationInkThickness = newProps.annotationInkThickness;
224
- [updatedPropNames addObject:@"annotationInkThickness"];
225
- }
226
160
  if (_fitPolicy != newProps.fitPolicy) {
227
161
  _fitPolicy = newProps.fitPolicy;
228
162
  [updatedPropNames addObject:@"fitPolicy"];
@@ -255,14 +189,6 @@ using namespace facebook::react;
255
189
 
256
190
  [super updateProps:props oldProps:oldProps];
257
191
  [self didSetProps:updatedPropNames];
258
-
259
- if (_annotationOverlay) {
260
- [_annotationOverlay replaceAnnotationsJSONString:_annotations editable:_annotationEditable idMode:_annotationIdMode];
261
- [_annotationOverlay setAnnotationMode:_annotationMode tool:_annotationTool editable:_annotationEditable idMode:_annotationIdMode];
262
- [_annotationOverlay setInkDefaultsColor:_annotationInkColor thickness:_annotationInkThickness];
263
- _annotationOverlay.pdfView = _pdfView;
264
- _annotationOverlay.pdfDocument = _pdfDocument;
265
- }
266
192
  }
267
193
 
268
194
  // already added in case https://github.com/facebook/react-native/pull/35378 has been merged
@@ -293,10 +219,6 @@ using namespace facebook::react;
293
219
  [self removeGestureRecognizer:_pinchRecognizer];
294
220
  [self removeGestureRecognizer:_longPressRecognizer];
295
221
  [self removeGestureRecognizer:_doubleTapEmptyRecognizer];
296
- [self removeGestureRecognizer:_annotationPanRecognizer];
297
-
298
- [_annotationOverlay removeFromSuperview];
299
- _annotationOverlay = nil;
300
222
 
301
223
  [self initCommonProps];
302
224
  }
@@ -306,7 +228,6 @@ using namespace facebook::react;
306
228
  // Fabric equivalent of `reactSetFrame` method
307
229
  [super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
308
230
  _pdfView.frame = CGRectMake(0, 0, layoutMetrics.frame.size.width, layoutMetrics.frame.size.height);
309
- _annotationOverlay.frame = CGRectMake(0, 0, layoutMetrics.frame.size.width, layoutMetrics.frame.size.height);
310
231
 
311
232
  NSMutableArray *mProps = [_changedProps mutableCopy];
312
233
  if (_initialed) {
@@ -368,8 +289,6 @@ using namespace facebook::react;
368
289
  _showsHorizontalScrollIndicator = YES;
369
290
  _showsVerticalScrollIndicator = YES;
370
291
  _scrollEnabled = YES;
371
- _annotationInkColor = @"#111111";
372
- _annotationInkThickness = 2.0f;
373
292
  _enableTextSelection = YES;
374
293
  _selectedText = nil;
375
294
  _currentPDFSelection = nil;
@@ -396,13 +315,6 @@ using namespace facebook::react;
396
315
  _autoScrollCurrentOffset = 0.0;
397
316
 
398
317
  [self addSubview:_pdfView];
399
- _annotationOverlay = [[RNPDFAnnotationOverlay alloc] initWithFrame:self.bounds];
400
- _annotationOverlay.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
401
- _annotationOverlay.backgroundColor = UIColor.clearColor;
402
- _annotationOverlay.userInteractionEnabled = YES;
403
- [_annotationOverlay setInkDefaultsColor:_annotationInkColor thickness:_annotationInkThickness];
404
- [self addSubview:_annotationOverlay];
405
- [self bringSubviewToFront:_annotationOverlay];
406
318
 
407
319
 
408
320
  // register notification
@@ -513,10 +425,6 @@ using namespace facebook::react;
513
425
  }
514
426
 
515
427
  _pdfView.document = _pdfDocument;
516
- if (_annotationOverlay) {
517
- _annotationOverlay.pdfView = _pdfView;
518
- _annotationOverlay.pdfDocument = _pdfDocument;
519
- }
520
428
  } else {
521
429
 
522
430
  [self notifyOnChangeWithMessage:[[NSString alloc] initWithString:[NSString stringWithFormat:@"error|Load pdf failed. path=%s",_path.UTF8String]]];
@@ -690,14 +598,6 @@ using namespace facebook::react;
690
598
  }
691
599
  }
692
600
 
693
- if (_annotationOverlay) {
694
- [_annotationOverlay replaceAnnotationsJSONString:_annotations editable:_annotationEditable idMode:_annotationIdMode];
695
- [_annotationOverlay setAnnotationMode:_annotationMode tool:_annotationTool editable:_annotationEditable idMode:_annotationIdMode];
696
- [_annotationOverlay setInkDefaultsColor:_annotationInkColor thickness:_annotationInkThickness];
697
- _annotationOverlay.pdfView = _pdfView;
698
- _annotationOverlay.pdfDocument = _pdfDocument;
699
- }
700
-
701
601
  _pdfView.backgroundColor = [UIColor clearColor];
702
602
  [_pdfView layoutDocumentView];
703
603
  [self setNeedsDisplay];
@@ -866,8 +766,6 @@ using namespace facebook::react;
866
766
  [self notifyOnChangeWithMessage:[[NSString alloc] initWithString:[NSString stringWithFormat:@"pageChanged|%lu|%lu", page+1, numberOfPages]]];
867
767
  }
868
768
 
869
- [_annotationOverlay refreshDisplay];
870
-
871
769
  }
872
770
 
873
771
  - (void)onScaleChanged:(NSNotification *)noti
@@ -879,8 +777,6 @@ using namespace facebook::react;
879
777
  [self notifyOnChangeWithMessage:[[NSString alloc] initWithString:[NSString stringWithFormat:@"scaleChanged|%f", _scale]]];
880
778
  }
881
779
  }
882
-
883
- [_annotationOverlay refreshDisplay];
884
780
  }
885
781
 
886
782
  #pragma mark gesture process
@@ -979,30 +875,6 @@ using namespace facebook::react;
979
875
  PDFPage *pdfPage = [_pdfView pageForPoint:point nearest:NO];
980
876
  if (pdfPage) {
981
877
  unsigned long page = [_pdfDocument indexForPage:pdfPage];
982
- if (_annotationMode && _annotationEditable) {
983
- if ([_annotationTool isEqualToString:@"select"]) {
984
- [_annotationOverlay commitTextEditingIfNeeded];
985
-
986
- NSDictionary *hit = [_annotationOverlay annotationSelectionHitAtPoint:point includeHandles:YES];
987
- if (hit) {
988
- NSDictionary *annotation = hit[@"annotation"];
989
- [_annotationOverlay selectAnnotation:annotation];
990
-
991
- return;
992
- }
993
-
994
- [_annotationOverlay clearSelection];
995
- [self notifyOnChangeWithMessage:
996
- [[NSString alloc] initWithString:[NSString stringWithFormat:@"pageSingleTap|%lu|%f|%f", page+1, point.x, point.y]]];
997
- return;
998
- }
999
-
1000
- if ([_annotationTool isEqualToString:@"text"]) {
1001
- [_annotationOverlay createTextAnnotationAtViewPoint:point page:pdfPage];
1002
- return;
1003
- }
1004
- }
1005
-
1006
878
  [self notifyOnChangeWithMessage:
1007
879
  [[NSString alloc] initWithString:[NSString stringWithFormat:@"pageSingleTap|%lu|%f|%f", page+1, point.x, point.y]]];
1008
880
  }
@@ -1032,86 +904,6 @@ using namespace facebook::react;
1032
904
 
1033
905
  }
1034
906
 
1035
- - (void)handleAnnotationPan:(UIPanGestureRecognizer *)sender
1036
- {
1037
- if (!_annotationMode || !_annotationEditable || _annotationTool == nil) {
1038
- return;
1039
- }
1040
-
1041
- CGPoint point = [sender locationInView:self];
1042
- PDFPage *pdfPage = [_pdfDocument pageAtIndex:MAX(0, [_pdfDocument indexForPage:[_pdfView pageForPoint:point nearest:NO]])];
1043
- if (!pdfPage) {
1044
- return;
1045
- }
1046
-
1047
- if ([_annotationTool isEqualToString:@"select"]) {
1048
- if (sender.state == UIGestureRecognizerStateBegan) {
1049
- [_annotationOverlay commitTextEditingIfNeeded];
1050
-
1051
- NSDictionary *hit = [_annotationOverlay annotationSelectionHitAtPoint:point includeHandles:YES];
1052
- if (!hit) {
1053
- return;
1054
- }
1055
-
1056
- [_annotationOverlay selectAnnotation:hit[@"annotation"]];
1057
- [_annotationOverlay beginSelectionInteractionAtPoint:point hit:hit];
1058
- } else if (sender.state == UIGestureRecognizerStateChanged) {
1059
- [_annotationOverlay updateSelectionInteractionAtPoint:point];
1060
- } else if (sender.state == UIGestureRecognizerStateEnded || sender.state == UIGestureRecognizerStateCancelled || sender.state == UIGestureRecognizerStateFailed) {
1061
- [_annotationOverlay endSelectionInteraction];
1062
- }
1063
- return;
1064
- }
1065
-
1066
- if (sender.state == UIGestureRecognizerStateBegan) {
1067
- if ([_annotationTool isEqualToString:@"ink"]) {
1068
- [_annotationOverlay beginInkAtViewPoint:point page:pdfPage];
1069
- } else if ([_annotationTool isEqualToString:@"highlight"]) {
1070
- [_annotationOverlay beginMarkupAtViewPoint:point page:pdfPage type:_annotationTool];
1071
- }
1072
- } else if (sender.state == UIGestureRecognizerStateChanged) {
1073
- if ([_annotationTool isEqualToString:@"ink"]) {
1074
- [_annotationOverlay appendInkPointAtViewPoint:point page:pdfPage];
1075
- } else if ([_annotationTool isEqualToString:@"highlight"]) {
1076
- [_annotationOverlay updateMarkupAtViewPoint:point page:pdfPage];
1077
- }
1078
- } else if (sender.state == UIGestureRecognizerStateEnded || sender.state == UIGestureRecognizerStateCancelled || sender.state == UIGestureRecognizerStateFailed) {
1079
- if ([_annotationTool isEqualToString:@"ink"]) {
1080
- [_annotationOverlay endInk];
1081
- } else if ([_annotationTool isEqualToString:@"highlight"]) {
1082
- [_annotationOverlay endMarkup];
1083
- }
1084
- }
1085
- }
1086
-
1087
- - (void)saveAnnotations
1088
- {
1089
- if (_annotationOverlay) {
1090
- [_annotationOverlay commitTextEditingIfNeeded];
1091
- NSString *jsonString = [_annotationOverlay serializedDocumentJSONStringWithEditable:_annotationEditable idMode:_annotationIdMode];
1092
- [self notifyOnChangeWithMessage:[NSString stringWithFormat:@"annotationSaveComplete|%@", jsonString]];
1093
- return;
1094
- }
1095
-
1096
- [self notifyOnChangeWithMessage:@"annotationSaveError|Annotation overlay unavailable"];
1097
- }
1098
-
1099
- - (void)deleteSelectedAnnotation
1100
- {
1101
- if (_annotationOverlay) {
1102
- [_annotationOverlay commitTextEditingIfNeeded];
1103
- [_annotationOverlay deleteSelectedAnnotation];
1104
- }
1105
- }
1106
-
1107
- - (void)deleteAllAnnotations
1108
- {
1109
- if (_annotationOverlay) {
1110
- [_annotationOverlay commitTextEditingIfNeeded];
1111
- [_annotationOverlay deleteAllAnnotations];
1112
- }
1113
- }
1114
-
1115
907
  /**
1116
908
  * Bind tap
1117
909
  *
@@ -1158,15 +950,6 @@ using namespace facebook::react;
1158
950
  [self addGestureRecognizer:longPressRecognizer];
1159
951
  _longPressRecognizer = longPressRecognizer;
1160
952
 
1161
- UIPanGestureRecognizer *annotationPanRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self
1162
- action:@selector(handleAnnotationPan:)];
1163
- annotationPanRecognizer.maximumNumberOfTouches = 1;
1164
- annotationPanRecognizer.minimumNumberOfTouches = 1;
1165
- annotationPanRecognizer.delegate = self;
1166
- annotationPanRecognizer.cancelsTouchesInView = YES;
1167
- [self addGestureRecognizer:annotationPanRecognizer];
1168
- _annotationPanRecognizer = annotationPanRecognizer;
1169
-
1170
953
  // Override the _pdfView double tap gesture recognizer so that it doesn't confilict with custom double tap
1171
954
  UITapGestureRecognizer *doubleTapEmptyRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
1172
955
  action:@selector(handleDoubleTapEmpty:)];
@@ -1178,28 +961,11 @@ using namespace facebook::react;
1178
961
  - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
1179
962
 
1180
963
  {
1181
- if (gestureRecognizer == _annotationPanRecognizer) {
1182
- if (!_annotationMode || !_annotationEditable || _annotationTool == nil) {
1183
- return NO;
1184
- }
1185
-
1186
- if ([_annotationTool isEqualToString:@"select"]) {
1187
- CGPoint point = [gestureRecognizer locationInView:self];
1188
- return [_annotationOverlay annotationSelectionHitAtPoint:point includeHandles:YES] != nil;
1189
- }
1190
-
1191
- return [@[@"ink", @"highlight"] containsObject:_annotationTool];
1192
- }
1193
-
1194
964
  return !_singlePage;
1195
965
  }
1196
966
 
1197
967
  - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
1198
968
  {
1199
- if (gestureRecognizer == _annotationPanRecognizer || otherGestureRecognizer == _annotationPanRecognizer) {
1200
- return NO;
1201
- }
1202
-
1203
969
  return !_singlePage;
1204
970
  }
1205
971
 
@@ -1371,1015 +1137,6 @@ using namespace facebook::react;
1371
1137
  if ([_originalScrollDelegate respondsToSelector:@selector(scrollViewDidScroll:)]) {
1372
1138
  [_originalScrollDelegate scrollViewDidScroll:scrollView];
1373
1139
  }
1374
-
1375
- [_annotationOverlay refreshDisplay];
1376
- }
1377
-
1378
- @end
1379
-
1380
- static UIColor *RNPDFColorFromHexString(NSString *hexString, UIColor *fallback)
1381
- {
1382
- if (![hexString isKindOfClass:[NSString class]] || hexString.length == 0) {
1383
- return fallback;
1384
- }
1385
-
1386
- NSString *cleanHex = [[hexString stringByReplacingOccurrencesOfString:@"#" withString:@""] uppercaseString];
1387
- unsigned int rgbValue = 0;
1388
- if (cleanHex.length == 6) {
1389
- NSScanner *scanner = [NSScanner scannerWithString:cleanHex];
1390
- [scanner scanHexInt:&rgbValue];
1391
- return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16) / 255.0f
1392
- green:((rgbValue & 0x00FF00) >> 8) / 255.0f
1393
- blue:(rgbValue & 0x0000FF) / 255.0f
1394
- alpha:1.0f];
1395
- }
1396
-
1397
- if (cleanHex.length == 8) {
1398
- NSScanner *scanner = [NSScanner scannerWithString:cleanHex];
1399
- [scanner scanHexInt:&rgbValue];
1400
- return [UIColor colorWithRed:((rgbValue & 0x00FF0000) >> 16) / 255.0f
1401
- green:((rgbValue & 0x0000FF00) >> 8) / 255.0f
1402
- blue:(rgbValue & 0x000000FF) / 255.0f
1403
- alpha:((rgbValue & 0xFF000000) >> 24) / 255.0f];
1404
- }
1405
-
1406
- return fallback;
1407
- }
1408
-
1409
- static NSString *RNPDFGenerateAnnotationId(void)
1410
- {
1411
- return [[NSUUID UUID] UUIDString];
1412
- }
1413
-
1414
- @implementation RNPDFAnnotationOverlay
1415
- {
1416
- NSMutableArray<NSMutableDictionary *> *_draftAnnotations;
1417
- NSMutableDictionary *_activeInkAnnotation;
1418
- NSMutableDictionary *_activeMarkupAnnotation;
1419
- NSMutableDictionary *_activeTextAnnotation;
1420
- NSString *_selectedAnnotationId;
1421
- NSMutableDictionary *_activeSelectionAnnotation;
1422
- NSString *_activeSelectionMode;
1423
- NSString *_activeSelectionHandle;
1424
- CGPoint _selectionStartPoint;
1425
- CGRect _selectionStartBounds;
1426
- NSArray *_selectionStartPoints;
1427
- NSInteger _selectionPageIndex;
1428
- CGPoint _activeMarkupStartNormalized;
1429
- UITextView *_activeTextView;
1430
- }
1431
-
1432
- - (instancetype)initWithFrame:(CGRect)frame
1433
- {
1434
- if (self = [super initWithFrame:frame]) {
1435
- _draftAnnotations = [NSMutableArray new];
1436
- _annotationMode = NO;
1437
- _annotationEditable = YES;
1438
- _annotationTool = @"select";
1439
- _annotationIdMode = @"auto";
1440
- _annotationInkColor = @"#111111";
1441
- _annotationInkThickness = 2.0f;
1442
- self.backgroundColor = UIColor.clearColor;
1443
- self.opaque = NO;
1444
- }
1445
- return self;
1446
- }
1447
-
1448
- - (void)setPdfView:(PDFView *)pdfView
1449
- {
1450
- _pdfView = pdfView;
1451
- [self refreshDisplay];
1452
- }
1453
-
1454
- - (void)setPdfDocument:(PDFDocument *)pdfDocument
1455
- {
1456
- _pdfDocument = pdfDocument;
1457
- [self refreshDisplay];
1458
- }
1459
-
1460
- - (void)replaceAnnotationsJSONString:(NSString *)json editable:(BOOL)editable idMode:(NSString *)idMode
1461
- {
1462
- self.annotationEditable = editable;
1463
- self.annotationIdMode = idMode ?: @"auto";
1464
-
1465
- NSArray *parsedAnnotations = [self parseAnnotationsFromJSONString:json];
1466
- _draftAnnotations = [parsedAnnotations mutableCopy] ?: [NSMutableArray new];
1467
-
1468
- [self commitTextEditingIfNeeded];
1469
- [self refreshDisplay];
1470
- }
1471
-
1472
- - (void)setAnnotationMode:(BOOL)annotationMode tool:(NSString *)tool editable:(BOOL)editable idMode:(NSString *)idMode
1473
- {
1474
- _annotationMode = annotationMode;
1475
- _annotationEditable = editable;
1476
- _annotationTool = [self normalizedAnnotationType:(tool ?: @"select")];
1477
- _annotationIdMode = idMode ?: @"auto";
1478
-
1479
- if (!annotationMode) {
1480
- [self commitTextEditingIfNeeded];
1481
- }
1482
- }
1483
-
1484
- - (void)setInkDefaultsColor:(NSString *)color thickness:(CGFloat)thickness
1485
- {
1486
- _annotationInkColor = color.length > 0 ? color : @"#111111";
1487
- _annotationInkThickness = thickness > 0 ? thickness : 2.0f;
1488
- }
1489
-
1490
- - (NSString *)normalizedAnnotationType:(NSString *)type
1491
- {
1492
- if ([type isEqualToString:@"underline"] || [type isEqualToString:@"strikeout"]) {
1493
- return @"highlight";
1494
- }
1495
-
1496
- return type;
1497
- }
1498
-
1499
- - (BOOL)annotationSupportsResize:(NSDictionary *)annotation
1500
- {
1501
- NSString *type = [self normalizedAnnotationType:annotation[@"type"]];
1502
- return [type isEqualToString:@"text"] || [type isEqualToString:@"highlight"];
1503
- }
1504
-
1505
- - (NSArray *)parseAnnotationsFromJSONString:(NSString *)json
1506
- {
1507
- if (![json isKindOfClass:[NSString class]] || json.length == 0) {
1508
- return @[];
1509
- }
1510
-
1511
- NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding];
1512
- if (!data) {
1513
- return @[];
1514
- }
1515
-
1516
- NSError *error = nil;
1517
- id parsed = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
1518
- if (error || !parsed) {
1519
- return @[];
1520
- }
1521
-
1522
- NSArray *items = nil;
1523
- if ([parsed isKindOfClass:[NSDictionary class]]) {
1524
- id candidate = parsed[@"annotations"];
1525
- if ([candidate isKindOfClass:[NSArray class]]) {
1526
- items = candidate;
1527
- }
1528
- } else if ([parsed isKindOfClass:[NSArray class]]) {
1529
- items = parsed;
1530
- }
1531
-
1532
- if (![items isKindOfClass:[NSArray class]]) {
1533
- return @[];
1534
- }
1535
-
1536
- NSMutableArray *normalized = [NSMutableArray arrayWithCapacity:items.count];
1537
- for (id item in items) {
1538
- if (![item isKindOfClass:[NSDictionary class]]) {
1539
- continue;
1540
- }
1541
-
1542
- NSMutableDictionary *annotation = [item mutableCopy];
1543
- NSString *type = [self normalizedAnnotationType:annotation[@"type"]];
1544
- if (type.length > 0) {
1545
- annotation[@"type"] = type;
1546
- }
1547
- if (!annotation[@"id"]) {
1548
- annotation[@"id"] = RNPDFGenerateAnnotationId();
1549
- }
1550
- if (!annotation[@"page"]) {
1551
- annotation[@"page"] = @(1);
1552
- }
1553
- [normalized addObject:annotation];
1554
- }
1555
-
1556
- return normalized;
1557
- }
1558
-
1559
- - (NSString *)serializedDocumentJSONStringWithEditable:(BOOL)editable idMode:(NSString *)idMode
1560
- {
1561
- NSMutableDictionary *document = [NSMutableDictionary dictionary];
1562
- document[@"editable"] = @(editable);
1563
- document[@"idMode"] = idMode ?: @"auto";
1564
- document[@"annotations"] = [_draftAnnotations copy] ?: @[];
1565
-
1566
- NSError *error = nil;
1567
- NSData *data = [NSJSONSerialization dataWithJSONObject:document options:0 error:&error];
1568
- if (error || !data) {
1569
- return @"{}";
1570
- }
1571
-
1572
- return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] ?: @"{}";
1573
- }
1574
-
1575
- - (void)refreshDisplay
1576
- {
1577
- [self setNeedsDisplay];
1578
- [self updateActiveTextEditorFrame];
1579
- }
1580
-
1581
- - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
1582
- {
1583
- if (_activeTextView) {
1584
- if (CGRectContainsPoint(_activeTextView.frame, point)) {
1585
- return _activeTextView;
1586
- }
1587
-
1588
- return self;
1589
- }
1590
-
1591
- return nil;
1592
- }
1593
-
1594
- - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
1595
- {
1596
- if (_activeTextView) {
1597
- [self commitTextEditingIfNeeded];
1598
- }
1599
-
1600
- [super touchesBegan:touches withEvent:event];
1601
- }
1602
-
1603
- - (void)layoutSubviews
1604
- {
1605
- [super layoutSubviews];
1606
- [self updateActiveTextEditorFrame];
1607
- }
1608
-
1609
- - (CGPoint)normalizedPointForViewPoint:(CGPoint)viewPoint page:(PDFPage *)page
1610
- {
1611
- if (!self.pdfView || !page) {
1612
- return CGPointZero;
1613
- }
1614
-
1615
- CGPoint pagePoint = [self.pdfView convertPoint:viewPoint toPage:page];
1616
- CGRect pageBounds = [page boundsForBox:kPDFDisplayBoxCropBox];
1617
- if (page.rotation == 90 || page.rotation == 270) {
1618
- pageBounds = CGRectMake(0, 0, pageBounds.size.height, pageBounds.size.width);
1619
- }
1620
-
1621
- CGFloat width = MAX(pageBounds.size.width, 1.0f);
1622
- CGFloat height = MAX(pageBounds.size.height, 1.0f);
1623
- return CGPointMake(pagePoint.x / width, 1.0f - (pagePoint.y / height));
1624
- }
1625
-
1626
- - (CGPoint)viewPointForNormalizedPoint:(CGPoint)normalizedPoint page:(PDFPage *)page
1627
- {
1628
- if (!self.pdfView || !page) {
1629
- return CGPointZero;
1630
- }
1631
-
1632
- CGRect pageBounds = [page boundsForBox:kPDFDisplayBoxCropBox];
1633
- if (page.rotation == 90 || page.rotation == 270) {
1634
- pageBounds = CGRectMake(0, 0, pageBounds.size.height, pageBounds.size.width);
1635
- }
1636
-
1637
- CGFloat width = MAX(pageBounds.size.width, 1.0f);
1638
- CGFloat height = MAX(pageBounds.size.height, 1.0f);
1639
- CGPoint pagePoint = CGPointMake(normalizedPoint.x * width, (1.0f - normalizedPoint.y) * height);
1640
- return [self.pdfView convertPoint:pagePoint fromPage:page];
1641
- }
1642
-
1643
- - (CGRect)viewRectForNormalizedBounds:(NSDictionary *)bounds page:(PDFPage *)page
1644
- {
1645
- if (!bounds || !page) {
1646
- return CGRectZero;
1647
- }
1648
-
1649
- CGFloat x = [bounds[@"x"] doubleValue];
1650
- CGFloat y = [bounds[@"y"] doubleValue];
1651
- CGFloat width = [bounds[@"width"] doubleValue];
1652
- CGFloat height = [bounds[@"height"] doubleValue];
1653
-
1654
- CGPoint topLeft = [self viewPointForNormalizedPoint:CGPointMake(x, y) page:page];
1655
- CGPoint topRight = [self viewPointForNormalizedPoint:CGPointMake(x + width, y) page:page];
1656
- CGPoint bottomLeft = [self viewPointForNormalizedPoint:CGPointMake(x, y + height) page:page];
1657
- CGPoint bottomRight = [self viewPointForNormalizedPoint:CGPointMake(x + width, y + height) page:page];
1658
-
1659
- CGFloat minX = MIN(MIN(topLeft.x, topRight.x), MIN(bottomLeft.x, bottomRight.x));
1660
- CGFloat maxX = MAX(MAX(topLeft.x, topRight.x), MAX(bottomLeft.x, bottomRight.x));
1661
- CGFloat minY = MIN(MIN(topLeft.y, topRight.y), MIN(bottomLeft.y, bottomRight.y));
1662
- CGFloat maxY = MAX(MAX(topLeft.y, topRight.y), MAX(bottomLeft.y, bottomRight.y));
1663
-
1664
- return CGRectMake(minX, minY, MAX(maxX - minX, 1.0f), MAX(maxY - minY, 1.0f));
1665
- }
1666
-
1667
- - (CGRect)viewRectForAnnotation:(NSDictionary *)annotation page:(PDFPage *)page
1668
- {
1669
- if (!annotation || !page) {
1670
- return CGRectZero;
1671
- }
1672
-
1673
- NSString *type = annotation[@"type"];
1674
- if ([type isEqualToString:@"ink"]) {
1675
- NSArray *points = annotation[@"points"];
1676
- if (![points isKindOfClass:[NSArray class]] || points.count == 0) {
1677
- return CGRectZero;
1678
- }
1679
-
1680
- CGFloat minX = CGFLOAT_MAX;
1681
- CGFloat minY = CGFLOAT_MAX;
1682
- CGFloat maxX = -CGFLOAT_MAX;
1683
- CGFloat maxY = -CGFLOAT_MAX;
1684
-
1685
- for (NSDictionary *point in points) {
1686
- if (![point isKindOfClass:[NSDictionary class]]) {
1687
- continue;
1688
- }
1689
-
1690
- CGPoint viewPoint = [self viewPointForNormalizedPoint:CGPointMake([point[@"x"] doubleValue], [point[@"y"] doubleValue]) page:page];
1691
- minX = MIN(minX, viewPoint.x);
1692
- minY = MIN(minY, viewPoint.y);
1693
- maxX = MAX(maxX, viewPoint.x);
1694
- maxY = MAX(maxY, viewPoint.y);
1695
- }
1696
-
1697
- if (minX == CGFLOAT_MAX || minY == CGFLOAT_MAX || maxX == -CGFLOAT_MAX || maxY == -CGFLOAT_MAX) {
1698
- return CGRectZero;
1699
- }
1700
-
1701
- return CGRectMake(minX, minY, MAX(maxX - minX, 1.0f), MAX(maxY - minY, 1.0f));
1702
- }
1703
-
1704
- NSDictionary *bounds = annotation[@"bounds"];
1705
- return [self viewRectForNormalizedBounds:bounds page:page];
1706
- }
1707
-
1708
- - (CGRect)normalizedBoundsForAnnotation:(NSDictionary *)annotation
1709
- {
1710
- if (!annotation) {
1711
- return CGRectZero;
1712
- }
1713
-
1714
- NSString *type = annotation[@"type"];
1715
- if ([type isEqualToString:@"ink"]) {
1716
- NSArray *points = annotation[@"points"];
1717
- if (![points isKindOfClass:[NSArray class]] || points.count == 0) {
1718
- return CGRectZero;
1719
- }
1720
-
1721
- CGFloat minX = CGFLOAT_MAX;
1722
- CGFloat minY = CGFLOAT_MAX;
1723
- CGFloat maxX = -CGFLOAT_MAX;
1724
- CGFloat maxY = -CGFLOAT_MAX;
1725
-
1726
- for (NSDictionary *point in points) {
1727
- if (![point isKindOfClass:[NSDictionary class]]) {
1728
- continue;
1729
- }
1730
-
1731
- CGFloat x = [point[@"x"] doubleValue];
1732
- CGFloat y = [point[@"y"] doubleValue];
1733
- minX = MIN(minX, x);
1734
- minY = MIN(minY, y);
1735
- maxX = MAX(maxX, x);
1736
- maxY = MAX(maxY, y);
1737
- }
1738
-
1739
- if (minX == CGFLOAT_MAX || minY == CGFLOAT_MAX || maxX == -CGFLOAT_MAX || maxY == -CGFLOAT_MAX) {
1740
- return CGRectZero;
1741
- }
1742
-
1743
- return CGRectMake(minX, minY, MAX(maxX - minX, 0.001f), MAX(maxY - minY, 0.001f));
1744
- }
1745
-
1746
- NSDictionary *bounds = annotation[@"bounds"];
1747
- if (![bounds isKindOfClass:[NSDictionary class]]) {
1748
- return CGRectZero;
1749
- }
1750
-
1751
- CGFloat x = [bounds[@"x"] doubleValue];
1752
- CGFloat y = [bounds[@"y"] doubleValue];
1753
- CGFloat width = [bounds[@"width"] doubleValue];
1754
- CGFloat height = [bounds[@"height"] doubleValue];
1755
- return CGRectMake(x, y, MAX(width, 0.001f), MAX(height, 0.001f));
1756
- }
1757
-
1758
- - (NSArray *)copyPointsForAnnotation:(NSDictionary *)annotation
1759
- {
1760
- if (![annotation[@"type"] isEqualToString:@"ink"]) {
1761
- return nil;
1762
- }
1763
-
1764
- NSArray *points = annotation[@"points"];
1765
- if (![points isKindOfClass:[NSArray class]]) {
1766
- return nil;
1767
- }
1768
-
1769
- return [points copy];
1770
- }
1771
-
1772
- - (NSDictionary *)selectedAnnotation
1773
- {
1774
- if (_selectedAnnotationId.length == 0) {
1775
- return nil;
1776
- }
1777
-
1778
- for (NSDictionary *annotation in [_draftAnnotations reverseObjectEnumerator]) {
1779
- if ([_selectedAnnotationId isEqualToString:annotation[@"id"]]) {
1780
- return annotation;
1781
- }
1782
- }
1783
-
1784
- return nil;
1785
- }
1786
-
1787
- - (CGRect)resizeHandleRectForRect:(CGRect)rect
1788
- {
1789
- CGFloat size = MAX(16.0f, MIN(rect.size.width, rect.size.height) * 0.18f);
1790
- return CGRectMake(CGRectGetMaxX(rect) - size, CGRectGetMaxY(rect) - size, size, size);
1791
- }
1792
-
1793
- - (NSDictionary *)annotationSelectionHitAtPoint:(CGPoint)point includeHandles:(BOOL)includeHandles
1794
- {
1795
- if (!self.pdfDocument || _draftAnnotations.count == 0) {
1796
- return nil;
1797
- }
1798
-
1799
- PDFPage *page = [self.pdfView pageForPoint:point nearest:NO];
1800
- if (!page) {
1801
- return nil;
1802
- }
1803
-
1804
- NSInteger pageIndex = [self.pdfDocument indexForPage:page];
1805
- for (NSDictionary *annotation in [_draftAnnotations reverseObjectEnumerator]) {
1806
- NSNumber *annotationPageNumber = annotation[@"page"];
1807
- if (!annotationPageNumber || annotationPageNumber.integerValue - 1 != pageIndex) {
1808
- continue;
1809
- }
1810
-
1811
- CGRect rect = [self viewRectForAnnotation:annotation page:page];
1812
- if (CGRectIsEmpty(rect)) {
1813
- continue;
1814
- }
1815
-
1816
- CGRect hitRect = CGRectInset(rect, -12.0f, -12.0f);
1817
- if (!CGRectContainsPoint(hitRect, point)) {
1818
- continue;
1819
- }
1820
-
1821
- NSString *hitPart = @"body";
1822
- if (includeHandles && [_selectedAnnotationId isEqualToString:annotation[@"id"]] && [self annotationSupportsResize:annotation] && CGRectContainsPoint([self resizeHandleRectForRect:rect], point)) {
1823
- hitPart = @"resize";
1824
- }
1825
-
1826
- return @{@"annotation": annotation,
1827
- @"pageIndex": @(pageIndex),
1828
- @"hitPart": hitPart,
1829
- @"rect": [NSValue valueWithCGRect:rect]};
1830
- }
1831
-
1832
- return nil;
1833
- }
1834
-
1835
- - (void)selectAnnotation:(NSDictionary *)annotation
1836
- {
1837
- _selectedAnnotationId = [annotation[@"id"] copy];
1838
- [self refreshDisplay];
1839
- }
1840
-
1841
- - (void)clearSelection
1842
- {
1843
- _selectedAnnotationId = nil;
1844
- [self refreshDisplay];
1845
- }
1846
-
1847
- - (void)deleteAnnotation:(NSDictionary *)annotation
1848
- {
1849
- if (!annotation) {
1850
- return;
1851
- }
1852
-
1853
- [self commitTextEditingIfNeeded];
1854
-
1855
- NSString *annotationId = annotation[@"id"];
1856
- if (annotationId.length == 0) {
1857
- return;
1858
- }
1859
-
1860
- NSUInteger removeIndex = NSNotFound;
1861
- for (NSUInteger index = 0; index < _draftAnnotations.count; index++) {
1862
- NSDictionary *candidate = _draftAnnotations[index];
1863
- if ([annotationId isEqualToString:candidate[@"id"]]) {
1864
- removeIndex = index;
1865
- break;
1866
- }
1867
- }
1868
-
1869
- if (removeIndex != NSNotFound) {
1870
- [_draftAnnotations removeObjectAtIndex:removeIndex];
1871
- }
1872
-
1873
- if ([_selectedAnnotationId isEqualToString:annotationId]) {
1874
- _selectedAnnotationId = nil;
1875
- }
1876
-
1877
- [self endSelectionInteraction];
1878
-
1879
- [self refreshDisplay];
1880
- }
1881
-
1882
- - (void)deleteSelectedAnnotation
1883
- {
1884
- NSDictionary *annotation = [self selectedAnnotation];
1885
- if (annotation) {
1886
- [self deleteAnnotation:annotation];
1887
- }
1888
- }
1889
-
1890
- - (void)deleteAllAnnotations
1891
- {
1892
- [self commitTextEditingIfNeeded];
1893
- [_draftAnnotations removeAllObjects];
1894
- _selectedAnnotationId = nil;
1895
- [self endSelectionInteraction];
1896
- [self refreshDisplay];
1897
- }
1898
-
1899
- - (void)beginSelectionInteractionAtPoint:(CGPoint)point hit:(NSDictionary *)hit
1900
- {
1901
- NSDictionary *annotation = hit[@"annotation"];
1902
- if (![annotation isKindOfClass:[NSDictionary class]]) {
1903
- return;
1904
- }
1905
-
1906
- _activeSelectionAnnotation = (NSMutableDictionary *)annotation;
1907
- _activeSelectionMode = [hit[@"hitPart"] isEqualToString:@"resize"] ? @"resize" : @"move";
1908
- _activeSelectionHandle = hit[@"hitPart"] ?: @"body";
1909
- _selectionStartPoint = point;
1910
- _selectionPageIndex = [hit[@"pageIndex"] integerValue];
1911
- _selectionStartBounds = [self normalizedBoundsForAnnotation:annotation];
1912
- _selectionStartPoints = [self copyPointsForAnnotation:annotation];
1913
- }
1914
-
1915
- - (void)updateSelectionInteractionAtPoint:(CGPoint)point
1916
- {
1917
- if (!_activeSelectionAnnotation || _selectionPageIndex < 0 || !_pdfDocument || _selectionPageIndex >= _pdfDocument.pageCount) {
1918
- return;
1919
- }
1920
-
1921
- PDFPage *page = [_pdfDocument pageAtIndex:_selectionPageIndex];
1922
- if (!page) {
1923
- return;
1924
- }
1925
-
1926
- CGPoint startNormalized = [self normalizedPointForViewPoint:_selectionStartPoint page:page];
1927
- CGPoint currentNormalized = [self normalizedPointForViewPoint:point page:page];
1928
- CGFloat deltaX = currentNormalized.x - startNormalized.x;
1929
- CGFloat deltaY = currentNormalized.y - startNormalized.y;
1930
-
1931
- CGRect newBounds = _selectionStartBounds;
1932
- if ([_activeSelectionMode isEqualToString:@"resize"]) {
1933
- newBounds.size.width = MAX(0.01f, _selectionStartBounds.size.width + deltaX);
1934
- newBounds.size.height = MAX(0.01f, _selectionStartBounds.size.height + deltaY);
1935
- } else {
1936
- newBounds.origin.x = _selectionStartBounds.origin.x + deltaX;
1937
- newBounds.origin.y = _selectionStartBounds.origin.y + deltaY;
1938
- }
1939
-
1940
- [self applySelectionBounds:newBounds toAnnotation:_activeSelectionAnnotation startBounds:_selectionStartBounds startPoints:_selectionStartPoints];
1941
- [self refreshDisplay];
1942
- }
1943
-
1944
- - (void)endSelectionInteraction
1945
- {
1946
- _activeSelectionAnnotation = nil;
1947
- _activeSelectionMode = nil;
1948
- _activeSelectionHandle = nil;
1949
- _selectionStartPoints = nil;
1950
- _selectionPageIndex = -1;
1951
- }
1952
-
1953
- - (void)applySelectionBounds:(CGRect)newBounds toAnnotation:(NSMutableDictionary *)annotation startBounds:(CGRect)startBounds startPoints:(NSArray *)startPoints
1954
- {
1955
- if (!annotation) {
1956
- return;
1957
- }
1958
-
1959
- NSString *type = annotation[@"type"];
1960
- if ([type isEqualToString:@"ink"]) {
1961
- if (![startPoints isKindOfClass:[NSArray class]]) {
1962
- return;
1963
- }
1964
-
1965
- CGFloat startWidth = MAX(startBounds.size.width, 0.001f);
1966
- CGFloat startHeight = MAX(startBounds.size.height, 0.001f);
1967
- CGFloat newWidth = MAX(newBounds.size.width, 0.001f);
1968
- CGFloat newHeight = MAX(newBounds.size.height, 0.001f);
1969
-
1970
- NSMutableArray *transformedPoints = [NSMutableArray arrayWithCapacity:startPoints.count];
1971
- for (NSDictionary *point in startPoints) {
1972
- if (![point isKindOfClass:[NSDictionary class]]) {
1973
- continue;
1974
- }
1975
-
1976
- CGFloat pointX = [point[@"x"] doubleValue];
1977
- CGFloat pointY = [point[@"y"] doubleValue];
1978
- CGFloat xRatio = (pointX - startBounds.origin.x) / startWidth;
1979
- CGFloat yRatio = (pointY - startBounds.origin.y) / startHeight;
1980
- CGFloat x = MIN(1.0f, MAX(0.0f, newBounds.origin.x + (xRatio * newWidth)));
1981
- CGFloat y = MIN(1.0f, MAX(0.0f, newBounds.origin.y + (yRatio * newHeight)));
1982
- [transformedPoints addObject:@{@"x": @(x), @"y": @(y)}];
1983
- }
1984
-
1985
- annotation[@"points"] = transformedPoints;
1986
- return;
1987
- }
1988
-
1989
- CGFloat x = MIN(1.0f, MAX(0.0f, newBounds.origin.x));
1990
- CGFloat y = MIN(1.0f, MAX(0.0f, newBounds.origin.y));
1991
- CGFloat width = MIN(1.0f, MAX(0.01f, newBounds.size.width));
1992
- CGFloat height = MIN(1.0f, MAX(0.01f, newBounds.size.height));
1993
- annotation[@"bounds"] = @{@"x": @(x),
1994
- @"y": @(y),
1995
- @"width": @(width),
1996
- @"height": @(height)};
1997
- }
1998
-
1999
- - (void)drawSelectionDecoration
2000
- {
2001
- if (!_annotationMode || !_annotationEditable || ![_annotationTool isEqualToString:@"select"]) {
2002
- return;
2003
- }
2004
-
2005
- NSDictionary *annotation = [self selectedAnnotation];
2006
- if (!annotation) {
2007
- return;
2008
- }
2009
-
2010
- NSNumber *pageIndexValue = annotation[@"page"];
2011
- NSInteger pageIndex = pageIndexValue.integerValue - 1;
2012
- if (pageIndex < 0 || pageIndex >= _pdfDocument.pageCount) {
2013
- return;
2014
- }
2015
-
2016
- PDFPage *page = [_pdfDocument pageAtIndex:pageIndex];
2017
- CGRect rect = [self viewRectForAnnotation:annotation page:page];
2018
- if (CGRectIsEmpty(rect)) {
2019
- return;
2020
- }
2021
-
2022
- UIColor *outlineColor = [UIColor colorWithRed:0.13 green:0.27 blue:0.67 alpha:0.9];
2023
- UIBezierPath *outlinePath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:4.0f];
2024
- outlinePath.lineWidth = 2.0f;
2025
- [outlineColor setStroke];
2026
- [outlinePath stroke];
2027
-
2028
- if ([self annotationSupportsResize:annotation]) {
2029
- CGRect resizeHandle = [self resizeHandleRectForRect:rect];
2030
- [[UIColor colorWithRed:0.13 green:0.27 blue:0.67 alpha:0.95] setFill];
2031
- UIBezierPath *resizePath = [UIBezierPath bezierPathWithRoundedRect:resizeHandle cornerRadius:2.0f];
2032
- [resizePath fill];
2033
- }
2034
- }
2035
-
2036
- - (NSDictionary *)normalizedBoundsForViewRect:(CGRect)viewRect page:(PDFPage *)page
2037
- {
2038
- if (!self.pdfView || !page) {
2039
- return @{@"x": @0, @"y": @0, @"width": @0, @"height": @0};
2040
- }
2041
-
2042
- CGPoint topLeft = [self normalizedPointForViewPoint:viewRect.origin page:page];
2043
- CGPoint bottomRight = [self normalizedPointForViewPoint:CGPointMake(CGRectGetMaxX(viewRect), CGRectGetMaxY(viewRect)) page:page];
2044
-
2045
- CGFloat minX = MIN(topLeft.x, bottomRight.x);
2046
- CGFloat maxX = MAX(topLeft.x, bottomRight.x);
2047
- CGFloat minY = MIN(topLeft.y, bottomRight.y);
2048
- CGFloat maxY = MAX(topLeft.y, bottomRight.y);
2049
-
2050
- return @{@"x": @(MAX(0, minX)),
2051
- @"y": @(MAX(0, minY)),
2052
- @"width": @(MAX(0, maxX - minX)),
2053
- @"height": @(MAX(0, maxY - minY))};
2054
- }
2055
-
2056
- - (NSString *)nextLocalAnnotationId
2057
- {
2058
- return [NSString stringWithFormat:@"local-%@", RNPDFGenerateAnnotationId()];
2059
- }
2060
-
2061
- - (UIColor *)colorForAnnotationType:(NSString *)type style:(NSDictionary *)style
2062
- {
2063
- NSString *normalizedType = [self normalizedAnnotationType:type];
2064
- NSString *colorString = [style isKindOfClass:[NSDictionary class]] ? style[@"color"] : nil;
2065
- if (colorString) {
2066
- return RNPDFColorFromHexString(colorString, UIColor.blackColor);
2067
- }
2068
-
2069
- if ([normalizedType isEqualToString:@"highlight"]) {
2070
- return [UIColor colorWithRed:1.0 green:0.93 blue:0.2 alpha:0.35];
2071
- }
2072
- if ([normalizedType isEqualToString:@"text"]) {
2073
- return [UIColor colorWithRed:0.13 green:0.27 blue:0.67 alpha:1.0];
2074
- }
2075
-
2076
- return UIColor.blackColor;
2077
- }
2078
-
2079
- - (CGFloat)lineWidthForAnnotation:(NSDictionary *)annotation
2080
- {
2081
- NSDictionary *style = [annotation[@"style"] isKindOfClass:[NSDictionary class]] ? annotation[@"style"] : nil;
2082
- NSNumber *thickness = style[@"thickness"];
2083
- if ([thickness isKindOfClass:[NSNumber class]]) {
2084
- return MAX(1.0f, thickness.floatValue);
2085
- }
2086
-
2087
- return 2.0f;
2088
- }
2089
-
2090
- - (UIFont *)fontForAnnotation:(NSDictionary *)annotation
2091
- {
2092
- NSDictionary *style = [annotation[@"style"] isKindOfClass:[NSDictionary class]] ? annotation[@"style"] : nil;
2093
- NSNumber *fontSize = style[@"fontSize"];
2094
- CGFloat size = [fontSize isKindOfClass:[NSNumber class]] ? MAX(10.0f, fontSize.floatValue) : 15.0f;
2095
- return [UIFont systemFontOfSize:size];
2096
- }
2097
-
2098
- - (NSTextAlignment)alignmentForAnnotation:(NSDictionary *)annotation
2099
- {
2100
- NSDictionary *style = [annotation[@"style"] isKindOfClass:[NSDictionary class]] ? annotation[@"style"] : nil;
2101
- NSString *alignment = style[@"textAlign"];
2102
- if ([alignment isEqualToString:@"center"]) {
2103
- return NSTextAlignmentCenter;
2104
- }
2105
- if ([alignment isEqualToString:@"right"]) {
2106
- return NSTextAlignmentRight;
2107
- }
2108
-
2109
- return NSTextAlignmentLeft;
2110
- }
2111
-
2112
- - (void)drawRect:(CGRect)rect
2113
- {
2114
- [super drawRect:rect];
2115
-
2116
- if (!_pdfDocument || _draftAnnotations.count == 0) {
2117
- return;
2118
- }
2119
-
2120
- CGContextRef context = UIGraphicsGetCurrentContext();
2121
- if (!context) {
2122
- return;
2123
- }
2124
-
2125
- for (NSDictionary *annotation in _draftAnnotations) {
2126
- NSNumber *pageIndexValue = annotation[@"page"];
2127
- NSInteger pageIndex = pageIndexValue.integerValue - 1;
2128
- if (pageIndex < 0 || pageIndex >= _pdfDocument.pageCount) {
2129
- continue;
2130
- }
2131
-
2132
- PDFPage *page = [_pdfDocument pageAtIndex:pageIndex];
2133
- NSString *type = [self normalizedAnnotationType:annotation[@"type"]];
2134
- if ([type isEqualToString:@"ink"]) {
2135
- NSArray *points = annotation[@"points"];
2136
- if (points.count < 2) {
2137
- continue;
2138
- }
2139
-
2140
- UIBezierPath *path = [UIBezierPath bezierPath];
2141
- BOOL firstPoint = YES;
2142
- for (NSDictionary *point in points) {
2143
- CGPoint normalizedPoint = CGPointMake([point[@"x"] doubleValue], [point[@"y"] doubleValue]);
2144
- CGPoint viewPoint = [self viewPointForNormalizedPoint:normalizedPoint page:page];
2145
- if (firstPoint) {
2146
- [path moveToPoint:viewPoint];
2147
- firstPoint = NO;
2148
- } else {
2149
- [path addLineToPoint:viewPoint];
2150
- }
2151
- }
2152
-
2153
- [[self colorForAnnotationType:type style:annotation[@"style"]] setStroke];
2154
- path.lineWidth = [self lineWidthForAnnotation:annotation];
2155
- path.lineJoinStyle = kCGLineJoinRound;
2156
- path.lineCapStyle = kCGLineCapRound;
2157
- [path stroke];
2158
- } else if ([type isEqualToString:@"text"]) {
2159
- NSDictionary *bounds = annotation[@"bounds"];
2160
- CGRect viewRect = [self viewRectForNormalizedBounds:bounds page:page];
2161
- if (CGRectIsEmpty(viewRect)) {
2162
- continue;
2163
- }
2164
-
2165
- UIColor *borderColor = [self colorForAnnotationType:type style:annotation[@"style"]];
2166
- [[UIColor colorWithWhite:1.0 alpha:0.78] setFill];
2167
- UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:viewRect cornerRadius:4.0f];
2168
- [path fill];
2169
- [borderColor setStroke];
2170
- path.lineWidth = 1.0f;
2171
- [path stroke];
2172
-
2173
- NSString *text = annotation[@"text"];
2174
- if (![text isKindOfClass:[NSString class]]) {
2175
- text = @"";
2176
- }
2177
-
2178
- NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
2179
- paragraphStyle.alignment = [self alignmentForAnnotation:annotation];
2180
- NSDictionary *attributes = @{
2181
- NSFontAttributeName: [self fontForAnnotation:annotation],
2182
- NSForegroundColorAttributeName: borderColor,
2183
- NSParagraphStyleAttributeName: paragraphStyle,
2184
- };
2185
- [text drawInRect:CGRectInset(viewRect, 6.0f, 4.0f) withAttributes:attributes];
2186
- } else if ([type isEqualToString:@"highlight"]) {
2187
- NSDictionary *bounds = annotation[@"bounds"];
2188
- CGRect viewRect = [self viewRectForNormalizedBounds:bounds page:page];
2189
- if (CGRectIsEmpty(viewRect)) {
2190
- continue;
2191
- }
2192
-
2193
- UIColor *fillColor = [self colorForAnnotationType:type style:annotation[@"style"]];
2194
- CGContextSetFillColorWithColor(context, fillColor.CGColor);
2195
- CGContextFillRect(context, viewRect);
2196
- }
2197
- }
2198
-
2199
- [self drawSelectionDecoration];
2200
- }
2201
-
2202
- - (void)beginInkAtViewPoint:(CGPoint)viewPoint page:(PDFPage *)page
2203
- {
2204
- if (!self.annotationEditable || !page) {
2205
- return;
2206
- }
2207
-
2208
- NSMutableDictionary *annotation = [@{
2209
- @"id": [self nextLocalAnnotationId],
2210
- @"page": @([_pdfDocument indexForPage:page] + 1),
2211
- @"type": @"ink",
2212
- @"points": [NSMutableArray array],
2213
- @"style": @{@"color": _annotationInkColor ?: @"#111111", @"thickness": @(_annotationInkThickness > 0 ? _annotationInkThickness : 2.0f)}
2214
- } mutableCopy];
2215
-
2216
- [_draftAnnotations addObject:annotation];
2217
- _activeInkAnnotation = annotation;
2218
- [self appendInkPointAtViewPoint:viewPoint page:page];
2219
- }
2220
-
2221
- - (void)appendInkPointAtViewPoint:(CGPoint)viewPoint page:(PDFPage *)page
2222
- {
2223
- if (!_activeInkAnnotation || !page) {
2224
- return;
2225
- }
2226
-
2227
- CGPoint normalizedPoint = [self normalizedPointForViewPoint:viewPoint page:page];
2228
- NSMutableArray *points = _activeInkAnnotation[@"points"];
2229
- if (![points isKindOfClass:[NSMutableArray class]]) {
2230
- points = [NSMutableArray array];
2231
- _activeInkAnnotation[@"points"] = points;
2232
- }
2233
-
2234
- [points addObject:@{@"x": @(normalizedPoint.x), @"y": @(normalizedPoint.y)}];
2235
- [self refreshDisplay];
2236
- }
2237
-
2238
- - (void)endInk
2239
- {
2240
- _activeInkAnnotation = nil;
2241
- [self refreshDisplay];
2242
- }
2243
-
2244
- - (void)beginMarkupAtViewPoint:(CGPoint)viewPoint page:(PDFPage *)page type:(NSString *)type
2245
- {
2246
- if (!self.annotationEditable || !page) {
2247
- return;
2248
- }
2249
-
2250
- CGPoint normalizedPoint = [self normalizedPointForViewPoint:viewPoint page:page];
2251
- _activeMarkupStartNormalized = normalizedPoint;
2252
-
2253
- NSMutableDictionary *annotation = [@{
2254
- @"id": [self nextLocalAnnotationId],
2255
- @"page": @([_pdfDocument indexForPage:page] + 1),
2256
- @"type": @"highlight",
2257
- @"bounds": @{@"x": @(normalizedPoint.x), @"y": @(normalizedPoint.y), @"width": @0, @"height": @0},
2258
- @"style": @{}
2259
- } mutableCopy];
2260
-
2261
- [_draftAnnotations addObject:annotation];
2262
- _activeMarkupAnnotation = annotation;
2263
- [self refreshDisplay];
2264
- }
2265
-
2266
- - (void)updateMarkupAtViewPoint:(CGPoint)viewPoint page:(PDFPage *)page
2267
- {
2268
- if (!_activeMarkupAnnotation || !page) {
2269
- return;
2270
- }
2271
-
2272
- CGPoint currentPoint = [self normalizedPointForViewPoint:viewPoint page:page];
2273
- CGFloat minX = MIN(_activeMarkupStartNormalized.x, currentPoint.x);
2274
- CGFloat minY = MIN(_activeMarkupStartNormalized.y, currentPoint.y);
2275
- CGFloat maxX = MAX(_activeMarkupStartNormalized.x, currentPoint.x);
2276
- CGFloat maxY = MAX(_activeMarkupStartNormalized.y, currentPoint.y);
2277
-
2278
- _activeMarkupAnnotation[@"bounds"] = @{@"x": @(minX), @"y": @(minY), @"width": @(MAX(0, maxX - minX)), @"height": @(MAX(0, maxY - minY))};
2279
- [self refreshDisplay];
2280
- }
2281
-
2282
- - (void)endMarkup
2283
- {
2284
- _activeMarkupAnnotation = nil;
2285
- [self refreshDisplay];
2286
- }
2287
-
2288
- - (void)createTextAnnotationAtViewPoint:(CGPoint)viewPoint page:(PDFPage *)page
2289
- {
2290
- if (!self.annotationEditable || !page) {
2291
- return;
2292
- }
2293
-
2294
- [self commitTextEditingIfNeeded];
2295
-
2296
- CGPoint normalizedPoint = [self normalizedPointForViewPoint:viewPoint page:page];
2297
- CGFloat width = 0.25f;
2298
- CGFloat height = 0.12f;
2299
- CGFloat maxX = MAX(0.0f, 1.0f - width);
2300
- CGFloat maxY = MAX(0.0f, 1.0f - height);
2301
- CGFloat x = MIN(MAX(normalizedPoint.x, 0.0f), maxX);
2302
- CGFloat y = MIN(MAX(normalizedPoint.y, 0.0f), maxY);
2303
- NSDictionary *bounds = @{@"x": @(x), @"y": @(y), @"width": @(width), @"height": @(height)};
2304
-
2305
- NSMutableDictionary *annotation = [@{
2306
- @"id": [self nextLocalAnnotationId],
2307
- @"page": @([_pdfDocument indexForPage:page] + 1),
2308
- @"type": @"text",
2309
- @"bounds": bounds,
2310
- @"text": @"",
2311
- @"style": @{@"color": @"#2244aa", @"fontSize": @(15.0f), @"textAlign": @"left"}
2312
- } mutableCopy];
2313
-
2314
- [_draftAnnotations addObject:annotation];
2315
- _activeTextAnnotation = annotation;
2316
-
2317
- UITextView *textView = [[UITextView alloc] initWithFrame:[self viewRectForNormalizedBounds:bounds page:page]];
2318
- textView.delegate = self;
2319
- textView.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.9f];
2320
- textView.layer.borderColor = [UIColor colorWithRed:0.2 green:0.4 blue:1.0 alpha:0.9].CGColor;
2321
- textView.layer.borderWidth = 1.0f;
2322
- textView.layer.cornerRadius = 4.0f;
2323
- textView.clipsToBounds = YES;
2324
- textView.textColor = [self colorForAnnotationType:@"text" style:annotation[@"style"]];
2325
- textView.font = [self fontForAnnotation:annotation];
2326
- textView.textAlignment = [self alignmentForAnnotation:annotation];
2327
- textView.scrollEnabled = YES;
2328
- textView.returnKeyType = UIReturnKeyDefault;
2329
-
2330
- if (_activeTextView) {
2331
- [_activeTextView removeFromSuperview];
2332
- }
2333
-
2334
- _activeTextView = textView;
2335
- [self addSubview:_activeTextView];
2336
- [_activeTextView becomeFirstResponder];
2337
- [self refreshDisplay];
2338
- }
2339
-
2340
- - (void)updateActiveTextEditorFrame
2341
- {
2342
- if (!_activeTextView || !_activeTextAnnotation || !self.pdfDocument || !self.pdfView) {
2343
- return;
2344
- }
2345
-
2346
- NSNumber *pageNumber = _activeTextAnnotation[@"page"];
2347
- NSInteger pageIndex = pageNumber.integerValue - 1;
2348
- if (pageIndex < 0 || pageIndex >= self.pdfDocument.pageCount) {
2349
- return;
2350
- }
2351
-
2352
- PDFPage *page = [self.pdfDocument pageAtIndex:pageIndex];
2353
- _activeTextView.frame = [self viewRectForNormalizedBounds:_activeTextAnnotation[@"bounds"] page:page];
2354
- }
2355
-
2356
- - (void)commitTextEditingIfNeeded
2357
- {
2358
- if (!_activeTextView || !_activeTextAnnotation) {
2359
- return;
2360
- }
2361
-
2362
- _activeTextAnnotation[@"text"] = _activeTextView.text ?: @"";
2363
- [_activeTextView resignFirstResponder];
2364
- [_activeTextView removeFromSuperview];
2365
- _activeTextView = nil;
2366
- _activeTextAnnotation = nil;
2367
- [self refreshDisplay];
2368
- }
2369
-
2370
- - (void)textViewDidChange:(UITextView *)textView
2371
- {
2372
- if (textView == _activeTextView && _activeTextAnnotation) {
2373
- _activeTextAnnotation[@"text"] = textView.text ?: @"";
2374
- [self setNeedsDisplay];
2375
- }
2376
- }
2377
-
2378
- - (void)textViewDidEndEditing:(UITextView *)textView
2379
- {
2380
- if (textView == _activeTextView) {
2381
- [self commitTextEditingIfNeeded];
2382
- }
2383
1140
  }
2384
1141
 
2385
1142
  @end