Skip to content

Commit f2bae96

Browse files
authored
Merge pull request #350 from PSPDFKit/rad/annotation-processing
Add API for annotation processing
2 parents 9c065e5 + fb7d16e commit f2bae96

File tree

14 files changed

+623
-59
lines changed

14 files changed

+623
-59
lines changed

android/src/main/java/com/pspdfkit/react/PSPDFKitModule.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,22 @@
3333
import com.facebook.react.bridge.ReactMethod;
3434
import com.facebook.react.bridge.ReadableMap;
3535
import com.pspdfkit.PSPDFKit;
36+
import com.pspdfkit.annotations.Annotation;
37+
import com.pspdfkit.annotations.AnnotationType;
3638
import com.pspdfkit.document.PdfDocument;
39+
import com.pspdfkit.document.PdfDocumentLoader;
3740
import com.pspdfkit.document.image.CameraImagePickerFragment;
3841
import com.pspdfkit.document.image.GalleryImagePickerFragment;
42+
import com.pspdfkit.document.processor.PdfProcessor;
43+
import com.pspdfkit.document.processor.PdfProcessorTask;
3944
import com.pspdfkit.instant.ui.InstantPdfActivity;
4045
import com.pspdfkit.listeners.SimpleDocumentListener;
46+
import com.pspdfkit.react.helper.ConversionHelpers;
4147
import com.pspdfkit.ui.PdfActivity;
4248
import com.pspdfkit.ui.PdfFragment;
4349

50+
import java.io.File;
51+
import java.util.EnumSet;
4452
import java.util.HashMap;
4553
import java.util.Map;
4654

@@ -178,6 +186,46 @@ public void setLicenseKey(@NonNull String licenseKey) {
178186
PSPDFKit.initialize(getReactApplicationContext().getApplicationContext(), licenseKey);
179187
}
180188

