Browse Source

PDFTool(Android) - 1.导入、创建数字签名证书交互界面

liuxiaolong 1 year ago
parent
commit
ccb2584937
89 changed files with 4133 additions and 5 deletions
  1. 30 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfsignature/CAddSignatureActivity.java
  2. 85 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/utils/CFileUtils.java
  3. 23 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/utils/CUriUtil.java
  4. 128 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/utils/view/CEditText.java
  5. 14 1
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/utils/window/CModeSwitchDialogFragment.java
  6. 4 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/views/CToolBar.java
  7. 5 1
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/views/pdfview/CPreviewMode.java
  8. 65 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/CSignatureToolBar.java
  9. 195 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/dialog/CImportCertificateDigitalDialog.java
  10. 146 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/dialog/CPDFSelectDigitalSignatureDialog.java
  11. 66 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/dialog/create/CertificateDigitalDatas.java
  12. 291 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/dialog/create/CreateCertificateDigitalDialog.java
  13. 273 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/dialog/preview/CDigitalSignStylePreviewDialog.java
  14. 94 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/dialog/preview/view/CSignStylePositionView.java
  15. 105 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/dialog/preview/view/CSignStyleReasonView.java
  16. 8 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/interfaces/COnSelectCertFileListener.java
  17. 133 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/pdfproperties/pdfsign/CDigitalSignStyleData.java
  18. 201 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/pdfproperties/pdfsign/CDigitalSignStylePreviewView.java
  19. 50 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/pdfproperties/pdfsign/CDigitalSignatureWidgetImpl.java
  20. 7 0
      ComPDFKit_Tools/src/main/res/anim/tools_slide_in_left.xml
  21. 7 0
      ComPDFKit_Tools/src/main/res/anim/tools_slide_out_right.xml
  22. 9 0
      ComPDFKit_Tools/src/main/res/drawable/tools_bg_import_certificate_digital_id_error_item.xml
  23. 15 0
      ComPDFKit_Tools/src/main/res/drawable/tools_bg_import_certificate_digital_id_item.xml
  24. 23 0
      ComPDFKit_Tools/src/main/res/drawable/tools_ic_compdfkit_logo.xml
  25. 13 0
      ComPDFKit_Tools/src/main/res/drawable/tools_ic_dark_oval_close.xml
  26. 7 0
      ComPDFKit_Tools/src/main/res/drawable/tools_ic_digital_sign_checkbox.xml
  27. 15 0
      ComPDFKit_Tools/src/main/res/drawable/tools_ic_digital_sign_checkbox_normal.xml
  28. 15 0
      ComPDFKit_Tools/src/main/res/drawable/tools_ic_digital_sign_checkbox_select.xml
  29. 10 0
      ComPDFKit_Tools/src/main/res/drawable/tools_ic_digital_signature.xml
  30. 27 0
      ComPDFKit_Tools/src/main/res/drawable/tools_ic_import_digital_signature.xml
  31. 10 0
      ComPDFKit_Tools/src/main/res/drawable/tools_ic_sign_none.xml
  32. 5 0
      ComPDFKit_Tools/src/main/res/drawable/tools_import_certificate_digital_id_btn.xml
  33. 19 0
      ComPDFKit_Tools/src/main/res/drawable/tools_signature_toolbar_btn_corner_status_bg.xml
  34. 16 0
      ComPDFKit_Tools/src/main/res/layout-land/tools_properties_signature_style_add_activity.xml
  35. 0 1
      ComPDFKit_Tools/src/main/res/layout/tools_dialog_tool_bar.xml
  36. 39 0
      ComPDFKit_Tools/src/main/res/layout/tools_layout_c_edit_text.xml
  37. 9 0
      ComPDFKit_Tools/src/main/res/layout/tools_pdf_mode_switch_dialog_fragment.xml
  38. 17 0
      ComPDFKit_Tools/src/main/res/layout/tools_properties_signature_style_add_activity.xml
  39. 41 0
      ComPDFKit_Tools/src/main/res/layout/tools_sign_create_cert_digital_id_fragment.xml
  40. 109 0
      ComPDFKit_Tools/src/main/res/layout/tools_sign_create_cert_digital_id_info_layout.xml
  41. 115 0
      ComPDFKit_Tools/src/main/res/layout/tools_sign_create_cert_digital_id_save_layout.xml
  42. 93 0
      ComPDFKit_Tools/src/main/res/layout/tools_sign_digital_sign_select_dialog.xml
  43. 153 0
      ComPDFKit_Tools/src/main/res/layout/tools_sign_import_certificate_digital_id_fragment.xml
  44. 59 0
      ComPDFKit_Tools/src/main/res/layout/tools_sign_style_preview_dialog.xml
  45. 224 0
      ComPDFKit_Tools/src/main/res/layout/tools_sign_style_preview_main.xml
  46. 52 0
      ComPDFKit_Tools/src/main/res/layout/tools_sign_style_preview_position.xml
  47. 81 0
      ComPDFKit_Tools/src/main/res/layout/tools_sign_style_preview_reason.xml
  48. 8 0
      ComPDFKit_Tools/src/main/res/layout/tools_sign_style_preview_reason_item.xml
  49. 59 0
      ComPDFKit_Tools/src/main/res/layout/tools_sign_style_preview_view.xml
  50. 58 0
      ComPDFKit_Tools/src/main/res/layout/tools_sign_style_preview_view_alignment_right.xml
  51. 82 0
      ComPDFKit_Tools/src/main/res/layout/tools_signature_tool_bar.xml
  52. 6 0
      ComPDFKit_Tools/src/main/res/values/tools_attrs.xml
  53. 2 0
      ComPDFKit_Tools/src/main/res/values/tools_colors.xml
  54. 37 0
      ComPDFKit_Tools/src/main/res/values/tools_strings.xml
  55. 8 2
      ComPDFKit_Tools/src/main/res/values/tools_styles.xml
  56. 1 0
      DigitalSignature/.gitignore
  57. 54 0
      DigitalSignature/build.gradle
  58. 21 0
      DigitalSignature/proguard-rules.pro
  59. 26 0
      DigitalSignature/src/androidTest/java/com/compdfkit/digitalsignature/ExampleInstrumentedTest.java
  60. 35 0
      DigitalSignature/src/main/AndroidManifest.xml
  61. BIN
      DigitalSignature/src/main/assets/PDF32000_2008.pdf
  62. 102 0
      DigitalSignature/src/main/java/com/compdfkit/digitalsignature/CViewerScreenStatusManager.java
  63. 205 0
      DigitalSignature/src/main/java/com/compdfkit/digitalsignature/PDFSignaturesSampleActivity.java
  64. 30 0
      DigitalSignature/src/main/res/drawable-v24/ic_launcher_foreground.xml
  65. 170 0
      DigitalSignature/src/main/res/drawable/ic_launcher_background.xml
  66. 63 0
      DigitalSignature/src/main/res/layout/signatures_pdf_sample_activity.xml
  67. 5 0
      DigitalSignature/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
  68. 5 0
      DigitalSignature/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
  69. BIN
      DigitalSignature/src/main/res/mipmap-hdpi/ic_launcher.png
  70. BIN
      DigitalSignature/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
  71. BIN
      DigitalSignature/src/main/res/mipmap-hdpi/ic_launcher_round.png
  72. BIN
      DigitalSignature/src/main/res/mipmap-mdpi/ic_launcher.png
  73. BIN
      DigitalSignature/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
  74. BIN
      DigitalSignature/src/main/res/mipmap-mdpi/ic_launcher_round.png
  75. BIN
      DigitalSignature/src/main/res/mipmap-xhdpi/ic_launcher.png
  76. BIN
      DigitalSignature/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
  77. BIN
      DigitalSignature/src/main/res/mipmap-xhdpi/ic_launcher_round.png
  78. BIN
      DigitalSignature/src/main/res/mipmap-xxhdpi/ic_launcher.png
  79. BIN
      DigitalSignature/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
  80. BIN
      DigitalSignature/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
  81. BIN
      DigitalSignature/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  82. BIN
      DigitalSignature/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
  83. BIN
      DigitalSignature/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
  84. 9 0
      DigitalSignature/src/main/res/values-night/themes.xml
  85. 10 0
      DigitalSignature/src/main/res/values/colors.xml
  86. 3 0
      DigitalSignature/src/main/res/values/strings.xml
  87. 10 0
      DigitalSignature/src/main/res/values/themes.xml
  88. 17 0
      DigitalSignature/src/test/java/com/compdfkit/digitalsignature/ExampleUnitTest.java
  89. 1 0
      settings.gradle

+ 30 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfsignature/CAddSignatureActivity.java

@@ -11,6 +11,7 @@ package com.compdfkit.tools.annotation.pdfproperties.pdfsignature;
 
 import android.app.Activity;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.net.Uri;
@@ -31,6 +32,8 @@ import com.bumptech.glide.Glide;
 import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
 import com.compdfkit.tools.R;
 import com.compdfkit.tools.annotation.pdfproperties.pdfsignature.data.CSignatureDatas;
+import com.compdfkit.tools.common.utils.CLog;
+import com.compdfkit.tools.common.utils.CToastUtil;
 import com.compdfkit.tools.common.utils.activitycontracts.CImageResultContracts;
 import com.compdfkit.tools.common.utils.dialog.CImportImageDialogFragment;
 import com.compdfkit.tools.common.utils.image.CBitmapUtil;
@@ -45,12 +48,22 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton;
 
 public class CAddSignatureActivity extends AppCompatActivity implements View.OnClickListener {
 
+    public static final String EXTRA_TITLE = "extra_title";
+
+    public static final String EXTRA_SHOW_NONE_TYPE = "extra_show_none_type";
+
+    public static final String EXTRA_SCREEN_ORIENTATION = "extra_screen_orientation";
+
+    public static final String RESULT_NONE = "result_none";
+
     private AppCompatImageView ivAddDrawSignature;
 
     private AppCompatImageView ivAddTextSignature;
 
     private AppCompatImageView ivAddPicSignature;
 
+    private AppCompatImageView ivNone;
+
     private CToolBar cToolBar;
 
     private CPDFSignatureEditView writingView;
@@ -89,6 +102,8 @@ public class CAddSignatureActivity extends AppCompatActivity implements View.OnC
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        int screenOrientation = getIntent().getIntExtra(EXTRA_SCREEN_ORIENTATION, ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+        setRequestedOrientation(screenOrientation);
         setContentView(R.layout.tools_properties_signature_style_add_activity);
         writingView = findViewById(R.id.writing_view);
         editText = findViewById(R.id.et_text);
@@ -98,6 +113,7 @@ public class CAddSignatureActivity extends AppCompatActivity implements View.OnC
         ivAddDrawSignature = findViewById(R.id.iv_add_draw_signature);
         ivAddTextSignature = findViewById(R.id.iv_add_text_signature);
         ivAddPicSignature = findViewById(R.id.iv_add_pic_signature);
+        ivNone = findViewById(R.id.iv_none);
         cToolBar = findViewById(R.id.tool_bar);
         colorListView = findViewById(R.id.color_list_view);
         btnSave = findViewById(R.id.btn_save);
@@ -133,6 +149,11 @@ public class CAddSignatureActivity extends AppCompatActivity implements View.OnC
             saveBitmap();
         } else if (v.getId() == R.id.btn_clean) {
             cleanSignature();
+        } else if (v.getId() == R.id.iv_none){
+            Intent intent = new Intent();
+            intent.putExtra(RESULT_NONE, true);
+            setResult(Activity.RESULT_OK, intent);
+            onBackPressed();
         }
     }
 
@@ -142,6 +163,7 @@ public class CAddSignatureActivity extends AppCompatActivity implements View.OnC
         ivAddDrawSignature.setOnClickListener(this);
         ivAddTextSignature.setOnClickListener(this);
         ivAddPicSignature.setOnClickListener(this);
+        ivNone.setOnClickListener(this);
         btnClean.setOnClickListener(this);
         btnSave.setOnClickListener(this);
         colorListView.setOnColorSelectListener(this::setSignatureColor);
@@ -170,6 +192,14 @@ public class CAddSignatureActivity extends AppCompatActivity implements View.OnC
 
     private void initView() {
         writingView.setAttribute(20,  Color.BLACK, 255);
+        if (getIntent().hasExtra(EXTRA_TITLE)) {
+            String title = getIntent().getStringExtra(EXTRA_TITLE);
+            cToolBar.setTitle(title);
+        }
+        if (getIntent().hasExtra(EXTRA_SHOW_NONE_TYPE)){
+            boolean showNoneType = getIntent().getBooleanExtra(EXTRA_SHOW_NONE_TYPE, false);
+            ivNone.setVisibility(showNoneType ? View.VISIBLE : View.GONE);
+        }
     }
 
     private void switchTab(int selectPosition) {

+ 85 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/utils/CFileUtils.java

@@ -2,11 +2,15 @@ package com.compdfkit.tools.common.utils;
 
 import android.content.ActivityNotFoundException;
 import android.content.ContentResolver;
+import android.content.ContentUris;
 import android.content.Context;
 import android.content.Intent;
+import android.database.Cursor;
 import android.net.Uri;
 import android.os.Build;
 import android.os.ParcelFileDescriptor;
+import android.provider.DocumentsContract;
+import android.provider.MediaStore;
 import android.util.Log;
 
 import androidx.core.content.FileProvider;
@@ -24,6 +28,8 @@ import java.io.OutputStream;
 
 public class CFileUtils {
 
+    public static final String CERTIFICATE_DIGITAL_TYPE = "application/x-pkcs12";
+
     public static final String ROOT_FOLDER = "compdfkit/";
 
     public static final String CACHE_FOLDER = "compdfkit/temp";
@@ -271,6 +277,22 @@ public class CFileUtils {
         return intent;
     }
 
+    public static Intent getIntent(String type) {
+        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+        intent.addCategory(Intent.CATEGORY_OPENABLE);
+        intent.setType(type);
+        intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
+        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+        return intent;
+    }
+
+    public static Intent selectSystemDir(boolean isOnlyLocal) {
+        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
+        intent.putExtra("android.content.extra.SHOW_ADVANCED", isOnlyLocal);
+        intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
+        return intent;
+    }
+
     public static void takeUriPermission(Context context, Uri uri){
         try{
             context.getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
@@ -278,4 +300,67 @@ public class CFileUtils {
 
         }
     }
+
+
+    public static String getFilePathFromUri(Context context, Uri uri) {
+        String filePath = null;
+
+        if (DocumentsContract.isDocumentUri(context, uri)) {
+            if ("com.android.externalstorage.documents".equals(uri.getAuthority())) {
+                final String docId = DocumentsContract.getDocumentId(uri);
+                final String[] split = docId.split(":");
+                final String type = split[0];
+
+                if ("primary".equalsIgnoreCase(type)) {
+                    filePath = context.getExternalFilesDir(null) + "/" + split[1];
+                }
+            } else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
+                final String id = DocumentsContract.getDocumentId(uri);
+                final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.parseLong(id));
+                filePath = getDataColumn(context, contentUri, null, null);
+            } else if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
+                final String docId = DocumentsContract.getDocumentId(uri);
+                final String[] split = docId.split(":");
+                final String type = split[0];
+
+                Uri contentUri = null;
+                if ("image".equals(type)) {
+                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
+                } else if ("video".equals(type)) {
+                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
+                } else if ("audio".equals(type)) {
+                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
+                }
+
+                final String selection = "_id=?";
+                final String[] selectionArgs = new String[] { split[1] };
+                filePath = getDataColumn(context, contentUri, selection, selectionArgs);
+            }
+        } else if ("content".equalsIgnoreCase(uri.getScheme())) {
+            filePath = getDataColumn(context, uri, null, null);
+        }
+
+        return filePath;
+    }
+
+    private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
+        String filePath = null;
+        String[] projection = { MediaStore.Images.Media.DATA };
+        Cursor cursor = null;
+
+        try {
+            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
+            if (cursor != null && cursor.moveToFirst()) {
+                int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
+                filePath = cursor.getString(columnIndex);
+            }
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+
+        return filePath;
+    }
+
 }

+ 23 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/utils/CUriUtil.java

@@ -34,6 +34,29 @@ public class CUriUtil {
         return "";
     }
 
+    public static String getUriData(Context context, Uri uri) {
+
+        Cursor cursor = null;
+        final String column = MediaStore.Files.FileColumns.DATA;
+        final String[] projection = {column};
+
+        try {
+            cursor = context.getContentResolver().query(uri, projection, null, null,
+                    null);
+            if (cursor != null && cursor.moveToFirst()) {
+                final int column_index = cursor.getColumnIndexOrThrow(column);
+                return cursor.getString(column_index);
+            }
+        } catch (Exception e) {
+
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+        return "";
+    }
+
     public static String copyUriToInternalCache(Context context, Uri uri) {
         try {
             File file = new File(context.getFilesDir(), CFileUtils.CACHE_FOLDER);

+ 128 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/utils/view/CEditText.java

@@ -0,0 +1,128 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ *
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ */
+
+package com.compdfkit.tools.common.utils.view;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.util.AttributeSet;
+import android.view.inputmethod.EditorInfo;
+import android.widget.FrameLayout;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.widget.AppCompatEditText;
+import androidx.appcompat.widget.AppCompatTextView;
+
+import com.compdfkit.tools.R;
+import com.compdfkit.tools.common.interfaces.COnTextChangedListener;
+
+
+public class CEditText extends FrameLayout {
+
+    AppCompatEditText editText;
+
+    AppCompatTextView tvTitle;
+
+    private COnTextChangedListener textChangedListener;
+
+    public CEditText(@NonNull Context context) {
+        this(context, null);
+    }
+
+    public CEditText(@NonNull Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public CEditText(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        initView(context);
+        initAttr(context, attrs);
+
+    }
+
+    private void initAttr(Context context, AttributeSet attrs) {
+        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CEditText);
+        if (typedArray != null) {
+            String title = typedArray.getString(R.styleable.CEditText_android_title);
+            int imeOptions = typedArray.getInt(R.styleable.CEditText_android_imeOptions, EditorInfo.IME_ACTION_DONE);
+            int inputType = typedArray.getInt(R.styleable.CEditText_android_inputType, EditorInfo.TYPE_CLASS_TEXT);
+            tvTitle.setVisibility(TextUtils.isEmpty(title)?  GONE : VISIBLE);
+            tvTitle.setText(title);
+            editText.setImeOptions(imeOptions);
+            editText.setInputType(inputType);
+            typedArray.recycle();
+        }
+    }
+
+    private void initView(Context context){
+        inflate(context, R.layout.tools_layout_c_edit_text, this);
+        editText = findViewById(R.id.edit_text);
+        tvTitle = findViewById(R.id.tv_title);
+        editText.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+
+            }
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {
+                if (textChangedListener != null) {
+                    textChangedListener.onTextChanged(s, start, before, count);
+                }
+            }
+
+            @Override
+            public void afterTextChanged(Editable s) {
+
+            }
+        });
+    }
+
+    public AppCompatEditText getEditText() {
+        return editText;
+    }
+
+    public AppCompatTextView getTitle() {
+        return tvTitle;
+    }
+
+    public void setTitle(String title) {
+        this.tvTitle.setText(title);
+    }
+
+    public void setOnEditorActionListener(TextView.OnEditorActionListener listener){
+        editText.setOnEditorActionListener(listener);
+    }
+
+    public void addTextChangedListener(COnTextChangedListener textChangedListener){
+       this.textChangedListener = textChangedListener;
+    }
+
+    public String getText() {
+        if (TextUtils.isEmpty(editText.getText())){
+            return "";
+        }else {
+            return editText.getText().toString();
+        }
+    }
+
+    public void setText(String text){
+        editText.setText(text);
+    }
+
+
+    public void setError(boolean error){
+        editText.setBackgroundResource(error ? R.drawable.tools_bg_import_certificate_digital_id_error_item : R.drawable.tools_bg_import_certificate_digital_id_item);
+    }
+}

