Kaynağa Gözat

ComPDFKit(flutter) - 2.2.0 安卓端新增部分document相关接口

liuxiaolong 2 hafta önce
ebeveyn
işleme
bc88734edb

+ 14 - 1
android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/constants/CPDFConstants.java

@@ -92,8 +92,21 @@ public class CPDFConstants {
 
     public static final String GET_PAGE_SIZE = "get_page_size";
 
-    public static final String HAS_CHANGE = "has_change";
+    public static final String GET_FILE_NAME = "get_file_name";
+
+    public static final String IS_ENCRYPTED = "is_encrypted";
+
+    public static final String IS_IMAGE_DOC = "is_image_doc";
+
+    public static final String GET_PERMISSIONS = "get_permissions";
 
+    public static final String CHECK_OWNER_UNLOCKED = "check_owner_unlocked";
+
+    public static final String CHECK_PASSWORD = "check_password";
+
+    public static final String CLOSE = "close";
+
+    public static final String HAS_CHANGE = "has_change";
   }
 
 }

+ 3 - 1
android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/platformview/CPDFViewCtrlFlutter.java

@@ -55,9 +55,11 @@ public class CPDFViewCtrlFlutter implements PlatformView {
         Log.e(LOG_TAG, "CPDFViewCtrlFlutter:Create CPDFDocumentFragment");
         initCPDFViewCtrl(context, creationParams);
 
+        // Register plug-ins related to interaction with the document
+        // interface to control document display, such as setting the document scrolling direction.
         methodChannel = new CPDFViewCtrlPlugin(context, binaryMessenger, viewId);
-        methodChannel.setDocumentFragment(documentFragment);
         methodChannel.register();
+        methodChannel.setDocumentFragment(documentFragment);
 
     }
 

+ 114 - 0
android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/plugin/CPDFDocumentPlugin.java

@@ -0,0 +1,114 @@
+/*
+ * Copyright © 2014-2024 PDF Technologies, Inc. All Rights Reserved.
+ *
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ *
+ */
+
+package com.compdfkit.flutter.compdfkit_flutter.plugin;
+
+
+import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.CHECK_OWNER_UNLOCKED;
+import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.CHECK_PASSWORD;
+import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.CLOSE;
+import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.GET_FILE_NAME;
+import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.GET_PERMISSIONS;
+import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.HAS_CHANGE;
+import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.IS_ENCRYPTED;
+import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.IS_IMAGE_DOC;
+import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.OPEN_DOCUMENT;
+
+import android.content.Context;
+import android.net.Uri;
+import android.text.TextUtils;
+import androidx.annotation.NonNull;
+import com.compdfkit.core.document.CPDFDocument;
+import com.compdfkit.core.document.CPDFDocument.PDFDocumentError;
+import com.compdfkit.tools.common.utils.threadpools.CThreadPoolUtils;
+import com.compdfkit.ui.reader.CPDFReaderView;
+import io.flutter.Log;
+import io.flutter.plugin.common.BinaryMessenger;
+import io.flutter.plugin.common.MethodCall;
+import io.flutter.plugin.common.MethodChannel.Result;
+
+public class CPDFDocumentPlugin extends BaseMethodChannelPlugin{
+
+  private String documentUid;
+
+  private CPDFReaderView readerView;
+
+  public CPDFDocumentPlugin(Context context,
+      BinaryMessenger binaryMessenger, String documentUid) {
+    super(context, binaryMessenger);
+    this.documentUid = documentUid;
+  }
+
+  public void setReaderView(CPDFReaderView readerView) {
+    this.readerView = readerView;
+  }
+
+
+  @Override
+  public String methodName() {
+    return "com.compdfkit.flutter.document_" + documentUid;
+  }
+
+  @Override
+  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
+    if (readerView == null || readerView.getPDFDocument() == null){
+      result.error("-1", "CPDFReaderView isnull or CPDFDocument is null", null);
+      return;
+    }
+    CPDFDocument document = readerView.getPDFDocument();
+    switch (call.method){
+      case OPEN_DOCUMENT:
+        String filePath = call.argument("filePath");
+        String fileUri = call.argument("fileUri");
+        String openPwd = call.argument("password");
+        PDFDocumentError error;
+        if (!TextUtils.isEmpty(filePath)){
+          error = document.open(filePath, openPwd);
+        } else {
+          error = document.open(Uri.parse(fileUri), openPwd);
+        }
+        if (error == PDFDocumentError.PDFDocumentErrorSuccess){
+          readerView.setPDFDocument(document);
+        }
+        result.success(error.ordinal());
+        break;
+      case GET_FILE_NAME:
+        result.success(document.getFileName());
+        break;
+      case IS_ENCRYPTED:
+        result.success(document.isEncrypted());
+        break;
+      case IS_IMAGE_DOC:
+        CThreadPoolUtils.getInstance().executeIO(()->{
+          boolean isImageDoc = document.isImageDoc();
+          result.success(isImageDoc);
+        });
+        break;
+      case GET_PERMISSIONS:
+        result.success(document.getPermissions().id);
+        break;
+      case CHECK_OWNER_UNLOCKED:
+        result.success(document.checkOwnerUnlocked());
+        break;
+      case CHECK_PASSWORD:
+        String password = call.argument("password");
+        boolean isOwnerPwd = call.argument("isOwnerPassword");
+        result.success(document.checkPassword(password, isOwnerPwd));
+      case CLOSE:
+        document.close();
+        result.success(true);
+        break;
+      case HAS_CHANGE:
+        result.success(document.hasChanges());
+        break;
+      default:break;
+    }
+  }
+}