189+
@ReactMethod
190+
public void processAnnotations(@NonNull final String processingMode,
191+
@Nullable final String annotationType,
192+
@NonNull final String sourceDocumentPath,
193+
@NonNull final String targetDocumentPath,
194+
@NonNull final Promise promise) {
195+
PdfDocumentLoader.openDocumentAsync(getReactApplicationContext(), Uri.parse(sourceDocumentPath))
196+
.flatMapCompletable(document -> {
197+
PdfProcessorTask task = PdfProcessorTask.fromDocument(document);
198+
final EnumSet<AnnotationType> types = ConversionHelpers.getAnnotationTypeFromString(annotationType);
199+
final PdfProcessorTask.AnnotationProcessingMode mode = getProcessingModeFromString(processingMode);
200+
for (AnnotationType type : types) {
201+
task.changeAnnotationsOfType(type, mode);
202+
}
203+
204+
return PdfProcessor.processDocumentAsync(task, new File(targetDocumentPath)).ignoreElements();
205+
})
206+
.subscribe(() -> {
207+
promise.resolve(Boolean.TRUE);
208+
}, throwable -> {
209+
promise.reject(throwable);
210+
});
211+
}
212+
213+
private static PdfProcessorTask.AnnotationProcessingMode getProcessingModeFromString(@NonNull final String mode) {
214+
if ("print".equalsIgnoreCase(mode)) {
215+
return PdfProcessorTask.AnnotationProcessingMode.PRINT;
216+
} else if ("remove".equalsIgnoreCase(mode)) {
217+
// Called remove to match iOS.
218+
return PdfProcessorTask.AnnotationProcessingMode.DELETE;
219+
} else if ("flatten".equalsIgnoreCase(mode)) {
220+
return PdfProcessorTask.AnnotationProcessingMode.FLATTEN;
221+
} else if ("embed".equalsIgnoreCase(mode)) {
222+
// Called embed to match iOS.
223+
return PdfProcessorTask.AnnotationProcessingMode.KEEP;
224+
} else {
225+
return PdfProcessorTask.AnnotationProcessingMode.KEEP;
226+
}
227+
}
228+
181229
@NonNull
182230
@Override
183231
public Map<String, Object> getConstants() {
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.pspdfkit.react.helper;
2+
3+
import androidx.annotation.Nullable;
4+
5+
import com.pspdfkit.annotations.AnnotationType;
6+
7+
import java.util.EnumSet;
8+
9+
public class ConversionHelpers {
10+
11+
public static EnumSet<AnnotationType> getAnnotationTypeFromString(@Nullable final String type) {
12+
if (type == null || "all".equalsIgnoreCase(type)) {
13+
return EnumSet.allOf(AnnotationType.class);
14+
}
15+
if ("pspdfkit/ink".equalsIgnoreCase(type)) {
16+
return EnumSet.of(AnnotationType.INK);
17+
}
18+
if ("pspdfkit/link".equalsIgnoreCase(type)) {
19+
return EnumSet.of(AnnotationType.LINK);
20+
}
21+
if ("pspdfkit/markup/highlight".equalsIgnoreCase(type)) {
22+
return EnumSet.of(AnnotationType.HIGHLIGHT);
23+
}
24+
if ("pspdfkit/markup/squiggly".equalsIgnoreCase(type)) {
25+
return EnumSet.of(AnnotationType.SQUIGGLY);
26+
}
27+
if ("pspdfkit/markup/strikeout".equalsIgnoreCase(type)) {
28+
return EnumSet.of(AnnotationType.STRIKEOUT);
29+
}
30+
if ("pspdfkit/markup/underline".equalsIgnoreCase(type)) {
31+
return EnumSet.of(AnnotationType.UNDERLINE);
32+
}
33+
if ("pspdfkit/note".equalsIgnoreCase(type)) {
34+
return EnumSet.of(AnnotationType.NOTE);
35+
}
36+
if ("pspdfkit/shape/ellipse".equalsIgnoreCase(type)) {
37+
return EnumSet.of(AnnotationType.CIRCLE);
38+
}
39+
if ("pspdfkit/shape/line".equalsIgnoreCase(type)) {
40+
return EnumSet.of(AnnotationType.LINE);
41+
}
42+
if ("pspdfkit/shape/polygon".equalsIgnoreCase(type)) {
43+
return EnumSet.of(AnnotationType.POLYGON);
44+
}
45+
if ("pspdfkit/shape/polyline".equalsIgnoreCase(type)) {
46+
return EnumSet.of(AnnotationType.POLYLINE);
47+
}
48+
if ("pspdfkit/shape/rectangle".equalsIgnoreCase(type)) {
49+
return EnumSet.of(AnnotationType.SQUARE);
50+
}
51+
if ("pspdfkit/text".equalsIgnoreCase(type)) {
52+
return EnumSet.of(AnnotationType.FREETEXT);
53+
}
54+
return EnumSet.noneOf(AnnotationType.class);
55+
}
56+
}

android/src/main/java/com/pspdfkit/views/PdfView.java

Lines changed: 6 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import com.facebook.react.common.MapBuilder;
1818
import com.facebook.react.uimanager.events.EventDispatcher;
1919
import com.pspdfkit.annotations.Annotation;
20-
import com.pspdfkit.annotations.AnnotationType;
2120
import com.pspdfkit.configuration.activity.PdfActivityConfiguration;
2221
import com.pspdfkit.document.PdfDocument;
2322
import com.pspdfkit.document.PdfDocumentLoader;
@@ -54,7 +53,6 @@
5453
import java.io.File;
5554
import java.util.ArrayList;
5655
import java.util.Collections;
57-
import java.util.EnumSet;
5856
import java.util.List;
5957
import java.util.Map;
6058
import java.util.NoSuchElementException;
@@ -72,6 +70,8 @@
7270
import io.reactivex.schedulers.Schedulers;
7371
import io.reactivex.subjects.BehaviorSubject;
7472

73+
import static com.pspdfkit.react.helper.ConversionHelpers.getAnnotationTypeFromString;
74+
7575
/**
7676
* This view displays a {@link com.pspdfkit.ui.PdfFragment} and all associated toolbars.
7777
*/
@@ -443,60 +443,16 @@ public Single<List<Annotation>> getAnnotations(final int pageIndex, @Nullable fi
443443
return getCurrentPdfFragment()
444444
.map(pdfFragment -> pdfFragment.getDocument())
445445
.flatMap((Function<PdfDocument, ObservableSource<Annotation>>) pdfDocument ->
446-
pdfDocument.getAnnotationProvider().getAllAnnotationsOfTypeAsync(getTypeFromString(type), pageIndex, 1)).toList();
446+
pdfDocument.getAnnotationProvider().getAllAnnotationsOfTypeAsync(getAnnotationTypeFromString(type), pageIndex, 1)).toList();
447447
}
448448