+ 14 - 1
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/utils/window/CModeSwitchDialogFragment.java

@@ -1,6 +1,7 @@
 package com.compdfkit.tools.common.utils.window;
 
 
+import android.graphics.Paint;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -42,6 +43,8 @@ public class CModeSwitchDialogFragment extends BottomSheetDialogFragment
 
     private RadioButton rbPageEdit;
 
+    private RadioButton rbSignature;
+
     private LinkedHashSet<CPreviewMode> previewModes = new LinkedHashSet<>();
 
     private CPreviewMode selectMode;
@@ -90,6 +93,7 @@ public class CModeSwitchDialogFragment extends BottomSheetDialogFragment
         rbPDFEdit = rootView.findViewById(R.id.r_btn_pdf_edit_mode);
         rbForm = rootView.findViewById(R.id.r_btn_form_mode);
         rbPageEdit = rootView.findViewById(R.id.r_btn_page_edit_mode);
+        rbSignature = rootView.findViewById(R.id.r_btn_signature_mode);
         return rootView;
     }
 
@@ -128,15 +132,18 @@ public class CModeSwitchDialogFragment extends BottomSheetDialogFragment
             case PageEdit:
                 rbPageEdit.setChecked(true);
                 break;
+            case Signature:
+                rbSignature.setChecked(true);
+                break;
             default:break;
         }
         modifyPopupMenuStatus();
-//        radioGroup.setOnCheckedChangeListener(this);
         rbViewer.setOnClickListener(this);
         rbAnnotation.setOnClickListener(this);
         rbPDFEdit.setOnClickListener(this);
         rbForm.setOnClickListener(this);
         rbPageEdit.setOnClickListener(this);
+        rbSignature.setOnClickListener(this);
     }
 
     @Override
@@ -156,6 +163,9 @@ public class CModeSwitchDialogFragment extends BottomSheetDialogFragment
         } else if (v.getId() == R.id.r_btn_form_mode) {
             rbForm.setChecked(true);
             changeMode(CPreviewMode.Form);
+        } else if (v.getId() == R.id.r_btn_signature_mode){
+            rbSignature.setChecked(true);
+            changeMode(CPreviewMode.Signature);
         }
         dismiss();
     }
@@ -177,6 +187,9 @@ public class CModeSwitchDialogFragment extends BottomSheetDialogFragment
         if (rbPageEdit != null) {
             rbPageEdit.setVisibility(previewModes.contains(CPreviewMode.PageEdit) ? View.VISIBLE : View.GONE);
         }
+        if (rbSignature != null) {
+            rbSignature.setVisibility(previewModes.contains(CPreviewMode.Signature) ? View.VISIBLE : View.GONE);
+        }
     }
 
 

+ 4 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/views/CToolBar.java

@@ -115,4 +115,8 @@ public class CToolBar extends FrameLayout {
     public void setBackImageIconResource(@DrawableRes int iconResId) {
         ivToolBarBackBtn.setImageResource(iconResId);
     }
+
+    public AppCompatImageView getIvToolBarBackBtn() {
+        return ivToolBarBackBtn;
+    }
 }

+ 5 - 1
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/views/pdfview/CPreviewMode.java

@@ -7,7 +7,9 @@ public enum CPreviewMode {
     Annotation,
     Edit,
     Form,
-    PageEdit;
+    PageEdit,
+
+    Signature;
 
     public int getTitleByMode() {
         switch (this) {
@@ -19,6 +21,8 @@ public enum CPreviewMode {
                 return R.string.tools_page_edit_mode;
             case Form:
                 return R.string.tools_form_mode;
+            case Signature:
+                return R.string.tools_signatures;
             default:
                 return R.string.tools_pdf_viewer_mode;
         }

+ 65 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/CSignatureToolBar.java

@@ -0,0 +1,65 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ * <p>
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ */
+
+package com.compdfkit.tools.signature;
+
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import com.compdfkit.core.annotation.form.CPDFWidget;
+import com.compdfkit.tools.R;
+import com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl;
+import com.compdfkit.ui.reader.CPDFReaderView;
+
+public class CSignatureToolBar extends FrameLayout {
+
+    ConstraintLayout clAddSignatures;
+
+    private CPDFViewCtrl pdfView;
+
+    public void initWithPDFView(CPDFViewCtrl pdfView) {
+        this.pdfView = pdfView;
+    }
+
+    public CSignatureToolBar(@NonNull Context context) {
+        this(context, null);
+    }
+
+    public CSignatureToolBar(@NonNull Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public CSignatureToolBar(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        initView(context);
+    }
+
+    private void initView(Context context) {
+        inflate(context, R.layout.tools_signature_tool_bar, this);
+        clAddSignatures = findViewById(R.id.cl_add_digital_signature);
+        clAddSignatures.setOnClickListener(v -> {
+            if (pdfView != null) {
+                clAddSignatures.setSelected(!clAddSignatures.isSelected());
+                if (clAddSignatures.isSelected()){
+                    pdfView.setViewMode(CPDFReaderView.ViewMode.FORM);
+                    pdfView.changeFormType(CPDFWidget.WidgetType.Widget_SignatureFields);
+                }else {
+                    pdfView.setViewMode(CPDFReaderView.ViewMode.VIEW);
+                    pdfView.changeFormType(CPDFWidget.WidgetType.Widget_Unknown);
+                }
+            }
+        });
+    }
+}

+ 195 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/dialog/CImportCertificateDigitalDialog.java

@@ -0,0 +1,195 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ * <p>
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ */
+
+package com.compdfkit.tools.signature.dialog;
+
+
+import static com.compdfkit.tools.common.utils.CFileUtils.CERTIFICATE_DIGITAL_TYPE;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.EditorInfo;
+
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.widget.AppCompatButton;
+import androidx.appcompat.widget.AppCompatEditText;
+import androidx.appcompat.widget.AppCompatImageView;
+import androidx.appcompat.widget.AppCompatTextView;
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import com.compdfkit.core.utils.TFileUtils;
+import com.compdfkit.tools.R;
+import com.compdfkit.tools.common.utils.CFileUtils;
+import com.compdfkit.tools.common.utils.CUriUtil;
+import com.compdfkit.tools.common.utils.dialog.CDialogFragmentUtil;
+import com.compdfkit.tools.common.utils.viewutils.CViewUtils;
+import com.compdfkit.tools.signature.interfaces.COnSelectCertFileListener;
+import com.google.android.material.bottomsheet.BottomSheetBehavior;
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
+
+public class CImportCertificateDigitalDialog extends BottomSheetDialogFragment implements View.OnClickListener {
+
+    public static final String EXTRA_CERTIFICATE_DIGITAL_URI = "extra_certificate_digital_uri";
+
+    private AppCompatTextView tvTitle;
+
+    private AppCompatImageView ivClose;
+
+    private ConstraintLayout clCertificate;
+
+    private AppCompatEditText etPassword;
+
+    private AppCompatImageView ivClearPassword;
+
+    private AppCompatButton btnOk;
+
+    private AppCompatTextView tvCertificateDigitalName;
+
+    private AppCompatTextView tvPasswordError;
+
+    private Uri certificateUri = null;
+
+    private COnSelectCertFileListener selectCertFileListener;
+
+    private ActivityResultLauncher<Intent> selectCertificateLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
+        if (result.getData() != null && result.getData().getData() != null) {
+            Uri certificateUri = result.getData().getData();
+            setCertificateInfo(certificateUri);
+            if (getArguments() != null) {
+                getArguments().putParcelable(EXTRA_CERTIFICATE_DIGITAL_URI, certificateUri);
+            }
+        }
+    });
+
+
+    public static CImportCertificateDigitalDialog newInstance(Uri certificateUri) {
+        Bundle args = new Bundle();
+        args.putParcelable(EXTRA_CERTIFICATE_DIGITAL_URI, certificateUri);
+        CImportCertificateDigitalDialog fragment = new CImportCertificateDigitalDialog();
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    @Override
+    public void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setStyle(STYLE_NORMAL, R.style.Tools_Base_Theme_BasicBottomSheetDialogStyle_TopCorners);
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        BottomSheetBehavior<View> behavior = BottomSheetBehavior.from((View) getView().getParent());
+        CDialogFragmentUtil.setBottomSheetDialogFragmentFullScreen(getDialog(), behavior);
+    }
+
+    @Nullable
+    @Override
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        View view = inflater.inflate(R.layout.tools_sign_import_certificate_digital_id_fragment, container, false);
+        tvTitle = view.findViewById(R.id.tv_tool_bar_title);
+        ivClose = view.findViewById(R.id.iv_tool_bar_close);
+        clCertificate = view.findViewById(R.id.cl_certificate);
+        tvCertificateDigitalName = view.findViewById(R.id.tv_certificate);
+        etPassword = view.findViewById(R.id.et_password);
+        ivClearPassword = view.findViewById(R.id.iv_remove_password);
+        tvPasswordError = view.findViewById(R.id.tv_password_error);
+        btnOk = view.findViewById(R.id.btn_ok);
+        ivClose.setOnClickListener(this);
+        ivClearPassword.setOnClickListener(this);
+        btnOk.setOnClickListener(this);
+        clCertificate.setOnClickListener(this);
+        etPassword.setOnEditorActionListener((v, actionId, event) -> {
+            if (actionId == EditorInfo.IME_ACTION_DONE){
+                verifyCertificate();
+                return true;
+            }
+            return false;
+        });
+        return view;
+    }
+
+    @Override
+    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+        Uri uri = getArguments().getParcelable(EXTRA_CERTIFICATE_DIGITAL_URI);
+        if (uri != null) {
+            setCertificateInfo(uri);
+        }
+        tvTitle.setText(R.string.tools_new_certificate_digital_id);
+        etPassword.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+
+            }
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {
+                ivClearPassword.setVisibility(TextUtils.isEmpty(s) ? View.GONE : View.VISIBLE);
+                if (TextUtils.isEmpty(s) && tvPasswordError.getVisibility() == View.VISIBLE) {
+                    tvPasswordError.setVisibility(View.GONE);
+                }
+                btnOk.setEnabled(!TextUtils.isEmpty(s));
+            }
+
+            @Override
+            public void afterTextChanged(Editable s) {
+
+            }
+        });
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v.getId() == R.id.iv_tool_bar_close) {
+            dismiss();
+        } else if (v.getId() == R.id.iv_remove_password) {
+            etPassword.setText("");
+        } else if (v.getId() == R.id.btn_ok) {
+            verifyCertificate();
+        } else if (v.getId() == R.id.cl_certificate) {
+            selectCertificateLauncher.launch(CFileUtils.getIntent(CERTIFICATE_DIGITAL_TYPE));
+        }
+    }
+
+    private void setCertificateInfo(Uri uri) {
+        certificateUri = uri;
+        String idName = CUriUtil.getUriFileName(getContext(), uri);
+        tvCertificateDigitalName.setText(idName);
+        etPassword.setText("");
+        etPassword.requestFocus();
+        CViewUtils.showKeyboard(etPassword);
+    }
+
+    private void verifyCertificate(){
+        if (TextUtils.isEmpty(etPassword.getText())){
+            tvPasswordError.setVisibility(View.VISIBLE);
+            return;
+        }
+        String password = etPassword.getText().toString();
+        if (selectCertFileListener != null && certificateUri != null) {
+            String certPath = TFileUtils.toPath(getContext(), certificateUri);
+            selectCertFileListener.certificateFile(certPath, password);
+        }
+    }
+
+    public void setSelectCertFileListener(COnSelectCertFileListener selectCertFileListener) {
+        this.selectCertFileListener = selectCertFileListener;
+    }
+}

+ 146 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/dialog/CPDFSelectDigitalSignatureDialog.java

@@ -0,0 +1,146 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ * <p>
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ */
+
+package com.compdfkit.tools.signature.dialog;
+
+
+import static com.compdfkit.tools.common.utils.CFileUtils.CERTIFICATE_DIGITAL_TYPE;
+
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.RadioGroup;
+
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.Fragment;
+
+import com.compdfkit.tools.R;
+import com.compdfkit.tools.annotation.pdfproperties.pdfsignature.CAddSignatureActivity;
+import com.compdfkit.tools.common.utils.CFileUtils;
+import com.compdfkit.tools.common.utils.CLog;
+import com.compdfkit.tools.signature.dialog.create.CreateCertificateDigitalDialog;
+import com.compdfkit.tools.signature.interfaces.COnSelectCertFileListener;
+
+public class CPDFSelectDigitalSignatureDialog extends DialogFragment implements View.OnClickListener {
+
+    private RadioGroup rgType;
+
+    private String certFilePath;
+
+    private String certPassword;
+
+    private COnCertDigitalSignListener certDigitalSignListener;
+
+    private ActivityResultLauncher<Intent> addSignatureLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
+        Fragment fragment = getChildFragmentManager().findFragmentByTag("certDialog");
+        if (fragment != null) {
+            ((DialogFragment) fragment).dismiss();
+        }
+        if (result.getData() != null) {
+            String signImagePath;
+            if (result.getData().getStringExtra("file_path") != null){
+                signImagePath = result.getData().getStringExtra("file_path");
+                if (certDigitalSignListener != null) {
+                    certDigitalSignListener.sign(certFilePath,certPassword, signImagePath);
+                }
+            }else if (result.getData().getBooleanExtra(CAddSignatureActivity.RESULT_NONE, false)){
+                //none
+                signImagePath = "";
+                if (certDigitalSignListener != null) {
+                    certDigitalSignListener.sign(certFilePath,certPassword, signImagePath);
+                }
+            }
+        }
+    });
+
+    private COnSelectCertFileListener selectCertFileListener = (filePath, password) -> {
+        certFilePath = filePath;
+        certPassword = password;
+        openSignActivity();
+    };
+
+    private void openSignActivity(){
+        Intent intent = new Intent(getContext(), CAddSignatureActivity.class);
+        intent.putExtra(CAddSignatureActivity.EXTRA_SHOW_NONE_TYPE, true);
+        intent.putExtra(CAddSignatureActivity.EXTRA_TITLE, getString(R.string.tools_digital_signatures));
+        intent.putExtra(CAddSignatureActivity.EXTRA_SCREEN_ORIENTATION, ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+        addSignatureLauncher.launch(intent);
+    }
+
+    public ActivityResultLauncher<Intent> selectCertificateLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
+        if (result.getData() != null && result.getData().getData()!=null) {
+            Uri certificateUri = result.getData().getData();
+            CImportCertificateDigitalDialog digitalDialog = CImportCertificateDigitalDialog.newInstance(certificateUri);
+            digitalDialog.setSelectCertFileListener(selectCertFileListener);
+            digitalDialog.show(getChildFragmentManager(), "certDialog");
+        }
+    });
+
+    public static CPDFSelectDigitalSignatureDialog newInstance() {
+        Bundle args = new Bundle();
+        CPDFSelectDigitalSignatureDialog fragment = new CPDFSelectDigitalSignatureDialog();
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    @Override
+    public void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setStyle(STYLE_NO_TITLE, R.style.tools_dialog_theme);
+    }
+
+    @Nullable
+    @Override
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        if (getDialog() != null && getDialog().getWindow() != null) {
+            getDialog().getWindow().setBackgroundDrawableResource(R.drawable.tools_dialog_background);
+        }
+        View view = inflater.inflate(R.layout.tools_sign_digital_sign_select_dialog, container, false);
+        rgType = view.findViewById(R.id.rg_type);
+        Button btnCancel = view.findViewById(R.id.btn_cancel);
+        Button btnDone = view.findViewById(R.id.btn_confirm);
+        btnCancel.setOnClickListener(this);
+        btnDone.setOnClickListener(this);
+        return view;
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v.getId() == R.id.btn_cancel) {
+            dismiss();
+        } else if (v.getId() == R.id.btn_confirm) {
+            if (rgType.getCheckedRadioButtonId() == R.id.rb_import_digital_sign){
+                selectCertificateLauncher.launch(CFileUtils.getIntent(CERTIFICATE_DIGITAL_TYPE));
+            }else {
+                CreateCertificateDigitalDialog dialog = CreateCertificateDigitalDialog.newInstance();
+                dialog.setSelectCertFileListener(selectCertFileListener);
+                dialog.show(getChildFragmentManager(), "certDialog");
+            }
+        }
+    }
+
+    public void setCertDigitalSignListener(COnCertDigitalSignListener certDigitalSignListener) {
+        this.certDigitalSignListener = certDigitalSignListener;
+    }
+
+    public interface COnCertDigitalSignListener{
+        void sign(String certFilePath, String certPassword, String signImagePath);
+    }
+}
+
+

+ 66 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/dialog/create/CertificateDigitalDatas.java