+ 40 - 22
android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/plugin/CPDFViewCtrlPlugin.java

@@ -11,9 +11,9 @@
 package com.compdfkit.flutter.compdfkit_flutter.plugin;
 
 import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.GET_CURRENT_PAGE_INDEX;
+import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.GET_PAGE_SIZE;
 import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.GET_READ_BACKGROUND_COLOR;
 import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.GET_SCALE;
-import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.HAS_CHANGE;
 import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.IS_CONTINUE_MODE;
 import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.IS_COVER_PAGE_MODE;
 import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.IS_CROP_MODE;
@@ -32,8 +32,8 @@ import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.Ch
 import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.SET_FIXED_SCROLL;
 import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.SET_FORM_FIELD_HIGHLIGHT;
 import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.SET_LINK_HIGHLIGHT;
-import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.SET_MARGIN;
 import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.SET_PAGE_SAME_WIDTH;
+import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.SET_MARGIN;
 import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.SET_READ_BACKGROUND_COLOR;
 import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.SET_SCALE;
 import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.SET_VERTICAL_MODE;
@@ -46,9 +46,10 @@ import android.util.Log;
 import androidx.annotation.NonNull;
 
 import com.compdfkit.core.document.CPDFDocument;
-import com.compdfkit.tools.common.pdf.CPDFDocumentFragment;
 
+import com.compdfkit.tools.common.pdf.CPDFDocumentFragment;
 import com.compdfkit.tools.common.utils.viewutils.CViewUtils;
+import com.compdfkit.tools.common.views.pdfview.CPDFIReaderViewCallback;
 import com.compdfkit.ui.reader.CPDFReaderView;
 import io.flutter.plugin.common.BinaryMessenger;
 import io.flutter.plugin.common.MethodCall;