449449
public Single<List<Annotation>> getAllAnnotations(@Nullable final String type) {
450450
return getCurrentPdfFragment().map(PdfFragment::getDocument)
451-
.flatMap(pdfDocument -> pdfDocument.getAnnotationProvider().getAllAnnotationsOfTypeAsync(getTypeFromString(type)))
451+
.flatMap(pdfDocument -> pdfDocument.getAnnotationProvider().getAllAnnotationsOfTypeAsync(getAnnotationTypeFromString(type)))
452452
.toList();
453453
}
454454

455-
private EnumSet<AnnotationType> getTypeFromString(@Nullable String type) {
456-
if (type == null) {
457-
return EnumSet.allOf(AnnotationType.class);
458-
}
459-
if ("pspdfkit/ink".equalsIgnoreCase(type)) {
460-
return EnumSet.of(AnnotationType.INK);
461-
}
462-
if ("pspdfkit/link".equalsIgnoreCase(type)) {
463-
return EnumSet.of(AnnotationType.LINK);
464-
}
465-
if ("pspdfkit/markup/highlight".equalsIgnoreCase(type)) {
466-
return EnumSet.of(AnnotationType.HIGHLIGHT);
467-
}
468-
if ("pspdfkit/markup/squiggly".equalsIgnoreCase(type)) {
469-
return EnumSet.of(AnnotationType.SQUIGGLY);
470-
}
471-
if ("pspdfkit/markup/strikeout".equalsIgnoreCase(type)) {
472-
return EnumSet.of(AnnotationType.STRIKEOUT);
473-
}
474-
if ("pspdfkit/markup/underline".equalsIgnoreCase(type)) {
475-
return EnumSet.of(AnnotationType.UNDERLINE);
476-
}
477-
if ("pspdfkit/note".equalsIgnoreCase(type)) {
478-
return EnumSet.of(AnnotationType.NOTE);
479-
}
480-
if ("pspdfkit/shape/ellipse".equalsIgnoreCase(type)) {
481-
return EnumSet.of(AnnotationType.CIRCLE);
482-
}
483-
if ("pspdfkit/shape/line".equalsIgnoreCase(type)) {
484-
return EnumSet.of(AnnotationType.LINE);
485-
}
486-
if ("pspdfkit/shape/polygon".equalsIgnoreCase(type)) {
487-
return EnumSet.of(AnnotationType.POLYGON);
488-
}
489-
if ("pspdfkit/shape/polyline".equalsIgnoreCase(type)) {
490-
return EnumSet.of(AnnotationType.POLYLINE);
491-
}
492-
if ("pspdfkit/shape/rectangle".equalsIgnoreCase(type)) {
493-
return EnumSet.of(AnnotationType.SQUARE);
494-
}
495-
if ("pspdfkit/text".equalsIgnoreCase(type)) {
496-
return EnumSet.of(AnnotationType.FREETEXT);
497-
}
498-
return EnumSet.noneOf(AnnotationType.class);
499-
}
455+
500456

501457
public Disposable addAnnotation(final int requestId, ReadableMap annotation) {
502458
return getCurrentPdfFragment().map(PdfFragment::getDocument).subscribeOn(Schedulers.io())
@@ -524,7 +480,7 @@ public Disposable removeAnnotation(final int requestId, ReadableMap annotation)
524480
return Observable.empty();
525481
}
526482

527-
return pdfDocument.getAnnotationProvider().getAllAnnotationsOfTypeAsync(getTypeFromString(type), pageIndex, 1)
483+
return pdfDocument.getAnnotationProvider().getAllAnnotationsOfTypeAsync(getAnnotationTypeFromString(type), pageIndex, 1)
528484
.filter(annotationToFilter -> name.equals(annotationToFilter.getName()))
529485
.map(filteredAnnotation -> new Pair<>(filteredAnnotation, pdfDocument));
530486
})