@@ -0,0 +1,66 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ *
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ */
+
+package com.compdfkit.tools.signature.dialog.create;
+
+
+import com.compdfkit.core.document.signature.CPDFCertInfo;
+import com.compdfkit.core.document.signature.CPDFOwnerInfo;
+import com.compdfkit.core.document.signature.CPDFSignature;
+import com.compdfkit.core.document.signature.CPDFX509;
+
+import java.io.File;
+
+public class CertificateDigitalDatas {
+
+
+
+    public static boolean generatePKCS12Cert(CPDFOwnerInfo ownerInfo, String password, String saveDir, String fileName){
+        CPDFSignature.CertUsage flag = CPDFSignature.CertUsage.PDFDigSig;
+        String pfxPath = new File(saveDir , fileName).getAbsolutePath();
+        return CPDFSignature.generatePKCS12Cert(ownerInfo, password, pfxPath, flag, true);
+    }
+
+    private void getX509ByPKCS12CertTest() {
+        String path = "/storage/emulated/0/certificate.pfx";
+        CPDFX509 x509 = CPDFSignature.getX509ByPKCS12Cert(path, "1234");
+        CPDFCertInfo info = x509.getCertInfo();
+    }
+
+    protected void signaturetest() {
+//        StringBuilder data = new StringBuilder();
+//        data.append("Signature number = " + currentDocument.getSignatureCount()+"\n\n");
+//        for (int i = 0; i < currentDocument.getSignatureCount(); i++) {
+//            data.append("Signature "+i +":\n");
+//
+//            CPDFSignature signature = currentDocument.getPdfSignature(i);
+//            if (signature == null) continue;
+//            data.append("reason="+ signature.getReason()+ ";  date="+signature.getDate()+ "; name="+signature.getName()
+//                    + "; bounds="+signature.getBounds().toString()+ "; filter="+signature.getFilter()+
+//                    "; locate=" + signature.getLocation() +
+//                    "; pageIndex=" + signature.getPageIndex(currentDocument) + " \n");
+//
+//            CPDFSigner[] signerArr = signature.getSignerArr();
+//            if (signerArr != null && signerArr.length > 0) {
+//                CPDFSigner signer = signerArr[0];
+//                CPDFX509 cert = signer.getCert();
+//                CPDFCertInfo info = cert.getCertInfo();
+//                data.append("begin date="+info.getValidDate_begin() + " \nend date="+info.getValidDate_end() + " \npublickey="+info.getPublic_key()
+//                        + " \nsubjectname="+ info.getSubjectName()+ " \nversion="+info.getVer());
+//
+//                String documentPath = "/storage/emulated/0/Download/jjjj.pdf";
+//                data.append("\n veryfy=" + signature.veryfyByPath(signer,documentPath));
+//                data.append("\n veryfy document=" + signature.veryfyDocument(currentDocument, documentPath));
+//                data.append("\n===============================\n");
+//            }
+//        }
+//        signInfo.setText(data);
+    }
+
+}

+ 291 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/dialog/create/CreateCertificateDigitalDialog.java

@@ -0,0 +1,291 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ * <p>
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ */
+
+package com.compdfkit.tools.signature.dialog.create;
+
+import android.app.Dialog;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.Switch;
+import android.widget.ViewSwitcher;
+
+import androidx.activity.ComponentDialog;
+import androidx.activity.OnBackPressedCallback;
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.widget.AppCompatButton;
+import androidx.appcompat.widget.AppCompatImageView;
+import androidx.appcompat.widget.AppCompatTextView;
+
+import com.compdfkit.core.document.signature.CPDFCertInfo;
+import com.compdfkit.core.document.signature.CPDFOwnerInfo;
+import com.compdfkit.core.document.signature.CPDFSignature;
+import com.compdfkit.core.document.signature.CPDFX509;
+import com.compdfkit.tools.R;
+import com.compdfkit.tools.common.utils.CFileUtils;
+import com.compdfkit.tools.common.utils.CLog;
+import com.compdfkit.tools.common.utils.dialog.CDialogFragmentUtil;
+import com.compdfkit.tools.common.utils.view.CEditText;
+import com.compdfkit.tools.signature.interfaces.COnSelectCertFileListener;
+import com.google.android.material.bottomsheet.BottomSheetBehavior;
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
+
+import java.io.File;
+import java.util.UUID;
+
+
+public class CreateCertificateDigitalDialog extends BottomSheetDialogFragment implements View.OnClickListener {
+
+    private AppCompatTextView tvTitle;
+
+    private AppCompatImageView ivClose;
+
+    private CEditText etName;
+
+    private CEditText etGrantor;
+
+    private CEditText etSectoral;
+
+    private CEditText etEmail;
+
+    private CEditText etCountryArea;
+
+    private Switch swContinuous;
+
+    private AppCompatButton btnOk;
+
+    private ViewSwitcher switcher;
+
+    private AppCompatTextView tvSaveAddress;
+
+    private LinearLayout llSaveAddress;
+
+    private CEditText etPassword;
+
+    private CEditText etConfirmPassword;
+
+    private AppCompatButton btnConfirmCreate;
+
+    private boolean showSaveStatus = false;
+
+    private OnBackPressedCallback callback;
+
+    private String customSavePath;
+
+    private COnSelectCertFileListener selectCertFileListener;
+
+    private ActivityResultLauncher<Intent> selectDirLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
+        if (result.getData() != null && result.getData().getData() != null) {
+            Uri uri = result.getData().getData();
+            CFileUtils.takeUriPermission(getContext(), result.getData().getData());
+            customSavePath = Environment.getExternalStorageDirectory().getAbsolutePath()  + File.separator + uri.getPath().replace("/tree/primary:", "");
+            tvSaveAddress.setText(getSaveAddress());
+        }
+    });
+
+    public static CreateCertificateDigitalDialog newInstance() {
+        Bundle args = new Bundle();
+        CreateCertificateDigitalDialog fragment = new CreateCertificateDigitalDialog();
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    @Override
+    public void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setStyle(STYLE_NORMAL, R.style.Tools_Base_Theme_BasicBottomSheetDialogStyle_TopCorners);
+    }
+
+    @NonNull
+    @Override
+    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+        Dialog dialog = super.onCreateDialog(savedInstanceState);
+        if (dialog instanceof ComponentDialog) {
+            ComponentDialog componentDialog = (ComponentDialog) dialog;
+            callback = new OnBackPressedCallback(true) {
+                @Override
+                public void handleOnBackPressed() {
+                    if (showSaveStatus) {
+                        showInfoStatusView();
+                        showSaveStatus = false;
+                        callback.setEnabled(false);
+                    } else {
+                        dismiss();
+                    }
+                }
+            };
+            componentDialog.getOnBackPressedDispatcher().addCallback(callback);
+        }
+        return dialog;
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        BottomSheetBehavior<View> behavior = BottomSheetBehavior.from((View) getView().getParent());
+        CDialogFragmentUtil.setBottomSheetDialogFragmentFullScreen(getDialog(), behavior);
+    }
+
+    @Nullable
+    @Override
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        View view = inflater.inflate(R.layout.tools_sign_create_cert_digital_id_fragment, container, false);
+        tvTitle = view.findViewById(R.id.tv_tool_bar_title);
+        ivClose = view.findViewById(R.id.iv_tool_bar_close);
+        etName = view.findViewById(R.id.et_name);
+        etGrantor = view.findViewById(R.id.et_grantor);
+        etSectoral = view.findViewById(R.id.et_sectoral);
+        etEmail = view.findViewById(R.id.et_email);
+        etCountryArea = view.findViewById(R.id.et_country_area);
+        swContinuous = view.findViewById(R.id.sw_continuous);
+        btnOk = view.findViewById(R.id.btn_ok);
+        switcher = view.findViewById(R.id.view_switcher);
+        tvSaveAddress = view.findViewById(R.id.tv_save_address);
+        llSaveAddress = view.findViewById(R.id.ll_save_address);
+        etPassword = view.findViewById(R.id.et_password);
+        etConfirmPassword = view.findViewById(R.id.et_confirm_password);
+        btnConfirmCreate = view.findViewById(R.id.btn_save);
+        btnOk.setOnClickListener(this);
+        tvSaveAddress.setOnClickListener(this);
+        btnConfirmCreate.setOnClickListener(this);
+        ivClose.setOnClickListener(this);
+        return view;
+    }
+
+    @Override
+    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+        tvTitle.setText(R.string.tools_new_certificate_digital_id);
+        etName.addTextChangedListener((s, start, before, count) -> {
+            enableConfirmButton();
+        });
+        etGrantor.addTextChangedListener((s, start, before, count) -> {
+            enableConfirmButton();
+        });
+        etEmail.addTextChangedListener((s, start, before, count) -> {
+            enableConfirmButton();
+        });
+        etSectoral.addTextChangedListener((s, start, before, count) -> {
+            enableConfirmButton();
+        });
+        etCountryArea.addTextChangedListener((s, start, before, count) -> {
+            enableConfirmButton();
+        });
+
+        swContinuous.setOnCheckedChangeListener((buttonView, isChecked) -> {
+            llSaveAddress.setVisibility(isChecked ? View.VISIBLE : View.GONE);
+            tvSaveAddress.setText(getSaveAddress());
+        });
+        tvSaveAddress.setText(getSaveAddress());
+        etName.setText("刘小龙");
+        etGrantor.setText("ComPDFKit");
+        etSectoral.setText("CR10");
+        etEmail.setText("xiaolong.liu.work@gmail.com");
+        etCountryArea.setText("China");
+
+
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v.getId() == R.id.btn_ok) {
+            callback.setEnabled(true);
+            showSaveStatusView();
+            showSaveStatus = true;
+        } else if (v.getId() == R.id.iv_tool_bar_close) {
+            dismiss();
+        } else if (v.getId() == R.id.tv_save_address) {
+            selectDirLauncher.launch(CFileUtils.selectSystemDir(true));
+        } else if (v.getId() == R.id.btn_save){
+            String name = etName.getText();
+            String grantor = etGrantor.getText();
+            String sectoral = etSectoral.getText();
+            String email = etEmail.getText();
+            String countryArea = etCountryArea.getText();
+            String password = etPassword.getText();
+            String verifyPassword = etConfirmPassword.getText();
+
+            if (TextUtils.isEmpty(password) || TextUtils.isEmpty(verifyPassword) || !password.equals(verifyPassword)){
+                etPassword.setError(true);
+                etConfirmPassword.setError(true);
+                return;
+            }
+            etPassword.setError(false);
+            etConfirmPassword.setError(false);
+
+            CPDFOwnerInfo ownerInfo = new CPDFOwnerInfo();
+            ownerInfo.setCommonName(name);
+            ownerInfo.setOrgnizeUnit(grantor);
+            ownerInfo.setOrgnize(sectoral);
+            ownerInfo.setEmail(email);
+            ownerInfo.setCountry(countryArea);
+            String uuid = UUID.randomUUID().toString();
+
+            String saveDir = getSaveAddress();
+            String fileName = "new_cert_"+  uuid.substring(uuid.length()-4, uuid.length())+".p12";
+            boolean success = CertificateDigitalDatas.generatePKCS12Cert(ownerInfo, etPassword.getText(),
+                    saveDir, fileName);
+            if (success){
+                if (selectCertFileListener != null) {
+                    selectCertFileListener.certificateFile(new File(saveDir, fileName).getAbsolutePath(), etPassword.getText());
+                }
+            }
+        }
+    }
+
+
+    private void enableConfirmButton() {
+        String name = etName.getText();
+        String grantor = etGrantor.getText();
+        String sectoral = etSectoral.getText();
+        String email = etEmail.getText();
+        String countryArea = etCountryArea.getText();
+        boolean enable = !TextUtils.isEmpty(name) && !TextUtils.isEmpty(grantor)
+                && !TextUtils.isEmpty(sectoral) && !TextUtils.isEmpty(email) && !TextUtils.isEmpty(countryArea);
+        btnOk.setEnabled(enable);
+    }
+
+    private void showSaveStatusView() {
+        switcher.setInAnimation(getContext(), R.anim.tools_slide_in_right);
+        switcher.setOutAnimation(getContext(), R.anim.tools_slide_out_left);
+        switcher.showNext();
+    }
+
+    private void showInfoStatusView() {
+        switcher.setInAnimation(getContext(), R.anim.tools_slide_in_left);
+        switcher.setOutAnimation(getContext(), R.anim.tools_slide_out_right);
+        switcher.showPrevious();
+    }
+
+    private String getSaveAddress() {
+        if (!TextUtils.isEmpty(customSavePath)){
+            return customSavePath;
+        }
+        File file;
+        if (swContinuous.isChecked()) {
+            file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), CFileUtils.ROOT_FOLDER);
+        } else {
+            file = new File(getContext().getCacheDir(), CFileUtils.CACHE_FOLDER);
+        }
+        return file.getAbsolutePath();
+    }
+
+    public void setSelectCertFileListener(COnSelectCertFileListener selectCertFileListener) {
+        this.selectCertFileListener = selectCertFileListener;
+    }
+}

+ 273 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/dialog/preview/CDigitalSignStylePreviewDialog.java

@@ -0,0 +1,273 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ * <p>
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ */
+
+package com.compdfkit.tools.signature.dialog.preview;
+
+import android.app.Dialog;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.ScrollView;
+
+import androidx.activity.ComponentDialog;
+import androidx.activity.OnBackPressedCallback;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.widget.AppCompatButton;
+import androidx.appcompat.widget.AppCompatCheckBox;
+import androidx.appcompat.widget.AppCompatImageView;
+import androidx.appcompat.widget.AppCompatTextView;
+
+import com.compdfkit.tools.R;
+import com.compdfkit.tools.annotation.pdfproperties.pdfsignature.data.CSignatureDatas;
+import com.compdfkit.tools.common.utils.dialog.CDialogFragmentUtil;
+import com.compdfkit.tools.common.utils.viewutils.CViewUtils;
+import com.compdfkit.tools.common.views.CToolBar;
+import com.compdfkit.tools.signature.dialog.preview.view.CSignStylePositionView;
+import com.compdfkit.tools.signature.dialog.preview.view.CSignStyleReasonView;
+import com.compdfkit.tools.signature.pdfproperties.pdfsign.CDigitalSignStyleData;
+import com.compdfkit.tools.signature.pdfproperties.pdfsign.CDigitalSignStylePreviewView;
+import com.google.android.material.bottomsheet.BottomSheetBehavior;
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
+
+
+public class CDigitalSignStylePreviewDialog extends BottomSheetDialogFragment implements View.OnClickListener {
+
+    public static final String EXTRA_SIGN_IMAGE_PATH = "extra_sign_image_path";
+
+    private CDigitalSignStylePreviewView previewView;
+
+    private AppCompatTextView tvPosition;
+
+    private AppCompatTextView tvReason;
+
+    private AppCompatTextView tvPositionDesc;
+
+    private AppCompatTextView tvReasonDesc;
+
+    private CSignStylePositionView positionView;
+
+    private CSignStyleReasonView reasonView;
+
+    private AppCompatButton btnSave;
+
+    private CToolBar toolBar;
+
+    private ScrollView slMain;
+
+    private AppCompatCheckBox cbName;
+
+    private AppCompatCheckBox cbDate;
+
+    private AppCompatCheckBox cbLogo;
+
+    private AppCompatCheckBox cbDistinguishableName;
+
+    private AppCompatCheckBox cbSDKVersion;
+
+    private AppCompatCheckBox cbTab;
+
+    private OnBackPressedCallback callback;
+
+    private LinearLayout llAlignment;
+
+    private AppCompatTextView tvAlignment;
+
+    private AppCompatImageView ivAlignmentLeft;
+
+    private AppCompatImageView ivAlignmentRight;
+
+    private COnResultDigitalSignListener resultDigitalSignListener;
+
+    public static CDigitalSignStylePreviewDialog newInstance(String signImagePath) {
+        Bundle args = new Bundle();
+        args.putString(EXTRA_SIGN_IMAGE_PATH, signImagePath);
+        CDigitalSignStylePreviewDialog fragment = new CDigitalSignStylePreviewDialog();
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    @NonNull
+    @Override
+    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+        Dialog dialog = super.onCreateDialog(savedInstanceState);
+        if (dialog instanceof ComponentDialog) {
+            ComponentDialog componentDialog = (ComponentDialog) dialog;
+            callback = new OnBackPressedCallback(true) {
+                @Override
+                public void handleOnBackPressed() {
+                    toolBar.getIvToolBarBackBtn().performClick();
+                }
+            };
+            componentDialog.getOnBackPressedDispatcher().addCallback(callback);
+        }
+        return dialog;
+    }
+
+    @Override
+    public void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setStyle(STYLE_NORMAL, R.style.Tools_Base_Theme_BasicBottomSheetDialogStyle_TopCorners);
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        BottomSheetBehavior<View> behavior = BottomSheetBehavior.from((View) getView().getParent());
+        CDialogFragmentUtil.setBottomSheetDialogFragmentFullScreen(getDialog(), behavior);
+        CDialogFragmentUtil.setDimAmount(getDialog(), CViewUtils.isLandScape(getContext()) ? 0.2F : 0F);
+    }
+
+    @Nullable
+    @Override
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        View view = inflater.inflate(R.layout.tools_sign_style_preview_dialog, container, false);
+        previewView = view.findViewById(R.id.digital_sign_preview);
+        tvPosition = view.findViewById(R.id.tv_position);
+        tvReason = view.findViewById(R.id.tv_reason);
+        tvPositionDesc = view.findViewById(R.id.tv_position_desc);
+        tvReasonDesc = view.findViewById(R.id.tv_reason_desc);
+        toolBar = view.findViewById(R.id.tool_bar);
+        positionView = view.findViewById(R.id.view_position);
+        reasonView = view.findViewById(R.id.view_reason);
+        slMain = view.findViewById(R.id.sl_main);
+        btnSave = view.findViewById(R.id.btn_save);
+        cbName = view.findViewById(R.id.cb_name);
+        cbDate = view.findViewById(R.id.cb_date);
+        cbLogo = view.findViewById(R.id.cb_logo);
+        cbDistinguishableName = view.findViewById(R.id.cb_distinguishable_name);
+        cbSDKVersion = view.findViewById(R.id.cb_compdfkit_version);
+        cbTab = view.findViewById(R.id.cb_tab);
+        ivAlignmentLeft = view.findViewById(R.id.iv_alignment_left);
+        ivAlignmentRight = view.findViewById(R.id.iv_alignment_right);
+        llAlignment = view.findViewById(R.id.ll_alignment_type);
+        tvAlignment = view.findViewById(R.id.tv_alignment);
+        return view;
+    }
+
+    @Override
+    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+        initListener();
+        initData();
+    }
+
+    private void initListener(){
+        tvPosition.setOnClickListener(this);
+        tvReason.setOnClickListener(this);
+        toolBar.setBackBtnClickListener(this);
+        btnSave.setOnClickListener(this);
+        ivAlignmentLeft.setOnClickListener(this);
+        ivAlignmentRight.setOnClickListener(this);
+        positionView.setCheckedChangeListener((buttonView, isChecked) -> {
+            if (isChecked){
+                tvPositionDesc.setText(positionView.getPosition());
+                previewView.setPosition(positionView.getPosition());
+            }else {
+                tvPositionDesc.setText(R.string.tools_close);
+                previewView.setPosition("");
+            }
+        });
+        positionView.setTextChangedListener((s, start, before, count) -> {
+            if (positionView.isEnablePosition()){
+                tvPositionDesc.setText(s);
+                previewView.setPosition(TextUtils.isEmpty(s) ?"" : s.toString());
+            }
+        });
+        reasonView.setOnCheckedChangeListener((buttonView, isChecked) -> {
+            if (isChecked){
+                tvReasonDesc.setText(reasonView.getReason());
+                previewView.setReason(reasonView.getReason());
+            } else {
+                tvReasonDesc.setText(R.string.tools_close);
+                previewView.setReason("");
+            }
+        });
+        reasonView.setSelectReasonListener(reason -> {
+            if (reasonView.isEnableReason()){
+                tvReasonDesc.setText(reason);
+                previewView.setReason(reason);
+            }
+        });
+        cbTab.setOnCheckedChangeListener((buttonView, isChecked) -> previewView.showTab(isChecked));
+        cbName.setOnCheckedChangeListener((buttonView, isChecked) -> previewView.showName(isChecked));
+        cbDate.setOnCheckedChangeListener((buttonView, isChecked) -> previewView.showDate(isChecked));
+        cbDistinguishableName.setOnCheckedChangeListener((buttonView, isChecked) -> previewView.showDistinguishableName(isChecked));
+        cbSDKVersion.setOnCheckedChangeListener((buttonView, isChecked) -> previewView.showComPDFKitVersion(isChecked));
+        cbLogo.setOnCheckedChangeListener((buttonView, isChecked) -> previewView.showLogo(isChecked));
+    }
+
+    private void initData(){
+        String signImagePath = getArguments().getString(EXTRA_SIGN_IMAGE_PATH, "");
+        previewView.setPreviewData(CDigitalSignStyleData.defaultConfig(signImagePath));
+        ivAlignmentLeft.setSelected(true);
+        tvAlignment.setVisibility(TextUtils.isEmpty(signImagePath) ? View.GONE : View.VISIBLE);
+        llAlignment.setVisibility(TextUtils.isEmpty(signImagePath) ? View.GONE : View.VISIBLE);
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v.getId() == R.id.tv_position) {
+            positionView.setVisibility(View.VISIBLE);
+            slMain.setVisibility(View.GONE);
+        } else if (v.getId() == R.id.tv_reason) {
+            reasonView.setVisibility(View.VISIBLE);
+            slMain.setVisibility(View.GONE);
+        } else if (v.getId() == toolBar.getIvToolBarBackBtn().getId()){
+            if (positionView.getVisibility() == View.VISIBLE){
+                positionView.setVisibility(View.GONE);
+                slMain.setVisibility(View.VISIBLE);
+                return;
+            }
+            if (reasonView.getVisibility() == View.VISIBLE){
+                reasonView.setVisibility(View.GONE);
+                slMain.setVisibility(View.VISIBLE);
+                return;
+            }
+            dismiss();
+        } else if (v.getId() == R.id.iv_alignment_left) {
+            ivAlignmentLeft.setSelected(true);
+            ivAlignmentRight.setSelected(false);
+            previewView.setAlignment(CDigitalSignStylePreviewView.Alignment.left);
+        } else if (v.getId() == R.id.iv_alignment_right) {
+            ivAlignmentLeft.setSelected(false);
+            ivAlignmentRight.setSelected(true);
+            previewView.setAlignment(CDigitalSignStylePreviewView.Alignment.right);
+        } else if (v.getId() == R.id.btn_save){
+            if (positionView.getVisibility() == View.VISIBLE){
+                positionView.setVisibility(View.GONE);
+                slMain.setVisibility(View.VISIBLE);
+                return;
+            }
+            if (reasonView.getVisibility() == View.VISIBLE){
+                reasonView.setVisibility(View.GONE);
+                slMain.setVisibility(View.VISIBLE);
+                return;
+            }
+            Bitmap bitmap = previewView.getBitmap();
+            String imagePath = CSignatureDatas.saveSignatureBitmap(getContext(), bitmap);
+            if (resultDigitalSignListener != null) {
+                resultDigitalSignListener.sign(imagePath);
+            }
+            dismiss();
+        }
+    }
+
+    public void setResultDigitalSignListener(COnResultDigitalSignListener resultDigitalSignListener) {
+        this.resultDigitalSignListener = resultDigitalSignListener;
+    }
+
+    public interface COnResultDigitalSignListener{
+        void sign(String digitalSignImagePath);
+    }
+}

