CPDFViewManager.java 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. /**
  2. * Copyright © 2014-2025 PDF Technologies, Inc. All Rights Reserved.
  3. * <p>
  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 ComPDFKit LICENSE AGREEMENT.
  6. * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES. This notice
  7. * may not be removed from this file.
  8. */
  9. package com.compdfkitpdf.reactnative.viewmanager;
  10. import static com.compdfkitpdf.reactnative.util.CPDFDocumentUtil.ASSETS_SCHEME;
  11. import static com.compdfkitpdf.reactnative.util.CPDFDocumentUtil.CONTENT_SCHEME;
  12. import static com.compdfkitpdf.reactnative.util.CPDFDocumentUtil.FILE_SCHEME;
  13. import android.app.Activity;
  14. import android.graphics.Color;
  15. import android.net.Uri;
  16. import android.text.TextUtils;
  17. import android.util.Log;
  18. import android.util.SparseArray;
  19. import android.view.View;
  20. import androidx.annotation.NonNull;
  21. import androidx.fragment.app.FragmentActivity;
  22. import com.compdfkit.core.common.CPDFDocumentException;
  23. import com.compdfkit.core.document.CPDFDocument;
  24. import com.compdfkit.core.document.CPDFDocument.PDFDocumentEncryptAlgo;
  25. import com.compdfkit.core.document.CPDFDocument.PDFDocumentError;
  26. import com.compdfkit.core.document.CPDFDocument.PDFDocumentPermissions;
  27. import com.compdfkit.core.document.CPDFDocument.PDFDocumentSaveType;
  28. import com.compdfkit.core.document.CPDFDocumentPermissionInfo;
  29. import com.compdfkit.core.page.CPDFPage.PDFFlattenOption;
  30. import com.compdfkit.tools.common.pdf.CPDFConfigurationUtils;
  31. import com.compdfkit.tools.common.pdf.config.CPDFConfiguration;
  32. import com.compdfkit.tools.common.utils.CFileUtils;
  33. import com.compdfkit.tools.common.utils.print.CPDFPrintUtils;
  34. import com.compdfkit.tools.common.utils.threadpools.CThreadPoolUtils;
  35. import com.compdfkit.tools.common.utils.viewutils.CViewUtils;
  36. import com.compdfkit.tools.common.views.pdfview.CPDFPageIndicatorView;
  37. import com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl;
  38. import com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl.COnSaveCallback;
  39. import com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl.COnSaveError;
  40. import com.compdfkit.tools.common.views.pdfview.CPreviewMode;
  41. import com.compdfkit.ui.reader.CPDFReaderView;
  42. import com.compdfkitpdf.reactnative.util.CPDFPageUtil;
  43. import com.compdfkitpdf.reactnative.util.CPDFDocumentUtil;
  44. import com.compdfkitpdf.reactnative.view.CPDFView;
  45. import com.facebook.react.bridge.Promise;
  46. import com.facebook.react.bridge.ReactApplicationContext;
  47. import com.facebook.react.bridge.WritableArray;
  48. import com.facebook.react.bridge.WritableMap;
  49. import com.facebook.react.uimanager.ThemedReactContext;
  50. import com.facebook.react.uimanager.ViewGroupManager;
  51. import com.facebook.react.uimanager.annotations.ReactProp;
  52. import java.io.File;
  53. public class CPDFViewManager extends ViewGroupManager<CPDFView> {
  54. private static final String TAG = "ComPDFKitRN";
  55. private ReactApplicationContext reactContext;
  56. private SparseArray<CPDFView> mDocumentViews = new SparseArray<>();
  57. public CPDFViewManager(ReactApplicationContext context) {
  58. this.reactContext = context;
  59. }
  60. @NonNull
  61. @Override
  62. public String getName() {
  63. return "RCTCPDFReaderView";
  64. }
  65. private View.OnAttachStateChangeListener mOnAttachStateChangeListener = new View.OnAttachStateChangeListener() {
  66. @Override
  67. public void onViewAttachedToWindow(View v) {
  68. CPDFView documentView = (CPDFView) v;
  69. mDocumentViews.put(v.getId(), documentView);
  70. try {
  71. CPDFReaderView readerView = documentView.getCPDFReaderView();
  72. if (readerView.getPDFDocument() != null) {
  73. readerView.reloadPages();
  74. }
  75. } catch (Exception e) {
  76. e.printStackTrace();
  77. }
  78. }
  79. @Override
  80. public void onViewDetachedFromWindow(View v) {
  81. mDocumentViews.remove(v.getId());
  82. }
  83. };
  84. @NonNull
  85. @Override
  86. protected CPDFView createViewInstance(@NonNull ThemedReactContext themedReactContext) {
  87. Activity currentActivity = themedReactContext.getCurrentActivity();
  88. if (currentActivity instanceof FragmentActivity fragmentActivity) {
  89. CPDFView pdfView = new CPDFView(fragmentActivity);
  90. pdfView.setup(themedReactContext, fragmentActivity.getSupportFragmentManager());
  91. pdfView.addOnAttachStateChangeListener(mOnAttachStateChangeListener);
  92. return pdfView;
  93. } else {
  94. throw new IllegalStateException("CPDFView can only be used in FragmentActivity subclasses");
  95. }
  96. }
  97. @Override
  98. public boolean needsCustomLayoutForChildren() {
  99. return true;
  100. }
  101. @ReactProp(name = "document")
  102. public void setDocument(CPDFView pdfView, String document) {
  103. Log.d(TAG, "CPDFViewManager-setDocument()");
  104. Log.d(TAG, "document:" + document);
  105. pdfView.setDocument(document);
  106. }
  107. @ReactProp(name = "password")
  108. public void setPassword(CPDFView pdfView, String password) {
  109. pdfView.setPassword(password);
  110. }
  111. @ReactProp(name = "configuration")
  112. public void setConfiguration(CPDFView pdfView, String configurationJson) {
  113. CPDFConfiguration configuration = CPDFConfigurationUtils.fromJson(configurationJson);
  114. pdfView.setConfiguration(configuration);
  115. }
  116. public void save(int tag, COnSaveCallback saveCallback, COnSaveError error) {
  117. CPDFView pdfView = mDocumentViews.get(tag);
  118. if (pdfView != null) {
  119. pdfView.documentFragment.pdfView.savePDF(saveCallback, error);
  120. } else {
  121. error.error(new Exception("save() Unable to find DocumentView"));
  122. }
  123. }
  124. public void setMargins(int tag, int left, int top, int right, int bottom) {
  125. CPDFView pdfView = mDocumentViews.get(tag);
  126. if (pdfView != null) {
  127. CPDFReaderView readerView = pdfView.documentFragment.pdfView.getCPdfReaderView();
  128. readerView.setReaderViewTopMargin(top);
  129. readerView.setReaderViewBottomMargin(bottom);
  130. readerView.setReaderViewHorizontalMargin(left, right);
  131. readerView.reloadPages();
  132. }
  133. }
  134. public boolean removeAllAnnotations(int tag) {
  135. try {
  136. CPDFView pdfView = mDocumentViews.get(tag);
  137. if (pdfView != null) {
  138. CPDFReaderView readerView = pdfView.documentFragment.pdfView.getCPdfReaderView();
  139. boolean result = readerView.getPDFDocument().removeAllAnnotations();
  140. if (result) {
  141. readerView.invalidateAllChildren();
  142. }
  143. return result;
  144. }
  145. return false;
  146. } catch (Exception e) {
  147. return false;
  148. }
  149. }
  150. public boolean importAnnotations(int tag, String xfdfFilePath) throws Exception {
  151. String xfdf = CPDFDocumentUtil.getImportFilePath(reactContext, xfdfFilePath);
  152. CPDFView pdfView = mDocumentViews.get(tag);
  153. CPDFReaderView readerView = pdfView.documentFragment.pdfView.getCPdfReaderView();
  154. CPDFDocument document = readerView.getPDFDocument();
  155. File file = new File(xfdf);
  156. if (!file.exists()) {
  157. throw new Exception("File not found: " + xfdf);
  158. }
  159. File cacheFile = new File(reactContext.getCacheDir(),
  160. CFileUtils.CACHE_FOLDER + File.separator + "importAnnotCache/"
  161. + CFileUtils.getFileNameNoExtension(document.getFileName()));
  162. cacheFile.mkdirs();
  163. boolean importResult = document.importAnnotations(xfdf,
  164. cacheFile.getAbsolutePath());
  165. readerView.reloadPages();
  166. return importResult;
  167. }
  168. public String exportAnnotations(int tag) throws Exception {
  169. CPDFView pdfView = mDocumentViews.get(tag);
  170. CPDFReaderView readerView = pdfView.documentFragment.pdfView.getCPdfReaderView();
  171. CPDFDocument document = readerView.getPDFDocument();
  172. // export file directory
  173. File dirFile = new File(reactContext.getFilesDir(), "compdfkit/annotation/export/");
  174. dirFile.mkdirs();
  175. // export file name
  176. String fileName = CFileUtils.getFileNameNoExtension(document.getFileName());
  177. // export file cache file
  178. File cacheFile = new File(reactContext.getCacheDir(),
  179. CFileUtils.CACHE_FOLDER + File.separator + "exportAnnotCache/" + fileName);
  180. cacheFile.mkdirs();
  181. // export file
  182. File saveFile = new File(dirFile, fileName + ".xfdf");
  183. saveFile = CFileUtils.renameNameSuffix(saveFile);
  184. boolean exportResult = document.exportAnnotations(saveFile.getAbsolutePath(),
  185. cacheFile.getAbsolutePath());
  186. if (exportResult) {
  187. return saveFile.getAbsolutePath();
  188. } else {
  189. return null;
  190. }
  191. }
  192. public void setDisplayPageIndex(int tag, int pageIndex) {
  193. CPDFView pdfView = mDocumentViews.get(tag);
  194. pdfView.getCPDFReaderView().setDisplayPageIndex(pageIndex);
  195. }
  196. public int getCurrentPageIndex(int tag) {
  197. CPDFView pdfView = mDocumentViews.get(tag);
  198. return pdfView.getCPDFReaderView().getPageNum();
  199. }
  200. public boolean hasChange(int tag) {
  201. CPDFView pdfView = mDocumentViews.get(tag);
  202. return pdfView.getCPDFReaderView().getPDFDocument().hasChanges();
  203. }
  204. public void setScale(int tag, float scale) {
  205. CPDFView pdfView = mDocumentViews.get(tag);
  206. pdfView.getCPDFReaderView().setScale(scale);
  207. }
  208. public float getScale(int tag) {
  209. CPDFView pdfView = mDocumentViews.get(tag);
  210. return pdfView.getCPDFReaderView().getScale();
  211. }
  212. public void setCanScale(int tag, boolean canScale) {
  213. CPDFView pdfView = mDocumentViews.get(tag);
  214. pdfView.getCPDFReaderView().setCanScale(canScale);
  215. }
  216. public void setReadBackgroundColor(int tag, String color) {
  217. CPDFView pdfView = mDocumentViews.get(tag);
  218. pdfView.getCPDFReaderView().setReadBackgroundColor(Color.parseColor(color));
  219. pdfView.getCPDFReaderView().setBackgroundColor(
  220. CViewUtils.getColor(Color.parseColor(color), 190));
  221. }
  222. public String getReadBackgroundColor(int tag) {
  223. CPDFView pdfView = mDocumentViews.get(tag);
  224. String readBgColor =
  225. "#" + Integer.toHexString(pdfView.getCPDFReaderView().getReadBackgroundColor()).toUpperCase();
  226. return readBgColor;
  227. }
  228. public void setFormFieldHighlight(int tag, boolean isFormFieldHighlight) {
  229. CPDFView pdfView = mDocumentViews.get(tag);
  230. pdfView.getCPDFReaderView().setFormFieldHighlight(isFormFieldHighlight);
  231. }
  232. public boolean isFormFieldHighlight(int tag) {
  233. CPDFView pdfView = mDocumentViews.get(tag);
  234. return pdfView.getCPDFReaderView().isFormFieldHighlight();
  235. }
  236. public void setLinkHighlight(int tag, boolean isLinkHighlight) {
  237. CPDFView pdfView = mDocumentViews.get(tag);
  238. pdfView.getCPDFReaderView().setLinkHighlight(isLinkHighlight);
  239. }
  240. public boolean isLinkHighlight(int tag) {
  241. CPDFView pdfView = mDocumentViews.get(tag);
  242. return pdfView.getCPDFReaderView().isLinkHighlight();
  243. }
  244. public void setVerticalMode(int tag, boolean isVerticalMode) {
  245. CPDFView pdfView = mDocumentViews.get(tag);
  246. pdfView.getCPDFReaderView().setVerticalMode(isVerticalMode);
  247. }
  248. public boolean isVerticalMode(int tag) {
  249. CPDFView pdfView = mDocumentViews.get(tag);
  250. return pdfView.getCPDFReaderView().isVerticalMode();
  251. }
  252. public void setPageSpacing(int tag, int spacing) {
  253. CPDFView pdfView = mDocumentViews.get(tag);
  254. pdfView.getCPDFReaderView().setPageSpacing(spacing);
  255. pdfView.getCPDFReaderView().reloadPages();
  256. }
  257. public void setContinueMode(int tag, boolean isContinueMode) {
  258. CPDFView pdfView = mDocumentViews.get(tag);
  259. pdfView.getCPDFReaderView().setContinueMode(isContinueMode);
  260. }
  261. public boolean isContinueMode(int tag) {
  262. CPDFView pdfView = mDocumentViews.get(tag);
  263. return pdfView.getCPDFReaderView().isContinueMode();
  264. }
  265. public void setDoublePageMode(int tag, boolean isDoublePageMode) {
  266. CPDFView pdfView = mDocumentViews.get(tag);
  267. pdfView.getCPDFReaderView().setDoublePageMode(isDoublePageMode);
  268. pdfView.getCPDFReaderView().setCoverPageMode(false);
  269. }
  270. public boolean isDoublePageMode(int tag) {
  271. CPDFView pdfView = mDocumentViews.get(tag);
  272. return pdfView.getCPDFReaderView().isDoublePageMode();
  273. }
  274. public void setCoverPageMode(int tag, boolean isCoverPageMode) {
  275. CPDFView pdfView = mDocumentViews.get(tag);
  276. pdfView.getCPDFReaderView().setDoublePageMode(isCoverPageMode);
  277. pdfView.getCPDFReaderView().setCoverPageMode(isCoverPageMode);
  278. }
  279. public boolean isCoverPageMode(int tag) {
  280. CPDFView pdfView = mDocumentViews.get(tag);
  281. return pdfView.getCPDFReaderView().isCoverPageMode();
  282. }
  283. public void setCropMode(int tag, boolean isCropMode) {
  284. CPDFView pdfView = mDocumentViews.get(tag);
  285. pdfView.getCPDFReaderView().setCropMode(isCropMode);
  286. }
  287. public boolean isCropMode(int tag) {
  288. CPDFView pdfView = mDocumentViews.get(tag);
  289. return pdfView.getCPDFReaderView().isCropMode();
  290. }
  291. public void setPageSameWidth(int tag, boolean isPageSameWidth) {
  292. CPDFView pdfView = mDocumentViews.get(tag);
  293. pdfView.getCPDFReaderView().setPageSameWidth(isPageSameWidth);
  294. pdfView.getCPDFReaderView().reloadPages();
  295. }
  296. public boolean isPageInScreen(int tag, int pageIndex) {
  297. CPDFView pdfView = mDocumentViews.get(tag);
  298. return pdfView.getCPDFReaderView().isPageInScreen(pageIndex);
  299. }
  300. public void setFixedScroll(int tag, boolean isFixedScroll) {
  301. CPDFView pdfView = mDocumentViews.get(tag);
  302. pdfView.getCPDFReaderView().setFixedScroll(isFixedScroll);
  303. }
  304. public void setPreviewMode(int tag, String previewMode) {
  305. CPDFView pdfView = mDocumentViews.get(tag);
  306. pdfView.documentFragment.setPreviewMode(CPreviewMode.fromAlias(previewMode));
  307. }
  308. public CPreviewMode getPreviewMode(int tag) {
  309. CPDFView pdfView = mDocumentViews.get(tag);
  310. return pdfView.documentFragment.pdfToolBar.getMode();
  311. }
  312. public void showThumbnailView(int tag, boolean editMode) {
  313. CPDFView pdfView = mDocumentViews.get(tag);
  314. pdfView.documentFragment.showPageEdit(editMode);
  315. }
  316. public void showBotaView(int tag) {
  317. CPDFView pdfView = mDocumentViews.get(tag);
  318. pdfView.documentFragment.showBOTA();
  319. }
  320. public void showAddWatermarkView(int tag, boolean saveAsNewFile) {
  321. CPDFView pdfView = mDocumentViews.get(tag);
  322. pdfView.documentFragment.showAddWatermarkDialog(saveAsNewFile);
  323. }
  324. public void showSecurityView(int tag) {
  325. CPDFView pdfView = mDocumentViews.get(tag);
  326. pdfView.documentFragment.showSecurityDialog();
  327. }
  328. public void showDisplaySettingView(int tag) {
  329. CPDFView pdfView = mDocumentViews.get(tag);
  330. pdfView.documentFragment.showDisplaySettings(pdfView.documentFragment.pdfView);
  331. }
  332. public void enterSnipMode(int tag) {
  333. CPDFView pdfView = mDocumentViews.get(tag);
  334. pdfView.documentFragment.enterSnipMode();
  335. }
  336. public void exitSnipMode(int tag) {
  337. CPDFView pdfView = mDocumentViews.get(tag);
  338. pdfView.documentFragment.exitSnipMode();
  339. }
  340. public void open(int tag, String filePath, String password, Promise promise) {
  341. CPDFView pdfView = mDocumentViews.get(tag);
  342. CPDFViewCtrl viewCtrl = pdfView.documentFragment.pdfView;
  343. if (filePath.startsWith(ASSETS_SCHEME)) {
  344. String assetsPath = filePath.replace(ASSETS_SCHEME + "/", "");
  345. String[] strs = filePath.split("/");
  346. String fileName = strs[strs.length - 1];
  347. String samplePDFPath = CFileUtils.getAssetsTempFile(reactContext, assetsPath, fileName);
  348. viewCtrl.openPDF(samplePDFPath, password, () -> {
  349. promise.resolve(true);
  350. });
  351. } else if (filePath.startsWith(CONTENT_SCHEME) || filePath.startsWith(FILE_SCHEME)) {
  352. Uri uri = Uri.parse(filePath);
  353. viewCtrl.openPDF(uri, password, () -> {
  354. promise.resolve(true);
  355. });
  356. } else {
  357. viewCtrl.openPDF(filePath, password, () -> {
  358. promise.resolve(true);
  359. });
  360. }
  361. }
  362. public String getFileName(int tag) {
  363. CPDFView pdfView = mDocumentViews.get(tag);
  364. return pdfView.getCPDFReaderView().getPDFDocument().getFileName();
  365. }
  366. public boolean isEncrypted(int tag) {
  367. CPDFView pdfView = mDocumentViews.get(tag);
  368. return pdfView.getCPDFReaderView().getPDFDocument().isEncrypted();
  369. }
  370. public boolean isImageDoc(int tag) {
  371. CPDFView pdfView = mDocumentViews.get(tag);
  372. return pdfView.getCPDFReaderView().getPDFDocument().isImageDoc();
  373. }
  374. public PDFDocumentPermissions getPermissions(int tag) {
  375. CPDFView pdfView = mDocumentViews.get(tag);
  376. return pdfView.getCPDFReaderView().getPDFDocument().getPermissions();
  377. }
  378. public boolean checkOwnerUnlocked(int tag) {
  379. CPDFView pdfView = mDocumentViews.get(tag);
  380. return pdfView.getCPDFReaderView().getPDFDocument().checkOwnerUnlocked();
  381. }
  382. public boolean checkOwnerPassword(int tag, String password) {
  383. CPDFView pdfView = mDocumentViews.get(tag);
  384. return pdfView.getCPDFReaderView().getPDFDocument().checkOwnerPassword(password);
  385. }
  386. public int getPageCount(int tag) {
  387. CPDFView pdfView = mDocumentViews.get(tag);
  388. return pdfView.getCPDFReaderView().getPDFDocument().getPageCount();
  389. }
  390. public void saveAs(int tag, String savePath, boolean removeSecurity, boolean fontSubSet,
  391. Promise result) {
  392. CPDFView pdfView = mDocumentViews.get(tag);
  393. CPDFDocument document = pdfView.getCPDFReaderView().getPDFDocument();
  394. pdfView.documentFragment.pdfView.exitEditMode();
  395. CThreadPoolUtils.getInstance().executeIO(() -> {
  396. try {
  397. boolean saveResult;
  398. if (savePath.startsWith(CONTENT_SCHEME)) {
  399. saveResult = document.saveAs(Uri.parse(savePath), removeSecurity, fontSubSet);
  400. } else {
  401. saveResult = document.saveAs(savePath, removeSecurity, false, fontSubSet);
  402. }
  403. CThreadPoolUtils.getInstance().executeMain(() -> {
  404. if (document.shouleReloadDocument()) {
  405. document.reload();
  406. }
  407. });
  408. result.resolve(saveResult);
  409. } catch (CPDFDocumentException e) {
  410. e.printStackTrace();
  411. result.reject("SAVE_FAIL",
  412. "The current saved directory is: " + savePath
  413. + ", please make sure you have write permission to this directory");
  414. }
  415. });
  416. }
  417. public void print(int tag) {
  418. if (reactContext.getCurrentActivity() != null) {
  419. CPDFView pdfView = mDocumentViews.get(tag);
  420. CPDFReaderView readerView = pdfView.getCPDFReaderView();
  421. CPDFPrintUtils.printCurrentDocument(reactContext.getCurrentActivity(),
  422. readerView.getPDFDocument());
  423. }
  424. }
  425. public void removePassword(int tag, Promise promise) {
  426. CPDFView pdfView = mDocumentViews.get(tag);
  427. CPDFReaderView readerView = pdfView.getCPDFReaderView();
  428. try {
  429. CPDFDocument document = readerView.getPDFDocument();
  430. boolean saveResult = document.save(PDFDocumentSaveType.PDFDocumentSaveRemoveSecurity,
  431. true);
  432. if (document.shouleReloadDocument()) {
  433. document.reload();
  434. }
  435. promise.resolve(saveResult);
  436. } catch (Exception e) {
  437. promise.reject("SAVE_FAIL",
  438. "An exception occurs when remove document opening password and saving it.,"
  439. + e.getMessage());
  440. }
  441. }
  442. public void setPassword(int tag,
  443. String userPassword,
  444. String ownerPassword,
  445. boolean allowsPrinting,
  446. boolean allowsCopying,
  447. String encryptAlgo,
  448. Promise promise) {
  449. CPDFView pdfView = mDocumentViews.get(tag);
  450. CPDFDocument document = pdfView.getCPDFReaderView().getPDFDocument();
  451. CThreadPoolUtils.getInstance().executeIO(() -> {
  452. try {
  453. if (!TextUtils.isEmpty(userPassword)) {
  454. document.setUserPassword(userPassword);
  455. }
  456. if (!TextUtils.isEmpty(ownerPassword)) {
  457. document.setOwnerPassword(ownerPassword);
  458. CPDFDocumentPermissionInfo permissionInfo = document.getPermissionsInfo();
  459. permissionInfo.setAllowsPrinting(allowsPrinting);
  460. permissionInfo.setAllowsCopying(allowsCopying);
  461. document.setPermissionsInfo(permissionInfo);
  462. }
  463. switch (encryptAlgo) {
  464. case "rc4":
  465. document.setEncryptAlgorithm(PDFDocumentEncryptAlgo.PDFDocumentRC4);
  466. break;
  467. case "aes128":
  468. document.setEncryptAlgorithm(PDFDocumentEncryptAlgo.PDFDocumentAES128);
  469. break;
  470. case "aes256":
  471. document.setEncryptAlgorithm(PDFDocumentEncryptAlgo.PDFDocumentAES256);
  472. break;
  473. case "noEncryptAlgo":
  474. document.setEncryptAlgorithm(PDFDocumentEncryptAlgo.PDFDocumentNoEncryptAlgo);
  475. break;
  476. default:
  477. break;
  478. }
  479. boolean saveResult = document.save(
  480. CPDFDocument.PDFDocumentSaveType.PDFDocumentSaveIncremental, true);
  481. if (document.shouleReloadDocument()) {
  482. if (!TextUtils.isEmpty(userPassword)) {
  483. document.reload(userPassword);
  484. } else if (!TextUtils.isEmpty(ownerPassword)) {
  485. document.reload(ownerPassword);
  486. } else {
  487. document.reload();
  488. }
  489. }
  490. promise.resolve(saveResult);
  491. } catch (Exception e) {
  492. promise.reject("SAVE_FAIL",
  493. "An exception occurs when setting a document opening password and saving it.,"
  494. + e.getMessage());
  495. }
  496. });
  497. }
  498. public String getEncryptAlgo(int tag) {
  499. CPDFView pdfView = mDocumentViews.get(tag);
  500. PDFDocumentEncryptAlgo encryptAlgo = pdfView.getCPDFReaderView().getPDFDocument()
  501. .getEncryptAlgorithm();
  502. return switch (encryptAlgo) {
  503. case PDFDocumentRC4 -> "rc4";
  504. case PDFDocumentAES128 -> "aes128";
  505. case PDFDocumentAES256 -> "aes256";
  506. case PDFDocumentNoEncryptAlgo -> "noEncryptAlgo";
  507. };
  508. }
  509. public boolean importWidgets(int tag, String xfdfFilePath) throws Exception {
  510. String xfdf = CPDFDocumentUtil.getImportFilePath(reactContext, xfdfFilePath);
  511. CPDFView pdfView = mDocumentViews.get(tag);
  512. CPDFReaderView readerView = pdfView.documentFragment.pdfView.getCPdfReaderView();
  513. CPDFDocument document = readerView.getPDFDocument();
  514. File file = new File(xfdf);
  515. if (!file.exists()) {
  516. throw new Exception("File not found: " + xfdf);
  517. }
  518. File cacheFile = new File(reactContext.getCacheDir(),
  519. CFileUtils.CACHE_FOLDER + File.separator + "importWidgetsCache/"
  520. + CFileUtils.getFileNameNoExtension(document.getFileName()));
  521. cacheFile.mkdirs();
  522. boolean importResult = document.importWidgets(xfdf,
  523. cacheFile.getAbsolutePath());
  524. readerView.reloadPages();
  525. return importResult;
  526. }
  527. public String exportWidgets(int tag) throws Exception {
  528. CPDFView pdfView = mDocumentViews.get(tag);
  529. CPDFReaderView readerView = pdfView.documentFragment.pdfView.getCPdfReaderView();
  530. CPDFDocument document = readerView.getPDFDocument();
  531. // export file directory
  532. File dirFile = new File(reactContext.getFilesDir(), "compdfkit/widgets/export/");
  533. dirFile.mkdirs();
  534. // export file name
  535. String fileName = CFileUtils.getFileNameNoExtension(document.getFileName());
  536. // export file cache file
  537. File cacheFile = new File(reactContext.getCacheDir(),
  538. CFileUtils.CACHE_FOLDER + File.separator + "exportWidgetsCache/" + fileName);
  539. cacheFile.mkdirs();
  540. // export file
  541. File saveFile = new File(dirFile, fileName + ".xfdf");
  542. saveFile = CFileUtils.renameNameSuffix(saveFile);
  543. boolean exportResult = document.exportWidgets(saveFile.getAbsolutePath(),
  544. cacheFile.getAbsolutePath());
  545. if (exportResult) {
  546. return saveFile.getAbsolutePath();
  547. } else {
  548. return null;
  549. }
  550. }
  551. public void flattenAllPages(int tag, String savePath, boolean fontSubset, Promise promise) {
  552. try {
  553. CPDFView pdfView = mDocumentViews.get(tag);
  554. CPDFReaderView readerView = pdfView.getCPDFReaderView();
  555. CPDFDocument document = readerView.getPDFDocument();
  556. boolean success = document.flattenAllPages(PDFFlattenOption.FLAT_NORMALDISPLAY);
  557. if (!success) {
  558. promise.reject("FLATTEN_FAIL", "Flatten all pages failed.");
  559. return;
  560. }
  561. boolean saveResult;
  562. if (savePath.startsWith(CONTENT_SCHEME)) {
  563. saveResult = document.saveAs(Uri.parse(savePath), false, fontSubset);
  564. } else {
  565. saveResult = document.saveAs(savePath, false, false, fontSubset);
  566. }
  567. if (document.shouleReloadDocument()) {
  568. document.reload();
  569. }
  570. if (saveResult) {
  571. promise.resolve(savePath);
  572. } else {
  573. promise.reject("SAVE_FAIL", "Save failed.");
  574. }
  575. } catch (Exception e) {
  576. if (e instanceof CPDFDocumentException) {
  577. promise.reject("SAVE_FAIL", ((CPDFDocumentException) e).getErrType().name());
  578. } else {
  579. promise.reject("SAVE_FAIL", e.getMessage());
  580. }
  581. }
  582. }
  583. public void reloadPages(int tag) {
  584. CPDFView cpdfView = mDocumentViews.get(tag);
  585. cpdfView.getCPDFReaderView().reloadPages();
  586. }
  587. public void importDocument(int tag, String filePath, String password, int[] pages,
  588. int insertPosition, Promise promise) {
  589. try {
  590. CPDFView cpdfView = mDocumentViews.get(tag);
  591. CPDFDocument document = cpdfView.getCPDFReaderView().getPDFDocument();
  592. CPDFDocument importDocument = new CPDFDocument(reactContext);
  593. String importDocumentPath = CPDFDocumentUtil.getImportFilePath(reactContext, filePath);
  594. PDFDocumentError error = importDocument.open(importDocumentPath, password);
  595. if (error != PDFDocumentError.PDFDocumentErrorSuccess) {
  596. promise.reject("IMPORT_DOCUMENT_FAIL", "open import document fail, error:" + error.name());
  597. return;
  598. }
  599. if (pages == null || pages.length == 0) {
  600. int pageCount = importDocument.getPageCount();
  601. pages = new int[pageCount];
  602. for (int i = 0; i < pageCount; i++) {
  603. pages[i] = i;
  604. }
  605. }
  606. if (insertPosition == -1) {
  607. insertPosition = document.getPageCount();
  608. }
  609. boolean importResult = document.importPages(importDocument, pages, insertPosition);
  610. promise.resolve(importResult);
  611. CPDFPageIndicatorView indicatorView = cpdfView.documentFragment.pdfView.indicatorView;
  612. cpdfView.getCPDFReaderView().reloadPages();
  613. indicatorView.setTotalPage(document.getPageCount());
  614. indicatorView.setCurrentPageIndex(cpdfView.getCPDFReaderView().getPageNum());
  615. } catch (Exception e) {
  616. promise.reject("IMPORT_DOCUMENT_FAIL", "error:" + e.getMessage());
  617. }
  618. }
  619. public void splitDocumentPage(int tag, String savePath, int[] pages, Promise promise) {
  620. try {
  621. CPDFView cpdfView = mDocumentViews.get(tag);
  622. CPDFDocument document = cpdfView.getCPDFReaderView().getPDFDocument();
  623. if (pages == null || pages.length == 0) {
  624. int pageCount = document.getPageCount();
  625. pages = new int[pageCount];
  626. for (int i = 0; i < pageCount; i++) {
  627. pages[i] = i;
  628. }
  629. }
  630. int[] finalPages = pages;
  631. CThreadPoolUtils.getInstance().executeIO(() -> {
  632. try {
  633. CPDFDocument newDocument = CPDFDocument.createDocument(reactContext);
  634. newDocument.importPages(document, finalPages, 0);
  635. boolean saveResult;
  636. if (savePath.startsWith(CONTENT_SCHEME)) {
  637. saveResult = newDocument.saveAs(Uri.parse(savePath), false, true);
  638. } else {
  639. saveResult = newDocument.saveAs(savePath, false, false, true);
  640. }
  641. promise.resolve(saveResult);
  642. newDocument.close();
  643. } catch (CPDFDocumentException e) {
  644. promise.reject("SPLIT_DOCUMENT_FAIL", "error:" + e.getErrType().name());
  645. }
  646. });
  647. } catch (Exception e) {
  648. e.printStackTrace();
  649. promise.reject("SPLIT_DOCUMENT_FAIL", "error:" + e.getMessage());
  650. }
  651. }
  652. public String getDocumentPath(int tag) {
  653. CPDFView pdfView = mDocumentViews.get(tag);
  654. CPDFReaderView readerView = pdfView.getCPDFReaderView();
  655. CPDFDocument document = readerView.getPDFDocument();
  656. if (!TextUtils.isEmpty(document.getAbsolutePath())){
  657. return document.getAbsolutePath();
  658. }
  659. return document.getUri().toString();
  660. }
  661. public WritableArray getAnnotations(int tag, int pageIndex){
  662. CPDFView pdfView = mDocumentViews.get(tag);
  663. CPDFPageUtil rcpdfPage = pdfView.getCPDFPageUtil();
  664. return rcpdfPage.getAnnotations(pageIndex);
  665. }
  666. public WritableArray getForms(int tag, int pageIndex){
  667. CPDFView pdfView = mDocumentViews.get(tag);
  668. CPDFPageUtil rcpdfPage = pdfView.getCPDFPageUtil();
  669. return rcpdfPage.getForms(pageIndex);
  670. }
  671. }