ios/RCTPSPDFKit.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
657278111D86AEC600A5E1A8 /* RCTConvert+PSPDFDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = 657278101D86AEC600A5E1A8 /* RCTConvert+PSPDFDocument.m */; };
1313
84545BA4210A5CCF00FBB0A7 /* RCTConvert+PSPDFAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 84545BA2210A5CCF00FBB0A7 /* RCTConvert+PSPDFAnnotation.m */; };
1414
84694AA822AFC7510077FD01 /* RCTConvert+UIBarButtonItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 84694AA722AFC7510077FD01 /* RCTConvert+UIBarButtonItem.m */; };
15+
84B9870023FC208600C6711A /* RCTConvert+PSPDFAnnotationChange.m in Sources */ = {isa = PBXBuildFile; fileRef = 84B986FF23FC208600C6711A /* RCTConvert+PSPDFAnnotationChange.m */; };
1516
84BC2EAD229EE9FF00A386C6 /* RCTConvert+PSPDFViewMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 84BC2EAC229EE9FF00A386C6 /* RCTConvert+PSPDFViewMode.m */; };
1617
B783BA3421C3F55300FD981A /* RCTConvert+PSPDFAnnotationToolbarConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = B783BA3321C3F55300FD981A /* RCTConvert+PSPDFAnnotationToolbarConfiguration.m */; };
1718
F84F8B192032D54F00153D9E /* RCTPSPDFKitView.m in Sources */ = {isa = PBXBuildFile; fileRef = F84F8B182032D54F00153D9E /* RCTPSPDFKitView.m */; };
@@ -42,6 +43,8 @@
4243
84545BA3210A5CCF00FBB0A7 /* RCTConvert+PSPDFAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+PSPDFAnnotation.h"; sourceTree = "<group>"; };
4344
84694AA622AFC7510077FD01 /* RCTConvert+UIBarButtonItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+UIBarButtonItem.h"; sourceTree = "<group>"; };
4445
84694AA722AFC7510077FD01 /* RCTConvert+UIBarButtonItem.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+UIBarButtonItem.m"; sourceTree = "<group>"; };
46+
84B986FE23FC208600C6711A /* RCTConvert+PSPDFAnnotationChange.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+PSPDFAnnotationChange.h"; sourceTree = "<group>"; };
47+
84B986FF23FC208600C6711A /* RCTConvert+PSPDFAnnotationChange.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+PSPDFAnnotationChange.m"; sourceTree = "<group>"; };
4548
84BC2EAB229EE9FF00A386C6 /* RCTConvert+PSPDFViewMode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+PSPDFViewMode.h"; sourceTree = "<group>"; };
4649
84BC2EAC229EE9FF00A386C6 /* RCTConvert+PSPDFViewMode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+PSPDFViewMode.m"; sourceTree = "<group>"; };
4750
B783BA3221C3F55300FD981A /* RCTConvert+PSPDFAnnotationToolbarConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+PSPDFAnnotationToolbarConfiguration.h"; sourceTree = "<group>"; };
@@ -92,6 +95,8 @@
9295
84BC2EAC229EE9FF00A386C6 /* RCTConvert+PSPDFViewMode.m */,
9396
84694AA622AFC7510077FD01 /* RCTConvert+UIBarButtonItem.h */,
9497
84694AA722AFC7510077FD01 /* RCTConvert+UIBarButtonItem.m */,
98+
84B986FE23FC208600C6711A /* RCTConvert+PSPDFAnnotationChange.h */,
99+
84B986FF23FC208600C6711A /* RCTConvert+PSPDFAnnotationChange.m */,
95100
);
96101
path = Converters;
97102
sourceTree = "<group>";
@@ -178,6 +183,7 @@
178183
84545BA4210A5CCF00FBB0A7 /* RCTConvert+PSPDFAnnotation.m in Sources */,
179184
6540D1841D89D22E00B8F94F /* RCTPSPDFKitManager.m in Sources */,
180185
84694AA822AFC7510077FD01 /* RCTConvert+UIBarButtonItem.m in Sources */,
186+
84B9870023FC208600C6711A /* RCTConvert+PSPDFAnnotationChange.m in Sources */,
181187
B783BA3421C3F55300FD981A /* RCTConvert+PSPDFAnnotationToolbarConfiguration.m in Sources */,
182188
F84F8B192032D54F00153D9E /* RCTPSPDFKitView.m in Sources */,
183189
6572780C1D86AE7300A5E1A8 /* RCTConvert+PSPDFConfiguration.m in Sources */,
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// Copyright © 2020 PSPDFKit GmbH. All rights reserved.
3+
//
4+
// THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
5+
// AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.
6+
// UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
7+
// This notice may not be removed from this file.
8+
//
9+
10+
#import <React/RCTConvert.h>
11+
@import PSPDFKit;
12+
@import PSPDFKitUI;
13+
14+
@interface RCTConvert (PSPDFAnnotationChange)
15+
16+
+ (PSPDFAnnotationChange)PSPDFAnnotationChange:(NSString *)annotationChange;
17+
18+
@end
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//
2+
// Copyright © 2020 PSPDFKit GmbH. All rights reserved.
3+
//
4+
// THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
5+
// AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.
6+
// UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
7+
// This notice may not be removed from this file.
8+
//
9+
10+
#import "RCTConvert+PSPDFAnnotationChange.h"
11+
12+
@implementation RCTConvert (PSPDFAnnotationChange)
13+
14+
+ (PSPDFAnnotationChange)PSPDFAnnotationChange:(NSString *)annotationChange {
15+
if ([annotationChange isEqualToString:@"flatten"]) {
16+
return PSPDFAnnotationChangeFlatten;
17+
} else if ([annotationChange isEqualToString:@"remove"]) {
18+
return PSPDFAnnotationChangeRemove;
19+
} else if ([annotationChange isEqualToString:@"embed"]) {
20+
return PSPDFAnnotationChangeEmbed;
21+
} else if ([annotationChange isEqualToString:@"print"]) {
22+
return PSPDFAnnotationChangePrint;
23+
} else {
24+
return PSPDFAnnotationChangeEmbed;
25+
}
26+
}
27+
28+
@end