+ 94 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/dialog/preview/view/CSignStylePositionView.java

@@ -0,0 +1,94 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ * <p>
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ */
+
+package com.compdfkit.tools.signature.dialog.preview.view;
+
+import android.content.Context;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.CompoundButton;
+import android.widget.EditText;
+import android.widget.FrameLayout;
+import android.widget.RadioGroup;
+import android.widget.Switch;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.compdfkit.tools.R;
+import com.compdfkit.tools.common.interfaces.COnTextChangedListener;
+import com.compdfkit.tools.common.utils.view.CEditText;
+
+
+public class CSignStylePositionView extends FrameLayout {
+
+    private Switch swPosition;
+
+    private CEditText etPosition;
+
+    private View line;
+
+    private COnTextChangedListener textChangedListener;
+
+    private CompoundButton.OnCheckedChangeListener checkedChangeListener;
+
+    public CSignStylePositionView(@NonNull Context context) {
+        this(context, null);
+    }
+
+    public CSignStylePositionView(@NonNull Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public CSignStylePositionView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        initView(context);
+    }
+
+    private void initView(Context context) {
+        inflate(context, R.layout.tools_sign_style_preview_position, this);
+        line = findViewById(R.id.view_line);
+        swPosition = findViewById(R.id.sw_position);
+        etPosition = findViewById(R.id.et_position);
+        swPosition.setOnCheckedChangeListener((buttonView, isChecked) -> {
+            etPosition.setVisibility(isChecked ? VISIBLE : GONE);
+            line.setVisibility(isChecked ? VISIBLE : GONE);
+            if (!isChecked){
+                etPosition.setText("");
+            }
+            if (checkedChangeListener != null) {
+                checkedChangeListener.onCheckedChanged(buttonView, isChecked);
+            }
+        });
+        etPosition.addTextChangedListener((s, start, before, count) -> {
+            if (textChangedListener != null) {
+                textChangedListener.onTextChanged(s, start, before, count);
+            }
+        });
+    }
+
+    public boolean isEnablePosition() {
+        return swPosition.isChecked();
+    }
+
+    public String getPosition() {
+        return etPosition.getText();
+    }
+
+    public void setCheckedChangeListener(CompoundButton.OnCheckedChangeListener checkedChangeListener) {
+        this.checkedChangeListener = checkedChangeListener;
+    }
+
+    public void setTextChangedListener(COnTextChangedListener textChangedListener) {
+        this.textChangedListener = textChangedListener;
+    }
+}

+ 105 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/dialog/preview/view/CSignStyleReasonView.java

@@ -0,0 +1,105 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ *
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ */
+
+package com.compdfkit.tools.signature.dialog.preview.view;
+
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.CompoundButton;
+import android.widget.FrameLayout;
+import android.widget.RadioGroup;
+import android.widget.Switch;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.widget.AppCompatRadioButton;
+
+import com.compdfkit.tools.R;
+
+public class CSignStyleReasonView extends FrameLayout {
+
+    private Switch swReason;
+
+    private RadioGroup rgReason;
+
+    private View viewLine;
+
+    private CompoundButton.OnCheckedChangeListener onCheckedChangeListener;
+
+    private COnSelectReasonListener selectReasonListener;
+
+    private String selectReason;
+
+    public CSignStyleReasonView(@NonNull Context context) {
+        this(context, null);
+    }
+
+    public CSignStyleReasonView(@NonNull Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public CSignStyleReasonView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        initView(context);
+    }
+
+    private void initView(Context context){
+        inflate(context, R.layout.tools_sign_style_preview_reason, this);
+        swReason = findViewById(R.id.sw_reason);
+        rgReason = findViewById(R.id.rg_reason);
+        viewLine = findViewById(R.id.view_line);
+        swReason.setOnCheckedChangeListener((buttonView, isChecked) -> {
+            rgReason.setVisibility(isChecked ? VISIBLE : GONE);
+            viewLine.setVisibility(isChecked ? VISIBLE : GONE);
+            if (onCheckedChangeListener != null) {
+                onCheckedChangeListener.onCheckedChanged(buttonView, isChecked);
+            }
+        });
+        selectReason = context.getString(R.string.tools_i_am_the_owner_of_the_document);
+        rgReason.setOnCheckedChangeListener((group, checkedId) -> {
+            if (checkedId == R.id.rb_approving){
+                selectReason = context.getString(R.string.tools_i_am_approving_the_document);
+            } else if (checkedId == R.id.rb_have_reviewed) {
+                selectReason = context.getString(R.string.tools_i_have_reviewed_this_document);
+            } else if (checkedId == R.id.rb_owner) {
+                selectReason = context.getString(R.string.tools_i_am_the_owner_of_the_document);
+            } else if (checkedId == R.id.rb_none){
+                selectReason = context.getString(R.string.tools_none);
+            }
+            if (selectReasonListener != null) {
+                selectReasonListener.reason(selectReason);
+            }
+        });
+    }
+
+
+
+    public String getReason(){
+        return selectReason;
+    }
+
+    public boolean isEnableReason(){
+        return swReason.isChecked();
+    }
+
+    public void setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener onCheckedChangeListener) {
+        this.onCheckedChangeListener = onCheckedChangeListener;
+    }
+
+    public void setSelectReasonListener(COnSelectReasonListener selectReasonListener) {
+        this.selectReasonListener = selectReasonListener;
+    }
+
+    public interface COnSelectReasonListener{
+        void reason(String reason);
+    }
+}

+ 8 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/interfaces/COnSelectCertFileListener.java

@@ -0,0 +1,8 @@
+package com.compdfkit.tools.signature.interfaces;
+
+
+public interface COnSelectCertFileListener {
+
+    void certificateFile(String filePath, String password);
+
+}

+ 133 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/pdfproperties/pdfsign/CDigitalSignStyleData.java

