map) {
18 | CPDFSignatureWidget signatureWidget = (CPDFSignatureWidget) widget;
19 | map.put("type", "signaturesFields");
20 | }
21 |
22 | public boolean addImageSignatures(Context context, CPDFAnnotation widget, String imagePath){
23 | CPDFSignatureWidget signatureWidget = (CPDFSignatureWidget) widget;
24 | try{
25 | String path = FileUtils.getImportFilePath(context, imagePath);
26 | Bitmap bitmap = CBitmapUtil.decodeBitmap(path);
27 | if (bitmap != null){
28 | return signatureWidget.updateApWithBitmap(bitmap, CPDFImageScaleType.SCALETYPE_fitCenter);
29 | }
30 | }catch (Exception e){
31 | e.printStackTrace();
32 | return false;
33 | }
34 | return false;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
20 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/example/lib/widgets/cpdf_app_bar.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014-2025 PDF Technologies, Inc. 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 ComPDFKit 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 |
11 | import 'package:flutter/material.dart';
12 | import 'package:flutter_svg/svg.dart';
13 |
14 | import '../page/settings_page.dart';
15 |
16 |
17 | class CAppBar extends StatelessWidget implements PreferredSizeWidget {
18 | const CAppBar({super.key});
19 |
20 |
21 | @override
22 | Widget build(BuildContext context) {
23 | return AppBar(
24 | title: const Text('ComPDFKit SDK for Flutter'),
25 | actions: [
26 | IconButton(
27 | padding: const EdgeInsets.all(16),
28 | onPressed: () {
29 | Navigator.push(context, MaterialPageRoute(builder: (context) {
30 | return const SettingsPage();
31 | }));
32 | },
33 | icon: SvgPicture.asset(
34 | 'images/ic_home_setting.svg',
35 | width: 24,
36 | height: 24,
37 | colorFilter: ColorFilter.mode(
38 | Theme.of(context).colorScheme.onPrimary, BlendMode.srcIn),
39 | ))
40 | ],
41 | );
42 | }
43 |
44 | @override
45 | Size get preferredSize => const Size(double.infinity, 56);
46 | }
47 |
--------------------------------------------------------------------------------
/android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/plugin/BaseMethodChannelPlugin.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright © 2014-2025 PDF Technologies, Inc. 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 ComPDFKit 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 | package com.compdfkit.flutter.compdfkit_flutter.plugin;
11 |
12 |
13 |
14 | import android.content.Context;
15 | import android.util.Log;
16 |
17 | import io.flutter.plugin.common.BinaryMessenger;
18 | import io.flutter.plugin.common.MethodChannel;
19 |
20 |
21 | public abstract class BaseMethodChannelPlugin implements MethodChannel.MethodCallHandler {
22 |
23 | public static final String LOG_TAG = "ComPDFKit-Plugin";
24 |
25 | protected MethodChannel methodChannel = null;
26 |
27 | protected Context context;
28 |
29 | protected BinaryMessenger binaryMessenger;
30 |
31 | public BaseMethodChannelPlugin(Context context, BinaryMessenger binaryMessenger) {
32 | this.context = context;
33 | this.binaryMessenger = binaryMessenger;
34 | }
35 |
36 | public abstract String methodName();
37 |
38 | public void register(){
39 | Log.e(LOG_TAG, "create MethodChannel:" + methodName());
40 | methodChannel = new MethodChannel(binaryMessenger, methodName());
41 | methodChannel.setMethodCallHandler(this);
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/platformview/CPDFViewCtrlFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014-2025 PDF Technologies, Inc. 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 ComPDFKit 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 |
11 | package com.compdfkit.flutter.compdfkit_flutter.platformview;
12 |
13 |
14 | import android.content.Context;
15 |
16 | import androidx.annotation.NonNull;
17 | import androidx.annotation.Nullable;
18 |
19 | import java.util.Map;
20 |
21 | import io.flutter.plugin.common.BinaryMessenger;
22 | import io.flutter.plugin.common.StandardMessageCodec;
23 | import io.flutter.plugin.platform.PlatformView;
24 | import io.flutter.plugin.platform.PlatformViewFactory;
25 |
26 | public class CPDFViewCtrlFactory extends PlatformViewFactory {
27 |
28 | private final BinaryMessenger binaryMessenger;
29 |
30 | public CPDFViewCtrlFactory(BinaryMessenger binaryMessenger) {
31 | super(StandardMessageCodec.INSTANCE);
32 | this.binaryMessenger = binaryMessenger;
33 | }
34 |
35 | @NonNull
36 | @Override
37 | public PlatformView create(Context context, int viewId, @Nullable Object args) {
38 | @SuppressWarnings("unchecked")
39 | Map creationParams = (Map) args;
40 | return new CPDFViewCtrlFlutter(context, binaryMessenger, viewId, creationParams);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/example/assets/license_key_flutter.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | flutter
4 | com.compdfkit.flutter.example
5 | 2025-06-24
6 | 2026-06-24
7 | online
8 | subscription
9 | NjhhZTZhMzQ4MWQ2ZA==
10 | Jeeb35TZTpvuM8r/CWUF3c6VFz+lDh5J+kgfHNf1RVRb4y7vI5Jv5joLyWI5Cg/lHP4yILoyR88V3nKZLy9yvSOo70SBmKC1Sr5OM5X9YxkeuA2gOuS2p3X2/7vBASJK40iSjNxeBDuCXgNHPf1607CPL2qcz2s7d3R2VCqYT9RQ9hubiZPhj49Z/1BhepVNAHERj6OEKmmpxUoXXqWhkkEN4QBY9sGkayC4F1sSuwfpKIai6yQisKssslGQGgNu8nqxGORCgrNZrWh6xMu+xXzYwb/pxpcWwN+JjuxBk1VXG9Yfvno7Y9n5eBxohSG3iPnFSiZIibGK1TxYNwvzoDxtH9Cv/VMxENxGz0h/6Bvzvl0BF1n4ttDab3FQLUFqODf3Z+1/gksh0aBE2Pyfdb6CiboPJJslZGPmzU9ygyoA4/rOQfGhWYsAT2bfT3kbwO4lBtWS+817NWLmnHDfJ0vJZOQQkYA4trij+/SXhFwc5Y3hvgio55+KS1V/vaBTTRaTjIbppEjZOTxdtdf1grDga+ZwgyEi+MudNtwsHSJxOSX1oSjA556P9LoW3WaGm8PUoNANMBsagy+pJBDNqCO8Ne106+KWcNWGWTMam2vGTojah2OcZUVmq55ndvrwgsImtuoYTMJgAjU9/tRxbUOQ2l1Li6nyHKmVHGxbMo9ei5ls1rJX8xC500/B7MElP9y7fwgdZjYT9csmn/VoNxG9PXGN1z688csOssTIHX8OnFNQdzujseLgCxJip4jkFvytK/6tQwABBr2jnj4CoZ64vMX4pWtk1G3b4LYjpSq8QQxxzs35J3qN6zsL18tsWHgQXZntungTEQdRZlTo94hNZQ5/rRn+TGoqy4i4Or2nCEYC9lWdpncHZrH8LoxBqrX8pUgPKv4AN/BHCq7VsISw0jKgupAKUsEvSemq5l17y+KOsPpuaZrTOLMzNpB/z1jNz5HFfXO+fwVkKXzGUXjU2OthrljT5OuwTdcAOGBQzOc7Q1bWXJf7F+xzkNmZejy03UBBK4zcSYGwJNtJ34HW6Vv3fsyDfPkaUKl6w27NTOpowY1zV/RHatoYac3gtc4A/VCikc9Ukzbes6mFXshxGvYOWYVpPDCQzR79yY2PTM3ASwJqur/voqpB5GHXx69rPL6kD4+KUvHZugpheCEhrHlezyaZrNtFfQ5z8rlfHt0GdlRWOdZKaq91Vf8gI7hwwyhWsOwpJ/hkGum5zNXfqD3279ZAUyayu7cfipDvUPRoP3ye1ZQoJHzE9XaHjTGuT0llnzf48Pi8HGZzNnCCF7l+9RQRwonvUPqd0rlBg/1MlvoZM9GW45tGVgOfd0k6asostcYPyW6Vqi8pbg==
11 |
--------------------------------------------------------------------------------
/android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/utils/annotation/FlutterCPDFBaseAnnotation.java:
--------------------------------------------------------------------------------
1 | package com.compdfkit.flutter.compdfkit_flutter.utils.annotation;
2 |
3 |
4 | import android.graphics.RectF;
5 | import android.util.Log;
6 | import com.compdfkit.core.common.CPDFDate;
7 | import com.compdfkit.tools.common.utils.date.CDateUtil;
8 | import java.util.HashMap;
9 | import java.util.Map;
10 |
11 | public abstract class FlutterCPDFBaseAnnotation implements FlutterCPDFAnnotation {
12 |
13 | @Override
14 | public HashMap getAnnotation(com.compdfkit.core.annotation.CPDFAnnotation annotation) {
15 | HashMap map = new HashMap<>();
16 | map.put("type", annotation.getType().name().toLowerCase());
17 | map.put("page", annotation.pdfPage.getPageNum());
18 | map.put("title", annotation.getTitle());
19 | map.put("content", annotation.getContent());
20 | map.put("uuid", annotation.getAnnotPtr()+"");
21 | RectF rect = annotation.getRect();
22 | Map rectMap = new HashMap<>();
23 | rectMap.put("left", rect.left);
24 | rectMap.put("top", rect.top);
25 | rectMap.put("right", rect.right);
26 | rectMap.put("bottom", rect.bottom);
27 | map.put("rect", rectMap);
28 |
29 | CPDFDate modifyDate = annotation.getRecentlyModifyDate();
30 | CPDFDate createDate = annotation.getCreationDate();
31 | if (modifyDate != null) {
32 | map.put("modifyDate", CDateUtil.transformToTimestamp(modifyDate));
33 | }
34 | if (createDate != null) {
35 | map.put("createDate", CDateUtil.transformToTimestamp(createDate));
36 | }
37 | covert(annotation, map);
38 | return map;
39 | }
40 |
41 | public abstract void covert(com.compdfkit.core.annotation.CPDFAnnotation annotation, HashMap map);
42 | }
43 |
--------------------------------------------------------------------------------
/example/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | platform :ios, '12.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def flutter_root
14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15 | unless File.exist?(generated_xcode_build_settings_path)
16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17 | end
18 |
19 | File.foreach(generated_xcode_build_settings_path) do |line|
20 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
21 | return matches[1].strip if matches
22 | end
23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24 | end
25 |
26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27 |
28 | flutter_ios_podfile_setup
29 |
30 | target 'Runner' do
31 | use_frameworks!
32 | use_modular_headers!
33 | pod 'ComPDFKit', :git => 'https://github.com/ComPDFKit/compdfkit-pdf-sdk-ios-swift.git', :tag => '2.5.3'
34 | pod 'ComPDFKit_Tools', :git => 'https://github.com/ComPDFKit/compdfkit-pdf-sdk-ios-swift.git', :tag => '2.5.3'
35 |
36 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
37 | target 'RunnerTests' do
38 | inherit! :search_paths
39 | end
40 | end
41 |
42 | post_install do |installer|
43 | installer.pods_project.targets.each do |target|
44 | flutter_additional_ios_build_settings(target)
45 | end
46 | end
47 |
--------------------------------------------------------------------------------
/lib/document/action/cpdf_action.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014-2025 PDF Technologies, Inc. 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 ComPDFKit 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 |
11 | import 'package:compdfkit_flutter/document/action/cpdf_uri_action.dart';
12 |
13 | import 'cpdf_goto_action.dart';
14 |
15 | class CPDFAction {
16 |
17 | final CPDFActionType actionType;
18 |
19 | CPDFAction({required this.actionType});
20 |
21 | factory CPDFAction.fromJson(Map json) {
22 | CPDFActionType actionType = CPDFActionType.values.firstWhere((element) => element.name == json["actionType"]);
23 | switch (actionType) {
24 | case CPDFActionType.goTo:
25 | return CPDFGoToAction.fromJson(json);
26 | case CPDFActionType.uri:
27 | return CPDFUriAction.fromJson(json);
28 | default:
29 | return CPDFAction(actionType: actionType);
30 | }
31 | }
32 |
33 | Map toJson() {
34 | return {
35 | "actionType": actionType.name,
36 | };
37 | }
38 |
39 | }
40 |
41 | enum CPDFActionType {
42 |
43 | unknown,
44 |
45 | goTo,
46 |
47 | goToR,
48 |
49 | goToE,
50 |
51 | launch,
52 |
53 | thread,
54 |
55 | uri,
56 |
57 | sound,
58 |
59 | movie,
60 |
61 | hide,
62 |
63 | named,
64 |
65 | submitForm,
66 |
67 | resetForm,
68 |
69 | importData,
70 |
71 | javaScript,
72 |
73 | setOCGState,
74 |
75 | rendition,
76 |
77 | trans,
78 |
79 | goTo3DView,
80 |
81 | uop,
82 |
83 | error;
84 |
85 |
86 | }
87 |
88 |
--------------------------------------------------------------------------------
/lib/annotation/cpdf_circle_annotation.dart:
--------------------------------------------------------------------------------
1 | // Copyright © 2014-2025 PDF Technologies, Inc. All Rights Reserved.
2 | //
3 | // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
4 | // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
5 | // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
6 | // This notice may not be removed from this file.
7 |
8 | import 'cpdf_square_annotation.dart';
9 |
10 | class CPDFCircleAnnotations extends CPDFSquareAnnotation {
11 | CPDFCircleAnnotations({
12 | required super.type,
13 | required super.title,
14 | required super.page,
15 | required super.content,
16 | required super.uuid,
17 | super.createDate,
18 | required super.rect,
19 | required super.borderWidth,
20 | required super.borderColor,
21 | required super.borderAlpha,
22 | required super.fillColor,
23 | required super.fillAlpha,
24 | required super.effectType,
25 | });
26 |
27 | factory CPDFCircleAnnotations.fromJson(Map json) {
28 | final square = CPDFSquareAnnotation.fromJson(json);
29 | return CPDFCircleAnnotations(
30 | type: square.type,
31 | title: square.title,
32 | page: square.page,
33 | content: square.content,
34 | uuid: square.uuid,
35 | createDate: square.createDate,
36 | rect: square.rect,
37 | borderWidth: square.borderWidth,
38 | borderColor: square.borderColor,
39 | borderAlpha: square.borderAlpha,
40 | fillColor: square.fillColor,
41 | fillAlpha: square.fillAlpha,
42 | effectType: square.effectType,
43 | );
44 | }
45 | }
--------------------------------------------------------------------------------
/example/lib/cpdf_configuration_manager.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014-2025 PDF Technologies, Inc. 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 ComPDFKit 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 |
11 | // config/cpdf_configuration_manager.dart
12 | import 'package:compdfkit_flutter/configuration/cpdf_configuration.dart';
13 | import 'package:compdfkit_flutter/configuration/cpdf_options.dart';
14 |
15 | class CPDFConfigurationManager {
16 |
17 | static CPDFConfiguration get defaultConfig => CPDFConfiguration();
18 |
19 | static CPDFConfiguration get annotationConfig => CPDFConfiguration(
20 | modeConfig: const CPDFModeConfig(
21 | initialViewMode: CPDFViewMode.annotations,
22 | uiVisibilityMode: CPDFUIVisibilityMode.never,
23 | ),
24 | toolbarConfig: const CPDFToolbarConfig(mainToolbarVisible: false),
25 | );
26 |
27 | static CPDFConfiguration get controllerExampleConfig => CPDFConfiguration();
28 |
29 | static CPDFConfiguration buildConfig({
30 | CPDFViewMode? initialViewMode,
31 | CPDFUIVisibilityMode? uiVisibilityMode,
32 | bool mainToolbarVisible = true,
33 | CPDFWatermarkConfig? watermark,
34 | }) {
35 | return CPDFConfiguration(
36 | modeConfig: CPDFModeConfig(
37 | initialViewMode: initialViewMode ?? CPDFViewMode.viewer,
38 | uiVisibilityMode: uiVisibilityMode ?? CPDFUIVisibilityMode.automatic,
39 | ),
40 | toolbarConfig: CPDFToolbarConfig(mainToolbarVisible: mainToolbarVisible),
41 | globalConfig: CPDFGlobalConfig(watermark: watermark ?? const CPDFWatermarkConfig())
42 | );
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/lib/annotation/form/cpdf_signature_widget.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014-2025 PDF Technologies, Inc. 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 ComPDFKit 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 |
11 |
12 | import 'package:compdfkit_flutter/annotation/form/cpdf_widget.dart';
13 | import 'package:compdfkit_flutter/configuration/cpdf_options.dart';
14 |
15 | import '../../util/cpdf_rectf.dart';
16 |
17 | class CPDFSignatureWidget extends CPDFWidget {
18 |
19 | CPDFSignatureWidget({
20 | required CPDFFormType type,
21 | required String title,
22 | required int page,
23 | required String uuid,
24 | DateTime? createDate,
25 | required CPDFRectF rect,
26 | required borderColor,
27 | required fillColor,
28 | required borderWidth
29 | }) : super(
30 | type: type,
31 | title: title,
32 | page: page,
33 | uuid: uuid,
34 | createDate: createDate,
35 | rect: rect,
36 | borderColor: borderColor,
37 | borderWidth: borderWidth,
38 | fillColor: fillColor);
39 |
40 | factory CPDFSignatureWidget.fromJson(Map json) {
41 | CPDFWidget common = CPDFWidget.fromJson(json);
42 | return CPDFSignatureWidget(
43 | type: common.type,
44 | title: common.title,
45 | page: common.page,
46 | uuid: common.uuid,
47 | createDate: common.createDate,
48 | rect: common.rect,
49 | borderColor: common.borderColor,
50 | borderWidth: common.borderWidth,
51 | fillColor: common.fillColor,
52 | );
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/example/images/ic_ink.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | group 'com.compdfkit.flutter.compdfkit_flutter'
2 | version '1.0'
3 |
4 | buildscript {
5 | repositories {
6 | google()
7 | mavenCentral()
8 | maven { url 'https://central.sonatype.com/repository/maven-snapshots/' }
9 |
10 |
11 | }
12 |
13 | dependencies {
14 | classpath 'com.android.tools.build:gradle:7.3.0'
15 | }
16 | }
17 |
18 | rootProject.allprojects {
19 | repositories {
20 | google()
21 | mavenCentral()
22 | maven { url 'https://central.sonatype.com/repository/maven-snapshots/' }
23 | }
24 | }
25 |
26 | apply plugin: 'com.android.library'
27 |
28 | android {
29 | compileSdk 35
30 | namespace "com.compdfkit.flutter.compdfkit_flutter"
31 | compileOptions {
32 | sourceCompatibility JavaVersion.VERSION_1_8
33 | targetCompatibility JavaVersion.VERSION_1_8
34 | }
35 |
36 | defaultConfig {
37 | minSdkVersion 21
38 | }
39 |
40 | dependencies {
41 | compileOnly fileTree(include: ['*.jar','*.aar'], dir: 'libs')
42 |
43 | // dependencies compdfkit pdf sdk
44 | api 'com.compdf:compdfkit-tools:2.5.3.1'
45 |
46 | testImplementation 'junit:junit:4.13.2'
47 | testImplementation 'org.mockito:mockito-core:5.0.0'
48 | api 'com.github.bumptech.glide:glide:4.15.1'
49 | annotationProcessor 'com.github.bumptech.glide:compiler:4.15.1'
50 | api 'androidx.documentfile:documentfile:1.0.1'
51 | }
52 |
53 | testOptions {
54 | unitTests.all {
55 | testLogging {
56 | events "passed", "skipped", "failed", "standardOut", "standardError"
57 | outputs.upToDateWhen {false}
58 | showStandardStreams = true
59 | }
60 | }
61 | }
62 | }
63 | // refresh snapshot implementation
64 | configurations.all { resolutionStrategy.cacheChangingModulesFor 0, 'seconds' }
65 |
66 |
--------------------------------------------------------------------------------
/lib/configuration/contextmenu/cpdf_context_menu_config.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014-2025 PDF Technologies, Inc. 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 ComPDFKit 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 |
11 | import 'package:compdfkit_flutter/configuration/contextmenu/cpdf_annotation_mode_context_menu.dart';
12 | import 'package:compdfkit_flutter/configuration/contextmenu/cpdf_content_editor_mode_context_menu.dart';
13 | import 'package:compdfkit_flutter/configuration/contextmenu/cpdf_form_mode_context_menu.dart';
14 | import 'package:compdfkit_flutter/configuration/contextmenu/cpdf_view_mode_context_menu.dart';
15 |
16 | import 'cpdf_global_context_menu.dart';
17 |
18 | class CPDFContextMenuConfig {
19 | final CPDFGlobalContextMenu global;
20 |
21 | final CPDFViewModeContextMenu viewMode;
22 |
23 | final CPDFAnnotationModeContextMenu annotationMode;
24 |
25 | final CPDFContentEditorModeContextMenu contentEditorMode;
26 |
27 | final CPDFFormModeContextMenu formMode;
28 |
29 | const CPDFContextMenuConfig({
30 | this.global = const CPDFGlobalContextMenu(),
31 | this.viewMode = const CPDFViewModeContextMenu(),
32 | this.annotationMode = const CPDFAnnotationModeContextMenu(),
33 | this.contentEditorMode = const CPDFContentEditorModeContextMenu(),
34 | this.formMode = const CPDFFormModeContextMenu(),
35 | });
36 |
37 | Map toJson() {
38 | return {
39 | 'global': global.toJson(),
40 | 'viewMode': viewMode.toJson(),
41 | 'annotationMode': annotationMode.toJson(),
42 | 'contentEditorMode': contentEditorMode.toJson(),
43 | 'formMode': formMode.toJson(),
44 | };
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/lib/annotation/form/cpdf_widget_registry.dart:
--------------------------------------------------------------------------------
1 | // Copyright © 2014-2025 PDF Technologies, Inc. All Rights Reserved.
2 | //
3 | // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
4 | // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
5 | // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
6 | // This notice may not be removed from this file.
7 |
8 |
9 | import 'package:compdfkit_flutter/annotation/form/cpdf_checkbox_widget.dart';
10 | import 'package:compdfkit_flutter/annotation/form/cpdf_combobox_widget.dart';
11 | import 'package:compdfkit_flutter/annotation/form/cpdf_listbox_widget.dart';
12 | import 'package:compdfkit_flutter/annotation/form/cpdf_pushbutton_widget.dart';
13 | import 'package:compdfkit_flutter/annotation/form/cpdf_radiobutton_widget.dart';
14 | import 'package:compdfkit_flutter/annotation/form/cpdf_signature_widget.dart';
15 | import 'package:compdfkit_flutter/annotation/form/cpdf_widget.dart';
16 | import 'package:compdfkit_flutter/configuration/cpdf_options.dart';
17 |
18 | import 'cpdf_text_widget.dart';
19 |
20 |
21 | typedef CPDFWidgetFactory = CPDFWidget Function(Map json);
22 |
23 | class CPDFWidgetRegistry {
24 | static final Map _factories = {
25 | CPDFFormType.textField: CPDFTextWidget.fromJson,
26 | CPDFFormType.checkBox: CPDFCheckBoxWidget.fromJson,
27 | CPDFFormType.radioButton: CPDFRadioButtonWidget.fromJson,
28 | CPDFFormType.comboBox: CPDFComboBoxWidget.fromJson,
29 | CPDFFormType.listBox: CPDFListBoxWidget.fromJson,
30 | CPDFFormType.pushButton: CPDFPushButtonWidget.fromJson,
31 | CPDFFormType.signaturesFields: CPDFSignatureWidget.fromJson,
32 | };
33 |
34 | static CPDFWidget fromJson(Map json) {
35 | final type = CPDFFormType.fromString(json['type']);
36 | final factory = _factories[type] ?? CPDFWidget.fromJson;
37 | return factory(json);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/lib/annotation/cpdf_annotation.dart:
--------------------------------------------------------------------------------
1 | // Copyright © 2014-2025 PDF Technologies, Inc. All Rights Reserved.
2 | //
3 | // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
4 | // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
5 | // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
6 | // This notice may not be removed from this file.
7 |
8 | import 'dart:convert';
9 |
10 | import 'package:compdfkit_flutter/configuration/cpdf_options.dart';
11 | import 'package:compdfkit_flutter/util/cpdf_rectf.dart';
12 |
13 | class CPDFAnnotation {
14 | final CPDFAnnotationType type;
15 |
16 | final String title;
17 |
18 | final int page;
19 |
20 | final String content;
21 |
22 | final String uuid;
23 |
24 | final DateTime? createDate;
25 |
26 | final CPDFRectF rect;
27 |
28 | CPDFAnnotation(
29 | {required this.type,
30 | required this.title,
31 | required this.page,
32 | required this.content,
33 | required this.uuid,
34 | this.createDate,
35 | required this.rect});
36 |
37 | factory CPDFAnnotation.fromJson(Map json) {
38 | return CPDFAnnotation(
39 | type: CPDFAnnotationType.fromString(json['type']),
40 | title: json['title'] ?? '',
41 | page: json['page'] ?? 0,
42 | content: json['content'] ?? '',
43 | uuid: json['uuid'] ?? '',
44 | createDate: json['createDate'] != null
45 | ? DateTime.fromMillisecondsSinceEpoch(json['createDate'])
46 | : null,
47 | rect: CPDFRectF.fromJson(Map.from(json['rect'] ?? {})),
48 | );
49 | }
50 |
51 | Map toJson() => {
52 | 'type': type.name,
53 | 'title': title,
54 | 'page': page,
55 | 'content': content,
56 | 'uuid': uuid,
57 | 'createDate': createDate?.toString(),
58 | 'rect': rect.toString()
59 | };
60 |
61 | @override
62 | String toString() => jsonEncode(toJson());
63 | }
64 |
--------------------------------------------------------------------------------
/android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/utils/annotation/FlutterCPDFLineAnnotation.java:
--------------------------------------------------------------------------------
1 | package com.compdfkit.flutter.compdfkit_flutter.utils.annotation;
2 |
3 |
4 | import com.compdfkit.core.annotation.CPDFAnnotation;
5 | import com.compdfkit.core.annotation.CPDFLineAnnotation;
6 | import com.compdfkit.core.annotation.CPDFLineAnnotation.LineType;
7 | import com.compdfkit.flutter.compdfkit_flutter.utils.CAppUtils;
8 | import java.util.HashMap;
9 |
10 | public class FlutterCPDFLineAnnotation extends FlutterCPDFBaseAnnotation {
11 |
12 |
13 | @Override
14 | public void covert(CPDFAnnotation annotation, HashMap map) {
15 | CPDFLineAnnotation lineAnnotation = (CPDFLineAnnotation) annotation;
16 | if (lineAnnotation.getLineHeadType() == LineType.LINETYPE_NONE
17 | && lineAnnotation.getLineTailType() == LineType.LINETYPE_NONE) {
18 | map.put("type", "line");
19 | } else {
20 | map.put("type", "arrow");
21 | }
22 | map.put("borderColor", CAppUtils.toHexColor(lineAnnotation.getBorderColor()));
23 | map.put("borderAlpha", (double) lineAnnotation.getBorderAlpha());
24 | map.put("fillColor", CAppUtils.toHexColor(lineAnnotation.getFillColor()));
25 | map.put("fillAlpha", (double) lineAnnotation.getFillAlpha());
26 | map.put("borderWidth", lineAnnotation.getBorderWidth());
27 | map.put("lineHeadType", getLineType(lineAnnotation.getLineHeadType()));
28 | map.put("lineTailType", getLineType(lineAnnotation.getLineTailType()));
29 | }
30 |
31 | private String getLineType(CPDFLineAnnotation.LineType lineType) {
32 | switch (lineType) {
33 | case LINETYPE_ARROW:
34 | return "openArrow";
35 | case LINETYPE_CIRCLE:
36 | return "circle";
37 | case LINETYPE_DIAMOND:
38 | return "diamond";
39 | case LINETYPE_SQUARE:
40 | return "square";
41 | case LINETYPE_CLOSEDARROW:
42 | return "closedArrow";
43 | case LINETYPE_NONE:
44 | return "none";
45 | default:
46 | return "unknown";
47 | }
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/lib/annotation/cpdf_link_annotation.dart:
--------------------------------------------------------------------------------
1 | // Copyright © 2014-2025 PDF Technologies, Inc. All Rights Reserved.
2 | //
3 | // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
4 | // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
5 | // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
6 | // This notice may not be removed from this file.
7 |
8 |
9 | import 'package:compdfkit_flutter/annotation/cpdf_annotation.dart';
10 | import 'package:compdfkit_flutter/configuration/cpdf_options.dart';
11 |
12 | import '../document/action/cpdf_action.dart';
13 | import '../util/cpdf_rectf.dart';
14 |
15 | class CPDFLinkAnnotation extends CPDFAnnotation {
16 | final CPDFAction? action;
17 |
18 | CPDFLinkAnnotation(
19 | {required CPDFAnnotationType type,
20 | required String title,
21 | required int page,
22 | required String content,
23 | required String uuid,
24 | DateTime? createDate,
25 | required CPDFRectF rect,
26 | this.action})
27 | : super(
28 | type: type,
29 | title: title,
30 | page: page,
31 | content: content,
32 | uuid: uuid,
33 | createDate: createDate,
34 | rect: rect);
35 |
36 | factory CPDFLinkAnnotation.fromJson(Map json) {
37 | final common = CPDFAnnotation.fromJson(json);
38 | return CPDFLinkAnnotation(
39 | type: common.type,
40 | title: common.title,
41 | page: common.page,
42 | content: common.content,
43 | uuid: common.uuid,
44 | createDate: common.createDate,
45 | rect: common.rect,
46 | action: json['action'] != null
47 | ? CPDFAction.fromJson(
48 | Map.from(json['action'] ?? {}))
49 | : null);
50 | }
51 |
52 | @override
53 | Map toJson() {
54 | return {
55 | ...super.toJson(),
56 | 'action': action?.toJson()
57 | };
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
17 |
25 |
28 |
29 |
30 |
31 |
32 |
33 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/lib/configuration/config/cpdf_search_config.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014-2025 PDF Technologies, Inc. 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 ComPDFKit 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 |
11 | import 'package:flutter/material.dart';
12 |
13 | import 'package:compdfkit_flutter/util/extension/cpdf_color_extension.dart';
14 |
15 | class CPDFSearchConfig {
16 |
17 | final CPDFKeywordConfig normalKeyword;
18 | final CPDFKeywordConfig focusKeyword;
19 |
20 | const CPDFSearchConfig({
21 | this.normalKeyword = const CPDFKeywordConfig(
22 | borderColor: Colors.transparent,
23 | fillColor: Color(0x77FFFF00),
24 | ),
25 | this.focusKeyword = const CPDFKeywordConfig(
26 | borderColor: Colors.transparent,
27 | fillColor: Color(0xCCFD7338),
28 | ),
29 | });
30 |
31 | factory CPDFSearchConfig.fromJson(Map json) {
32 | return CPDFSearchConfig(
33 | normalKeyword: CPDFKeywordConfig.fromJson(json['normalKeyword']),
34 | focusKeyword: CPDFKeywordConfig.fromJson(json['focusKeyword']),
35 | );
36 | }
37 |
38 | Map toJson() {
39 | return {
40 | 'normalKeyword': normalKeyword.toJson(),
41 | 'focusKeyword': focusKeyword.toJson(),
42 | };
43 | }
44 | }
45 |
46 | class CPDFKeywordConfig {
47 |
48 | final Color borderColor;
49 | final Color fillColor;
50 |
51 | const CPDFKeywordConfig({
52 | required this.borderColor,
53 | required this.fillColor,
54 | });
55 |
56 | factory CPDFKeywordConfig.fromJson(Map json) {
57 | return CPDFKeywordConfig(
58 | borderColor: HexColor.fromHex(json['borderColor']),
59 | fillColor: HexColor.fromHex(json['fillColor']),
60 | );
61 | }
62 |
63 | Map toJson() {
64 | return {
65 | 'borderColor': borderColor.toHex(),
66 | 'fillColor': fillColor.toHex(),
67 | };
68 | }
69 | }
--------------------------------------------------------------------------------
/android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/utils/annotation/FlutterCPDFLinkAnnotation.java:
--------------------------------------------------------------------------------
1 | package com.compdfkit.flutter.compdfkit_flutter.utils.annotation;
2 |
3 |
4 | import static com.compdfkit.flutter.compdfkit_flutter.utils.annotation.forms.FlutterCPDFPushbuttonWidget.getActionType;
5 |
6 | import com.compdfkit.core.annotation.CPDFAnnotation;
7 | import com.compdfkit.core.annotation.CPDFInkAnnotation;
8 | import com.compdfkit.core.annotation.CPDFLinkAnnotation;
9 | import com.compdfkit.core.document.CPDFDestination;
10 | import com.compdfkit.core.document.CPDFDocument;
11 | import com.compdfkit.core.document.action.CPDFAction;
12 | import com.compdfkit.core.document.action.CPDFAction.ActionType;
13 | import com.compdfkit.core.document.action.CPDFGoToAction;
14 | import com.compdfkit.core.document.action.CPDFUriAction;
15 | import com.compdfkit.flutter.compdfkit_flutter.utils.CAppUtils;
16 | import java.util.HashMap;
17 | import java.util.Map;
18 |
19 | public class FlutterCPDFLinkAnnotation extends FlutterCPDFBaseAnnotation {
20 |
21 | private CPDFDocument document;
22 |
23 | public void setDocument(CPDFDocument document) {
24 | this.document = document;
25 | }
26 |
27 | @Override
28 | public void covert(CPDFAnnotation annotation, HashMap map) {
29 | CPDFLinkAnnotation linkAnnotation = (CPDFLinkAnnotation) annotation;
30 | CPDFAction action = linkAnnotation.getLinkAction();
31 | if (action != null){
32 | Map actionMap = new HashMap<>();
33 | actionMap.put("actionType", getActionType(action));
34 | if (action.getActionType() == ActionType.PDFActionType_URI){
35 | CPDFUriAction uriAction = (CPDFUriAction) action;
36 | String uri = uriAction.getUri();
37 | actionMap.put("uri", uri);
38 | } else if (action.getActionType() == ActionType.PDFActionType_GoTo){
39 | CPDFGoToAction goToAction = (CPDFGoToAction) action;
40 | if (document != null){
41 | CPDFDestination destination = goToAction.getDestination(document);
42 | actionMap.put("pageIndex", destination.getPageIndex());
43 | }
44 | }
45 | map.put("action", actionMap);
46 | }
47 | }
48 |
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/utils/annotation/forms/FlutterCPDFListBoxWidget.java:
--------------------------------------------------------------------------------
1 | package com.compdfkit.flutter.compdfkit_flutter.utils.annotation.forms;
2 |
3 | import android.text.TextUtils;
4 | import com.compdfkit.core.annotation.form.CPDFListboxWidget;
5 | import com.compdfkit.core.annotation.form.CPDFWidget;
6 | import com.compdfkit.core.annotation.form.CPDFWidgetItem;
7 | import com.compdfkit.core.font.CPDFFont;
8 | import com.compdfkit.flutter.compdfkit_flutter.utils.CAppUtils;
9 | import java.util.ArrayList;
10 | import java.util.HashMap;
11 | import java.util.List;
12 |
13 |
14 | public class FlutterCPDFListBoxWidget extends FlutterCPDFBaseWidget {
15 |
16 | @Override
17 | public void covert(CPDFWidget widget, HashMap map) {
18 | CPDFListboxWidget listboxWidget = (CPDFListboxWidget) widget;
19 | map.put("type", "listBox");
20 | ArrayList> options = new ArrayList<>();
21 | CPDFWidgetItem[] items = listboxWidget.getOptions();
22 | if (items != null && items.length > 0){
23 | for (CPDFWidgetItem item : items) {
24 | HashMap option = new HashMap<>();
25 | option.put("text", item.text);
26 | option.put("value", item.value);
27 | options.add(option);
28 | }
29 | }
30 | map.put("options", options);
31 | map.put("selectedIndexes", listboxWidget.getSelectedIndexes());
32 | map.put("fontColor", CAppUtils.toHexColor(listboxWidget.getFontColor()));
33 | map.put("fontSize", listboxWidget.getFontSize());
34 |
35 | String fontName = listboxWidget.getFontName();
36 | String familyName = CPDFFont.getFamilyName(listboxWidget.getFontName());
37 | String styleName = "Regular";
38 | if (TextUtils.isEmpty(familyName)){
39 | familyName = listboxWidget.getFontName();
40 | }else {
41 | List styleNames = CPDFFont.getStyleName(familyName);
42 | if (styleNames != null) {
43 | for (String styleNameItem : styleNames) {
44 | if (fontName.endsWith(styleNameItem)){
45 | styleName = styleNameItem;
46 | }
47 | }
48 | }
49 | }
50 |
51 |
52 | map.put("familyName", familyName);
53 | map.put("styleName", styleName);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/utils/annotation/forms/FlutterCPDFComboBoxWidget.java:
--------------------------------------------------------------------------------
1 | package com.compdfkit.flutter.compdfkit_flutter.utils.annotation.forms;
2 |
3 | import android.text.TextUtils;
4 | import com.compdfkit.core.annotation.form.CPDFComboboxWidget;
5 | import com.compdfkit.core.annotation.form.CPDFWidget;
6 | import com.compdfkit.core.annotation.form.CPDFWidgetItem;
7 | import com.compdfkit.core.font.CPDFFont;
8 | import com.compdfkit.flutter.compdfkit_flutter.utils.CAppUtils;
9 | import java.util.ArrayList;
10 | import java.util.HashMap;
11 | import java.util.List;
12 |
13 |
14 | public class FlutterCPDFComboBoxWidget extends FlutterCPDFBaseWidget {
15 | @Override
16 | public void covert(CPDFWidget widget, HashMap map) {
17 | CPDFComboboxWidget comboBoxWidget = (CPDFComboboxWidget) widget;
18 | map.put("type", "comboBox");
19 | ArrayList> options = new ArrayList<>();
20 | CPDFWidgetItem[] items = comboBoxWidget.getOptions();
21 | if (items != null && items.length > 0){
22 | for (CPDFWidgetItem item : items) {
23 | HashMap option = new HashMap<>();
24 | option.put("text", item.text);
25 | option.put("value", item.value);
26 | options.add(option);
27 | }
28 | }
29 | map.put("options", options);
30 | map.put("selectedIndexes", comboBoxWidget.getSelectedIndexes());
31 | map.put("fontColor", CAppUtils.toHexColor(comboBoxWidget.getFontColor()));
32 | map.put("fontSize", comboBoxWidget.getFontSize());
33 |
34 | String fontName = comboBoxWidget.getFontName();
35 | String familyName = CPDFFont.getFamilyName(comboBoxWidget.getFontName());
36 | String styleName = "Regular";
37 | if (TextUtils.isEmpty(familyName)){
38 | familyName = comboBoxWidget.getFontName();
39 | }else {
40 | List styleNames = CPDFFont.getStyleName(familyName);
41 | if (styleNames != null) {
42 | for (String styleNameItem : styleNames) {
43 | if (fontName.endsWith(styleNameItem)){
44 | styleName = styleNameItem;
45 | }
46 | }
47 | }
48 | }
49 |
50 | map.put("familyName", familyName);
51 | map.put("styleName", styleName);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/utils/annotation/forms/FlutterCPDFTextFieldWidget.java:
--------------------------------------------------------------------------------
1 | package com.compdfkit.flutter.compdfkit_flutter.utils.annotation.forms;
2 |
3 | import android.text.TextUtils;
4 | import com.compdfkit.core.annotation.CPDFAnnotation;
5 | import com.compdfkit.core.annotation.form.CPDFTextWidget;
6 | import com.compdfkit.core.annotation.form.CPDFWidget;
7 | import com.compdfkit.core.font.CPDFFont;
8 | import com.compdfkit.flutter.compdfkit_flutter.utils.CAppUtils;
9 | import java.util.HashMap;
10 | import java.util.List;
11 |
12 |
13 | public class FlutterCPDFTextFieldWidget extends FlutterCPDFBaseWidget {
14 |
15 |
16 | @Override
17 | public void covert(CPDFWidget widget, HashMap map) {
18 | CPDFTextWidget textWidget = (CPDFTextWidget) widget;
19 | map.put("type", "textField");
20 | map.put("text", textWidget.getText());
21 | map.put("isMultiline", textWidget.isMultiLine());
22 | map.put("fontColor", CAppUtils.toHexColor(textWidget.getFontColor()));
23 | map.put("fontSize", textWidget.getFontSize());
24 | switch (textWidget.getTextAlignment()){
25 | case ALIGNMENT_RIGHT:
26 | map.put("alignment", "right");
27 | break;
28 | case ALIGNMENT_CENTER:
29 | map.put("alignment", "center");
30 | break;
31 | default:
32 | map.put("alignment", "left");
33 | break;
34 | }
35 |
36 | String fontName = textWidget.getFontName();
37 | String familyName = CPDFFont.getFamilyName(textWidget.getFontName());
38 | String styleName = "Regular";
39 | if (TextUtils.isEmpty(familyName)){
40 | familyName = textWidget.getFontName();
41 | }else {
42 | List styleNames = CPDFFont.getStyleName(familyName);
43 | if (styleNames != null) {
44 | for (String styleNameItem : styleNames) {
45 | if (fontName.endsWith(styleNameItem)){
46 | styleName = styleNameItem;
47 | }
48 | }
49 | }
50 | }
51 |
52 | map.put("familyName", familyName);
53 | map.put("styleName", styleName);
54 | }
55 |
56 | public void setText(CPDFAnnotation annotation, String text) {
57 | CPDFTextWidget textWidget = (CPDFTextWidget) annotation;
58 | textWidget.setText(text);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/lib/annotation/cpdf_ink_annotation.dart:
--------------------------------------------------------------------------------
1 | // Copyright © 2014-2025 PDF Technologies, Inc. All Rights Reserved.
2 | //
3 | // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
4 | // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
5 | // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
6 | // This notice may not be removed from this file.
7 |
8 | import 'dart:ui';
9 |
10 | import 'package:compdfkit_flutter/annotation/cpdf_annotation.dart';
11 | import 'package:compdfkit_flutter/configuration/cpdf_options.dart';
12 | import 'package:compdfkit_flutter/util/extension/cpdf_color_extension.dart';
13 |
14 | import '../util/cpdf_rectf.dart';
15 |
16 | class CPDFInkAnnotation extends CPDFAnnotation {
17 | final Color color;
18 | final double alpha;
19 | final double borderWidth;
20 |
21 | CPDFInkAnnotation(
22 | {required CPDFAnnotationType type,
23 | required String title,
24 | required int page,
25 | required String content,
26 | required String uuid,
27 | DateTime? createDate,
28 | required CPDFRectF rect,
29 | required this.color,
30 | required this.alpha,
31 | required this.borderWidth})
32 | : super(
33 | type: type,
34 | title: title,
35 | page: page,
36 | content: content,
37 | uuid: uuid,
38 | createDate: createDate,
39 | rect: rect);
40 |
41 | factory CPDFInkAnnotation.fromJson(Map json) {
42 | final common = CPDFAnnotation.fromJson(json);
43 | return CPDFInkAnnotation(
44 | type: common.type,
45 | title: common.title,
46 | page: common.page,
47 | content: common.content,
48 | uuid: common.uuid,
49 | createDate: common.createDate,
50 | rect: common.rect,
51 | color: HexColor.fromHex(json['color'] ?? '#000000'),
52 | alpha: json['alpha'] ?? 255.0,
53 | borderWidth: json['borderWidth'] ?? 0,
54 | );
55 | }
56 |
57 | @override
58 | Map toJson() {
59 | return {
60 | ...super.toJson(),
61 | 'color': color.toHex(),
62 | 'alpha': alpha,
63 | 'borderWidth': borderWidth,
64 | };
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/lib/annotation/cpdf_markup_annotation.dart:
--------------------------------------------------------------------------------
1 | // Copyright © 2014-2025 PDF Technologies, Inc. All Rights Reserved.
2 | //
3 | // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
4 | // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
5 | // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
6 | // This notice may not be removed from this file.
7 |
8 | import 'dart:ui';
9 |
10 | import 'package:compdfkit_flutter/annotation/cpdf_annotation.dart';
11 | import 'package:compdfkit_flutter/configuration/cpdf_options.dart';
12 | import 'package:compdfkit_flutter/util/extension/cpdf_color_extension.dart';
13 |
14 | import '../util/cpdf_rectf.dart';
15 |
16 | class CPDFMarkupAnnotation extends CPDFAnnotation {
17 | final String markedText;
18 | final Color color;
19 | final double alpha;
20 |
21 | CPDFMarkupAnnotation(
22 | {required CPDFAnnotationType type,
23 | required String title,
24 | required int page,
25 | required String content,
26 | required String uuid,
27 | DateTime? createDate,
28 | required CPDFRectF rect,
29 | required this.markedText,
30 | required this.color,
31 | required this.alpha})
32 | : super(
33 | type: type,
34 | title: title,
35 | page: page,
36 | content: content,
37 | uuid: uuid,
38 | createDate: createDate,
39 | rect: rect);
40 |
41 | factory CPDFMarkupAnnotation.fromJson(Map json) {
42 | final common = CPDFAnnotation.fromJson(json);
43 | return CPDFMarkupAnnotation(
44 | type: common.type,
45 | title: common.title,
46 | page: common.page,
47 | content: common.content,
48 | uuid: common.uuid,
49 | createDate: common.createDate,
50 | rect: common.rect,
51 | markedText: json['markedText'] ?? '',
52 | color: HexColor.fromHex(json['color'] ?? '#000000'),
53 | alpha: json['alpha'] ?? 255,
54 | );
55 | }
56 |
57 | @override
58 | Map toJson() {
59 | return {
60 | ...super.toJson(),
61 | 'markedText': markedText,
62 | 'color': color.toHex(),
63 | 'alpha': alpha,
64 | };
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/example/lib/widgets/cpdf_fun_item.dart:
--------------------------------------------------------------------------------
1 | // Copyright © 2014-2025 PDF Technologies, Inc. All Rights Reserved.
2 | //
3 | // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
4 | // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
5 | // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
6 | // This notice may not be removed from this file.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_svg/flutter_svg.dart';
10 |
11 | class FeatureItem extends StatelessWidget {
12 | final String title;
13 |
14 | final String description;
15 |
16 | final GestureTapCallback onTap;
17 |
18 | const FeatureItem(
19 | {super.key,
20 | required this.title,
21 | required this.description,
22 | required this.onTap});
23 |
24 | @override
25 | Widget build(BuildContext context) {
26 | return Ink(
27 | child: InkWell(
28 | borderRadius: BorderRadius.circular(8),
29 | onTap: onTap,
30 | child: Padding(
31 | padding: const EdgeInsets.symmetric(vertical: 12),
32 | child: Row(
33 | mainAxisSize: MainAxisSize.min,
34 | children: [
35 | SvgPicture.asset(
36 | 'images/ic_home_viewer.svg',
37 | width: 38,
38 | height: 38,
39 | ),
40 | const Padding(padding: EdgeInsets.only(left: 8.0)),
41 | Expanded(
42 | child: Column(
43 | crossAxisAlignment: CrossAxisAlignment.start,
44 | children: [
45 | Text(title, style: Theme.of(context).textTheme.titleSmall),
46 | Text(
47 | description,
48 | style: const TextStyle(fontSize: 12.0),
49 | )
50 | ],
51 | )),
52 | SvgPicture.asset(
53 | 'images/ic_syasarrow.svg',
54 | width: 24,
55 | height: 24,
56 | colorFilter: ColorFilter.mode(
57 | Theme.of(context).colorScheme.onPrimary, BlendMode.srcIn),
58 | )
59 | ],
60 | )),
61 | ),
62 | );
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/utils/annotation/FlutterCPDFFreeTextAnnotation.java:
--------------------------------------------------------------------------------
1 | package com.compdfkit.flutter.compdfkit_flutter.utils.annotation;
2 |
3 |
4 | import android.text.TextUtils;
5 | import android.util.Log;
6 | import com.compdfkit.core.annotation.CPDFAnnotation;
7 | import com.compdfkit.core.annotation.CPDFFreetextAnnotation;
8 | import com.compdfkit.core.annotation.CPDFTextAttribute;
9 | import com.compdfkit.core.font.CPDFFont;
10 | import com.compdfkit.flutter.compdfkit_flutter.utils.CAppUtils;
11 | import java.util.HashMap;
12 | import java.util.List;
13 | import java.util.Map;
14 |
15 | public class FlutterCPDFFreeTextAnnotation extends FlutterCPDFBaseAnnotation {
16 |
17 | @Override
18 | public void covert(CPDFAnnotation annotation, HashMap map) {
19 | CPDFFreetextAnnotation freetextAnnotation = (CPDFFreetextAnnotation) annotation;
20 | map.put("alpha", (double) freetextAnnotation.getAlpha());
21 | CPDFTextAttribute textAttribute = freetextAnnotation.getFreetextDa();
22 | Map textAttributeMap = new HashMap<>();
23 | textAttributeMap.put("color", CAppUtils.toHexColor(textAttribute.getColor()));
24 |
25 | String fontName = textAttribute.getFontName();
26 | String familyName = CPDFFont.getFamilyName(textAttribute.getFontName());
27 | String styleName = "Regular";
28 | if (TextUtils.isEmpty(familyName)){
29 | familyName = textAttribute.getFontName();
30 | }else {
31 | List styleNames = CPDFFont.getStyleName(familyName);
32 | if (styleNames != null) {
33 | for (String styleNameItem : styleNames) {
34 | if (fontName.endsWith(styleNameItem)){
35 | styleName = styleNameItem;
36 | }
37 | }
38 | }
39 | }
40 |
41 | textAttributeMap.put("familyName", familyName);
42 | textAttributeMap.put("styleName", styleName);
43 | textAttributeMap.put("fontSize", textAttribute.getFontSize());
44 |
45 | switch (freetextAnnotation.getFreetextAlignment()){
46 | case ALIGNMENT_RIGHT:
47 | map.put("alignment", "right");
48 | break;
49 | case ALIGNMENT_CENTER:
50 | map.put("alignment", "center");
51 | break;
52 | default:
53 | map.put("alignment", "left");
54 | break;
55 | }
56 |
57 | map.put("textAttribute", textAttributeMap);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/lib/annotation/cpdf_freetext_annotation.dart:
--------------------------------------------------------------------------------
1 | // Copyright © 2014-2025 PDF Technologies, Inc. All Rights Reserved.
2 | //
3 | // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
4 | // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
5 | // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
6 | // This notice may not be removed from this file.
7 |
8 |
9 | import 'package:compdfkit_flutter/annotation/cpdf_text_attribute.dart';
10 | import 'package:compdfkit_flutter/annotation/cpdf_annotation.dart';
11 | import 'package:compdfkit_flutter/configuration/cpdf_options.dart';
12 |
13 | import '../util/cpdf_rectf.dart';
14 |
15 | class CPDFFreeTextAnnotation extends CPDFAnnotation {
16 | final CPDFTextAttribute textAttribute;
17 |
18 | final double alpha;
19 |
20 | final CPDFAlignment alignment;
21 |
22 | CPDFFreeTextAnnotation(
23 | {required CPDFAnnotationType type,
24 | required String title,
25 | required int page,
26 | required String content,
27 | required String uuid,
28 | DateTime? createDate,
29 | required CPDFRectF rect,
30 | required this.textAttribute,
31 | required this.alpha,
32 | required this.alignment})
33 | : super(
34 | type: type,
35 | title: title,
36 | page: page,
37 | content: content,
38 | uuid: uuid,
39 | createDate: createDate,
40 | rect: rect);
41 |
42 | factory CPDFFreeTextAnnotation.fromJson(Map json) {
43 | final common = CPDFAnnotation.fromJson(json);
44 | return CPDFFreeTextAnnotation(
45 | type: common.type,
46 | title: common.title,
47 | page: common.page,
48 | content: common.content,
49 | uuid: common.uuid,
50 | createDate: common.createDate,
51 | rect: common.rect,
52 | textAttribute: CPDFTextAttribute.fromJson(
53 | Map.from(json['textAttribute'] ?? {})),
54 | alpha: json['alpha'] ?? 255.0,
55 | alignment: CPDFAlignment.fromString(json['alignment']),
56 | );
57 | }
58 |
59 | @override
60 | Map toJson() {
61 | return {
62 | ...super.toJson(),
63 | 'textAttribute': textAttribute.toJson(),
64 | 'alpha': alpha,
65 | 'alignment': alignment.name,
66 | };
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/lib/annotation/cpdf_annotation_registry.dart:
--------------------------------------------------------------------------------
1 | // Copyright © 2014-2025 PDF Technologies, Inc. All Rights Reserved.
2 | //
3 | // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
4 | // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
5 | // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
6 | // This notice may not be removed from this file.
7 |
8 |
9 | import 'package:compdfkit_flutter/annotation/cpdf_circle_annotation.dart';
10 | import 'package:compdfkit_flutter/annotation/cpdf_freetext_annotation.dart';
11 | import 'package:compdfkit_flutter/annotation/cpdf_ink_annotation.dart';
12 | import 'package:compdfkit_flutter/annotation/cpdf_line_annotation.dart';
13 | import 'package:compdfkit_flutter/annotation/cpdf_link_annotation.dart';
14 | import 'package:compdfkit_flutter/annotation/cpdf_markup_annotation.dart';
15 | import 'package:compdfkit_flutter/annotation/cpdf_square_annotation.dart';
16 |
17 | import '../configuration/cpdf_options.dart';
18 | import 'cpdf_annotation.dart';
19 |
20 | typedef CPDFAnnotationFactory = CPDFAnnotation Function(Map json);
21 |
22 | class CPDFAnnotationRegistry {
23 | static final Map _factories = {
24 | CPDFAnnotationType.highlight: (json) => CPDFMarkupAnnotation.fromJson(json),
25 | CPDFAnnotationType.underline: (json) => CPDFMarkupAnnotation.fromJson(json),
26 | CPDFAnnotationType.squiggly: (json) => CPDFMarkupAnnotation.fromJson(json),
27 | CPDFAnnotationType.strikeout: (json) => CPDFMarkupAnnotation.fromJson(json),
28 | CPDFAnnotationType.ink: (json) => CPDFInkAnnotation.fromJson(json),
29 | CPDFAnnotationType.freetext: (json) => CPDFFreeTextAnnotation.fromJson(json),
30 | CPDFAnnotationType.square: (json) => CPDFSquareAnnotation.fromJson(json),
31 | CPDFAnnotationType.circle: (json) => CPDFCircleAnnotations.fromJson(json),
32 | CPDFAnnotationType.line: (json) => CPDFLineAnnotation.fromJson(json),
33 | CPDFAnnotationType.arrow: (json) => CPDFLineAnnotation.fromJson(json),
34 | CPDFAnnotationType.link: (json) => CPDFLinkAnnotation.fromJson(json),
35 | };
36 |
37 | static CPDFAnnotation fromJson(Map json) {
38 | final type = CPDFAnnotationType.fromString(json['type']);
39 | final factory = _factories[type] ?? CPDFAnnotation.fromJson;
40 | return factory(json);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/lib/annotation/form/cpdf_widget.dart:
--------------------------------------------------------------------------------
1 | // Copyright © 2014-2025 PDF Technologies, Inc. All Rights Reserved.
2 | //
3 | // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
4 | // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
5 | // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
6 | // This notice may not be removed from this file.
7 |
8 | import 'dart:convert';
9 | import 'dart:ui';
10 |
11 | import 'package:compdfkit_flutter/configuration/cpdf_options.dart';
12 |
13 | import '../../util/cpdf_rectf.dart';
14 | import '../../util/extension/cpdf_color_extension.dart';
15 |
16 | class CPDFWidget {
17 | final CPDFFormType type;
18 | final String title;
19 | final int page;
20 | final String uuid;
21 | final DateTime? createDate;
22 | final CPDFRectF rect;
23 | final Color borderColor;
24 | final Color fillColor;
25 | final double borderWidth;
26 |
27 | CPDFWidget(
28 | {required this.type,
29 | required this.title,
30 | required this.page,
31 | required this.uuid,
32 | this.createDate,
33 | required this.rect,
34 | required this.borderColor,
35 | required this.fillColor,
36 | required this.borderWidth});
37 |
38 | factory CPDFWidget.fromJson(Map json) {
39 | return CPDFWidget(
40 | type: CPDFFormType.fromString(json['type']),
41 | title: json['title'] ?? '',
42 | page: json['page'] ?? 0,
43 | uuid: json['uuid'] ?? '',
44 | createDate: json['createDate'] != null
45 | ? DateTime.fromMillisecondsSinceEpoch(json['createDate'])
46 | : null,
47 | rect: CPDFRectF.fromJson(Map.from(json['rect'] ?? {})),
48 | borderColor: HexColor.fromHex(json['borderColor'] ?? '#000000'),
49 | fillColor: HexColor.fromHex(json['fillColor'] ?? '#000000'),
50 | borderWidth: json['borderWidth'] ?? 0,
51 | );
52 | }
53 |
54 | Map toJson() => {
55 | 'type': type.name,
56 | 'title': title,
57 | 'page': page,
58 | 'uuid': uuid,
59 | 'createDate': createDate?.toString(),
60 | 'rect': rect.toString(),
61 | 'borderColor': borderColor.toHex(),
62 | 'fillColor': fillColor.toHex(),
63 | 'borderWidth': borderWidth,
64 | };
65 |
66 | @override
67 | String toString() => jsonEncode(toJson());
68 | }
69 |
--------------------------------------------------------------------------------
/lib/page/cpdf_text_range.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014-2025 PDF Technologies, Inc. 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 ComPDFKit 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 |
11 | class CPDFTextRange {
12 |
13 | final int pageIndex;
14 |
15 | final int location;
16 |
17 | final int length;
18 |
19 | final int textRangeIndex;
20 |
21 | const CPDFTextRange({
22 | required this.pageIndex,
23 | required this.location,
24 | required this.length,
25 | this.textRangeIndex = 0,
26 | });
27 |
28 | factory CPDFTextRange.fromJson(Map map) {
29 | return CPDFTextRange(
30 | pageIndex: map['page_index']?? 0,
31 | location: map['location'] ?? 0,
32 | length: map['length'] ?? 0,
33 | textRangeIndex: map['text_range_index'] ?? 0,
34 | );
35 | }
36 |
37 |
38 | Map toJson() {
39 | return {
40 | 'page_index': pageIndex,
41 | 'location': location,
42 | 'length': length,
43 | 'text_range_index': textRangeIndex,
44 | };
45 | }
46 |
47 | }
48 |
49 | extension CPDFTextRangeExtension on CPDFTextRange {
50 |
51 | /// Returns a new CPDFTextRange that expands the current range by the given number of characters
52 | /// before and after the original range.
53 | ///
54 | /// If the `before` value causes the start position to be less than 0, it will automatically
55 | /// clamp the start to 0 and reduce the total length accordingly to avoid overflow.
56 | ///
57 | /// Parameters:
58 | /// - [before]: The number of characters to include before the original range. Default is 0.
59 | /// - [after]: The number of characters to include after the original range. Default is 0.
60 | ///
61 | /// Returns:
62 | /// A new CPDFTextRange instance with adjusted `location` and `length`.
63 | CPDFTextRange expanded({int before = 0, int after = 0}) {
64 | int newStart = location - before;
65 | int newLength = length + before + after;
66 |
67 | if (newStart < 0) {
68 | newLength += newStart;
69 | newStart = 0;
70 | }
71 |
72 | return CPDFTextRange(
73 | pageIndex: pageIndex,
74 | location: newStart,
75 | length: newLength,
76 | );
77 | }
78 | }
--------------------------------------------------------------------------------
/example/images/ic_sign.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/example/lib/examples/document/base_document_example.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014-2025 PDF Technologies, Inc. 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 ComPDFKit 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 |
11 | import 'dart:io';
12 |
13 | import 'package:compdfkit_flutter/document/cpdf_document.dart';
14 | import 'package:flutter/material.dart';
15 |
16 | import '../../utils/file_util.dart';
17 | import 'log_info_page.dart';
18 |
19 | abstract class BaseDocumentExample extends StatefulWidget {
20 | const BaseDocumentExample({super.key});
21 |
22 | String get assetPath; // Example: 'pdfs/PDF_Document.pdf'
23 | String get title;
24 |
25 | @override
26 | State createState() => BaseDocumentExampleState();
27 | }
28 |
29 | class BaseDocumentExampleState extends State {
30 | List logs = [];
31 | late CPDFDocument document;
32 |
33 | @override
34 | void initState() {
35 | super.initState();
36 | openDocument();
37 | }
38 |
39 | Future openDocument() async {
40 | File file = await extractAsset(context, shouldOverwrite: true, widget.assetPath);
41 | applyLog('filePath: ${file.path}');
42 | document = await CPDFDocument.createInstance();
43 | final error = await document.open(file.path);
44 | applyLog('Open result: ${error.name}');
45 | onDocumentReady();
46 | }
47 |
48 | /// Called after the document is successfully opened
49 | void onDocumentReady() {}
50 |
51 | void applyLog(String msg) {
52 | setState(() {
53 | logs.add('$msg\n');
54 | });
55 | }
56 |
57 | void clearLogs() {
58 | setState(() {
59 | logs.clear();
60 | });
61 | }
62 |
63 | /// Child class should override this to add buttons
64 | List buildExampleContent(BuildContext context) => [];
65 |
66 | @override
67 | Widget build(BuildContext context) {
68 | return Scaffold(
69 | appBar: AppBar(title: Text(widget.title)),
70 | body: Column(
71 | crossAxisAlignment: CrossAxisAlignment.start,
72 | children: [
73 | ...buildExampleContent(context),
74 | Expanded(child: LogInfoPage(logs: logs)),
75 | ],
76 | ),
77 | );
78 | }
79 | }
--------------------------------------------------------------------------------
/android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/utils/annotation/forms/FlutterCPDFBaseWidget.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright © 2014-2025 PDF Technologies, Inc. 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 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.compdfkit.flutter.compdfkit_flutter.utils.annotation.forms;
10 |
11 |
12 | import android.graphics.RectF;
13 | import com.compdfkit.core.annotation.CPDFAnnotation;
14 | import com.compdfkit.core.annotation.form.CPDFWidget;
15 | import com.compdfkit.core.common.CPDFDate;
16 | import com.compdfkit.flutter.compdfkit_flutter.utils.CAppUtils;
17 | import com.compdfkit.tools.common.utils.date.CDateUtil;
18 | import java.util.HashMap;
19 | import java.util.Map;
20 |
21 | public abstract class FlutterCPDFBaseWidget implements FlutterCPDFWidget {
22 |
23 |
24 | @Override
25 | public HashMap getWidget(CPDFAnnotation annotation) {
26 | HashMap map = new HashMap<>();
27 | CPDFWidget widget = (CPDFWidget) annotation;
28 | map.put("page", widget.pdfPage.getPageNum());
29 | map.put("title", widget.getFieldName());
30 | map.put("uuid", widget.getAnnotPtr()+"");
31 |
32 | RectF rect = annotation.getRect();
33 | Map rectMap = new HashMap<>();
34 | rectMap.put("left", rect.left);
35 | rectMap.put("top", rect.top);
36 | rectMap.put("right", rect.right);
37 | rectMap.put("bottom", rect.bottom);
38 | map.put("rect", rectMap);
39 |
40 | CPDFDate modifyDate = annotation.getRecentlyModifyDate();
41 | CPDFDate createDate = annotation.getCreationDate();
42 | if (modifyDate != null) {
43 | map.put("modifyDate", CDateUtil.transformToTimestamp(modifyDate));
44 | }
45 | if (createDate != null) {
46 | map.put("createDate", CDateUtil.transformToTimestamp(createDate));
47 | }
48 |
49 | map.put("borderColor", CAppUtils.toHexColor(widget.getBorderColor()));
50 | map.put("borderWidget", widget.getBorderWidth());
51 | map.put("fillColor", CAppUtils.toHexColor(widget.getFillColor()));
52 |
53 | covert(widget, map);
54 | return map;
55 | }
56 |
57 | public abstract void covert(com.compdfkit.core.annotation.form.CPDFWidget widget, HashMap map);
58 | }
59 |
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/example/lib/examples/document/cpdf_document_widget_example.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014-2025 PDF Technologies, Inc. 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 ComPDFKit 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 |
11 | import 'dart:convert';
12 |
13 | import 'package:compdfkit_flutter/annotation/form/cpdf_widget.dart';
14 | import 'package:flutter/material.dart';
15 |
16 | import 'base_document_example.dart';
17 |
18 | class CPDFDocumentWidgetExample extends BaseDocumentExample {
19 | const CPDFDocumentWidgetExample({super.key});
20 |
21 | @override
22 | String get assetPath => 'pdfs/annot_test.pdf';
23 |
24 | @override
25 | String get title => 'Widgets Example';
26 |
27 | @override
28 | State createState() =>
29 | _CPDFDocumentWidgetExampleState();
30 | }
31 |
32 | class _CPDFDocumentWidgetExampleState
33 | extends BaseDocumentExampleState {
34 | final List widgets = [];
35 |
36 | @override
37 | List buildExampleContent(BuildContext context) {
38 | return [
39 | TextButton(
40 | onPressed: _getWidgets,
41 | child: const Text('Get Widgets'),
42 | ),
43 | TextButton(
44 | onPressed: _deleteFirstWidget,
45 | child: const Text('Delete First'),
46 | ),
47 | ];
48 | }
49 |
50 | Future _getWidgets() async {
51 | clearLogs();
52 | widgets.clear();
53 | int pageCount = await document.getPageCount();
54 |
55 | for (int i = 0; i < pageCount; i++) {
56 | final page = document.pageAtIndex(i);
57 | final pageWidgets = await page.getWidgets();
58 | widgets.addAll(pageWidgets);
59 | }
60 |
61 | applyLog('Widgets found: ${widgets.length}');
62 | final jsonData = json.decode(jsonEncode(widgets));
63 | final prettyJson = const JsonEncoder.withIndent(' ').convert(jsonData);
64 | applyLog(prettyJson);
65 | }
66 |
67 | Future _deleteFirstWidget() async {
68 | if (widgets.isEmpty) return;
69 |
70 | final first = widgets.first;
71 | final page = document.pageAtIndex(first.page);
72 | final result = await page.removeWidget(first);
73 | clearLogs();
74 | applyLog('Removed widget result: $result');
75 | }
76 | }
--------------------------------------------------------------------------------
/ios/Classes/reader/CPDFSearchUtil.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CPDFSearchUtil.swift
3 | // Pods
4 | //
5 | // Created by kdanmobile on 2025/7/23.
6 | //
7 |
8 | import Foundation
9 | import ComPDFKit
10 | import Flutter
11 | import ComPDFKit_Tools
12 |
13 |
14 | class CPDFSearchUtil {
15 |
16 | static func searchText(from document : CPDFDocument?, keywords : String , options : CPDFSearchOptions) -> [[String: Any]] {
17 | var searchResults : [Dictionary] = []
18 | if(document == nil){
19 | return searchResults;
20 | }
21 | if let resultArray = document?.find(keywords, with: options) as? [[CPDFSelection]] {
22 |
23 | for array in resultArray {
24 | for selection in array {
25 | var dict: [String : Any] = [:]
26 | dict["page_index"] = selection.page.pageIndexInteger
27 | dict["location"] = selection.range.location
28 | dict["length"] = selection.range.length
29 | dict["text_range_index"] = array.firstIndex(of: selection)
30 | searchResults.append(dict)
31 |
32 | }
33 | }
34 | }
35 | return searchResults;
36 | }
37 |
38 |
39 | static func selection(from document : CPDFDocument?, info : [String : Any]) -> CPDFSelection? {
40 | guard
41 | let pageIndex = info["page_index"] as? Int,
42 | let location = info["location"] as? Int,
43 | let length = info["length"] as? Int
44 | else {
45 | return nil
46 | }
47 |
48 | guard let page = document?.page(at: UInt(pageIndex)) else {
49 | return nil
50 | }
51 |
52 | let range = NSRange(location: location, length: length)
53 | return page.selection(for: range)
54 | }
55 |
56 | static func getSearchText(from document: CPDFDocument?, info: [String : Any]) -> String? {
57 | guard
58 | let pageIndex = info["page_index"] as? Int,
59 | let location = info["location"] as? Int,
60 | let length = info["length"] as? Int
61 | else {
62 | return nil
63 | }
64 | guard let page = document?.page(at: UInt(pageIndex)) else {
65 | return nil
66 | }
67 |
68 | let range = NSRange(location: location, length: length)
69 | let selection = page.selection(for: range)
70 | return selection?.string();
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/lib/annotation/form/cpdf_checkbox_widget.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014-2025 PDF Technologies, Inc. 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 ComPDFKit 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 |
11 | import 'dart:ui';
12 |
13 | import 'package:compdfkit_flutter/annotation/form/cpdf_widget.dart';
14 | import 'package:compdfkit_flutter/configuration/cpdf_options.dart';
15 | import 'package:compdfkit_flutter/util/extension/cpdf_color_extension.dart';
16 |
17 | import '../../util/cpdf_rectf.dart';
18 |
19 | class CPDFCheckBoxWidget extends CPDFWidget {
20 | final bool isChecked;
21 | final CPDFCheckStyle checkStyle;
22 | final Color checkColor;
23 |
24 | CPDFCheckBoxWidget({
25 | required CPDFFormType type,
26 | required String title,
27 | required int page,
28 | required String uuid,
29 | DateTime? createDate,
30 | required CPDFRectF rect,
31 | required borderColor,
32 | required fillColor,
33 | required borderWidth,
34 | required this.isChecked,
35 | required this.checkStyle,
36 | required this.checkColor
37 | }) : super(
38 | type: type,
39 | title: title,
40 | page: page,
41 | uuid: uuid,
42 | createDate: createDate,
43 | rect: rect,
44 | borderColor: borderColor,
45 | borderWidth: borderWidth,
46 | fillColor: fillColor);
47 |
48 | factory CPDFCheckBoxWidget.fromJson(Map json) {
49 | CPDFWidget common = CPDFWidget.fromJson(json);
50 | return CPDFCheckBoxWidget(
51 | type: common.type,
52 | title: common.title,
53 | page: common.page,
54 | uuid: common.uuid,
55 | createDate: common.createDate,
56 | rect: common.rect,
57 | borderColor: common.borderColor,
58 | borderWidth: common.borderWidth,
59 | fillColor: common.fillColor,
60 | isChecked: json['isChecked'],
61 | checkStyle: CPDFCheckStyle.fromString(json['checkStyle']),
62 | checkColor: HexColor.fromHex(json['checkColor'] ?? '#000000')
63 | );
64 | }
65 |
66 | @override
67 | Map toJson() {
68 | return {
69 | ...super.toJson(),
70 | 'isChecked': isChecked,
71 | 'checkStyle': checkStyle.name,
72 | 'checkColor' : checkColor.toHex(),
73 | };
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/lib/annotation/form/cpdf_radiobutton_widget.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014-2025 PDF Technologies, Inc. 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 ComPDFKit 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 |
11 | import 'dart:ui';
12 |
13 | import 'package:compdfkit_flutter/annotation/form/cpdf_widget.dart';
14 | import 'package:compdfkit_flutter/configuration/cpdf_options.dart';
15 | import 'package:compdfkit_flutter/util/extension/cpdf_color_extension.dart';
16 |
17 | import '../../util/cpdf_rectf.dart';
18 |
19 | class CPDFRadioButtonWidget extends CPDFWidget {
20 | final bool isChecked;
21 | final CPDFCheckStyle checkStyle;
22 | final Color checkColor;
23 |
24 | CPDFRadioButtonWidget({
25 | required CPDFFormType type,
26 | required String title,
27 | required int page,
28 | required String uuid,
29 | DateTime? createDate,
30 | required CPDFRectF rect,
31 | required borderColor,
32 | required fillColor,
33 | required borderWidth,
34 | required this.isChecked,
35 | required this.checkStyle,
36 | required this.checkColor
37 | }) : super(
38 | type: type,
39 | title: title,
40 | page: page,
41 | uuid: uuid,
42 | createDate: createDate,
43 | rect: rect,
44 | borderColor: borderColor,
45 | borderWidth: borderWidth,
46 | fillColor: fillColor);
47 |
48 | factory CPDFRadioButtonWidget.fromJson(Map json) {
49 | CPDFWidget common = CPDFWidget.fromJson(json);
50 | return CPDFRadioButtonWidget(
51 | type: common.type,
52 | title: common.title,
53 | page: common.page,
54 | uuid: common.uuid,
55 | createDate: common.createDate,
56 | rect: common.rect,
57 | borderColor: common.borderColor,
58 | borderWidth: common.borderWidth,
59 | fillColor: common.fillColor,
60 | isChecked: json['isChecked'],
61 | checkStyle: CPDFCheckStyle.fromString(json['checkStyle']),
62 | checkColor: HexColor.fromHex(json['checkColor'] ?? '#000000')
63 | );
64 | }
65 |
66 | @override
67 | Map toJson() {
68 | return {
69 | ...super.toJson(),
70 | 'isChecked': isChecked,
71 | 'checkStyle': checkStyle.name,
72 | 'checkColor' : checkColor.toHex(),
73 | };
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/example/lib/examples/document/cpdf_document_annotation_example.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014-2025 PDF Technologies, Inc. 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 ComPDFKit 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 |
11 | import 'dart:convert';
12 |
13 | import 'package:compdfkit_flutter/annotation/cpdf_annotation.dart';
14 | import 'package:flutter/material.dart';
15 |
16 | import 'base_document_example.dart';
17 |
18 | class CPDFDocumentAnnotationExample extends BaseDocumentExample {
19 | const CPDFDocumentAnnotationExample({super.key});
20 |
21 | @override
22 | String get assetPath => 'pdfs/annot_test.pdf';
23 |
24 | @override
25 | String get title => 'Annotations Example';
26 |
27 | @override
28 | State createState() =>
29 | _CPDFDocumentAnnotationExampleState();
30 | }
31 |
32 | class _CPDFDocumentAnnotationExampleState
33 | extends BaseDocumentExampleState {
34 | final List annotations = [];
35 |
36 | @override
37 | List buildExampleContent(BuildContext context) {
38 | return [
39 | TextButton(
40 | onPressed: _getAnnotations,
41 | child: const Text('Get Annotations'),
42 | ),
43 | TextButton(
44 | onPressed: _deleteFirstAnnotation,
45 | child: const Text('Delete First'),
46 | ),
47 | ];
48 | }
49 |
50 | Future _getAnnotations() async {
51 | clearLogs();
52 | annotations.clear();
53 | int pageCount = await document.getPageCount();
54 |
55 | for (int i = 0; i < pageCount; i++) {
56 | final page = document.pageAtIndex(i);
57 | final pageAnnotations = await page.getAnnotations();
58 | annotations.addAll(pageAnnotations);
59 | }
60 |
61 | applyLog('Annotations found: ${annotations.length}');
62 |
63 | final jsonData = json.decode(jsonEncode(annotations));
64 | final prettyJson = const JsonEncoder.withIndent(' ').convert(jsonData);
65 | applyLog(prettyJson);
66 | }
67 |
68 | Future _deleteFirstAnnotation() async {
69 | if (annotations.isEmpty) return;
70 |
71 | final first = annotations.first;
72 | final page = document.pageAtIndex(first.page);
73 | final result = await page.removeAnnotation(first);
74 | clearLogs();
75 | applyLog('Removed annotation result: $result');
76 | }
77 | }
--------------------------------------------------------------------------------
/example/lib/page/annotations/tools/cpdf_annotation_tools_widget.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014-2025 PDF Technologies, Inc. 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 ComPDFKit 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 'package:compdfkit_flutter/configuration/cpdf_options.dart';
11 | import 'package:compdfkit_flutter/widgets/cpdf_reader_widget_controller.dart';
12 | import 'package:compdfkit_flutter_example/page/annotations/tools/cpdf_annotation_history_manager_widget.dart';
13 | import 'package:compdfkit_flutter_example/page/annotations/tools/cpdf_annotation_mode_list_widget.dart';
14 | import 'package:flutter/material.dart';
15 |
16 | class CPDFAnnotationToolsWidget extends StatefulWidget {
17 | final CPDFReaderWidgetController controller;
18 |
19 | const CPDFAnnotationToolsWidget({super.key, required this.controller});
20 |
21 | @override
22 | State createState() =>
23 | _CPDFAnnotationToolsWidgetState();
24 | }
25 |
26 | class _CPDFAnnotationToolsWidgetState extends State {
27 | late CPDFAnnotationType currentAnnotationType = CPDFAnnotationType.unknown;
28 |
29 | @override
30 | void initState() {
31 | super.initState();
32 | _initializeCurrentAnnotationType();
33 | }
34 |
35 | void _initializeCurrentAnnotationType() async {
36 | CPDFAnnotationType type = await widget.controller.getAnnotationMode();
37 | setState(() {
38 | currentAnnotationType = type;
39 | });
40 | }
41 |
42 | @override
43 | Widget build(BuildContext context) {
44 | return Container(
45 | padding: const EdgeInsets.only(bottom: 16),
46 | decoration: BoxDecoration(
47 | color: Theme.of(context).appBarTheme.backgroundColor,
48 | boxShadow: [
49 | BoxShadow(
50 | color: Colors.black.withAlpha(20),
51 | blurRadius: 4,
52 | offset: const Offset(0, -2),
53 | ),
54 | ]),
55 | width: double.infinity,
56 | height: 72,
57 | child: Row(
58 | children: [
59 | Expanded(
60 | child: CpdfAnnotationModeListWidget(
61 | controller: widget.controller)),
62 | CpdfAnnotationHistoryManagerWidget(controller: widget.controller)
63 | ],
64 | ));
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/example/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id "com.android.application"
3 | id "kotlin-android"
4 | id "dev.flutter.flutter-gradle-plugin"
5 | }
6 |
7 | def localProperties = new Properties()
8 | def localPropertiesFile = rootProject.file('local.properties')
9 | if (localPropertiesFile.exists()) {
10 | localPropertiesFile.withReader('UTF-8') { reader ->
11 | localProperties.load(reader)
12 | }
13 | }
14 |
15 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
16 | if (flutterVersionCode == null) {
17 | flutterVersionCode = '1'
18 | }
19 |
20 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
21 | if (flutterVersionName == null) {
22 | flutterVersionName = '1.0'
23 | }
24 |
25 | android {
26 | namespace "com.compdfkit.flutter.example"
27 | compileSdk flutter.compileSdkVersion
28 | ndkVersion "27.0.12077973"
29 | signingConfigs {
30 | release {
31 | if (project.hasProperty("Keystore.properties")) {
32 | String filePath = project.property("Keystore.properties")
33 | File propsFile = new File(filePath)
34 | if (propsFile.exists()) {
35 | Properties props = new Properties()
36 | props.load(propsFile.newDataInputStream())
37 |
38 | storeFile file(props['storeFile'])
39 | storePassword props['keystore.password']
40 | keyAlias props['keyAlias']
41 | keyPassword props['keyAlias.password']
42 | }
43 | }
44 | }
45 | }
46 | compileOptions {
47 | sourceCompatibility JavaVersion.VERSION_1_8
48 | targetCompatibility JavaVersion.VERSION_1_8
49 | }
50 |
51 | kotlinOptions {
52 | jvmTarget = '1.8'
53 | }
54 |
55 |
56 | defaultConfig {
57 | applicationId "com.compdfkit.flutter.example"
58 | // You can update the following values to match your application needs.
59 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
60 | minSdkVersion rootProject.ext.android.MINSDK
61 | targetSdkVersion flutter.targetSdkVersion
62 | versionCode rootProject.ext.android.VERSIONCODE
63 | versionName flutterVersionName
64 | }
65 |
66 | buildTypes {
67 | release {
68 | minifyEnabled true
69 | signingConfig signingConfigs.release
70 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
71 | }
72 | }
73 | }
74 |
75 | flutter {
76 | source '../..'
77 | }
78 |
79 |
--------------------------------------------------------------------------------
/example/lib/utils/file_util.dart:
--------------------------------------------------------------------------------
1 | // Copyright © 2014-2025 PDF Technologies, Inc. All Rights Reserved.
2 | //
3 | // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
4 | // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
5 | // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
6 | // This notice may not be removed from this file.
7 |
8 | import 'dart:convert';
9 | import 'dart:io';
10 |
11 | import 'package:compdfkit_flutter/compdfkit.dart';
12 | import 'package:flutter/foundation.dart';
13 | import 'package:flutter/material.dart';
14 | import 'package:flutter/services.dart';
15 |
16 | Future extractAsset(BuildContext context, String assetPath,
17 | {bool shouldOverwrite = false, String prefix = ''}) async {
18 | final bytes = await DefaultAssetBundle.of(context).load(assetPath);
19 | final list = bytes.buffer.asUint8List();
20 |
21 | final tempDir = await ComPDFKit.getTemporaryDirectory();
22 | final tempDocumentPath = '${tempDir.path}/$prefix$assetPath';
23 | final file = File(tempDocumentPath);
24 |
25 | if (shouldOverwrite || !file.existsSync()) {
26 | await file.create(recursive: true);
27 | file.writeAsBytesSync(list);
28 | }
29 | return file;
30 | }
31 |
32 | Future extractAssetFolder(BuildContext context, String folder) async {
33 | final tempDir = await ComPDFKit.getTemporaryDirectory();
34 | final assetPaths = await getAssetPaths(folder);
35 | for (var path in assetPaths) {
36 | if (context.mounted) {
37 | await extractAsset(context, path);
38 | }
39 | }
40 | String dir = '${tempDir.path}/$folder';
41 | debugPrint('ComPDFKit-fontDir: $dir');
42 | return dir;
43 | }
44 |
45 | Future> getAssetPaths(String folderPath) async {
46 | final manifestJson = await rootBundle.loadString('AssetManifest.json');
47 | final Map manifestMap = json.decode(manifestJson);
48 | final assetPaths =
49 | manifestMap.keys.where((key) => key.startsWith(folderPath)).toList();
50 | return assetPaths;
51 | }
52 |
53 | void printJsonString(String jsonStr) {
54 | try {
55 | final dynamic jsonData = json.decode(jsonStr);
56 | const JsonEncoder encoder = JsonEncoder.withIndent(' ');
57 | final String prettyJson = encoder.convert(jsonData);
58 | _printLongText(prettyJson);
59 | } catch (e) {
60 | if (kDebugMode) {
61 | print('Invalid JSON: $e');
62 | }
63 | }
64 | }
65 |
66 | void _printLongText(String text, {int chunkSize = 800}) {
67 | final pattern = RegExp('.{1,$chunkSize}', dotAll: true);
68 | for (final match in pattern.allMatches(text)) {
69 | if (kDebugMode) {
70 | print(match.group(0));
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/example/lib/page/cpdf_reader_widget_switch_preview_mode_page.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014-2025 PDF Technologies, Inc. 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 ComPDFKit 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 'package:compdfkit_flutter/configuration/cpdf_options.dart';
11 | import 'package:flutter/material.dart';
12 |
13 | class CpdfReaderWidgetSwitchPreviewModePage extends StatefulWidget {
14 | final CPDFViewMode viewMode;
15 |
16 | const CpdfReaderWidgetSwitchPreviewModePage(
17 | {super.key, required this.viewMode});
18 |
19 | @override
20 | State createState() =>
21 | _CpdfReaderWidgetSwitchPreviewModePageState();
22 | }
23 |
24 | class _CpdfReaderWidgetSwitchPreviewModePageState
25 | extends State {
26 | @override
27 | void initState() {
28 | super.initState();
29 | }
30 |
31 | @override
32 | Widget build(BuildContext context) {
33 | var textStyle = Theme.of(context).textTheme.labelLarge;
34 | return SizedBox(
35 | height: 336,
36 | width: double.infinity,
37 | child: Column(
38 | children: [
39 | SizedBox(
40 | width: double.infinity,
41 | height: 56,
42 | child: Stack(
43 | alignment: Alignment.center,
44 | children: [
45 | Text('Mode', style: Theme.of(context).textTheme.titleMedium),
46 | Positioned(
47 | right: 16,
48 | child: IconButton(
49 | onPressed: () {
50 | Navigator.pop(context);
51 | },
52 | icon: const Icon(Icons.close)))
53 | ],
54 | ),
55 | ),
56 | Expanded(
57 | child: ListView.builder(
58 | itemCount: CPDFViewMode.values.length,
59 | itemBuilder: (context, index) {
60 | CPDFViewMode mode = CPDFViewMode.values[index];
61 | return ListTile(
62 | onTap: () async {
63 | Navigator.pop(context, mode);
64 | },
65 | title: Text(mode.name, style: textStyle),
66 | trailing: widget.viewMode == mode
67 | ? const Icon(Icons.check)
68 | : null);
69 | }))
70 | ],
71 | ));
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/utils/FileUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014-2025 PDF Technologies, Inc. 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 ComPDFKit 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 |
11 | package com.compdfkit.flutter.compdfkit_flutter.utils;
12 |
13 | import android.content.Context;
14 | import android.content.Intent;
15 | import android.net.Uri;
16 | import com.compdfkit.tools.common.pdf.CPDFDocumentActivity;
17 | import com.compdfkit.tools.common.utils.CFileUtils;
18 | import com.compdfkit.tools.common.utils.CUriUtil;
19 | import java.io.File;
20 |
21 |
22 | public class FileUtils {
23 |
24 | public static final String ASSETS_SCHEME = "file:///android_asset";
25 |
26 | public static final String CONTENT_SCHEME = "content://";
27 | public static final String FILE_SCHEME = "file://";
28 |
29 | public static void parseDocument(Context context, String document, Intent intent) {
30 | if (document.startsWith(ASSETS_SCHEME)) {
31 | String assetsPath = document.replace(ASSETS_SCHEME + "/","");
32 | String[] strs = document.split("/");
33 | String fileName = strs[strs.length -1];
34 | String samplePDFPath = CFileUtils.getAssetsTempFile(context, assetsPath, fileName);
35 | intent.putExtra(CPDFDocumentActivity.EXTRA_FILE_PATH, samplePDFPath);
36 | } else if (document.startsWith(CONTENT_SCHEME)) {
37 | Uri uri = Uri.parse(document);
38 | intent.setData(uri);
39 | } else if (document.startsWith(FILE_SCHEME)) {
40 | Uri uri = Uri.parse(document);
41 | intent.setData(uri);
42 | } else {
43 | intent.putExtra(CPDFDocumentActivity.EXTRA_FILE_PATH, document);
44 | }
45 | }
46 |
47 | public static String getImportFilePath(Context context, String xfdf) {
48 | if (xfdf.startsWith(ASSETS_SCHEME)) {
49 | String assetsPath = xfdf.replace(ASSETS_SCHEME + "/","");
50 | String[] strs = xfdf.split("/");
51 | String fileName = strs[strs.length -1];
52 | return CFileUtils.getAssetsTempFile(context, assetsPath, fileName);
53 | } else if (xfdf.startsWith(CONTENT_SCHEME)) {
54 | Uri uri = Uri.parse(xfdf);
55 | String fileName = CUriUtil.getUriFileName(context, uri);
56 | String dir = new File(context.getCacheDir(), CFileUtils.CACHE_FOLDER + File.separator + "xfdfFile").getAbsolutePath();
57 | // Get the saved file path
58 | return CFileUtils.copyFileToInternalDirectory(context, uri, dir, fileName);
59 | } else if (xfdf.startsWith(FILE_SCHEME)) {
60 | return xfdf;
61 | } else {
62 | return xfdf;
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/lib/annotation/cpdf_square_annotation.dart:
--------------------------------------------------------------------------------
1 | // Copyright © 2014-2025 PDF Technologies, Inc. All Rights Reserved.
2 | //
3 | // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
4 | // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
5 | // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
6 | // This notice may not be removed from this file.
7 |
8 | import 'dart:ui';
9 |
10 | import 'package:compdfkit_flutter/annotation/cpdf_annotation.dart';
11 | import 'package:compdfkit_flutter/configuration/cpdf_options.dart';
12 | import 'package:compdfkit_flutter/util/extension/cpdf_color_extension.dart';
13 |
14 | import '../util/cpdf_rectf.dart';
15 |
16 | class CPDFSquareAnnotation extends CPDFAnnotation {
17 | final double borderWidth;
18 | final Color borderColor;
19 | final double borderAlpha;
20 | final Color fillColor;
21 | final double fillAlpha;
22 | final CPDFBorderEffectType effectType;
23 |
24 | CPDFSquareAnnotation(
25 | {required CPDFAnnotationType type,
26 | required String title,
27 | required int page,
28 | required String content,
29 | required String uuid,
30 | DateTime? createDate,
31 | required CPDFRectF rect,
32 | required this.borderWidth,
33 | required this.borderColor,
34 | required this.borderAlpha,
35 | required this.fillColor,
36 | required this.fillAlpha,
37 | required this.effectType})
38 | : super(
39 | type: type,
40 | title: title,
41 | page: page,
42 | content: content,
43 | uuid: uuid,
44 | createDate: createDate,
45 | rect: rect);
46 |
47 | factory CPDFSquareAnnotation.fromJson(Map json) {
48 | final common = CPDFAnnotation.fromJson(json);
49 | return CPDFSquareAnnotation(
50 | type: common.type,
51 | title: common.title,
52 | page: common.page,
53 | content: common.content,
54 | uuid: common.uuid,
55 | createDate: common.createDate,
56 | rect: common.rect,
57 | borderWidth: json['borderWidth'] ?? 0,
58 | borderColor: HexColor.fromHex(json['borderColor'] ?? '#000000'),
59 | borderAlpha: json['borderAlpha'] ?? 255,
60 | fillColor: HexColor.fromHex(json['fillColor'] ?? '#000000'),
61 | fillAlpha: json['fillAlpha'] ?? 255,
62 | effectType: CPDFBorderEffectType.fromString(json['bordEffectType'])
63 | );
64 | }
65 |
66 | @override
67 | Map toJson() {
68 | return {
69 | ...super.toJson(),
70 | 'borderWidth': borderWidth,
71 | 'borderColor': borderColor.toHex(),
72 | 'borderAlpha': borderAlpha,
73 | 'fillColor': fillColor.toHex(),
74 | 'fillAlpha': fillAlpha,
75 | 'bordEffectType': effectType.name
76 | };
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/example/lib/page/annotations/tools/cpdf_annotation_history_manager_widget.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014-2025 PDF Technologies, Inc. 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 ComPDFKit 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 |
11 | import 'package:compdfkit_flutter/history/cpdf_annotation_history_manager.dart';
12 | import 'package:compdfkit_flutter/widgets/cpdf_reader_widget_controller.dart';
13 | import 'package:flutter/material.dart';
14 |
15 | class CpdfAnnotationHistoryManagerWidget extends StatefulWidget {
16 | final CPDFReaderWidgetController controller;
17 |
18 | const CpdfAnnotationHistoryManagerWidget(
19 | {super.key, required this.controller});
20 |
21 | @override
22 | State createState() =>
23 | _CpdfAnnotationHistoryManagerWidgetState();
24 | }
25 |
26 | class _CpdfAnnotationHistoryManagerWidgetState
27 | extends State {
28 | bool _canUndo = false;
29 |
30 | bool _canRedo = false;
31 |
32 | @override
33 | void initState() {
34 | super.initState();
35 | _updateHistoryState();
36 | widget.controller.annotationHistoryManager.setOnHistoryChangedListener((isCanUndo, isCanRedo){
37 | setState(() {
38 | _canUndo = isCanUndo;
39 | _canRedo = isCanRedo;
40 | });
41 | });
42 | }
43 |
44 | void _updateHistoryState() async {
45 | CPDFAnnotationHistoryManager historyManager = widget.controller.annotationHistoryManager;
46 |
47 | bool canUndoResult = await historyManager.canUndo();
48 | bool canRedoResult = await historyManager.canRedo();
49 |
50 | if (mounted) {
51 | setState(() {
52 | _canUndo = canUndoResult;
53 | _canRedo = canRedoResult;
54 | });
55 | }
56 | }
57 |
58 | @override
59 | Widget build(BuildContext context) {
60 | return Row(
61 | children: [
62 | IconButton(
63 | onPressed: () {
64 | if (_canUndo) {
65 | widget.controller.annotationHistoryManager.undo();
66 | _updateHistoryState();
67 | }
68 | },
69 | icon: Icon(
70 | Icons.undo_rounded,
71 | color: _canUndo ? Colors.black : Colors.black12,
72 | )),
73 | IconButton(
74 | onPressed: () {
75 | if (_canRedo) {
76 | widget.controller.annotationHistoryManager.redo();
77 | _updateHistoryState();
78 | }
79 | },
80 | icon: Icon(
81 | Icons.redo_rounded,
82 | color: _canRedo ? Colors.black : Colors.black12,
83 | )),
84 | ],
85 | );
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/example/lib/cpdf_document_example_list_screen.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014-2025 PDF Technologies, Inc. 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 ComPDFKit 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 'package:flutter/material.dart';
11 | import 'examples/document/cpdf_document_open_pdf_example.dart';
12 | import 'examples/document/cpdf_document_annotation_example.dart';
13 | import 'examples/document/cpdf_document_widget_example.dart';
14 | import 'examples/document/cpdf_document_search_text_example.dart';
15 | import 'examples/document/cpdf_document_render_page_example.dart';
16 |
17 | /// Single document example item
18 | class DocumentExampleItem {
19 | final String title;
20 | final Widget page;
21 |
22 | const DocumentExampleItem({required this.title, required this.page});
23 | }
24 |
25 | /// List of document examples
26 | final List documentExamples = [
27 | const DocumentExampleItem(title: 'Open PDF Document', page: CPDFDocumentOpenPDFExample()),
28 | const DocumentExampleItem(title: 'Manage Annotations', page: CPDFDocumentAnnotationExample()),
29 | const DocumentExampleItem(title: 'Form & Widget Handling', page: CPDFDocumentWidgetExample()),
30 | const DocumentExampleItem(title: 'Text Search', page: CPDFDocumentSearchTextExample()),
31 | const DocumentExampleItem(title: 'Render Page to Image', page: CPDFDocumentRenderPageExample()),
32 | ];
33 |
34 | /// CPDFDocument example menu screen
35 | class CPDFDocumentExamplesScreen extends StatelessWidget {
36 | const CPDFDocumentExamplesScreen({super.key});
37 |
38 | void _openExamplePage(BuildContext context, Widget page) {
39 | Navigator.push(context, MaterialPageRoute(builder: (_) => page));
40 | }
41 |
42 | @override
43 | Widget build(BuildContext context) {
44 | return Scaffold(
45 | appBar: AppBar(
46 | title: const Text('CPDFDocument APIs Examples'),
47 | leading: IconButton(
48 | icon: const Icon(Icons.arrow_back),
49 | onPressed: () => Navigator.pop(context),
50 | ),
51 | ),
52 | body: ListView.separated(
53 | itemCount: documentExamples.length,
54 | separatorBuilder: (_, __) => Container(
55 | margin: const EdgeInsets.symmetric(horizontal: 16),
56 | height: 0.5,
57 | color: Colors.grey.shade300,
58 | ),
59 | itemBuilder: (context, index) {
60 | final example = documentExamples[index];
61 | return ListTile(
62 | title: Text(example.title),
63 | onTap: () => _openExamplePage(context, example.page),
64 | trailing: const Icon(Icons.arrow_forward_ios, size: 16),
65 | );
66 | },
67 | ),
68 | );
69 | }
70 | }
--------------------------------------------------------------------------------