ios/RCTPSPDFKit/RCTPSPDFKitManager.m

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#import <React/RCTLog.h>
1313
#import <React/RCTUtils.h>
1414
#import <React/RCTConvert.h>
15+
#import "RCTConvert+PSPDFAnnotation.h"
16+
#import "RCTConvert+PSPDFAnnotationChange.h"
1517

1618
#define PROPERTY(property) NSStringFromSelector(@selector(property))
1719

@@ -77,6 +79,28 @@ @implementation RCTPSPDFKitManager
7779
}
7880
}
7981

82+
#pragma mark - Annotation Processing
83+
84+
RCT_REMAP_METHOD(processAnnotations, processAnnotations:(PSPDFAnnotationChange)annotationChange annotationType:(PSPDFAnnotationType)annotationType sourceDocument:(PSPDFDocument *)sourceDocument processedDocumentPath:(nonnull NSString *)processedDocumentPath resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
85+
NSError *error;
86+
NSURL *processedDocumentURL = [NSURL fileURLWithPath:processedDocumentPath];
87+
88+
// Create a processor configuration with the current document.
89+
PSPDFProcessorConfiguration *configuration = [[PSPDFProcessorConfiguration alloc] initWithDocument:sourceDocument];
90+
91+
// Modify annotations.
92+
[configuration modifyAnnotationsOfTypes:annotationType change:annotationChange];
93+
94+
// Create the PDF processor and write the processed file.
95+
PSPDFProcessor *processor = [[PSPDFProcessor alloc] initWithConfiguration:configuration securityOptions:nil];
96+
BOOL success = [processor writeToFileURL:processedDocumentURL error:&error];
97+
if (success) {
98+
resolve(@(success));
99+
} else {
100+
reject(@"error", @"Failed to process annotations.", error);
101+
}
102+
}
103+
80104
- (dispatch_queue_t)methodQueue {
81105
return dispatch_get_main_queue();
82106
}

ios/RCTPSPDFKit/RCTPSPDFKitViewManager.m

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -237,11 +237,11 @@ @implementation RCTPSPDFKitViewManager
237237
dispatch_async(dispatch_get_main_queue(), ^{
238238
RCTPSPDFKitView *component = (RCTPSPDFKitView *)[self.bridge.uiManager viewForReactTag:reactTag];
239239
BOOL success = [component setFormFieldValue:value fullyQualifiedName:fullyQualifiedName];
240-
if (success) {
241-
resolve(@(success));
242-
} else {
243-
reject(@"error", @"Failed to set form field value.", nil);
244-
}
240+
if (success) {
241+
resolve(@(success));
242+
} else {
243+
reject(@"error", @"Failed to set form field value.", nil);
244+
}
245245
});
246246
}
247247

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-pspdfkit",
3-
"version": "1.27.3",
3+
"version": "1.27.4",
44
"description": "A React Native module for the PSPDFKit library.",
55
"keywords": [
66
"react native",

0 commit comments

Comments
 (0)