@@ -0,0 +1,133 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ *
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ */
+
+package com.compdfkit.tools.signature.pdfproperties.pdfsign;
+
+
+import com.compdfkit.tools.common.utils.date.CDateUtil;
+
+public class CDigitalSignStyleData {
+
+
+    public CDigitalSignStyleData(){
+
+    }
+
+    public static CDigitalSignStyleData defaultConfig(String signImagePath){
+        CDigitalSignStyleData data = new CDigitalSignStyleData();
+        data.setShowLogo(true);
+        data.setSignImagePath(signImagePath);
+        data.setDate(CDateUtil.getDataTime(CDateUtil.NORMAL_DATE_FORMAT));
+        data.setName("long");
+        data.setTab(true);
+        data.setAlignment(CDigitalSignStylePreviewView.Alignment.left);
+        return data;
+    }
+
+    private String signImagePath;
+
+    private CDigitalSignStylePreviewView.Alignment alignment = CDigitalSignStylePreviewView.Alignment.left;
+
+    private String position;
+
+    private String reason;
+
+    private boolean tab;
+
+    private String name;
+
+    private String date;
+
+    private boolean showLogo;
+
+    private String digtinguishableName;
+
+    private String comPDFKitVersion;
+
+    public String getSignImagePath() {
+        return signImagePath;
+    }
+
+    public void setSignImagePath(String signImagePath) {
+        this.signImagePath = signImagePath;
+    }
+
+    public String getPosition() {
+        return position;
+    }
+
+    public void setPosition(String position) {
+        this.position = position;
+    }
+
+    public String getReason() {
+        return reason;
+    }
+
+    public void setReason(String reason) {
+        this.reason = reason;
+    }
+
+    public boolean isTab() {
+        return tab;
+    }
+
+    public void setTab(boolean tab) {
+        this.tab = tab;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDate() {
+        return date;
+    }
+
+    public void setDate(String date) {
+        this.date = date;
+    }
+
+    public boolean isShowLogo() {
+        return showLogo;
+    }
+
+    public void setShowLogo(boolean showLogo) {
+        this.showLogo = showLogo;
+    }
+
+    public String getDigtinguishableName() {
+        return digtinguishableName;
+    }
+
+    public void setDigtinguishableName(String digtinguishableName) {
+        this.digtinguishableName = digtinguishableName;
+    }
+
+    public String getComPDFKitVersion() {
+        return comPDFKitVersion;
+    }
+
+    public void setComPDFKitVersion(String comPDFKitVersion) {
+        this.comPDFKitVersion = comPDFKitVersion;
+    }
+
+
+    public void setAlignment(CDigitalSignStylePreviewView.Alignment alignment) {
+        this.alignment = alignment;
+    }
+
+    public CDigitalSignStylePreviewView.Alignment getAlignment() {
+        return alignment;
+    }
+}

+ 201 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/pdfproperties/pdfsign/CDigitalSignStylePreviewView.java

@@ -0,0 +1,201 @@
+package com.compdfkit.tools.signature.pdfproperties.pdfsign;
+
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.widget.FrameLayout;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.StringRes;
+import androidx.appcompat.widget.AppCompatImageView;
+import androidx.appcompat.widget.AppCompatTextView;
+import androidx.constraintlayout.widget.ConstraintLayout;
+import androidx.constraintlayout.widget.ConstraintSet;
+import androidx.transition.TransitionManager;
+
+import com.compdfkit.core.document.CPDFSdk;
+import com.compdfkit.tools.R;
+import com.compdfkit.tools.common.utils.date.CDateUtil;
+import com.compdfkit.tools.common.utils.glide.GlideApp;
+import com.compdfkit.tools.common.utils.image.CBitmapUtil;
+
+public class CDigitalSignStylePreviewView extends FrameLayout {
+
+    private AppCompatImageView ivSignImage;
+
+    private AppCompatTextView tvSignInfo;
+
+    private AppCompatImageView ivLogo;
+
+    private ConstraintLayout clPreview;
+
+    private CDigitalSignStyleData previewData;
+
+    private ConstraintLayout clRoot;
+
+    private ConstraintSet constraintSet = new ConstraintSet();
+
+    public CDigitalSignStylePreviewView(@NonNull Context context) {
+        this(context, null);
+    }
+
+    public CDigitalSignStylePreviewView(@NonNull Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public CDigitalSignStylePreviewView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        initView(context);
+    }
+
+    private void initView(Context context) {
+        inflate(context, R.layout.tools_sign_style_preview_view, this);
+        ivSignImage = findViewById(R.id.iv_sign);
+        tvSignInfo = findViewById(R.id.tv_sign_info);
+        ivLogo = findViewById(R.id.iv_logo);
+        clPreview = findViewById(R.id.cl_preview);
+        clRoot = findViewById(R.id.cl_root);
+        constraintSet.clone(clPreview);
+    }
+
+    public void setPreviewData(CDigitalSignStyleData data) {
+        previewData = data;
+        update();
+    }
+
+    private void setSignImage(String signImagePath) {
+        previewData.setSignImagePath(signImagePath);
+        update();
+    }
+
+    public void showName(boolean show) {
+        previewData.setName(show ? "long" : "");
+        update();
+    }
+
+    public void showTab(boolean show) {
+        previewData.setTab(show);
+        update();
+    }
+
+    public void showComPDFKitVersion(boolean show) {
+        previewData.setComPDFKitVersion(show ? CPDFSdk.getSDKVersion() : "");
+        update();
+    }
+
+    public void showDate(boolean show) {
+        previewData.setDate(show ? CDateUtil.getDataTime(CDateUtil.NORMAL_DATE_FORMAT) : "");
+        update();
+    }
+
+    public void showLogo(boolean show) {
+        previewData.setShowLogo(show);
+        update();
+    }
+
+    public void showDistinguishableName(boolean show) {
+        previewData.setDigtinguishableName(show ? "Digtinguishable" : "");
+        update();
+    }
+
+    public void setPosition(String position) {
+        previewData.setPosition(position);
+        update();
+    }
+
+    public void setReason(String reason) {
+        previewData.setReason(reason);
+        update();
+    }
+
+    public void setAlignment(Alignment alignment){
+        previewData.setAlignment(alignment);
+        update();
+        if (alignment == Alignment.left){
+            constraintSet.connect(R.id.iv_sign, ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START);
+            constraintSet.connect(R.id.iv_sign, ConstraintSet.END, R.id.tv_sign_info, ConstraintSet.START);
+            constraintSet.connect(R.id.tv_sign_info, ConstraintSet.START, R.id.iv_sign, ConstraintSet.END);
+            constraintSet.connect(R.id.tv_sign_info, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END);
+        }else {
+            constraintSet.connect(R.id.iv_sign, ConstraintSet.START, R.id.tv_sign_info, ConstraintSet.END);
+            constraintSet.connect(R.id.iv_sign, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END);
+            constraintSet.connect(R.id.tv_sign_info, ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START);
+            constraintSet.connect(R.id.tv_sign_info, ConstraintSet.END, R.id.iv_sign, ConstraintSet.START);
+        }
+        TransitionManager.beginDelayedTransition(clPreview);
+        constraintSet.applyTo(clPreview);
+    }
+
+    private void update() {
+        if (previewData != null) {
+            if (!TextUtils.isEmpty(previewData.getSignImagePath())) {
+                GlideApp.with(getContext())
+                        .load(previewData.getSignImagePath())
+                        .into(ivSignImage);
+            }
+            ivSignImage.setVisibility(TextUtils.isEmpty(previewData.getSignImagePath()) ? GONE : VISIBLE);
+            ivLogo.setVisibility(previewData.isShowLogo() ? VISIBLE : GONE);
+            StringBuilder builder = new StringBuilder();
+            appendData(builder, previewData.isTab(), R.string.tools_field_name, previewData.getName());
+            if (!TextUtils.isEmpty(previewData.getDigtinguishableName())){
+                builder.append("\n");
+            }
+            appendData(builder, previewData.isTab(), R.string.tools_distinguishable_name, previewData.getDigtinguishableName());
+            if (!TextUtils.isEmpty(previewData.getReason())){
+                builder.append("\n");
+            }
+            appendData(builder, previewData.isTab(), R.string.tools_reason, previewData.getReason());
+            if (!TextUtils.isEmpty(previewData.getPosition())){
+                builder.append("\n");
+            }
+            appendData(builder, previewData.isTab(), R.string.tools_position, previewData.getPosition());
+            if (!TextUtils.isEmpty(previewData.getDate())){
+                builder.append("\n");
+            }
+            appendData(builder, previewData.isTab(), R.string.tools_date, previewData.getDate());
+            if (!TextUtils.isEmpty(previewData.getComPDFKitVersion())){
+                builder.append("\n");
+            }
+            appendData(builder, previewData.isTab(), R.string.tools_compdfkit_versions, previewData.getComPDFKitVersion());
+            tvSignInfo.setText(builder);
+            if (previewData.getAlignment() == Alignment.left) {
+                tvSignInfo.setGravity(Gravity.CENTER_VERTICAL | Gravity.START);
+            }else {
+                tvSignInfo.setGravity(Gravity.CENTER_VERTICAL | Gravity.END);
+            }
+
+        }
+    }
+
+
+
+    private void appendData(StringBuilder builder, boolean showTab, @StringRes int tabStringResId, String value) {
+        if (!TextUtils.isEmpty(value)) {
+            if (showTab) {
+                builder.append(getString(tabStringResId)).append(": ");
+            }
+            builder.append(value);
+        }
+    }
+
+    private String getString(@StringRes int stringResId) {
+        return getContext().getString(stringResId);
+    }
+
+    public Bitmap getBitmap(){
+        buildDrawingCache();
+        Bitmap bitmap = Bitmap.createBitmap(getDrawingCache());
+        Bitmap resultBitmap = CBitmapUtil.cropTransparent(bitmap);
+        return resultBitmap;
+    }
+
+    public enum Alignment {
+        left,
+        right
+    }
+
+}

+ 50 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/pdfproperties/pdfsign/CDigitalSignatureWidgetImpl.java

@@ -0,0 +1,50 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ * <p>
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ */
+
+package com.compdfkit.tools.signature.pdfproperties.pdfsign;
+
+import android.graphics.Bitmap;
+
+import androidx.fragment.app.FragmentActivity;
+
+import com.compdfkit.core.annotation.CPDFImageScaleType;
+import com.compdfkit.core.annotation.form.CPDFSignatureWidget;
+import com.compdfkit.tools.common.utils.image.CBitmapUtil;
+import com.compdfkit.tools.signature.dialog.CPDFSelectDigitalSignatureDialog;
+import com.compdfkit.tools.signature.dialog.preview.CDigitalSignStylePreviewDialog;
+import com.compdfkit.tools.signature.interfaces.COnSelectCertFileListener;
+import com.compdfkit.ui.proxy.form.CPDFSignatureWidgetImpl;
+
+
+public class CDigitalSignatureWidgetImpl extends CPDFSignatureWidgetImpl {
+
+    @Override
+    public void onSignatureWidgetFocused(CPDFSignatureWidget cpdfSignatureWidget) {
+        CPDFSelectDigitalSignatureDialog dialog = CPDFSelectDigitalSignatureDialog.newInstance();
+        dialog.setCertDigitalSignListener((certFilePath, certPassword, signImagePath) -> {
+            CDigitalSignStylePreviewDialog previewDialog = CDigitalSignStylePreviewDialog.newInstance(signImagePath);
+            previewDialog.setResultDigitalSignListener(digitalSignImagePath -> {
+                try {
+                    Bitmap bitmap = CBitmapUtil.decodeBitmap(digitalSignImagePath);
+                    ((CPDFSignatureWidget) pdfAnnotation).updateApWithBitmap(bitmap, CPDFImageScaleType.SCALETYPE_fitCenter);
+                    refresh();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+                dialog.dismiss();
+            });
+            if (readerView.getContext() instanceof FragmentActivity) {
+                previewDialog.show(((FragmentActivity) readerView.getContext()).getSupportFragmentManager(), "digitalSignPreviewDialog");
+            }
+        });
+        if (readerView.getContext() instanceof FragmentActivity) {
+            dialog.show(((FragmentActivity) readerView.getContext()).getSupportFragmentManager(), "styleDialog");
+        }
+    }
+}

+ 7 - 0
ComPDFKit_Tools/src/main/res/anim/tools_slide_in_left.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <translate android:fromXDelta="-50%p" android:toXDelta="0"
+        android:duration="@android:integer/config_mediumAnimTime"/>
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+        android:duration="@android:integer/config_mediumAnimTime" />
+</set>

+ 7 - 0
ComPDFKit_Tools/src/main/res/anim/tools_slide_out_right.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <translate android:fromXDelta="0" android:toXDelta="100%p"
+        android:duration="@android:integer/config_mediumAnimTime"/>
+    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+        android:duration="@android:integer/config_mediumAnimTime" />
+</set>

+ 9 - 0
ComPDFKit_Tools/src/main/res/drawable/tools_bg_import_certificate_digital_id_error_item.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item >
+        <shape >
+            <solid android:color="@color/tools_text_color_primary_inverse"/>
+            <stroke android:color="@color/tools_error" android:width="2dp"/>
+        </shape>
+    </item>
+</selector>

+ 15 - 0
ComPDFKit_Tools/src/main/res/drawable/tools_bg_import_certificate_digital_id_item.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_focused="true">
+        <shape >
+            <solid android:color="@color/tools_text_color_primary_inverse"/>
+            <stroke android:color="@color/tools_color_accent" android:width="2dp"/>
+        </shape>
+    </item>
+    <item >
+        <shape >
+            <solid android:color="@color/tools_text_color_primary_inverse"/>
+            <stroke android:color="@color/tools_item_dividing_line_color" android:width="1px"/>
+        </shape>
+    </item>
+</selector>

+ 23 - 0
ComPDFKit_Tools/src/main/res/drawable/tools_ic_compdfkit_logo.xml

@@ -0,0 +1,23 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="60dp"
+    android:height="61dp"
+    android:viewportWidth="60"
+    android:viewportHeight="61">
+  <path
+      android:pathData="M0,5.417C0,2.577 2.303,0.274 5.143,0.274H41.143C43.983,0.274 46.286,2.577 46.286,5.417V49.131H5.143C2.303,49.131 0,46.829 0,43.988V5.417Z"
+      android:strokeAlpha="0.4"
+      android:fillColor="#3863F1"
+      android:fillAlpha="0.4"/>
+  <path
+      android:pathData="M32.572,11.417C22.157,11.417 13.715,19.86 13.715,30.274C13.715,40.688 22.157,49.131 32.572,49.131H46.286V11.417H32.572ZM32.572,23.417C28.785,23.417 25.715,26.487 25.715,30.274C25.715,34.061 28.785,37.131 32.572,37.131H46.286V23.417H32.572Z"
+      android:strokeAlpha="0.4"
+      android:fillColor="#ffffff"
+      android:fillType="evenOdd"
+      android:fillAlpha="1"/>
+  <path
+      android:pathData="M13.715,32.721C13.715,32.763 13.715,32.804 13.715,32.846V49.131V55.131C13.715,57.971 16.017,60.274 18.858,60.274H54.858C57.698,60.274 60,57.971 60,55.131V16.56C60,13.719 57.698,11.417 54.858,11.417H35.143C35.11,11.417 35.077,11.417 35.044,11.417H46.286V49.131H13.715V32.721ZM25.715,30.274C25.715,26.487 28.785,23.417 32.572,23.417H46.286V37.131H32.572C28.785,37.131 25.715,34.061 25.715,30.274Z"
+      android:strokeAlpha="0.4"
+      android:fillColor="#31BC98"
+      android:fillType="evenOdd"
+      android:fillAlpha="0.4"/>
+</vector>

+ 13 - 0
ComPDFKit_Tools/src/main/res/drawable/tools_ic_dark_oval_close.xml

@@ -0,0 +1,13 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="21dp"
+    android:height="20dp"
+    android:viewportWidth="21"
+    android:viewportHeight="20">
+  <path
+      android:pathData="M10.5,10m0,9a9,9 0,1 1,0 -18a9,9 0,1 1,0 18"
+      android:fillColor="#666666"/>
+  <path
+      android:pathData="M9.616,9.911L5.639,13.889L6.523,14.773L10.5,10.795L14.477,14.773L15.361,13.889L11.384,9.911L15.361,5.934L14.477,5.05L10.5,9.027L6.523,5.05L5.639,5.934L9.616,9.911Z"
+      android:fillColor="#ffffff"
+      android:fillType="evenOdd"/>
+</vector>

+ 7 - 0
ComPDFKit_Tools/src/main/res/drawable/tools_ic_digital_sign_checkbox.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/tools_ic_digital_sign_checkbox_select" android:state_checked="true"/>
+    <item android:drawable="@drawable/tools_ic_digital_sign_checkbox_normal" android:state_checked="false"/>
+
+    <item android:drawable="@drawable/tools_ic_digital_sign_checkbox_normal"/>
+</selector>

+ 15 - 0
ComPDFKit_Tools/src/main/res/drawable/tools_ic_digital_sign_checkbox_normal.xml

@@ -0,0 +1,15 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="20dp"
+    android:height="20dp"
+    android:viewportWidth="20"
+    android:viewportHeight="20">
+  <group>
+    <clip-path
+        android:pathData="M1,0L19,0A1,1 0,0 1,20 1L20,19A1,1 0,0 1,19 20L1,20A1,1 0,0 1,0 19L0,1A1,1 0,0 1,1 0z"/>
+    <path
+        android:pathData="M1,0L19,0A1,1 0,0 1,20 1L20,19A1,1 0,0 1,19 20L1,20A1,1 0,0 1,0 19L0,1A1,1 0,0 1,1 0z"
+        android:strokeWidth="3"
+        android:fillColor="#ffffff"
+        android:strokeColor="#D9D9D9"/>
+  </group>
+</vector>

+ 15 - 0
ComPDFKit_Tools/src/main/res/drawable/tools_ic_digital_sign_checkbox_select.xml

@@ -0,0 +1,15 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="20dp"
+    android:height="20dp"
+    android:viewportWidth="20"
+    android:viewportHeight="20">
+  <path
+      android:pathData="M1,0L19,0A1,1 0,0 1,20 1L20,19A1,1 0,0 1,19 20L1,20A1,1 0,0 1,0 19L0,1A1,1 0,0 1,1 0z"
+      android:fillColor="#2D77FA"/>
+  <path
+      android:pathData="M14.683,7.541L8.352,13.872L6.004,11.524"
+      android:strokeWidth="1.5"
+      android:fillColor="#00000000"
+      android:strokeColor="#ffffff"
+      android:strokeLineCap="square"/>
+</vector>

File diff suppressed because it is too large
+ 10 - 0
ComPDFKit_Tools/src/main/res/drawable/tools_ic_digital_signature.xml


File diff suppressed because it is too large
+ 27 - 0
ComPDFKit_Tools/src/main/res/drawable/tools_ic_import_digital_signature.xml


+ 10 - 0
ComPDFKit_Tools/src/main/res/drawable/tools_ic_sign_none.xml

@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:pathData="M18.5,12C18.5,15.59 15.59,18.5 12,18.5C8.41,18.5 5.5,15.59 5.5,12C5.5,8.41 8.41,5.5 12,5.5C15.59,5.5 18.5,8.41 18.5,12ZM20,12C20,16.418 16.418,20 12,20C7.582,20 4,16.418 4,12C4,7.582 7.582,4 12,4C16.418,4 20,7.582 20,12ZM15.705,9.8C15.998,9.508 15.998,9.033 15.705,8.74C15.412,8.447 14.937,8.447 14.644,8.74L8.359,15.025C8.066,15.318 8.066,15.793 8.359,16.086C8.651,16.379 9.126,16.379 9.419,16.086L15.705,9.8Z"
+      android:fillColor="#43474D"
+      android:fillType="evenOdd"/>
+</vector>

+ 5 - 0
ComPDFKit_Tools/src/main/res/drawable/tools_import_certificate_digital_id_btn.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/tools_color_accent"/>
+    <corners android:radius="2dp"/>
+</shape>

+ 19 - 0
ComPDFKit_Tools/src/main/res/drawable/tools_signature_toolbar_btn_corner_status_bg.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item android:state_selected="true">
+        <shape android:shape="rectangle">
+            <corners android:radius="4dp" />
+            <solid android:color="@color/tools_annot_list_item_select_bg_color" />
+        </shape>
+    </item>
+
+    <item>
+        <shape android:shape="rectangle">
+            <corners android:radius="4dp" />
+            <solid android:color="@color/tools_color_primary" />
+        </shape>
+    </item>
+
+
+</selector>

+ 16 - 0
ComPDFKit_Tools/src/main/res/layout-land/tools_properties_signature_style_add_activity.xml

@@ -83,6 +83,22 @@
             app:layout_constraintTop_toTopOf="@id/iv_add_draw_signature"
             app:srcCompat="@drawable/tools_ic_annotation_pic" />
 
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/iv_none"
+            android:layout_width="38dp"
+            android:layout_height="38dp"
+            android:layout_marginStart="12dp"
+            android:background="@drawable/tools_annot_properties_signature_type_btn_bg"
+            android:foreground="@drawable/tools_common_btn_corner_ripple"
+            android:padding="4dp"
+            app:tint="@color/tools_icon_status_color"
+            app:layout_constraintBottom_toBottomOf="@id/iv_add_draw_signature"
+            app:layout_constraintStart_toEndOf="@id/iv_add_pic_signature"
+            app:layout_constraintTop_toTopOf="@id/iv_add_draw_signature"
+            android:visibility="gone"
+            tools:visibility="visible"
+            app:srcCompat="@drawable/tools_ic_sign_none" />
+
         <com.compdfkit.tools.common.views.pdfproperties.colorlist.ColorListView
             android:id="@+id/color_list_view"
             android:layout_width="200dp"

+ 0 - 1
ComPDFKit_Tools/src/main/res/layout/tools_dialog_tool_bar.xml

@@ -22,7 +22,6 @@
         app:layout_constraintTop_toTopOf="parent"
         tools:text="Tools" />
 
-
     <androidx.appcompat.widget.AppCompatImageView
         android:id="@+id/iv_tool_bar_previous"
         android:layout_width="30dp"

+ 39 - 0
ComPDFKit_Tools/src/main/res/layout/tools_layout_c_edit_text.xml

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_marginHorizontal="16dp">
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        tools:text="@tools:sample/first_names"
+        android:textColor="@color/tools_text_color_disable"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+
+    <androidx.appcompat.widget.AppCompatEditText
+        android:id="@+id/edit_text"
+        android:layout_width="match_parent"
+        android:layout_height="40dp"
+        android:layout_marginTop="8dp"
+        android:background="@drawable/tools_bg_import_certificate_digital_id_item"
+        android:ellipsize="end"
+        android:paddingHorizontal="8dp"
+        android:singleLine="true"
+        android:textColor="@color/tools_text_color_primary"
+        android:textSize="14sp"
+        app:drawableTint="@color/tools_text_color_primary"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_title"
+        app:layout_goneMarginTop="0dp"
+         />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
+

+ 9 - 0
ComPDFKit_Tools/src/main/res/layout/tools_pdf_mode_switch_dialog_fragment.xml

@@ -62,6 +62,15 @@
             tools:visibility="visible"
             android:drawableStart="@drawable/tools_page_edit"
             android:text="@string/tools_page_edit_mode" />
+
+        <androidx.appcompat.widget.AppCompatRadioButton
+            android:id="@+id/r_btn_signature_mode"
+            style="@style/tools_pdf_reader_mode_radio_button_style"
+            android:layout_height="60dp"
+            android:visibility="gone"
+            tools:visibility="visible"
+            android:drawableStart="@drawable/tools_ic_digital_signature"
+            android:text="@string/tools_signatures" />
     </RadioGroup>
 
 

+ 17 - 0
ComPDFKit_Tools/src/main/res/layout/tools_properties_signature_style_add_activity.xml

@@ -84,6 +84,23 @@
             app:layout_constraintTop_toTopOf="@id/iv_add_draw_signature"
             app:srcCompat="@drawable/tools_ic_annotation_pic" />
 
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/iv_none"
+            android:layout_width="38dp"
+            android:layout_height="38dp"
+            android:layout_marginStart="12dp"
+            android:background="@drawable/tools_annot_properties_signature_type_btn_bg"
+            android:foreground="@drawable/tools_common_btn_corner_ripple"
+            android:padding="4dp"
+            app:tint="@color/tools_icon_status_color"
+            app:layout_constraintBottom_toBottomOf="@id/iv_add_draw_signature"
+            app:layout_constraintStart_toEndOf="@id/iv_add_pic_signature"
+            app:layout_constraintTop_toTopOf="@id/iv_add_draw_signature"
+            android:visibility="gone"
+            tools:visibility="visible"
+            app:srcCompat="@drawable/tools_ic_sign_none" />
+
+
         <com.compdfkit.tools.common.views.pdfproperties.colorlist.ColorListView
             android:id="@+id/color_list_view"
             android:layout_width="0dp"

+ 41 - 0
ComPDFKit_Tools/src/main/res/layout/tools_sign_create_cert_digital_id_fragment.xml

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@drawable/tools_annot_style_dialog_window_bg">
+
+    <include
+        android:id="@+id/tool_bar"
+        layout="@layout/tools_dialog_tool_bar" />
+
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:fillViewport="true"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tool_bar">
+
+        <ViewSwitcher
+            android:id="@+id/view_switcher"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:inAnimation="@anim/tools_slide_in_right"
+            android:outAnimation="@anim/tools_slide_out_left">
+
+            <include
+                layout="@layout/tools_sign_create_cert_digital_id_info_layout"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent" />
+
+            <include
+                layout="@layout/tools_sign_create_cert_digital_id_save_layout"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent" />
+        </ViewSwitcher>
+    </ScrollView>
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 109 - 0
ComPDFKit_Tools/src/main/res/layout/tools_sign_create_cert_digital_id_info_layout.xml

@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_import_desc"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginHorizontal="16dp"
+        android:layout_marginTop="16dp"
+        android:background="@color/tools_reader_setting_head_bg_color"
+        android:lineSpacingMultiplier="1.25"
+        android:padding="16dp"
+        android:text="@string/tools_create_certificate_digital_id_desc"
+        android:textColor="@color/tools_text_color_primary"
+        android:textSize="12sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <androidx.constraintlayout.helper.widget.Flow
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        app:constraint_referenced_ids="et_name,et_grantor,et_sectoral,et_email,et_country_area"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_import_desc" />
+
+    <com.compdfkit.tools.common.utils.view.CEditText
+        android:id="@+id/et_name"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:imeOptions="actionNext"
+        android:title="@string/tools_field_name" />
+
+    <com.compdfkit.tools.common.utils.view.CEditText
+        android:id="@+id/et_grantor"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:imeOptions="actionNext"
+        android:title="@string/tools_grantor" />
+
+    <com.compdfkit.tools.common.utils.view.CEditText
+        android:id="@+id/et_sectoral"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:imeOptions="actionNext"
+
+        android:title="@string/tools_sectoral" />
+
+    <com.compdfkit.tools.common.utils.view.CEditText
+        android:id="@+id/et_email"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:imeOptions="actionNext"
+
+        android:title="@string/tools_email" />
+
+    <com.compdfkit.tools.common.utils.view.CEditText
+        android:id="@+id/et_country_area"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:imeOptions="actionDone"
+        android:title="@string/tools_country_area" />
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_continuous"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="16dp"
+        android:layout_marginTop="24dp"
+        android:text="@string/tools_continuous_page_flip"
+        android:textColor="@color/tools_text_color_disable"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/et_country_area" />
+
+    <Switch
+        android:id="@+id/sw_continuous"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:checked="true"
+        android:layout_marginEnd="16dp"
+        app:layout_constraintBottom_toBottomOf="@id/tv_continuous"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="@id/tv_continuous" />
+
+    <androidx.appcompat.widget.AppCompatButton
+        android:id="@+id/btn_ok"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginHorizontal="16dp"
+        android:layout_marginTop="10dp"
+        android:layout_marginBottom="32dp"
+        android:background="@drawable/tools_verify_pwd_confirm_btn_bg"
+        android:elevation="0dp"
+        android:text="@string/tools_okay"
+        android:textColor="@android:color/white"
+        android:textSize="16sp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_continuous"
+        app:layout_constraintVertical_bias="1" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
+

+ 115 - 0
ComPDFKit_Tools/src/main/res/layout/tools_sign_create_cert_digital_id_save_layout.xml

@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    xmlns:tools="http://schemas.android.com/tools">
+
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_save_desc"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginHorizontal="16dp"
+        android:layout_marginTop="16dp"
+        android:background="@color/tools_reader_setting_head_bg_color"
+        android:lineSpacingMultiplier="1.25"
+        android:padding="16dp"
+        android:text="@string/tools_certificate_digital_id_save_info"
+        android:textColor="@color/tools_text_color_primary"
+        android:textSize="12sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <androidx.constraintlayout.helper.widget.Flow
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        app:constraint_referenced_ids="ll_save_address,et_password,et_confirm_password"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        android:layout_marginTop="16dp"
+        android:layout_marginHorizontal="16dp"
+        app:layout_constraintTop_toBottomOf="@id/tv_save_desc" />
+
+
+    <LinearLayout
+        android:id="@+id/ll_save_address"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        android:layout_marginHorizontal="16dp"
+        android:orientation="vertical">
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_save_address_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/tools_save_address"
+            android:textColor="@color/tools_text_color_disable"
+            app:layout_constraintStart_toStartOf="@id/tv_save_desc"
+            />
+
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_save_address"
+            android:layout_width="match_parent"
+            android:layout_height="40dp"
+            android:layout_marginTop="8dp"
+            android:background="@drawable/tools_bg_import_certificate_digital_id_item"
+            android:paddingHorizontal="8dp"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            android:textColor="@color/tools_text_color_primary"
+            android:textSize="14sp"
+            android:singleLine="true"
+            android:ellipsize="start"
+            android:gravity="center_vertical"
+            tools:text="Document/compdfkit"
+            android:foreground="@drawable/tools_common_btn_rectangle_ripple"
+            />
+
+    </LinearLayout>
+
+
+
+    <com.compdfkit.tools.common.utils.view.CEditText
+        android:id="@+id/et_password"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:imeOptions="actionNext"
+        android:inputType="textPassword"
+        android:title="@string/tools_document_password" />
+
+    <com.compdfkit.tools.common.utils.view.CEditText
+        android:id="@+id/et_confirm_password"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:imeOptions="actionDone"
+        android:inputType="textPassword"
+        android:title="@string/tools_confirm_password" />
+
+
+    <androidx.appcompat.widget.AppCompatButton
+        android:id="@+id/btn_save"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginHorizontal="16dp"
+        android:layout_marginTop="10dp"
+        android:layout_marginBottom="32dp"
+        android:background="@drawable/tools_verify_pwd_confirm_btn_bg"
+        android:elevation="0dp"
+        android:text="@string/tools_okay"
+        android:textColor="@android:color/white"
+        android:textSize="16sp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/et_confirm_password"
+        app:layout_constraintVertical_bias="1" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
+
+
+

+ 93 - 0
ComPDFKit_Tools/src/main/res/layout/tools_sign_digital_sign_select_dialog.xml

@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="@dimen/tools_dialog_layout_width"
+        android:layout_height="wrap_content"
+        android:paddingTop="24dp"
+        android:paddingBottom="8dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_title"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center_vertical"
+            android:layout_marginHorizontal="24dp"
+            android:textColor="@color/tools_text_color_primary"
+            app:layout_constraintEnd_toEndOf="parent"
+            android:textSize="16sp"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            android:text="@string/tools_select_digital_signatures" />
+
+
+        <RadioGroup
+            android:id="@+id/rg_type"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="8dp"
+            android:layout_marginHorizontal="24dp"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/tv_title"
+            app:layout_constraintStart_toStartOf="parent"
+             >
+
+            <androidx.appcompat.widget.AppCompatRadioButton
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:id="@+id/rb_import_digital_sign"
+                android:checked="true"
+                android:textColor="@color/tools_text_color_primary"
+                android:text="@string/tools_import_certificate_digital_id"
+                />
+
+            <androidx.appcompat.widget.AppCompatRadioButton
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:id="@+id/rb_new_digital_sign"
+                android:layout_marginTop="8dp"
+                android:textColor="@color/tools_text_color_primary"
+
+                android:text="@string/tools_new_certificate_digital_id"
+                />
+
+        </RadioGroup>
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="end"
+            android:layout_marginTop="12dp"
+            android:orientation="horizontal"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/rg_type">
+
+            <Button
+                android:id="@+id/btn_cancel"
+                style="@style/tools_dialog_button_style"
+                android:background="@drawable/tools_common_btn_corner_ripple"
+                android:text="@string/tools_cancel"
+                tools:textColor="@color/tools_normal_btn_text_color" />
+
+            <Button
+                android:id="@+id/btn_confirm"
+                style="@style/tools_dialog_button_style"
+                android:background="@drawable/tools_common_btn_corner_ripple"
+                android:text="@string/tools_page_edit_toolbar_done"
+                tools:textColor="@color/tools_normal_btn_text_color" />
+
+        </LinearLayout>
+
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 153 - 0
ComPDFKit_Tools/src/main/res/layout/tools_sign_import_certificate_digital_id_fragment.xml

@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:background="@drawable/tools_annot_style_dialog_window_bg"
+    android:layout_height="match_parent">
+
+    <include
+        android:id="@+id/tool_bar"
+        layout="@layout/tools_dialog_tool_bar" />
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_import_desc"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginHorizontal="16dp"
+        android:layout_marginTop="16dp"
+        android:background="@color/tools_reader_setting_head_bg_color"
+        android:lineSpacingMultiplier="1.25"
+        android:padding="16dp"
+        android:text="@string/tools_import_digital_desc"
+        android:textColor="@color/tools_text_color_primary"
+        android:textSize="12sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tool_bar" />
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_certification"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="16dp"
+        android:layout_marginTop="16dp"
+        android:text="@string/tools_certification_documents"
+        android:textColor="@color/tools_text_color_disable"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_import_desc" />
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl_certificate"
+        android:layout_width="match_parent"
+        android:layout_height="40dp"
+        android:layout_marginHorizontal="16dp"
+        android:layout_marginTop="8dp"
+        android:background="@drawable/tools_bg_import_certificate_digital_id_item"
+        android:foreground="@drawable/tools_common_btn_rectangle_ripple"
+        app:layout_constraintTop_toBottomOf="@id/tv_certification">
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_certificate"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="8dp"
+            android:layout_marginEnd="8dp"
+            android:drawableRight="@drawable/tools_ic_right_arrow"
+            android:ellipsize="end"
+            android:maxLines="1"
+            android:gravity="center_vertical"
+            android:textColor="@color/tools_text_color_primary"
+            android:textSize="14sp"
+            app:drawableTint="@color/tools_text_color_primary"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            tools:text="Test Certificate digital id.p12" />
+
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_certificate_password"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="16dp"
+        android:layout_marginTop="16dp"
+        android:text="@string/tools_certificate_password"
+        android:textColor="@color/tools_text_color_disable"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/cl_certificate" />
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl_certificate_password"
+        android:layout_width="match_parent"
+        android:layout_height="40dp"
+        android:layout_marginHorizontal="16dp"
+        android:layout_marginTop="8dp"
+        app:layout_constraintTop_toBottomOf="@id/tv_certificate_password">
+
+        <androidx.appcompat.widget.AppCompatEditText
+            android:id="@+id/et_password"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:paddingHorizontal="8dp"
+            android:background="@drawable/tools_bg_import_certificate_digital_id_item"
+            android:ellipsize="end"
+            android:inputType="textPassword"
+            android:maxLines="1"
+            android:textColor="@color/tools_text_color_primary"
+            android:textSize="14sp"
+            android:imeOptions="actionDone"
+            app:drawableTint="@color/tools_text_color_primary"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            tools:text="Test Certificate digital id.p12" />
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/iv_remove_password"
+            android:layout_width="40dp"
+            android:layout_height="40dp"
+            android:background="@drawable/tools_common_oval_ripple"
+            android:padding="10dp"
+            android:visibility="gone"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:srcCompat="@drawable/tools_ic_dark_oval_close"
+            tools:visibility="visible" />
+
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_password_error"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:text="@string/tools_wrong_password"
+        android:textColor="@color/tools_error"
+        android:visibility="gone"
+        tools:visibility="visible"
+        app:layout_constraintStart_toStartOf="@id/cl_certificate_password"
+        app:layout_constraintTop_toBottomOf="@id/cl_certificate_password" />
+
+    <androidx.appcompat.widget.AppCompatButton
+        android:id="@+id/btn_ok"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginHorizontal="16dp"
+        android:layout_marginBottom="48dp"
+        android:background="@drawable/tools_verify_pwd_confirm_btn_bg"
+        android:elevation="0dp"
+        android:text="@string/tools_okay"
+        android:textColor="@android:color/white"
+        android:textSize="16sp"
+        android:enabled="false"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_password_error"
+        app:layout_constraintVertical_bias="1" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 59 - 0
ComPDFKit_Tools/src/main/res/layout/tools_sign_style_preview_dialog.xml

@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/tools_style_content_bg">
+
+    <com.compdfkit.tools.common.views.CToolBar
+        android:id="@+id/tool_bar"
+        android:layout_width="match_parent"
+        android:layout_height="?android:attr/actionBarSize"
+        android:elevation="4dp"
+        android:title="@string/tools_add_signatures"
+        app:layout_constraintTop_toTopOf="parent"
+        app:tools_toolbar_back_icon="@drawable/tools_ic_back">
+
+        <androidx.appcompat.widget.AppCompatButton
+            android:id="@+id/btn_save"
+            android:layout_width="wrap_content"
+            android:layout_height="32dp"
+            android:layout_gravity="end|center_vertical"
+            android:layout_marginEnd="16dp"
+            android:background="@drawable/tools_properties_signature_add_sign"
+            android:minWidth="70dp"
+            android:text="@string/tools_save"
+            android:textColor="@color/tools_color_accent"
+            android:textSize="16sp" />
+
+    </com.compdfkit.tools.common.views.CToolBar>
+
+
+    <include
+        android:id="@+id/sl_main"
+        layout="@layout/tools_sign_style_preview_main"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:layout_constraintTop_toBottomOf="@id/tool_bar" />
+
+    <com.compdfkit.tools.signature.dialog.preview.view.CSignStylePositionView
+        android:id="@+id/view_position"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:visibility="gone"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tool_bar" />
+
+    <com.compdfkit.tools.signature.dialog.preview.view.CSignStyleReasonView
+        android:id="@+id/view_reason"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:visibility="gone"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tool_bar" />
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 224 - 0
ComPDFKit_Tools/src/main/res/layout/tools_sign_style_preview_main.xml

@@ -0,0 +1,224 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+
+
+        <com.compdfkit.tools.signature.pdfproperties.pdfsign.CDigitalSignStylePreviewView
+            android:id="@+id/digital_sign_preview"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_margin="16dp"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_text_signature"
+            android:layout_width="match_parent"
+            android:layout_height="28dp"
+            android:layout_marginTop="16dp"
+            android:background="@color/tools_reader_setting_head_bg_color"
+            android:gravity="center_vertical"
+            android:paddingStart="16dp"
+            android:paddingEnd="16dp"
+            android:text="@string/tools_text_signature"
+            android:textColor="@color/tools_text_color_primary"
+            android:textSize="12sp"
+            app:layout_constraintTop_toBottomOf="@id/digital_sign_preview" />
+
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_alignment"
+            android:layout_width="match_parent"
+            android:layout_height="48dp"
+            android:background="@drawable/tools_common_btn_rectangle_ripple"
+            android:gravity="center_vertical"
+            android:paddingStart="16dp"
+            android:paddingEnd="16dp"
+            android:text="@string/tools_annot_align_type"
+            android:textColor="@color/tools_text_color_primary"
+            app:layout_constraintTop_toBottomOf="@id/tv_text_signature" />
+
+
+        <LinearLayout
+            android:id="@+id/ll_alignment_type"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="24dp"
+            android:background="@drawable/tools_annotation_font_alignment_root_bg"
+            android:orientation="horizontal"
+            app:layout_constraintBottom_toBottomOf="@id/tv_alignment"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="@id/tv_alignment">
+
+            <androidx.appcompat.widget.AppCompatImageView
+                android:id="@+id/iv_alignment_left"
+                android:layout_width="49dp"
+                android:layout_height="32dp"
+                android:background="@drawable/tools_annotation_font_alignment_bg"
+                android:button="@null"
+                android:padding="4dp"
+                android:textSize="0sp"
+                app:srcCompat="@drawable/tools_font_alignment_left"
+                app:tint="@color/tools_font_style_iv_color" />
+
+            <androidx.appcompat.widget.AppCompatImageView
+                android:id="@+id/iv_alignment_right"
+                android:layout_width="49dp"
+                android:layout_height="32dp"
+                android:background="@drawable/tools_annotation_font_alignment_bg"
+                android:padding="4dp"
+                app:srcCompat="@drawable/tools_font_alignment_right"
+                app:tint="@color/tools_font_style_iv_color" />
+
+        </LinearLayout>
+
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_position"
+            android:layout_width="match_parent"
+            android:layout_height="48dp"
+            android:background="@drawable/tools_common_btn_rectangle_ripple"
+            android:drawableEnd="@drawable/tools_ic_right_arrow"
+            android:gravity="center_vertical"
+            android:paddingStart="16dp"
+            android:paddingEnd="16dp"
+            android:text="@string/tools_position"
+            app:drawableTint="@color/tools_text_color_primary"
+            android:textColor="@color/tools_text_color_primary"
+            app:layout_constraintTop_toBottomOf="@id/tv_alignment" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_position_desc"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="48dp"
+            android:text="@string/tools_close"
+            android:textColor="@color/tools_text_color_primary"
+            app:layout_constraintBaseline_toBaselineOf="@id/tv_position"
+            app:layout_constraintEnd_toEndOf="parent" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_reason"
+            android:layout_width="match_parent"
+            android:layout_height="48dp"
+            android:background="@drawable/tools_common_btn_rectangle_ripple"
+            android:drawableEnd="@drawable/tools_ic_right_arrow"
+            android:gravity="center_vertical"
+            android:paddingStart="16dp"
+            android:paddingEnd="16dp"
+            android:text="@string/tools_reason"
+            app:drawableTint="@color/tools_text_color_primary"
+            android:textColor="@color/tools_text_color_primary"
+            app:layout_constraintTop_toBottomOf="@id/tv_position" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_reason_desc"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="48dp"
+            android:text="@string/tools_close"
+            android:textColor="@color/tools_text_color_primary"
+            app:layout_constraintBaseline_toBaselineOf="@id/tv_reason"
+            app:layout_constraintEnd_toEndOf="parent" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_optional_reasons"
+            android:layout_width="match_parent"
+            android:layout_height="28dp"
+            android:background="@color/tools_reader_setting_head_bg_color"
+            android:gravity="center_vertical"
+            android:paddingStart="16dp"
+            android:paddingEnd="16dp"
+            android:text="@string/tools_optional_reasons"
+            android:textColor="@color/tools_text_color_primary"
+            android:textSize="12sp"
+            app:layout_constraintTop_toBottomOf="@id/tv_reason" />
+
+        <androidx.constraintlayout.helper.widget.Flow
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginHorizontal="16dp"
+            android:orientation="vertical"
+            app:constraint_referenced_ids="cb_name,cb_date,cb_logo,cb_distinguishable_name,cb_compdfkit_version,cb_tab"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/tv_optional_reasons"
+
+            />
+
+        <androidx.appcompat.widget.AppCompatCheckBox
+            android:id="@+id/cb_name"
+            android:layout_width="0dp"
+            android:layout_height="45dp"
+            android:button="@drawable/tools_ic_digital_sign_checkbox"
+            android:checked="true"
+            android:gravity="center_vertical"
+            android:paddingStart="8dp"
+            android:text="@string/tools_field_name"
+            android:textColor="@color/tools_text_color_primary" />
+
+        <androidx.appcompat.widget.AppCompatCheckBox
+            android:id="@+id/cb_date"
+            android:layout_width="0dp"
+            android:layout_height="45dp"
+            android:button="@drawable/tools_ic_digital_sign_checkbox"
+            android:checked="true"
+            android:gravity="center_vertical"
+            android:paddingStart="8dp"
+            android:text="@string/tools_date"
+            android:textColor="@color/tools_text_color_primary" />
+
+        <androidx.appcompat.widget.AppCompatCheckBox
+            android:id="@+id/cb_logo"
+            android:layout_width="0dp"
+            android:layout_height="45dp"
+            android:button="@drawable/tools_ic_digital_sign_checkbox"
+            android:checked="true"
+            android:gravity="center_vertical"
+            android:paddingStart="8dp"
+            android:text="@string/tools_logo"
+            android:textColor="@color/tools_text_color_primary" />
+
+        <androidx.appcompat.widget.AppCompatCheckBox
+            android:id="@+id/cb_distinguishable_name"
+            android:layout_width="0dp"
+            android:layout_height="45dp"
+            android:button="@drawable/tools_ic_digital_sign_checkbox"
+            android:gravity="center_vertical"
+            android:paddingStart="8dp"
+            android:text="@string/tools_distinguishable_name"
+            android:textColor="@color/tools_text_color_primary" />
+
+        <androidx.appcompat.widget.AppCompatCheckBox
+            android:id="@+id/cb_compdfkit_version"
+            android:layout_width="0dp"
+            android:layout_height="45dp"
+            android:button="@drawable/tools_ic_digital_sign_checkbox"
+            android:gravity="center_vertical"
+            android:paddingStart="8dp"
+            android:text="@string/tools_compdfkit_versions"
+            android:textColor="@color/tools_text_color_primary" />
+
+        <androidx.appcompat.widget.AppCompatCheckBox
+            android:id="@+id/cb_tab"
+            android:layout_width="0dp"
+            android:layout_height="45dp"
+            android:button="@drawable/tools_ic_digital_sign_checkbox"
+            android:checked="true"
+            android:gravity="center_vertical"
+            android:paddingStart="8dp"
+            android:text="@string/tools_tab"
+            android:textColor="@color/tools_text_color_primary" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</ScrollView>
+

+ 52 - 0
ComPDFKit_Tools/src/main/res/layout/tools_sign_style_preview_position.xml

@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:clickable="true"
+    android:focusable="true"
+    xmlns:tools="http://schemas.android.com/tools">
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_reason_title"
+        android:layout_width="match_parent"
+        android:layout_height="48dp"
+        android:gravity="center_vertical"
+        android:paddingStart="16dp"
+        android:text="@string/tools_position"
+        android:textColor="@color/tools_text_color_primary"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <Switch
+        android:id="@+id/sw_position"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="16dp"
+        android:checked="false"
+        app:layout_constraintBottom_toBottomOf="@id/tv_reason_title"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="@id/tv_reason_title" />
+
+    <View
+        android:id="@+id/view_line"
+        android:layout_width="match_parent"
+        android:layout_height="28dp"
+        android:visibility="gone"
+        tools:visibility="visible"
+        android:background="@color/tools_reader_setting_head_bg_color"
+        app:layout_constraintTop_toBottomOf="@id/tv_reason_title" />
+
+
+    <com.compdfkit.tools.common.utils.view.CEditText
+        android:id="@+id/et_position"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:visibility="gone"
+        android:title="@string/tools_position"
+        tools:visibility="visible"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/view_line"
+        />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 81 - 0
ComPDFKit_Tools/src/main/res/layout/tools_sign_style_preview_reason.xml

@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:clickable="true"
+    android:focusable="true">
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_reason_title"
+        android:layout_width="match_parent"
+        android:layout_height="48dp"
+        android:gravity="center_vertical"
+        android:paddingStart="16dp"
+        android:text="@string/tools_reason"
+        android:textColor="@color/tools_text_color_primary"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <Switch
+        android:id="@+id/sw_reason"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="16dp"
+        android:checked="false"
+        app:layout_constraintBottom_toBottomOf="@id/tv_reason_title"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="@id/tv_reason_title" />
+
+
+    <View
+        android:id="@+id/view_line"
+        android:layout_width="match_parent"
+        android:layout_height="28dp"
+        android:background="@color/tools_reader_setting_head_bg_color"
+        android:visibility="gone"
+        app:layout_constraintTop_toBottomOf="@id/tv_reason_title"
+        tools:visibility="visible" />
+
+
+    <RadioGroup
+        android:id="@+id/rg_reason"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="@color/tools_color_background"
+        android:visibility="gone"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/view_line"
+        tools:visibility="visible">
+
+        <androidx.appcompat.widget.AppCompatRadioButton
+            android:id="@+id/rb_owner"
+            style="@style/tools_pdf_reader_mode_radio_button_style"
+            android:layout_width="match_parent"
+            android:checked="true"
+            android:text="@string/tools_i_am_the_owner_of_the_document" />
+
+        <androidx.appcompat.widget.AppCompatRadioButton
+            android:id="@+id/rb_approving"
+            style="@style/tools_pdf_reader_mode_radio_button_style"
+            android:layout_width="match_parent"
+            android:text="@string/tools_i_am_approving_the_document" />
+
+
+        <androidx.appcompat.widget.AppCompatRadioButton
+            android:id="@+id/rb_have_reviewed"
+            style="@style/tools_pdf_reader_mode_radio_button_style"
+            android:layout_width="match_parent"
+            android:text="@string/tools_i_have_reviewed_this_document" />
+
+        <androidx.appcompat.widget.AppCompatRadioButton
+            android:id="@+id/rb_none"
+            style="@style/tools_pdf_reader_mode_radio_button_style"
+            android:layout_width="match_parent"
+            android:text="@string/tools_none" />
+
+    </RadioGroup>
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 8 - 0
ComPDFKit_Tools/src/main/res/layout/tools_sign_style_preview_reason_item.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.appcompat.widget.AppCompatRadioButton xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    tools:text="@string/tools_i_am_the_owner_of_the_document"
+    style="@style/tools_pdf_reader_mode_radio_button_style">
+
+</androidx.appcompat.widget.AppCompatRadioButton>

+ 59 - 0
ComPDFKit_Tools/src/main/res/layout/tools_sign_style_preview_view.xml

@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/cl_root"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@color/tools_sign_preview_bg_color">
+
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/iv_logo"
+        android:layout_width="60dp"
+        android:layout_height="60dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:srcCompat="@drawable/tools_ic_compdfkit_logo" />
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl_preview"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintDimensionRatio="328:116"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/iv_sign"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toStartOf="@id/tv_sign_info"
+            app:layout_constraintHorizontal_weight="0.50"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            tools:src="@tools:sample/avatars" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_sign_info"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:gravity="center_vertical"
+            android:lineSpacingMultiplier="1.15"
+            android:textColor="@color/tools_sign_preview_text_color"
+            app:autoSizeMaxTextSize="28sp"
+            app:autoSizeMinTextSize="2sp"
+            app:autoSizeTextType="uniform"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintHorizontal_weight="0.50"
+            app:layout_constraintStart_toEndOf="@id/iv_sign"
+            tools:text="数字签名者:ComPDFKit\nDN:辨别名\n原因:我是本文档的作者\n位置:长沙\n日期:2023.08.15 10:00:00\nComPDFKit Version:1.9.0" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 58 - 0
ComPDFKit_Tools/src/main/res/layout/tools_sign_style_preview_view_alignment_right.xml

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:id="@+id/cl_root"
+    android:layout_height="wrap_content">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl_preview"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:background="@color/tools_sign_preview_bg_color"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintDimensionRatio="328:116"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/iv_logo"
+            android:layout_width="60dp"
+            android:layout_height="60dp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:srcCompat="@drawable/tools_ic_compdfkit_logo" />
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/iv_sign"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toEndOf="@id/tv_sign_info"
+            app:layout_constraintHorizontal_weight="0.50"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            tools:src="@tools:sample/avatars" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_sign_info"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            app:autoSizeMinTextSize="2sp"
+            android:gravity="center_vertical|end"
+            android:textColor="@color/tools_sign_preview_text_color"
+            app:autoSizeMaxTextSize="28sp"
+            app:autoSizeTextType="uniform"
+            android:lineSpacingMultiplier="1.15"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintHorizontal_weight="0.50"
+            app:layout_constraintEnd_toStartOf="@id/iv_sign"
+            tools:text="数字签名者:ComPDFKit\nDN:辨别名\n原因:我是本文档的作者\n位置:长沙\n日期:2023.08.15 10:00:00\nComPDFKit Version:1.9.0" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 82 - 0
ComPDFKit_Tools/src/main/res/layout/tools_signature_tool_bar.xml

@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="?android:attr/actionBarSize"
+    android:background="@color/tools_color_primary">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl_add_digital_signature"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:background="@drawable/tools_signature_toolbar_btn_corner_status_bg"
+        android:foreground="@drawable/tools_common_btn_corner_ripple"
+        android:padding="8dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toStartOf="@id/cl_verify_digital_signature"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/iv_add"
+            android:layout_width="24dp"
+            android:layout_height="24dp"
+            android:src="@drawable/tools_ic_digital_signature"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:tint="@color/tools_text_color_primary" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_add"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="8dp"
+            android:text="@string/tools_add_signatures"
+            android:textColor="@color/tools_text_color_primary"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toEndOf="@id/iv_add"
+            app:layout_constraintTop_toTopOf="parent" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl_verify_digital_signature"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:background="@drawable/tools_signature_toolbar_btn_corner_status_bg"
+        android:foreground="@drawable/tools_common_btn_corner_ripple"
+        android:padding="8dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@id/cl_add_digital_signature"
+        app:layout_constraintTop_toTopOf="parent">
+
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/iv_verify"
+            android:layout_width="24dp"
+            android:layout_height="24dp"
+            android:src="@drawable/tools_ic_digital_signature"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:tint="@color/tools_text_color_primary" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_verify"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="8dp"
+            android:text="@string/tools_verify_signatures"
+            android:textColor="@color/tools_text_color_primary"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toEndOf="@id/iv_verify"
+            app:layout_constraintTop_toTopOf="parent" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 6 - 0
ComPDFKit_Tools/src/main/res/values/tools_attrs.xml

@@ -87,4 +87,10 @@
         <attr name="tools_show_alpha_slider_bar" format="boolean"/>
     </declare-styleable>
 
+    <declare-styleable name="CEditText"  tools:ignore="ResourceName">
+        <attr name="android:title"/>
+        <attr name="android:imeOptions"/>
+        <attr name="android:inputType"/>
+    </declare-styleable>
+
 </resources>

+ 2 - 0
ComPDFKit_Tools/src/main/res/values/tools_colors.xml

@@ -58,5 +58,7 @@
     <color name="tools_editpage_checkbox_normal">#d9d9d9</color>
 
     <color name="tools_form_default_bg_color">#CCE5E5FF</color>
+    <color name="tools_sign_preview_text_color">#232531</color>
+    <color name="tools_sign_preview_bg_color">#F4F7FF</color>
 
 </resources>

+ 37 - 0
ComPDFKit_Tools/src/main/res/values/tools_strings.xml

@@ -302,4 +302,41 @@
     <string name="tools_reader_view_error_no_email">There is no email app found.</string>
     <string name="tools_reader_view_error_no_browser">There is no browser app found.</string>
     <string name="tools_reader_view_error_invalid_link">Invalid link address.</string>
+
+    <string name="tools_signatures">Signatures</string>
+    <string name="tools_digital_signatures">Digital Signatures</string>
+    <string name="tools_add_signatures">Add Signature</string>
+    <string name="tools_verify_signatures">Verify Signature</string>
+    <string name="tools_import_certificate_digital_id">Import certificate digital ID</string>
+    <string name="tools_import_certificate_digital_id_desc">Import an existing Digital ID that you have obtained as a file</string>
+    <string name="tools_new_certificate_digital_id">New certificate digital ID</string>
+    <string name="tools_select_digital_signatures">Select Signing Certificate</string>
+    <string name="tools_import_digital_desc">Browse digital ID files. The Digital ID file is password protected. If you do not know its password, you cannot access the digital ID card.</string>
+    <string name="tools_create_certificate_digital_id_desc">Digital IDs are only used for: digital signatures, data encryption, digital signatures and data encryption</string>
+    <string name="tools_certification_documents">Certification Documents</string>
+    <string name="tools_certificate_password">Certificate Password</string>
+    <string name="tools_wrong_password">Wrong Password</string>
+    <string name="tools_grantor">Grantor</string>
+    <string name="tools_sectoral">Sectoral</string>
+    <string name="tools_country_area">Country/Area</string>
+    <string name="tools_continuous_page_flip">Continuous Page Flip</string>
+    <string name="tools_certificate_digital_id_save_info">Digitally signed ID cards can be saved locally for secondary use</string>
+    <string name="tools_save_address">Save Address</string>
+    <string name="tools_document_password">Document Password</string>
+    <string name="tools_confirm_password">Confirm Password</string>
+    <string name="tools_text_signature">Text Signature</string>
+    <string name="tools_position">Position</string>
+    <string name="tools_reason">Reason</string>
+    <string name="tools_optional_reasons">Optional reasons</string>
+    <string name="tools_date">Date</string>
+    <string name="tools_logo">Logo</string>
+    <string name="tools_distinguishable_name">Distinguishable Name</string>
+    <string name="tools_compdfkit_versions">ComPDFKit Versions</string>
+    <string name="tools_tab">Tab</string>
+    <string name="tools_i_am_the_owner_of_the_document">I am the owner of the document</string>
+    <string name="tools_i_am_approving_the_document">I am approving the document</string>
+    <string name="tools_i_have_reviewed_this_document">I have reviewed this document</string>
+    <string name="tools_none">None</string>
+    <string name="tools_close">Close</string>
+
 </resources>

+ 8 - 2
ComPDFKit_Tools/src/main/res/values/tools_styles.xml

@@ -72,7 +72,8 @@
     <style name="tools_pdf_reader_mode_radio_button_style" parent="tools_pdf_reader_setting_item_style">
         <item name="android:button">@null</item>
         <item name="android:drawablePadding">16dp</item>
-        <item name="android:drawableEnd">@drawable/tools_reader_settings_page_mode_radio_button</item>
+        <item name="android:drawableEnd">@drawable/tools_reader_settings_page_mode_radio_button
+        </item>
         <item name="android:background">@drawable/tools_reader_settings_radio_button_ripple</item>
     </style>
 
@@ -157,7 +158,7 @@
     <style name="tools_edit_page_insertpage_cursize_style">
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">wrap_content</item>
-        <item name = "android:maxWidth"> 200dp</item>
+        <item name="android:maxWidth">200dp</item>
         <item name="android:minHeight">40dp</item>
         <item name="android:gravity">center_vertical</item>
         <item name="android:textColor">@color/tools_themes_dark</item>
@@ -166,5 +167,10 @@
     <style name="tools_dialog_theme" parent="Theme.AppCompat.Light.Dialog">
         <item name="android:windowNoTitle">true</item>
         <item name="windowNoTitle">true</item>
+        <item name="android:colorAccent">@color/tools_color_accent</item>
+        <item name="colorPrimary">@color/tools_color_primary</item>
+        <item name="colorPrimaryContainer">@color/tools_primary_container</item>
+        <item name="colorSecondary">@color/tools_secondary</item>
+        <item name="colorAccent">@color/tools_color_accent</item>
     </style>
 </resources>

+ 1 - 0
DigitalSignature/.gitignore

@@ -0,0 +1 @@
+/build

+ 54 - 0
DigitalSignature/build.gradle

@@ -0,0 +1,54 @@
+plugins {
+    id 'com.android.application'
+}
+
+android {
+    namespace 'com.compdfkit.digitalsignature'
+    compileSdk 33
+
+    defaultConfig {
+        applicationId "com.compdfkit.viewer"
+        minSdk rootProject.ext.android.MINSDK
+        targetSdk rootProject.ext.android.TARGETSDK
+        versionCode rootProject.ext.android.VERSIONCODE as int
+        versionName rootProject.ext.sdk.COMPDFKit_SDK_VERSION
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+            android.applicationVariants.all { variant ->
+                variant.outputs.all {
+                    if (outputFileName.toLowerCase().endsWith('unsigned.apk')) {
+                        outputFileName = "Viewer_ComPDFKit.apk"
+                    }
+                }
+            }
+        }
+        debug {
+            android.applicationVariants.all { variant ->
+                variant.outputs.all {
+                    if (outputFileName.toLowerCase().endsWith('debug.apk')) {
+                        outputFileName = "Viewer_ComPDFKit.apk"
+                    }
+                }
+            }
+        }
+    }
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
+    }
+    buildFeatures {
+        viewBinding = true
+    }
+}
+
+dependencies {
+    implementation 'androidx.appcompat:appcompat:1.6.1'
+    implementation 'com.google.android.material:material:1.8.0'
+    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
+    implementation project(':ComPDFKit_Tools')
+    implementation 'pub.devrel:easypermissions:3.0.0'
+}