@@ -63,13 +64,34 @@ public class CPDFViewCtrlPlugin extends BaseMethodChannelPlugin {
 
   private CPDFDocumentFragment documentFragment;
 
+  private CPDFDocumentPlugin documentPlugin;
+
   public CPDFViewCtrlPlugin(Context context, BinaryMessenger binaryMessenger, int viewId) {
     super(context, binaryMessenger);
     this.viewId = viewId;
+
+    // Register document plugin,get document info
+    documentPlugin = new CPDFDocumentPlugin(context, binaryMessenger, String.valueOf(viewId));
+    documentPlugin.register();
   }
 
   public void setDocumentFragment(CPDFDocumentFragment documentFragment) {
     this.documentFragment = documentFragment;
+    this.documentFragment.setInitListener((pdfView)->{
+      documentPlugin.setReaderView(pdfView.getCPdfReaderView());
+      pdfView.addReaderViewCallback(new CPDFIReaderViewCallback() {
+        @Override
+        public void onMoveToChild(int pageIndex) {
+          super.onMoveToChild(pageIndex);
+          io.flutter.Log.e("ComPDFKit", "onMoveToChild:" + pageIndex);
+          Map<String, Object> map = new HashMap<>();
+          map.put("pageIndex", pageIndex);
+          if (methodChannel != null) {
+            methodChannel.invokeMethod("onPageChanged", map);
+          }
+        }
+      });
+    });
   }
 
   @Override
@@ -80,6 +102,7 @@ public class CPDFViewCtrlPlugin extends BaseMethodChannelPlugin {
   @Override
   public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
     Log.e(LOG_TAG, "CPDFViewCtrlFlutter:onMethodCall:" + call.method);
+
     if (documentFragment == null) {
       Log.e(LOG_TAG,
           "CPDFViewCtrlFlutter:onMethodCall: documentFragment is Null return not implemented.");
@@ -176,7 +199,6 @@ public class CPDFViewCtrlPlugin extends BaseMethodChannelPlugin {
         result.success(readerView.getPageNum());
         break;
       case SET_PAGE_SAME_WIDTH:
-        Log.e("ComPDFKit", "setPageSameWidth:" + call.arguments);
         readerView.setPageSameWidth((Boolean) call.arguments);
         readerView.reloadPages();
         break;
@@ -194,24 +216,20 @@ public class CPDFViewCtrlPlugin extends BaseMethodChannelPlugin {
       case SET_FIXED_SCROLL:
         readerView.setFixedScroll((Boolean) call.arguments);
         break;
-      case HAS_CHANGE:
-        CPDFDocument document = readerView.getPDFDocument();
-        result.success(document.hasChanges());
-        break;
-//      case GET_PAGE_SIZE:
-//        boolean noZoomPage = call.argument("noZoom");
-//        int page = call.argument("pageIndex");
-//        RectF rectF;
-//        if (noZoomPage){
-//          rectF = readerView.getPageNoZoomSize(page);
-//        }else {
-//          rectF = readerView.getPageSize(page);
-//        }
-//        Map<String, Float> pageSizeMap = new HashMap<>();
-//        pageSizeMap.put("width", rectF.width());
-//        pageSizeMap.put("height", rectF.height());
-//        result.success(pageSizeMap);
-//        break;
+      case GET_PAGE_SIZE:
+        boolean noZoomPage = call.argument("noZoom");
+        int page = call.argument("pageIndex");
+        RectF rectF;
+        if (noZoomPage){
+          rectF = readerView.getPageNoZoomSize(page);
+        }else {
+          rectF = readerView.getPageSize(page);
+        }
+        Map<String, Float> pageSizeMap = new HashMap<>();
+        pageSizeMap.put("width", rectF.width());
+        pageSizeMap.put("height", rectF.height());
+        result.success(pageSizeMap);
+        break;
       default:
         Log.e(LOG_TAG, "CPDFViewCtrlFlutter:onMethodCall:notImplemented");
         result.notImplemented();

+ 1 - 1
example/android/config.gradle

@@ -3,6 +3,6 @@ ext {
             COMPILESDK: 33,
             MINSDK: 21,
             TARGETSDK: 33,
-            VERSIONCODE: 11
+            VERSIONCODE: 13
     ]
 }

+ 9 - 9
example/ios/Runner.xcodeproj/project.pbxproj

@@ -490,10 +490,10 @@
 				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
 				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
-				DEVELOPMENT_TEAM = 59AC9PMNH2;
+				DEVELOPMENT_TEAM = 4GGQPGRTSV;
 				ENABLE_BITCODE = NO;
-				FLUTTER_BUILD_NAME = 2.1.2;
-				FLUTTER_BUILD_NUMBER = 2.1.2;
+				FLUTTER_BUILD_NAME = 2.1.3;
+				FLUTTER_BUILD_NUMBER = 2.1.3;
 				INFOPLIST_FILE = Runner/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = (
@@ -680,10 +680,10 @@
 				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
 				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
-				DEVELOPMENT_TEAM = 59AC9PMNH2;
+				DEVELOPMENT_TEAM = 4GGQPGRTSV;
 				ENABLE_BITCODE = NO;
-				FLUTTER_BUILD_NAME = 2.1.2;
-				FLUTTER_BUILD_NUMBER = 2.1.2;
+				FLUTTER_BUILD_NAME = 2.1.3;
+				FLUTTER_BUILD_NUMBER = 2.1.3;
 				INFOPLIST_FILE = Runner/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = (
@@ -709,10 +709,10 @@
 				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
 				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
-				DEVELOPMENT_TEAM = 59AC9PMNH2;
+				DEVELOPMENT_TEAM = 4GGQPGRTSV;
 				ENABLE_BITCODE = NO;
-				FLUTTER_BUILD_NAME = 2.1.2;
-				FLUTTER_BUILD_NUMBER = 2.1.2;
+				FLUTTER_BUILD_NAME = 2.1.3;
+				FLUTTER_BUILD_NUMBER = 2.1.3;
 				INFOPLIST_FILE = Runner/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = (

+ 31 - 2
example/lib/cpdf_reader_widget_controller_example.dart

@@ -10,8 +10,10 @@ import 'dart:math';
 
 import 'package:compdfkit_flutter/configuration/cpdf_configuration.dart';
 import 'package:compdfkit_flutter/configuration/cpdf_options.dart';
+import 'package:compdfkit_flutter/util/extension/cpdf_color_extension.dart';
 import 'package:compdfkit_flutter/widgets/cpdf_reader_widget.dart';
 import 'package:compdfkit_flutter/widgets/cpdf_reader_widget_controller.dart';
+import 'package:file_picker/file_picker.dart';
 import 'package:flutter/material.dart';
 
 class CPDFReaderWidgetControllerExample extends StatefulWidget {
@@ -150,10 +152,34 @@ class _CPDFReaderWidgetControllerExampleState
         isFixedScroll = !isFixedScroll;
         await controller.setFixedScroll(isFixedScroll);
         break;
+      case 'setReadBackgroundColor':
+        var currentReadBackgroundColor = await controller.getReadBackgroundColor();
+        debugPrint('readBackgroundColor:${currentReadBackgroundColor.toHex()}');
+        await controller.setReadBackgroundColor(theme: CPDFThemes.light);
+        break;
       case 'isChanged':
         bool hasChange = await controller.hasChange();
         debugPrint('ComPDFKit:hasChange:$hasChange');
         break;
+      case "documentInfo":
+        var document = controller.document;
+        debugPrint('ComPDFKit:Document: fileName:${await document.getFileName()}');
+        debugPrint('ComPDFKit:Document: checkOwnerUnlocked:${await document.checkOwnerUnlocked()}');
+        debugPrint('ComPDFKit:Document: hasChange:${await document.hasChange()}');
+        debugPrint('ComPDFKit:Document: isEncrypted:${await document.isEncrypted()}');
+        debugPrint('ComPDFKit:Document: isImageDoc:${await document.isImageDoc()}');
+        debugPrint('ComPDFKit:Document: getPermissions:${await document.getPermissions()}');
+        break;
+      case "openDocument":
+        FilePickerResult? result = await FilePicker.platform.pickFiles(
+          type: FileType.custom,
+          allowedExtensions: ['pdf'],
+        );
+        if (result != null) {
+          var document = controller.document;
+          document.open(result.files.first.path!, "");
+        }
+        break;
     }
   }
 }
@@ -165,7 +191,8 @@ var actions = [
     'setCanScale',
     'pageSameWidth',
     'isPageInScreen',
-    'setFixedScroll'
+    'setFixedScroll',
+    'setReadBackgroundColor',
   ],
   'setFormHighlight',
   'setLinkHighlight',
@@ -177,7 +204,9 @@ var actions = [
   'setDisplayPageIndex',
   'getCurrentPageIndex',
   'setCoverPageMode',
-  'isChanged'
+  'isChanged',
+  'documentInfo',
+  'openDocument'
 ];
 
 Color randomColor() {

+ 7 - 1
ios/Classes/CompdfkitFlutterPlugin.swift

@@ -4,11 +4,17 @@ import ComPDFKit
 import ComPDFKit_Tools
 
 public class CompdfkitFlutterPlugin: NSObject, FlutterPlugin, CPDFViewBaseControllerDelete {
+
+    public var messager : FlutterBinaryMessenger?
+
+
     public static func register(with registrar: FlutterPluginRegistrar) {
         let channel = FlutterMethodChannel(name: "com.compdfkit.flutter.plugin", binaryMessenger: registrar.messenger())
+
         let instance = CompdfkitFlutterPlugin()
+        instance.messager = registrar.messenger()
         registrar.addMethodCallDelegate(instance, channel: channel)
-        
+
         let factory = CPDFViewCtrlFactory(messenger: registrar.messenger())
         registrar.register(factory, withId: "com.compdfkit.flutter.ui.pdfviewer")
     }

+ 1 - 5
ios/Classes/reader/CPDFViewCtrlFactory.swift

@@ -82,17 +82,13 @@ class CPDFViewCtrlFlutter: NSObject, FlutterPlatformView, CPDFViewBaseController
         navigationController.view.frame = frame
         
         var plugin = CPDFViewCtrlPlugin(viewId: viewId, binaryMessenger: messenger!, controller: pdfViewController)
-        
+
         super.init()
         
         // Proxy set, but not used
         pdfViewController.delegate = self
         
         navigationController.setViewControllers([pdfViewController], animated: true)
-
-        
-
-        
     }
 
     func view() -> UIView {

+ 25 - 8
ios/Classes/reader/CPDFViewCtrlPlugin.swift

@@ -22,11 +22,14 @@ class CPDFViewCtrlPlugin {
     init(viewId: Int64, binaryMessenger messenger: FlutterBinaryMessenger, controller : CPDFViewController) {
         self.pdfViewController = controller
         _methodChannel = FlutterMethodChannel.init(name: "com.compdfkit.flutter.ui.pdfviewer.\(viewId)", binaryMessenger: messenger)
-        registeryMethodChannel(viewId: viewId, binaryMessenger: messenger)
+        registeryMethodChannel()
+
+        var documentPlugin = CPDFDocumentPlugin(pdfViewController: pdfViewController, uid: String(describing: viewId), binaryMessager: messenger)
+
     }
     
     
-    private func registeryMethodChannel(viewId: Int64, binaryMessenger messenger: FlutterBinaryMessenger){
+    private func registeryMethodChannel(){
 
         _methodChannel.setMethodCallHandler({
             (call: FlutterMethodCall, result: FlutterResult) -> Void in
@@ -66,6 +69,26 @@ class CPDFViewCtrlPlugin {
                     return
                 }
                 result(pdfListView.scaleFactor)
+            case "set_read_background_color":
+                guard let pdfListView = self.pdfViewController.pdfListView else {
+                    return
+                }
+                // TODO: 需要设置阅读的背景颜色
+                // hex color, for example: '#FFFFFF'
+                // 需要设置给PDFListView
+                let bgColor = call.arguments as! String
+                let color = ColorHelper.colorWithHexString(hex: bgColor)
+                print("bgColor:\(bgColor), color:\(color.description)")
+//                pdfListView.displayModeCustomColor = CPDFDisplayModeCustom()
+//                pdfListView.layoutDocumentView()
+            case "get_read_background_color":
+                guard let pdfListView = self.pdfViewController.pdfListView else {
+                    result("#FFFFFF")
+                    return
+                }
+                // TODO: 返回当前阅读的背景颜色
+                // 需要返回Hex 颜色给Flutter, 例如:'#FFFFFF'
+//                result(pdfListView.displayModeCustomColor.toHexString())
             case "set_form_field_highlight":
                 guard let pdfListView = self.pdfViewController.pdfListView else {
                     return
@@ -178,12 +201,6 @@ class CPDFViewCtrlPlugin {
                     return
                 }
                 result(pdfListView.currentPageIndex)
-            case "has_change":
-                guard let pdfListView = self.pdfViewController.pdfListView else {
-                    result(false)
-                    return
-                }
-                result(pdfListView.document.isModified())
             default:
                 result(FlutterMethodNotImplemented)
             }

+ 60 - 4
lib/configuration/cpdf_options.dart

@@ -6,6 +6,10 @@
 // This notice may not be removed from this file.
 
 
+import 'dart:ui';
+
+import 'package:compdfkit_flutter/util/extension/cpdf_color_extension.dart';
+
 enum CPDFViewMode { viewer, annotations, contentEditor, forms, signatures }
 
 /// The [CPDFToolbarAction.back] button will only be displayed on the leftmost side of the top toolbar on the Android platform
@@ -32,16 +36,26 @@ enum CPDFDisplayMode { singlePage, doublePage, coverPage }
 /// readerView background themes
 enum CPDFThemes {
   /// Bright mode, readerview background is white
-  light,
+  light('#FFFFFF'),
 
   /// dark mode, readerview background is black
-  dark,
+  dark('#000000'),
 
   /// brown paper color
-  sepia,
+  sepia('#FFEFBE'),
 
   /// Light green, eye protection mode
-  reseda
+  reseda('#CDE6D0');
+
+  final String color;
+
+  const CPDFThemes(this.color);
+
+  // 获取颜色值
+  String getColor() {
+    return color;
+  }
+
 }
 
 enum CPDFAnnotationType {
@@ -164,4 +178,46 @@ class CPDFEdgeInsets {
         'right': right,
         'bottom': bottom,
       };
+}
+
+
+enum CPDFDocumentPermissions {
+
+  none,
+
+  user,
+
+  owner
+
+}
+
+/// Error types of the opening document.
+enum CPDFDocumentError {
+  /// No read permission.
+  noReadPermission,
+
+  /// SDK No verified license
+  notVerifyLicense,
+
+  /// open document success.
+  success,
+
+  /// Unknown error
+  unknown,
+
+  /// File not found or could not be opened.
+  errorFile,
+
+  /// File not in PDF format or corrupted.
+  errorFormat,
+
+  /// Password required or incorrect password.
+  errorPassword,
+
+  /// Unsupported security scheme.
+  errorSecurity,
+
+  /// Error page.
+  errorPage
+
 }

+ 109 - 8
lib/document/cpdf_document.dart

@@ -5,7 +5,9 @@
 // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
 // This notice may not be removed from this file.
 
-
+import 'package:compdfkit_flutter/configuration/cpdf_options.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter/widgets.dart';
 
 /// A class to handle PDF documents without using [CPDFReaderWidget]
 ///
@@ -21,12 +23,111 @@
 /// var fileName = await document.getFileName();
 /// ```
 class CPDFDocument {
-  // late MethodChannel _channel;
-  //
-  // bool _isValid = false;
-  //
-  // CPDFDocument.withController(int viewId)
-  //     : _channel = MethodChannel('com.compdfkit.flutter.document_$viewId'),
-  //       _isValid = true;
+  late MethodChannel _channel;
+
+  bool _isValid = false;
+
+  get isValid => _isValid;
+
+  CPDFDocument.withController(int viewId)
+      : _channel = MethodChannel('com.compdfkit.flutter.document_$viewId'),
+        _isValid = true;
+
+  Future<CPDFDocumentError> open(String filePath, String password) async {
+    var errorCode = await _channel.invokeMethod(
+        'open_document', {'filePath': filePath, 'password': password});
+    var error = CPDFDocumentError.values[errorCode];
+    _isValid = error == CPDFDocumentError.success;
+    return error;
+  }
+
+  /// Gets the file name of the PDF document.
+  ///
+  /// example:
+  /// ```dart
+  /// var fileName = await document.getFileName();
+  /// ```
+  Future<String> getFileName() async {
+    return await _channel.invokeMethod('get_file_name');
+  }
+
+  /// Checks if the PDF document is encrypted.
+  ///
+  /// example:
+  /// ```dart
+  /// var isEncrypted = await document.isEncrypted();
+  /// ```
+  Future<bool> isEncrypted() async {
+    return await _channel.invokeMethod('is_encrypted');
+  }
+
+  /// Checks if the PDF document is an image document.
+  /// This is a time-consuming operation that depends on the document size.
+  ///
+  /// example:
+  /// ```dart
+  /// var isImageDoc = await document.isImageDoc();
+  /// ```
+  Future<bool> isImageDoc() async {
+    return await _channel.invokeMethod('is_image_doc');
+  }
+
+  /// Gets the current document's permissions. There are three types of permissions:
+  /// No restrictions: [CPDFDocumentPermissions.none]
+  /// If the document has an open password and an owner password,
+  /// using the open password will grant [CPDFDocumentPermissions.user] permissions,
+  /// and using the owner password will grant [CPDFDocumentPermissions.owner] permissions.
+  ///
+  /// example:
+  /// ```dart
+  /// var permissions = await document.getPermissions();
+  /// ```
+  Future<CPDFDocumentPermissions> getPermissions() async {
+    int permissionId = await _channel.invokeMethod('get_permissions');
+    return CPDFDocumentPermissions.values[permissionId];
+  }
+
+  /// Check if owner permissions are unlocked
+  ///
+  /// example:
+  /// ```dart
+  /// var isUnlocked = await document.checkOwnerUnlocked();
+  /// ```
+  Future<bool> checkOwnerUnlocked() async {
+    return await _channel.invokeMethod('check_owner_unlocked');
+  }
+
+  /// Whether the password is correct.
+  ///
+  /// example:
+  /// ```dart
+  /// var isCorrect = await document.checkPassword('password', isOwnerPassword: true);
+  /// ```
+  Future<bool> checkPassword(String password,
+      {bool isOwnerPassword = false}) async {
+    return await _channel.invokeMethod('check_password',
+        {'password': password, 'isOwnerPassword': isOwnerPassword});
+  }
+
+  /// Check the document for modifications
+  ///
+  /// example:
+  /// ```dart
+  /// bool hasChange = await document.hasChange();
+  /// ```
+  Future<bool> hasChange() async {
+    return await _channel.invokeMethod('has_change');
+  }
+
+  /// After completing the operation of the document,
+  /// please close the document at the appropriate location to release resources.
+  Future<void> close() async {
+    if (!_isValid) return;
+    await _channel.invokeMethod('close');
+    debugPrint('ComPDFKit:CPDFDocument.close');
+    _isValid = false;
+  }
+
+  Future<void> getInfo() async {}
 
 }

+ 8 - 2
lib/widgets/cpdf_reader_widget.dart

@@ -19,6 +19,9 @@ import 'package:flutter/services.dart';
 typedef CPDFReaderWidgetCreatedCallback = void Function(
     CPDFReaderWidgetController controller);
 
+typedef CPDFPageChangedCallback = void Function(int pageIndex);
+
+
 class CPDFReaderWidget extends StatefulWidget {
   /// pdf file path
   final String document;
@@ -30,13 +33,16 @@ class CPDFReaderWidget extends StatefulWidget {
 
   final CPDFReaderWidgetCreatedCallback onCreated;
 
+  final CPDFPageChangedCallback? onPageChanged;
+
   /// init callback
   const CPDFReaderWidget(
       {Key? key,
       required this.document,
       this.password = '',
       required this.configuration,
-      required this.onCreated})
+      required this.onCreated,
+      this.onPageChanged})
       : super(key: key);
 
   @override
@@ -94,6 +100,6 @@ class _CPDFReaderWidgetState extends State<CPDFReaderWidget> {
 
   Future<void> _onPlatformViewCreated(int id) async {
     debugPrint('ComPDFKit-Flutter: CPDFReaderWidget created');
-    widget.onCreated(CPDFReaderWidgetController(id));
+    widget.onCreated(CPDFReaderWidgetController(id, onPageChanged: widget.onPageChanged));
   }
 }

+ 33 - 13
lib/widgets/cpdf_reader_widget_controller.dart

@@ -5,10 +5,14 @@
 // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
 // This notice may not be removed from this file.
 
+import 'dart:ffi';
 import 'dart:io';
 import 'package:flutter/services.dart';
 
 import '../configuration/cpdf_options.dart';
+import '../document/cpdf_document.dart';
+import '../util/extension/cpdf_color_extension.dart';
+import 'cpdf_reader_widget.dart';
 
 /// PDF Reader Widget Controller
 ///
@@ -30,15 +34,22 @@ import '../configuration/cpdf_options.dart';
 class CPDFReaderWidgetController {
   late MethodChannel _channel;
 
-  // late CPDFDocument _document;
+  late CPDFDocument _document;
 
-  CPDFReaderWidgetController(int id) {
+  CPDFReaderWidgetController(int id, {CPDFPageChangedCallback? onPageChanged}) {
     _channel = MethodChannel('com.compdfkit.flutter.ui.pdfviewer.$id');
-    _channel.setMethodCallHandler((call) async {});
-    // _document = CPDFDocument.withController(id);
+    _channel.setMethodCallHandler((call) async {
+      switch (call.method) {
+        case 'onPageChanged':
+          var pageIndex = call.arguments['pageIndex'];
+          onPageChanged?.call(pageIndex);
+          break;
+      }
+    });
+    _document = CPDFDocument.withController(id);
   }
 
-  // CPDFDocument get document => _document;
+  CPDFDocument get document => _document;
 
   /// Save document
   /// Return value: **true** if the save is successful,
@@ -87,9 +98,18 @@ class CPDFReaderWidgetController {
   /// ```dart
   /// await _controller.setReadBackgroundColor(Colors.white);
   /// ```
-  // Future<void> setReadBackgroundColor(Color color) async {
-  //   await _channel.invokeMethod('set_read_background_color', color.toHex());
-  // }
+  Future<void> setReadBackgroundColor({CPDFThemes? theme, Color? customColor}) async {
+    String colorToUse;
+    if (theme != null) {
+      colorToUse = theme.getColor();
+    } else if (customColor != null) {
+      colorToUse = customColor.toHex();
+    } else {
+      throw ArgumentError('Either theme or customColor must be provided.');
+    }
+    await _channel.invokeMethod('set_read_background_color', colorToUse);
+  }
+
 
   /// Get background color of reader.
   ///
@@ -97,10 +117,10 @@ class CPDFReaderWidgetController {
   /// ```dart
   /// Color color = await _controller.getReadBackgroundColor();
   /// ```
-  // Future<Color> getReadBackgroundColor() async {
-  //   String hexColor = await _channel.invokeMethod('get_read_background_color');
-  //   return HexColor.fromHex(hexColor);
-  // }
+  Future<Color> getReadBackgroundColor() async {
+    String hexColor = await _channel.invokeMethod('get_read_background_color');
+    return HexColor.fromHex(hexColor);
+  }
 
   /// Sets whether to display highlight Form Field.
   /// [isFormFieldHighlight] : true to display highlight Form Field.
@@ -331,6 +351,6 @@ class CPDFReaderWidgetController {
   /// bool hasChange = await document.hasChange();
   /// ```
   Future<bool> hasChange() async {
-    return await _channel.invokeMethod('has_change');
+    return await _document.hasChange();
   }
 }