+ 21 - 0
DigitalSignature/proguard-rules.pro

@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile

+ 26 - 0
DigitalSignature/src/androidTest/java/com/compdfkit/digitalsignature/ExampleInstrumentedTest.java

@@ -0,0 +1,26 @@
+package com.compdfkit.digitalsignature;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+    @Test
+    public void useAppContext() {
+        // Context of the app under test.
+        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        assertEquals("com.compdfkit.digitalsignature", appContext.getPackageName());
+    }
+}

File diff suppressed because it is too large
+ 35 - 0
DigitalSignature/src/main/AndroidManifest.xml


BIN
DigitalSignature/src/main/assets/PDF32000_2008.pdf


+ 102 - 0
DigitalSignature/src/main/java/com/compdfkit/digitalsignature/CViewerScreenStatusManager.java

@@ -0,0 +1,102 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ * <p>
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ */
+
+package com.compdfkit.digitalsignature;
+
+
+import androidx.constraintlayout.widget.ConstraintSet;
+import androidx.core.view.WindowCompat;
+import androidx.core.view.WindowInsetsCompat;
+import androidx.core.view.WindowInsetsControllerCompat;
+import androidx.fragment.app.FragmentActivity;
+
+import com.compdfkit.digitalsignature.databinding.SignaturesPdfSampleActivityBinding;
+import com.compdfkit.tools.common.utils.animation.CFillScreenManager;
+import com.compdfkit.tools.common.utils.animation.ConstraintSetUtils;
+import com.compdfkit.tools.common.utils.viewutils.CViewUtils;
+import com.compdfkit.tools.common.views.pdfview.CPreviewMode;
+
+public class CViewerScreenStatusManager {
+
+    private SignaturesPdfSampleActivityBinding binding;
+
+    private boolean isFillScreen;
+
+    private ConstraintSet constraintSet = new ConstraintSet();
+
+    private ConstraintSetUtils constraintSetUtils = new ConstraintSetUtils();
+
+    private CFillScreenManager manager = new CFillScreenManager();
+
+    public CViewerScreenStatusManager(SignaturesPdfSampleActivityBinding binding) {
+        this.binding = binding;
+        constraintSet.clone(binding.getRoot());
+        manager.bindRightToolViewList(binding.pdfView.slideBar);
+        manager.bindBottomToolViewList(binding.pdfView.indicatorView);
+        manager.bindBottomToolViewList(binding.signatureToolBar);
+    }
+
+    public void changeWindowStatus(CPreviewMode mode) {
+        if (mode == CPreviewMode.Viewer) {
+            manager.removeToolView(binding.signatureToolBar);
+            constraintSetUtils.hideFromBottom(constraintSet, binding.signatureToolBar);
+        } else if (mode == CPreviewMode.Signature) {
+            manager.bindBottomToolViewList(binding.signatureToolBar);
+            constraintSetUtils.showFromBottom(constraintSet, binding.signatureToolBar);
+        }
+        constraintSetUtils.apply(constraintSet, binding.getRoot());
+    }
+
+
+    public void fillScreenChange() {
+        manager.fillScreenChange(!isFillScreen);
+        if (!isFillScreen) {
+            //enter full screen
+            //hide top toolbar
+            constraintSetUtils.hideFromTop(constraintSet, binding.flTool);
+            constraintSetUtils.hideFromBottom(constraintSet, binding.signatureToolBar);
+            isFillScreen = true;
+        } else {
+            //enter normal state
+            constraintSetUtils.showFromTop(constraintSet, binding.flTool);
+            if (manager.bottomToolViewList.contains(binding.signatureToolBar)) {
+                constraintSetUtils.showFromBottom(constraintSet, binding.signatureToolBar);
+            }else {
+                constraintSetUtils.hideFromBottom(constraintSet, binding.signatureToolBar);
+            }
+            isFillScreen = false;
+        }
+        constraintSetUtils.apply(constraintSet, binding.getRoot());
+    }
+
+    private void setFullScreen() {
+        if (binding.pdfView.getContext() instanceof FragmentActivity) {
+            FragmentActivity fragmentActivity = (FragmentActivity) binding.pdfView.getContext();
+            if (!CViewUtils.isLandScape(binding.pdfView.getContext())) {
+                WindowCompat.setDecorFitsSystemWindows(fragmentActivity.getWindow(), false);
+            }
+            WindowInsetsControllerCompat compat = new WindowInsetsControllerCompat(fragmentActivity.getWindow(), binding.getRoot());
+            compat.hide(WindowInsetsCompat.Type.systemBars());
+        }
+    }
+
+    /**
+     * exit full screen
+     */
+    private void cancelFullScreen() {
+        if (binding.pdfView.getContext() instanceof FragmentActivity) {
+            FragmentActivity fragmentActivity = (FragmentActivity) binding.pdfView.getContext();
+            if (!CViewUtils.isLandScape(binding.pdfView.getContext())) {
+                WindowCompat.setDecorFitsSystemWindows(fragmentActivity.getWindow(), true);
+            }
+            WindowInsetsControllerCompat compat = new WindowInsetsControllerCompat(fragmentActivity.getWindow(), binding.getRoot());
+            compat.show(WindowInsetsCompat.Type.systemBars());
+        }
+    }
+}

+ 205 - 0
DigitalSignature/src/main/java/com/compdfkit/digitalsignature/PDFSignaturesSampleActivity.java

@@ -0,0 +1,205 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ * <p>
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ */
+
+package com.compdfkit.digitalsignature;
+
+import android.Manifest;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Environment;
+import android.provider.Settings;
+import android.view.View;
+
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
+import androidx.annotation.NonNull;
+
+import com.compdfkit.core.annotation.CPDFTextAnnotation;
+import com.compdfkit.core.annotation.form.CPDFSignatureWidget;
+import com.compdfkit.core.annotation.form.CPDFWidget;
+import com.compdfkit.digitalsignature.databinding.SignaturesPdfSampleActivityBinding;
+import com.compdfkit.tools.annotation.pdfproperties.pdfnote.CPDFtextAnnotImpl;
+import com.compdfkit.tools.common.activity.CBasicActivity;
+import com.compdfkit.tools.common.utils.CFileUtils;
+import com.compdfkit.tools.common.utils.task.CExtractAssetFileTask;
+import com.compdfkit.tools.common.utils.window.CPopupMenuWindow;
+import com.compdfkit.tools.common.views.pdfbota.CPDFBOTA;
+import com.compdfkit.tools.common.views.pdfbota.CPDFBotaDialogFragment;
+import com.compdfkit.tools.common.views.pdfbota.CPDFBotaFragmentTabs;
+import com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl;
+import com.compdfkit.tools.common.views.pdfview.CPreviewMode;
+import com.compdfkit.tools.signature.pdfproperties.pdfsign.CDigitalSignatureWidgetImpl;
+import com.compdfkit.tools.viewer.pdfsearch.CSearchResultDialogFragment;
+import com.compdfkit.ui.reader.CPDFReaderView;
+
+import java.util.ArrayList;
+
+import pub.devrel.easypermissions.EasyPermissions;
+
+public class PDFSignaturesSampleActivity extends CBasicActivity {
+
+    /**
+     * assets folder pdf file
+     */
+    public static final String QUICK_START_GUIDE = "PDF32000_2008.pdf";
+
+    private SignaturesPdfSampleActivityBinding binding;
+
+    private CViewerScreenStatusManager screenStatusManager;
+
+    private ActivityResultLauncher<Intent> selectDocumentLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
+        if (result.getData() != null && result.getData().getData() != null) {
+            Uri uri = result.getData().getData();
+            CFileUtils.takeUriPermission(this, uri);
+            binding.pdfView.openPDF(uri);
+        }
+    });
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        binding = SignaturesPdfSampleActivityBinding.inflate(getLayoutInflater());
+        setContentView(binding.getRoot());
+        binding.pdfView.setViewMode(CPDFReaderView.ViewMode.FORM);
+        screenStatusManager = new CViewerScreenStatusManager(binding);
+        initToolbarListener();
+        initSearchBar();
+        initSignatureToolbar();
+        //Extract PDF files from the Android assets folder
+        CExtractAssetFileTask.extract(this, QUICK_START_GUIDE, QUICK_START_GUIDE, (filePath) -> {
+            binding.pdfView.openPDF(filePath);
+        });
+        resetContextMenu(binding.pdfView, CPreviewMode.Signature);
+        binding.pdfView.setOnTapMainDocAreaCallback(() -> {
+            screenStatusManager.fillScreenChange();
+        });
+        binding.pdfView.getCPdfReaderView().setMinScaleEnable(false);
+        binding.pdfView.getCPdfReaderView().getAnnotImplRegistry().registImpl(CPDFTextAnnotation.class, CPDFtextAnnotImpl.class);
+        registerSignaturesHelper(binding.pdfView);
+        initFormAttr(binding.pdfView);
+    }
+
+    private void initToolbarListener() {
+        binding.pdfToolBar.addMode(CPreviewMode.Viewer);
+        binding.pdfToolBar.addMode(CPreviewMode.Signature);
+        binding.pdfToolBar.selectMode(CPreviewMode.Signature);
+        binding.pdfToolBar.setPreviewModeChangeListener(mode -> {
+            binding.pdfToolBar.selectMode(mode);
+            screenStatusManager.changeWindowStatus(mode);
+            if (mode == CPreviewMode.Viewer) {
+                binding.pdfView.setViewMode(CPDFReaderView.ViewMode.VIEW);
+                binding.pdfView.changeFormType(CPDFWidget.WidgetType.Widget_Unknown);
+            } else {
+                binding.pdfView.setViewMode(CPDFReaderView.ViewMode.FORM);
+            }
+            resetContextMenu(binding.pdfView, mode);
+        });
+        binding.pdfToolBar.setSearchBtnClickListener(v -> {
+            binding.pdfToolBar.setVisibility(View.GONE);
+            binding.pdfSearchToolBar.setVisibility(View.VISIBLE);
+            binding.pdfSearchToolBar.showKeyboard();
+        });
+
+        binding.pdfToolBar.setBoTaBtnClickListener(v -> {
+            //Show a fragment of the PDF thumbnail and a dialog fragment of the PDF outline list.
+            CPDFBotaDialogFragment boTaDialogFragment = CPDFBotaDialogFragment.newInstance();
+            boTaDialogFragment.initWithPDFView(binding.pdfView);
+            CPDFBotaFragmentTabs outlineTabs = new CPDFBotaFragmentTabs(CPDFBOTA.OUTLINE, getString(R.string.tools_outlines));
+            CPDFBotaFragmentTabs bookmarks = new CPDFBotaFragmentTabs(CPDFBOTA.BOOKMARKS, getString(R.string.tools_bookmarks));
+            ArrayList<CPDFBotaFragmentTabs> tabs = new ArrayList<>();
+            tabs.add(outlineTabs);
+            tabs.add(bookmarks);
+            boTaDialogFragment.setBotaDialogTabs(tabs);
+            boTaDialogFragment.show(getSupportFragmentManager(), "boTaDialogFragment");
+        });
+
+        binding.pdfToolBar.setThumbnailBtnClickListener(v -> {
+            CPDFBotaDialogFragment boTaDialogFragment = CPDFBotaDialogFragment.newInstance();
+            boTaDialogFragment.initWithPDFView(binding.pdfView);
+            CPDFBotaFragmentTabs thumbnailTabs = new CPDFBotaFragmentTabs(CPDFBOTA.THUMBNAIL, getString(R.string.tools_thumbnails));
+            ArrayList<CPDFBotaFragmentTabs> tabs = new ArrayList<>();
+            tabs.add(thumbnailTabs);
+            boTaDialogFragment.setBotaDialogTabs(tabs);
+            boTaDialogFragment.show(getSupportFragmentManager(), "boTaDialogFragment");
+        });
+
+        binding.pdfToolBar.setMoreBtnClickListener(v -> {
+            v.setSelected(true);
+            //Show the PDF settings dialog fragment
+            CPopupMenuWindow menuWindow = new CPopupMenuWindow(this);
+            menuWindow.addItem(R.drawable.tools_ic_preview_settings, R.string.tools_view_setting, v1 -> {
+                showDisplaySettings(binding.pdfView);
+            });
+            menuWindow.addItem(R.drawable.tools_ic_document_info, R.string.tools_document_info, v1 -> {
+                showDocumentInfo(binding.pdfView);
+            });
+            menuWindow.addItem(R.drawable.tools_ic_share, R.string.tools_share, v1 -> {
+                sharePDF(binding.pdfView);
+            });
+            menuWindow.addItem(R.drawable.tools_ic_new_file, R.string.tools_open_document, v1 -> {
+                if (hasPermissions(STORAGE_PERMISSIONS)) {
+                    selectDocumentLauncher.launch(CFileUtils.getContentIntent());
+                } else {
+                    requestStoragePermissions();
+                }
+            });
+            menuWindow.setOnDismissListener(() -> v.setSelected(false));
+            menuWindow.showAsDropDown(v);
+        });
+    }
+
+    private void requestStoragePermissions(){
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU){
+            startActivity(new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION));
+        }else {
+            EasyPermissions.requestPermissions(this, "request permission", REQUEST_EXTERNAL_PERMISSION, STORAGE_PERMISSIONS);
+        }
+    }
+
+    private void initSearchBar() {
+        binding.pdfSearchToolBar.initWithPDFView(binding.pdfView);
+        binding.pdfSearchToolBar.onSearchQueryResults(list -> {
+            CSearchResultDialogFragment searchResultDialog = new CSearchResultDialogFragment();
+            searchResultDialog.show(getSupportFragmentManager(), "searchResultDialogFragment");
+            searchResultDialog.setSearchTextInfos(list);
+            searchResultDialog.setOnClickSearchItemListener(clickItem -> {
+                binding.pdfView.getCPdfReaderView().setDisplayPageIndex(clickItem.page);
+                binding.pdfView.getCPdfReaderView().getTextSearcher().searchBegin(clickItem.page, clickItem.textRangeIndex);
+                searchResultDialog.dismiss();
+            });
+        });
+
+        binding.pdfSearchToolBar.setExitSearchListener(() -> {
+            binding.pdfToolBar.setVisibility(View.VISIBLE);
+            binding.pdfSearchToolBar.setVisibility(View.GONE);
+            binding.pdfSearchToolBar.showKeyboard();
+        });
+    }
+
+    private void initSignatureToolbar(){
+        binding.signatureToolBar.initWithPDFView(binding.pdfView);
+    }
+
+    private void registerSignaturesHelper(CPDFViewCtrl pdfView) {
+        pdfView.getCPdfReaderView().getAnnotImplRegistry()
+                .registImpl(CPDFSignatureWidget.class, CDigitalSignatureWidgetImpl.class);
+    }
+
+    @Override
+    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+        if (requestCode == REQUEST_EXTERNAL_PERMISSION) {
+            if (EasyPermissions.hasPermissions(this, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
+                selectDocumentLauncher.launch(CFileUtils.getContentIntent());
+            }
+        }
+    }
+}

File diff suppressed because it is too large
+ 30 - 0
DigitalSignature/src/main/res/drawable-v24/ic_launcher_foreground.xml


+ 170 - 0
DigitalSignature/src/main/res/drawable/ic_launcher_background.xml

@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportWidth="108"
+    android:viewportHeight="108">
+    <path
+        android:fillColor="#3DDC84"
+        android:pathData="M0,0h108v108h-108z" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M9,0L9,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,0L19,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,0L29,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,0L39,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,0L49,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,0L59,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,0L69,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,0L79,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M89,0L89,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M99,0L99,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,9L108,9"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,19L108,19"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,29L108,29"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,39L108,39"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,49L108,49"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,59L108,59"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,69L108,69"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,79L108,79"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,89L108,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,99L108,99"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,29L89,29"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,39L89,39"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,49L89,49"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,59L89,59"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,69L89,69"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,79L89,79"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,19L29,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,19L39,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,19L49,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,19L59,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,19L69,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,19L79,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+</vector>

+ 63 - 0
DigitalSignature/src/main/res/layout/signatures_pdf_sample_activity.xml

@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:animateLayoutChanges="true"
+    android:elevation="4dp"
+    tools:context=".PDFSignaturesSampleActivity">
+
+    <FrameLayout
+        android:id="@+id/fl_tool"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="@color/tools_color_primary"
+        android:elevation="4dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <com.compdfkit.tools.common.views.CPDFToolBar
+            android:id="@+id/pdf_tool_bar"
+            android:layout_width="match_parent"
+            android:layout_height="?android:attr/actionBarSize"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            android:title="@string/tools_pdf_viewer_mode" />
+
+        <com.compdfkit.tools.viewer.pdfsearch.CSearchToolbar
+            android:id="@+id/pdf_search_tool_bar"
+            android:layout_width="match_parent"
+            android:layout_height="?android:attr/actionBarSize"
+            android:visibility="gone"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            />
+
+    </FrameLayout>
+
+
+    <com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl
+        android:id="@+id/pdf_view"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        app:layout_constraintBottom_toTopOf="@id/signature_tool_bar"
+        app:layout_constraintTop_toBottomOf="@id/fl_tool"
+        app:tools_enable_page_indicator="true"
+        app:tools_enable_slider_bar="true"
+        app:tools_page_indicator_margin_bottom="20dp"
+        app:tools_slider_bar_icon="@drawable/tools_ic_pdf_slider_bar"
+        app:tools_slider_bar_position="right" />
+
+    <com.compdfkit.tools.signature.CSignatureToolBar
+        android:id="@+id/signature_tool_bar"
+        android:layout_width="match_parent"
+        android:layout_height="?android:attr/actionBarSize"
+        app:layout_constraintBottom_toBottomOf="parent"
+        />
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 5 - 0
DigitalSignature/src/main/res/mipmap-anydpi-v26/ic_launcher.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@color/white"/>
+    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
+</adaptive-icon>

+ 5 - 0
DigitalSignature/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@color/white"/>
+    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
+</adaptive-icon>

BIN
DigitalSignature/src/main/res/mipmap-hdpi/ic_launcher.png


BIN
DigitalSignature/src/main/res/mipmap-hdpi/ic_launcher_foreground.png


BIN
DigitalSignature/src/main/res/mipmap-hdpi/ic_launcher_round.png


BIN
DigitalSignature/src/main/res/mipmap-mdpi/ic_launcher.png


BIN
DigitalSignature/src/main/res/mipmap-mdpi/ic_launcher_foreground.png


BIN
DigitalSignature/src/main/res/mipmap-mdpi/ic_launcher_round.png


BIN
DigitalSignature/src/main/res/mipmap-xhdpi/ic_launcher.png


BIN
DigitalSignature/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png


BIN
DigitalSignature/src/main/res/mipmap-xhdpi/ic_launcher_round.png


BIN
DigitalSignature/src/main/res/mipmap-xxhdpi/ic_launcher.png


BIN
DigitalSignature/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png


BIN
DigitalSignature/src/main/res/mipmap-xxhdpi/ic_launcher_round.png


BIN
DigitalSignature/src/main/res/mipmap-xxxhdpi/ic_launcher.png


BIN
DigitalSignature/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png


BIN
DigitalSignature/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png


+ 9 - 0
DigitalSignature/src/main/res/values-night/themes.xml

@@ -0,0 +1,9 @@
+<resources xmlns:tools="http://schemas.android.com/tools">
+    <!-- Base application theme. -->
+    <style name="Theme.Compdfkit_android_demo" parent="Theme.MaterialComponents.DayNight.NoActionBar">
+        <item name="android:statusBarColor">@color/tools_color_primary</item>
+        <item name="android:colorAccent">@color/tools_color_accent</item>
+        <item name="android:colorPrimary">@color/tools_color_accent</item>
+        <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
+    </style>
+</resources>

+ 10 - 0
DigitalSignature/src/main/res/values/colors.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="purple_200">#FFBB86FC</color>
+    <color name="purple_500">#FF6200EE</color>
+    <color name="purple_700">#FF3700B3</color>
+    <color name="teal_200">#FF03DAC5</color>
+    <color name="teal_700">#FF018786</color>
+    <color name="black">#FF000000</color>
+    <color name="white">#FFFFFFFF</color>
+</resources>

+ 3 - 0
DigitalSignature/src/main/res/values/strings.xml

@@ -0,0 +1,3 @@
+<resources>
+    <string name="app_name">Digital Signature_ComPDFKit</string>
+</resources>

+ 10 - 0
DigitalSignature/src/main/res/values/themes.xml

@@ -0,0 +1,10 @@
+<resources xmlns:tools="http://schemas.android.com/tools">
+    <!-- Base application theme. -->
+    <style name="Theme.Compdfkit_android_demo" parent="Theme.MaterialComponents.DayNight.NoActionBar">
+        <item name="android:statusBarColor">@color/tools_color_primary</item>
+        <item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
+        <item name="android:colorAccent">@color/tools_color_accent</item>
+        <item name="android:colorPrimary">@color/tools_color_accent</item>
+        <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
+    </style>
+</resources>

+ 17 - 0
DigitalSignature/src/test/java/com/compdfkit/digitalsignature/ExampleUnitTest.java

@@ -0,0 +1,17 @@
+package com.compdfkit.digitalsignature;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+public class ExampleUnitTest {
+    @Test
+    public void addition_isCorrect() {
+        assertEquals(4, 2 + 2);
+    }
+}

+ 1 - 0
settings.gradle

@@ -23,3 +23,4 @@ include ':ComPDFKit_Tools'
 include ':ComPDFKit_Repo:compdfkit'
 include ':ComPDFKit_Repo:compdfkit-ui'
 include ':Samples'
+include ':DigitalSignature'