Przeglądaj źródła

PDFTool(Android) - 1.Bug修复

liuxiaolong 1 rok temu
rodzic
commit
76165b0155
38 zmienionych plików z 723 dodań i 380 usunięć
  1. BIN
      ComPDFKit_Repo/compdfkit-ui/ComPDFKit-UI.aar
  2. BIN
      ComPDFKit_Repo/compdfkit/ComPDFKit.aar
  3. 6 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/contextmenu/CPDFContextMenuHelper.java
  4. 5 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/utils/view/CEditText.java
  5. 36 7
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/CertificateDigitalDatas.java
  6. 2 22
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/bean/CPDFOwnerItemData.java
  7. 6 9
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/importcert/create/CreateCertificateDigitalDialog.java
  8. 5 30
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/info/CertAttrDatas.java
  9. 28 2
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/info/signlist/CPDFCertDigitalSignListDialog.java
  10. 0 129
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/pdfproperties/pdfsign/CDigitalSignStyleData.java
  11. 117 80
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/pdfproperties/pdfsign/CDigitalSignStylePreviewView.java
  12. 22 11
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/pdfproperties/pdfsign/CDigitalSignatureWidgetImpl.java
  13. 36 27
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/preview/CDigitalSignStylePreviewDialog.java
  14. 4 7
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/verify/CVerifySignStatusView.java
  15. 0 2
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/viewer/pdfsearch/data/CPDFSearchKeywordsDatas.java
  16. BIN
      ComPDFKit_Tools/src/main/res/drawable/tools_logo.png
  17. 12 0
      ComPDFKit_Tools/src/main/res/layout/tools_layout_c_edit_text.xml
  18. 2 0
      ComPDFKit_Tools/src/main/res/layout/tools_sign_certificate_attributes_list_trusted_cert_item.xml
  19. 2 0
      ComPDFKit_Tools/src/main/res/layout/tools_sign_create_cert_digital_id_info_layout.xml
  20. 4 1
      ComPDFKit_Tools/src/main/res/layout/tools_sign_style_preview_dialog.xml
  21. 77 43
      ComPDFKit_Tools/src/main/res/layout/tools_sign_style_preview_main.xml
  22. 7 5
      ComPDFKit_Tools/src/main/res/layout/tools_sign_style_preview_view.xml
  23. 1 0
      ComPDFKit_Tools/src/main/res/values/tools_attrs.xml
  24. 1 0
      ComPDFKit_Tools/src/main/res/values/tools_strings.xml
  25. 11 2
      DigitalSignature/src/main/java/com/compdfkit/digitalsignature/PDFSignaturesSampleActivity.java
  26. 16 1
      Samples/build.gradle
  27. BIN
      Samples/src/main/assets/Certificate.pfx
  28. BIN
      Samples/src/main/assets/CommonFivePage_Signed.pdf
  29. BIN
      Samples/src/main/assets/Signed.pdf
  30. 2 0
      Samples/src/main/java/com/compdfkit/samples/SampleApplication.java
  31. 1 0
      Samples/src/main/java/com/compdfkit/samples/SampleListActivity.java
  32. 300 0
      Samples/src/main/java/com/compdfkit/samples/samples/DigitalSignaturesTest.java
  33. 8 0
      Samples/src/main/java/com/compdfkit/samples/util/DateUtil.java
  34. 1 1
      Samples/src/main/java/com/compdfkit/samples/util/FileUtils.java
  35. 6 0
      Samples/src/main/res/values/strings.xml
  36. 3 1
      Samples_kotlin/src/main/java/com/compdfkit/samples/SampleDetailActivity.kt
  37. 1 0
      build.gradle
  38. 1 0
      settings.gradle

BIN
ComPDFKit_Repo/compdfkit-ui/ComPDFKit-UI.aar


BIN
ComPDFKit_Repo/compdfkit/ComPDFKit.aar


+ 6 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/contextmenu/CPDFContextMenuHelper.java

@@ -15,6 +15,9 @@ import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.PopupWindow;
 
+import com.compdfkit.core.document.CPDFDocument;
+import com.compdfkit.core.page.CPDFTextPage;
+import com.compdfkit.core.page.CPDFTextSelection;
 import com.compdfkit.tools.common.contextmenu.impl.CCheckBoxContextMenuView;
 import com.compdfkit.tools.common.contextmenu.impl.CFreeTextContextMenuView;
 import com.compdfkit.tools.common.contextmenu.impl.CInkContextMenuView;
@@ -47,6 +50,7 @@ import com.compdfkit.tools.common.contextmenu.interfaces.ContextMenuSelectConten
 import com.compdfkit.tools.common.contextmenu.interfaces.ContextMenuSoundContentProvider;
 import com.compdfkit.tools.common.contextmenu.interfaces.ContextMenuStampProvider;
 import com.compdfkit.tools.common.contextmenu.interfaces.ContextMenuTextFieldProvider;
+import com.compdfkit.tools.common.utils.CLog;
 import com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl;
 import com.compdfkit.tools.viewer.contextmenu.CopyContextMenuView;
 import com.compdfkit.ui.contextmenu.CPDFContextMenuShowHelper;
@@ -67,6 +71,8 @@ import com.compdfkit.ui.proxy.form.CPDFTextWidgetImpl;
 import com.compdfkit.ui.reader.CPDFPageView;
 import com.compdfkit.ui.reader.CPDFReaderView;
 
+import java.util.List;
+
 
 public class CPDFContextMenuHelper extends CPDFContextMenuShowHelper {
 

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

@@ -34,6 +34,8 @@ public class CEditText extends FrameLayout {
 
     AppCompatTextView tvTitle;
 
+    AppCompatTextView tvTitleTag;
+
     private COnTextChangedListener textChangedListener;
 
     public CEditText(@NonNull Context context) {
@@ -58,6 +60,8 @@ public class CEditText extends FrameLayout {
             String hint = typedArray.getString(R.styleable.CEditText_android_hint);
             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);
+            boolean showKeyTag = typedArray.getBoolean(R.styleable.CEditText_showKeyTag, false);
+            tvTitleTag.setVisibility(showKeyTag ? VISIBLE : GONE);
             tvTitle.setVisibility(TextUtils.isEmpty(title)?  GONE : VISIBLE);
             tvTitle.setText(title);
             editText.setImeOptions(imeOptions);
@@ -71,6 +75,7 @@ public class CEditText extends FrameLayout {
         inflate(context, R.layout.tools_layout_c_edit_text, this);
         editText = findViewById(R.id.edit_text);
         tvTitle = findViewById(R.id.tv_title);
+        tvTitleTag = findViewById(R.id.tv_title_1);
         editText.addTextChangedListener(new TextWatcher() {
             @Override
             public void beforeTextChanged(CharSequence s, int start, int count, int after) {

+ 36 - 7
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/CertificateDigitalDatas.java

@@ -11,6 +11,7 @@ package com.compdfkit.tools.signature;
 
 
 import android.content.Context;
+import android.text.TextUtils;
 
 import androidx.annotation.Nullable;
 
@@ -24,7 +25,7 @@ import com.compdfkit.core.signature.CPDFX509;
 import com.compdfkit.tools.R;
 import com.compdfkit.tools.signature.bean.CPDFDocumentSignInfo;
 import com.compdfkit.tools.signature.bean.CPDFSignatureStatusInfo;
-import com.compdfkit.tools.signature.pdfproperties.pdfsign.CDigitalSignStyleData;
+import com.compdfkit.ui.reader.CPDFReaderView;
 
 import org.jetbrains.annotations.NotNull;
 
@@ -98,7 +99,6 @@ public class CertificateDigitalDatas {
      *
      * @param document
      * @param signatureWidget
-     * @param styleData       Signature related information, such as: reason for signing, location, time, etc.
      * @param certPath        Signed certificate local file path
      * @param password        certificate password
      * @param savePath        Document save path
@@ -106,7 +106,8 @@ public class CertificateDigitalDatas {
      */
     public static boolean writeSignature(CPDFDocument document,
                                          CPDFSignatureWidget signatureWidget,
-                                         CDigitalSignStyleData styleData,
+                                         String location,
+                                         String reason,
                                          String certPath,
                                          String password,
                                          String savePath
@@ -115,8 +116,8 @@ public class CertificateDigitalDatas {
                 savePath,
                 certPath,
                 password,
-                styleData.getLocation(),
-                styleData.getReason(),
+                location,
+                reason,
                 CPDFDocument.PDFDocMdpP.PDFDocMdpPForbidAllModify
         );
     }
@@ -200,9 +201,11 @@ public class CertificateDigitalDatas {
         }
     }
 
-    public static boolean removeDigitalSign(CPDFDocument document, CPDFSignature signature) {
+    public static boolean removeDigitalSign(CPDFReaderView readerView, CPDFDocument document, CPDFSignature signature) {
         try {
-            boolean result = document.removeSignature(signature, true);
+            boolean result = document.removeSignature(signature, true, cpdfSignatureWidget ->{
+                readerView.refreshSignatureWidget(cpdfSignatureWidget);
+            });
             document.save();
             return result;
         } catch (Exception e) {
@@ -233,4 +236,30 @@ public class CertificateDigitalDatas {
             loopVerifyGetChain(context, list, signature, a);
         }
     }
+
+
+    public static String getOwnerContent(CPDFOwnerInfo ownerInfo, String separator){
+        StringBuilder builder = new StringBuilder();
+        List<String> infos = new ArrayList<>();
+        if (!TextUtils.isEmpty(ownerInfo.getCountry())){
+            infos.add("C="+ownerInfo.getCountry());
+        }
+        if (!TextUtils.isEmpty(ownerInfo.getOrgnize())){
+            infos.add("O="+ownerInfo.getOrgnize());
+        }
+        if (!TextUtils.isEmpty(ownerInfo.getOrgnizeUnit())){
+            infos.add("OU="+ownerInfo.getOrgnizeUnit());
+        }
+        if (!TextUtils.isEmpty(ownerInfo.getCommonName())){
+            infos.add("CN="+ownerInfo.getCommonName());
+        }
+        for (int i = 0; i < infos.size(); i++) {
+            String item = infos.get(i);
+            builder.append(item);
+            if (i != infos.size() -1){
+                builder.append(separator);
+            }
+        }
+        return builder.toString();
+    }
 }

+ 2 - 22
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/bean/CPDFOwnerItemData.java

@@ -14,6 +14,7 @@ import android.text.TextUtils;
 
 import com.compdfkit.core.signature.CPDFOwnerInfo;
 import com.compdfkit.core.signature.CPDFX509;
+import com.compdfkit.tools.signature.CertificateDigitalDatas;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -26,29 +27,8 @@ public class CPDFOwnerItemData {
 
     public CPDFOwnerItemData(CPDFX509 cpdfx509){
         this.cpdfx509 = cpdfx509;
-        StringBuilder builder = new StringBuilder();
         CPDFOwnerInfo ownerInfo = cpdfx509.getCertInfo().getSubject();
-        List<String> infos = new ArrayList<>();
-        if (!TextUtils.isEmpty(ownerInfo.getCountry())){
-            infos.add("C="+ownerInfo.getCountry());
-        }
-        if (!TextUtils.isEmpty(ownerInfo.getOrgnize())){
-            infos.add("O="+ownerInfo.getOrgnize());
-        }
-        if (!TextUtils.isEmpty(ownerInfo.getOrgnizeUnit())){
-            infos.add("OU="+ownerInfo.getOrgnizeUnit());
-        }
-        if (!TextUtils.isEmpty(ownerInfo.getCommonName())){
-            infos.add("CN="+ownerInfo.getCommonName());
-        }
-        for (int i = 0; i < infos.size(); i++) {
-            String item = infos.get(i);
-            builder.append(item);
-            if (i != infos.size() -1){
-                builder.append(",");
-            }
-        }
-        this.content = builder.toString();
+        this.content = CertificateDigitalDatas.getOwnerContent(ownerInfo, ",");
     }
 
     private CPDFX509 cpdfx509;

+ 6 - 9
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/importcert/create/CreateCertificateDigitalDialog.java

@@ -171,7 +171,7 @@ public class CreateCertificateDigitalDialog extends CBasicBottomSheetDialogFragm
     @Override
     protected void onViewCreate() {
         String uuid = UUID.randomUUID().toString();
-        fileName = "new_cert_" + uuid.substring(uuid.length() - 4, uuid.length()) + ".p12";
+        fileName = "new_cert_" + uuid.substring(uuid.length() - 4, uuid.length()) + ".pfx";
         tvTitle.setText(R.string.tools_create_a_self_signed_digital_id);
         initCountryReginData();
         etName.addTextChangedListener((s, start, before, count) -> {
@@ -238,14 +238,15 @@ public class CreateCertificateDigitalDialog extends CBasicBottomSheetDialogFragm
             ownerInfo.setOrgnize(sectoral);
             ownerInfo.setEmail(email);
             ownerInfo.setCountry(countryArea);
-
             String saveDir = getSaveAddress();
             File certFile = new File(saveDir, fileName);
-            certFile.getParentFile().mkdirs();
+            if (certFile.getParentFile() != null) {
+                certFile.getParentFile().mkdirs();
+            }
             boolean success = CertificateDigitalDatas.generatePKCS12Cert(ownerInfo, etPassword.getText(),
                     saveDir, fileName);
             boolean exists = certFile.exists();
-            if (success) {
+            if (success && exists) {
                 if (selectCertFileListener != null) {
                     selectCertFileListener.certificateFile(certFile.getAbsolutePath(), etPassword.getText());
                 }
@@ -287,12 +288,8 @@ public class CreateCertificateDigitalDialog extends CBasicBottomSheetDialogFragm
 
     private void enableConfirmButton() {
         String name = etName.getText();
-        String grantor = etOrganizationUnit.getText();
-        String sectoral = etOrganizationName.getText();
         String email = etEmailAddress.getText();
-        String countryArea = "CN";
-        boolean enable = !TextUtils.isEmpty(name) && !TextUtils.isEmpty(grantor)
-                && !TextUtils.isEmpty(sectoral) && !TextUtils.isEmpty(email) && !TextUtils.isEmpty(countryArea);
+        boolean enable = !TextUtils.isEmpty(name)  && !TextUtils.isEmpty(email);
         btnOk.setEnabled(enable);
     }
 

+ 5 - 30
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/info/CertAttrDatas.java

@@ -20,6 +20,7 @@ import com.compdfkit.core.signature.CPDFOwnerInfo;
 import com.compdfkit.core.signature.CPDFX509;
 import com.compdfkit.tools.R;
 import com.compdfkit.tools.common.utils.date.CDateUtil;
+import com.compdfkit.tools.signature.CertificateDigitalDatas;
 import com.compdfkit.tools.signature.bean.CPDFCertAttrDataItem;
 
 import java.util.ArrayList;
@@ -31,8 +32,8 @@ public class CertAttrDatas {
         List<CPDFCertAttrDataItem> list = new ArrayList<>();
         CPDFCertInfo certInfo = cpdfx509.getCertInfo();
         CPDFExtInfo extInfo = certInfo.getExtInfo();
-        list.add(new CPDFCertAttrDataItem(context.getString(R.string.tools_issued_to), getOwnerContent(certInfo.getSubject())));
-        list.add(new CPDFCertAttrDataItem(context.getString(R.string.tools_issuer), getOwnerContent(certInfo.getIssuer())));
+        list.add(new CPDFCertAttrDataItem(context.getString(R.string.tools_issued_to), CertificateDigitalDatas.getOwnerContent(certInfo.getSubject(),"\n")));
+        list.add(new CPDFCertAttrDataItem(context.getString(R.string.tools_issuer), CertificateDigitalDatas.getOwnerContent(certInfo.getIssuer(), "\n")));
         String validForm = CDateUtil.formatPDFUTCDate(certInfo.getValidDateBegin());
         list.add(new CPDFCertAttrDataItem(context.getString(R.string.tools_valid_from), CDateUtil.formatDate(validForm, CDateUtil.NORMAL_DATE_FORMAT_2)));
         String validTo =  CDateUtil.formatPDFUTCDate(certInfo.getValidDateEnd());
@@ -50,8 +51,8 @@ public class CertAttrDatas {
         CPDFCertInfo.CPDFAlgorithmType algorithmType = certInfo.getAlgorithmType(certInfo.getSignatureAlgOid());
         String signatureAlgorithm = algorithmType.name().replace("PDFSignatureAlgorithmType","");
         list.add(new CPDFCertAttrDataItem(context.getString(R.string.tools_algorithm), signatureAlgorithm + "(" +  certInfo.getSignatureAlgOid() +")"));
-        list.add(new CPDFCertAttrDataItem(context.getString(R.string.tools_subject), getOwnerContent(certInfo.getSubject())));
-        list.add(new CPDFCertAttrDataItem(context.getString(R.string.tools_issuer), getOwnerContent(certInfo.getIssuer())));
+        list.add(new CPDFCertAttrDataItem(context.getString(R.string.tools_subject), CertificateDigitalDatas.getOwnerContent(certInfo.getSubject(), "\n")));
+        list.add(new CPDFCertAttrDataItem(context.getString(R.string.tools_issuer), CertificateDigitalDatas.getOwnerContent(certInfo.getIssuer(), "\n")));
         list.add(new CPDFCertAttrDataItem(context.getString(R.string.tools_serial_number), certInfo.getSeriaNumber()));
         String validForm = CDateUtil.formatPDFUTCDate(certInfo.getValidDateBegin());
         list.add(new CPDFCertAttrDataItem(context.getString(R.string.tools_valid_from), CDateUtil.formatDate(validForm, CDateUtil.NORMAL_DATE_FORMAT_2)));
@@ -104,30 +105,4 @@ public class CertAttrDatas {
         return "";
     }
 
-
-    private static String getOwnerContent(CPDFOwnerInfo ownerInfo){
-        StringBuilder builder = new StringBuilder();
-        List<String> infos = new ArrayList<>();
-        if (!TextUtils.isEmpty(ownerInfo.getCountry())){
-            infos.add("C="+ownerInfo.getCountry());
-        }
-        if (!TextUtils.isEmpty(ownerInfo.getOrgnize())){
-            infos.add("O="+ownerInfo.getOrgnize());
-        }
-        if (!TextUtils.isEmpty(ownerInfo.getOrgnizeUnit())){
-            infos.add("OU="+ownerInfo.getOrgnizeUnit());
-        }
-        if (!TextUtils.isEmpty(ownerInfo.getCommonName())){
-            infos.add("CN="+ownerInfo.getCommonName());
-        }
-        for (int i = 0; i < infos.size(); i++) {
-            String item = infos.get(i);
-            builder.append(item);
-            if (i != infos.size() -1){
-                builder.append("\n");
-            }
-        }
-        return builder.toString();
-    }
-
 }

+ 28 - 2
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/info/signlist/CPDFCertDigitalSignListDialog.java

@@ -1,10 +1,12 @@
 package com.compdfkit.tools.signature.info.signlist;
 
 
+import android.content.DialogInterface;
 import android.os.Bundle;
 import android.view.View;
 import android.widget.ProgressBar;
 
+import androidx.annotation.NonNull;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
@@ -12,6 +14,7 @@ import com.compdfkit.core.document.CPDFDocument;
 import com.compdfkit.core.signature.CPDFSignature;
 import com.compdfkit.tools.R;
 import com.compdfkit.tools.common.basic.fragment.CBasicBottomSheetDialogFragment;
+import com.compdfkit.tools.common.interfaces.COnDialogDismissListener;
 import com.compdfkit.tools.common.utils.dialog.CAlertDialog;
 import com.compdfkit.tools.common.utils.threadpools.SimpleBackgroundTask;
 import com.compdfkit.tools.common.utils.viewutils.CViewUtils;
@@ -37,6 +40,8 @@ public class CPDFCertDigitalSignListDialog extends CBasicBottomSheetDialogFragme
 
     private CertDigitalSignListAdapter signListAdapter;
 
+    private COnDialogDismissListener dialogDismissListener;
+
 
     public void initWithPDFView(CPDFViewCtrl pdfView) {
         this.pdfView = pdfView;
@@ -93,7 +98,7 @@ public class CPDFCertDigitalSignListDialog extends CBasicBottomSheetDialogFragme
         signListAdapter.setOnItemClickListener((adapter, view1, position) -> {
             CPDFSignatureStatusInfo signature = adapter.list.get(position);
             CertDigitalSignInfoDialog infoDialog = CertDigitalSignInfoDialog.newInstance();
-            infoDialog.setTrustedCertRefreshListener(()-> initSignatureDatas());
+            infoDialog.setTrustedCertRefreshListener(this::initSignatureDatas);
             infoDialog.setPDFSignature(signature.getSignature());
             infoDialog.setDocument(pdfView.getCPdfReaderView().getPDFDocument());
             infoDialog.show(getChildFragmentManager(), "signInfoDialog");
@@ -105,7 +110,8 @@ public class CPDFCertDigitalSignListDialog extends CBasicBottomSheetDialogFragme
                 alertDialog.dismiss();
             });
             alertDialog.setConfirmClickListener(v -> {
-                boolean result = CertificateDigitalDatas.removeDigitalSign(pdfView.getCPdfReaderView().getPDFDocument(), signature.getSignature());
+                boolean result = CertificateDigitalDatas.removeDigitalSign(pdfView.getCPdfReaderView(),
+                        pdfView.getCPdfReaderView().getPDFDocument(), signature.getSignature());
                 if (result) {
                     signListAdapter.remove(position);
                 }
@@ -141,4 +147,24 @@ public class CPDFCertDigitalSignListDialog extends CBasicBottomSheetDialogFragme
         };
         task.execute();
     }
+
+    @Override
+    public void onCancel(@NonNull DialogInterface dialog) {
+        super.onCancel(dialog);
+        if (dialogDismissListener != null) {
+            dialogDismissListener.dismiss();
+        }
+    }
+
+    @Override
+    public void dismiss() {
+        super.dismiss();
+        if (dialogDismissListener != null) {
+            dialogDismissListener.dismiss();
+        }
+    }
+
+    public void setDialogDismissListener(COnDialogDismissListener dialogDismissListener) {
+        this.dialogDismissListener = dialogDismissListener;
+    }
 }

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

@@ -1,129 +0,0 @@
-/**
- * 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 androidx.annotation.DrawableRes;
-
-import com.compdfkit.core.document.CPDFSdk;
-import com.compdfkit.tools.R;
-import com.compdfkit.tools.common.utils.date.CDateUtil;
-
-import java.io.Serializable;
-
-public class CDigitalSignStyleData implements Serializable {
-
-
-    public CDigitalSignStyleData(){
-
-    }
-
-    public static CDigitalSignStyleData defaultConfig(String signImagePath){
-        CDigitalSignStyleData data = new CDigitalSignStyleData();
-        data.setLogoResId(R.drawable.tools_ic_compdfkit_logo);
-        data.setSignImagePath(signImagePath);
-        data.setDate(CDateUtil.getDataTime(CDateUtil.NORMAL_DATE_FORMAT));
-        data.setName("");
-        data.setSdkVersion(CPDFSdk.getSDKVersion());
-        data.setAlignment(CDigitalSignStylePreviewView.Alignment.left);
-        return data;
-    }
-
-    private String signImagePath;
-
-    private CDigitalSignStylePreviewView.Alignment alignment = CDigitalSignStylePreviewView.Alignment.left;
-
-    private String location;
-
-    private String reason;
-
-    private String name;
-
-    private String date;
-
-    private @DrawableRes int logoResId;
-
-    private String digtinguishableName;
-
-    private String sdkVersion;
-
-    public String getSignImagePath() {
-        return signImagePath;
-    }
-
-    public void setSignImagePath(String signImagePath) {
-        this.signImagePath = signImagePath;
-    }
-
-    public String getLocation() {
-        return location;
-    }
-
-    public void setLocation(String location) {
-        this.location = location;
-    }
-
-    public String getReason() {
-        return reason;
-    }
-
-    public void setReason(String reason) {
-        this.reason = reason;
-    }
-
-    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 String getDigtinguishableName() {
-        return digtinguishableName;
-    }
-
-    public void setDigtinguishableName(String digtinguishableName) {
-        this.digtinguishableName = digtinguishableName;
-    }
-
-    public String getSdkVersion() {
-        return sdkVersion;
-    }
-
-    public void setSdkVersion(String sdkVersion) {
-        this.sdkVersion = sdkVersion;
-    }
-
-
-    public void setAlignment(CDigitalSignStylePreviewView.Alignment alignment) {
-        this.alignment = alignment;
-    }
-
-    public CDigitalSignStylePreviewView.Alignment getAlignment() {
-        return alignment;
-    }
-
-    public int getLogoResId() {
-        return logoResId;
-    }
-
-    public void setLogoResId(int logoResId) {
-        this.logoResId = logoResId;
-    }
-}

+ 117 - 80
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/pdfproperties/pdfsign/CDigitalSignStylePreviewView.java

@@ -3,6 +3,7 @@ package com.compdfkit.tools.signature.pdfproperties.pdfsign;
 
 import android.content.Context;
 import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.Gravity;
@@ -17,11 +18,16 @@ import androidx.constraintlayout.widget.ConstraintLayout;
 import androidx.constraintlayout.widget.ConstraintSet;
 import androidx.transition.TransitionManager;
 
+import com.compdfkit.core.document.CPDFSdk;
+import com.compdfkit.core.signature.CPDFDigitalSigConfig;
 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;
 
+import java.util.ArrayList;
+import java.util.List;
+
 public class CDigitalSignStylePreviewView extends FrameLayout {
 
     private AppCompatImageView ivSignImage;
@@ -32,12 +38,22 @@ public class CDigitalSignStylePreviewView extends FrameLayout {
 
     private ConstraintLayout clPreview;
 
-    private CDigitalSignStyleData previewData;
+    private String location = "";
+
+    private String reason;
+
+    private String commonName;
 
-    private ConstraintLayout clRoot;
+    private String distinguishableName;
+
+    private String date;
+
+    private CPDFDigitalSigConfig digitalSigConfig = new CPDFDigitalSigConfig();
 
     private ConstraintSet constraintSet = new ConstraintSet();
 
+    private String signImagePath;
+
     private boolean showName = false;
 
     private boolean showDate = false;
@@ -50,10 +66,12 @@ public class CDigitalSignStylePreviewView extends FrameLayout {
 
     private boolean showTab;
 
-    private boolean showPosition;
+    private boolean showLocation;
 
     private boolean showReason;
 
+    private boolean contentAlignLeft = false;
+
     public CDigitalSignStylePreviewView(@NonNull Context context) {
         this(context, null);
     }
@@ -73,17 +91,22 @@ public class CDigitalSignStylePreviewView extends FrameLayout {
         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);
+        ConstraintLayout clRoot = findViewById(R.id.cl_root);
         constraintSet.clone(clPreview);
     }
 
-    public void setPreviewData(CDigitalSignStyleData data) {
-        previewData = data;
+    public void setCommonName(String commonName) {
+        this.commonName = commonName;
+        update();
+    }
+
+    public void setDistinguishableName(String distinguishableName) {
+        this.distinguishableName = distinguishableName;
         update();
     }
 
-    private void setSignImage(String signImagePath) {
-        previewData.setSignImagePath(signImagePath);
+    public void setSignImage(String signImagePath) {
+        this.signImagePath = signImagePath;
         update();
     }
 
@@ -103,9 +126,7 @@ public class CDigitalSignStylePreviewView extends FrameLayout {
     }
 
     public void setShowDate(boolean show) {
-        if (previewData != null) {
-            previewData.setDate(show ? CDateUtil.getDataTime(CDateUtil.NORMAL_DATE_FORMAT_1) : "");
-        }
+        this.date = show ? CDateUtil.getDataTime(CDateUtil.NORMAL_DATE_FORMAT_1) : "";
         this.showDate = show;
         update();
     }
@@ -120,39 +141,64 @@ public class CDigitalSignStylePreviewView extends FrameLayout {
         update();
     }
 
-    public void setShowPosition(boolean show){
-        this.showPosition = show;
+    public void setShowLocation(boolean show) {
+        this.showLocation = show;
         update();
     }
 
-    public void setShowReason(boolean show){
+    public void setShowReason(boolean show) {
         this.showReason = show;
         update();
     }
 
-    public void setPosition(String position) {
-        previewData.setLocation(position);
+    public void setLocation(String location) {
+        this.location = location;
         update();
     }
 
     public void setReason(String reason) {
-        previewData.setReason(reason);
+        this.reason = reason;
         update();
     }
 
-    public CDigitalSignStyleData getPreviewData() {
-        return previewData;
+    public CPDFDigitalSigConfig getConfig() {
+        digitalSigConfig.setDrawLogo(showLogo);
+        digitalSigConfig.setContentColor(0xFF000000);
+        digitalSigConfig.setTextColor(0xFF000000);
+        digitalSigConfig.setContentAlginLeft(contentAlignLeft);
+        digitalSigConfig.setContent(getContent());
+        digitalSigConfig.setDrawOnlyContent(TextUtils.isEmpty(signImagePath));
+        if (!TextUtils.isEmpty(signImagePath)) {
+            BitmapFactory.Options op = new BitmapFactory.Options();
+            op.inJustDecodeBounds = false;
+            op.inPreferredConfig = Bitmap.Config.ARGB_8888;
+            Bitmap bitmap = BitmapFactory.decodeFile(signImagePath, op);
+            digitalSigConfig.setImage(bitmap);
+        }
+        if (showLogo) {
+            digitalSigConfig.setLogo(BitmapFactory.decodeResource(getResources(), R.drawable.tools_logo));
+        }
+        return digitalSigConfig;
+    }
+
+    public String getLocation() {
+        return location;
     }
 
-    public void setAlignment(Alignment alignment){
-        previewData.setAlignment(alignment);
+    public String getReason() {
+        return reason;
+    }
+
+
+    public void setContentAlignLeft(boolean contentAlignLeft) {
+        this.contentAlignLeft = contentAlignLeft;
         update();
-        if (alignment == Alignment.left){
+        if (!contentAlignLeft) {
             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 {
+        } 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);
@@ -163,65 +209,57 @@ public class CDigitalSignStylePreviewView extends FrameLayout {
     }
 
     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(showLogo ? VISIBLE : GONE);
-            StringBuilder builder = new StringBuilder();
-            if (showName){
-                appendData(builder, showTab, R.string.tools_field_name, previewData.getName());
-            }
-            if (!TextUtils.isEmpty(builder) && showDistinguishableName && !TextUtils.isEmpty(previewData.getDigtinguishableName())){
-                builder.append("\n");
-            }
-            if (showDistinguishableName){
-                appendData(builder, showTab, R.string.tools_distinguishable_name, previewData.getDigtinguishableName());
-            }
-            if (!TextUtils.isEmpty(builder) && showReason && !TextUtils.isEmpty(previewData.getReason())){
-                builder.append("\n");
-            }
-            if (showReason){
-                appendData(builder, showTab, R.string.tools_reason, previewData.getReason());
-            }
-            if (!TextUtils.isEmpty(builder) && showPosition && !TextUtils.isEmpty(previewData.getLocation())){
-                builder.append("\n");
-            }
-            if (showPosition){
-                appendData(builder, showTab, R.string.tools_location, previewData.getLocation());
-            }
-            if (!TextUtils.isEmpty(builder) && showDate && !TextUtils.isEmpty(previewData.getDate())){
-                builder.append("\n");
-            }
-            if (showDate){
-                appendData(builder, showTab, R.string.tools_date, previewData.getDate());
-            }
-            if (!TextUtils.isEmpty(builder) && showSDKVersion && !TextUtils.isEmpty(previewData.getSdkVersion())){
+        if (!TextUtils.isEmpty(signImagePath)) {
+            GlideApp.with(getContext())
+                    .load(signImagePath)
+                    .into(ivSignImage);
+        }
+        ivSignImage.setVisibility(TextUtils.isEmpty(signImagePath) ? GONE : VISIBLE);
+        ivLogo.setVisibility(showLogo ? VISIBLE : GONE);
+
+        tvSignInfo.setText(getContent());
+        if (!contentAlignLeft) {
+            tvSignInfo.setGravity(Gravity.CENTER_VERTICAL | Gravity.START);
+        } else {
+            tvSignInfo.setGravity(Gravity.CENTER_VERTICAL | Gravity.END);
+        }
+    }
+
+    private String getContent() {
+        List<String> list = new ArrayList<>();
+        if (showName) {
+            appendData(list, R.string.tools_field_name, commonName);
+        }
+        if (showDistinguishableName) {
+            appendData(list, R.string.tools_dn, distinguishableName);
+        }
+        if (showReason) {
+            appendData(list, R.string.tools_reason, reason);
+        }
+        if (showLocation) {
+            appendData(list, R.string.tools_location, location);
+        }
+        if (showDate) {
+            appendData(list, R.string.tools_date, date);
+        }
+        if (showSDKVersion) {
+            appendData(list, R.string.tools_compdfkit_versions, CPDFSdk.getSDKVersion());
+        }
+        StringBuilder builder = new StringBuilder();
+        for (int i = 0; i < list.size(); i++) {
+            builder.append(list.get(i));
+            if (i != list.size() - 1) {
                 builder.append("\n");
             }
-            if (showSDKVersion) {
-                appendData(builder, showTab, R.string.tools_compdfkit_versions, previewData.getSdkVersion());
-            }
-            tvSignInfo.setText(builder);
-            if (previewData.getAlignment() == Alignment.left) {
-                tvSignInfo.setGravity(Gravity.CENTER_VERTICAL | Gravity.START);
-            }else {
-                tvSignInfo.setGravity(Gravity.CENTER_VERTICAL | Gravity.END);
-            }
         }
+        return builder.toString();
     }
 
-
-
-    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 void appendData(List<String> list, @StringRes int tabStringResId, String value) {
+        if (showTab) {
+            list.add(getString(tabStringResId) + ": " + value);
+        } else {
+            list.add(value);
         }
     }
 
@@ -229,11 +267,10 @@ public class CDigitalSignStylePreviewView extends FrameLayout {
         return getContext().getString(stringResId);
     }
 
-    public Bitmap getBitmap(){
+    public Bitmap getBitmap() {
         buildDrawingCache();
         Bitmap bitmap = Bitmap.createBitmap(getDrawingCache());
-        Bitmap resultBitmap = CBitmapUtil.cropTransparent(bitmap);
-        return resultBitmap;
+        return CBitmapUtil.cropTransparent(bitmap);
     }
 
     public enum Alignment {

+ 22 - 11
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/pdfproperties/pdfsign/CDigitalSignatureWidgetImpl.java

@@ -18,14 +18,17 @@ import androidx.fragment.app.FragmentActivity;
 import com.compdfkit.core.annotation.CPDFImageScaleType;
 import com.compdfkit.core.annotation.form.CPDFSignatureWidget;
 import com.compdfkit.core.signature.CPDFCertInfo;
+import com.compdfkit.core.signature.CPDFDigitalSigConfig;
 import com.compdfkit.core.signature.CPDFSignature;
 import com.compdfkit.tools.R;
+import com.compdfkit.tools.common.utils.CLog;
 import com.compdfkit.tools.common.utils.CToastUtil;
 import com.compdfkit.tools.common.utils.image.CBitmapUtil;
 import com.compdfkit.tools.common.views.directory.CFileDirectoryDialog;
 import com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl;
 import com.compdfkit.tools.signature.CertificateDigitalDatas;
 import com.compdfkit.tools.signature.importcert.create.CPDFSelectDigitalSignatureDialog;
+import com.compdfkit.tools.signature.info.CertAttrDatas;
 import com.compdfkit.tools.signature.info.CertDigitalSignInfoDialog;
 import com.compdfkit.tools.signature.preview.CDigitalSignStylePreviewDialog;
 import com.compdfkit.ui.proxy.form.CPDFSignatureWidgetImpl;
@@ -52,10 +55,10 @@ public class CDigitalSignatureWidgetImpl extends CPDFSignatureWidgetImpl {
         CPDFSelectDigitalSignatureDialog dialog = CPDFSelectDigitalSignatureDialog.newInstance();
         dialog.setCertDigitalSignListener((certFilePath, certPassword, signImagePath) -> {
             CPDFCertInfo certInfo = CertificateDigitalDatas.getCertInfo(certFilePath, certPassword);
-            CDigitalSignStylePreviewDialog previewDialog = CDigitalSignStylePreviewDialog.newInstance(signImagePath, certInfo.getSubject().getCommonName());
-            previewDialog.setResultDigitalSignListener((digitalSignImagePath, styleData) -> {
+            String dn = CertificateDigitalDatas.getOwnerContent(certInfo.getSubject(), ",");
+            CDigitalSignStylePreviewDialog previewDialog = CDigitalSignStylePreviewDialog.newInstance(signImagePath, certInfo.getSubject().getCommonName(), dn);
+            previewDialog.setResultDigitalSignListener((config, location, reason) -> {
                 try {
-
                     Context context = readerView.getContext();
                     CFileDirectoryDialog directoryDialog = CFileDirectoryDialog.newInstance(
                             Environment.getExternalStorageDirectory().getAbsolutePath(),
@@ -63,12 +66,7 @@ public class CDigitalSignatureWidgetImpl extends CPDFSignatureWidgetImpl {
                             context.getString(R.string.tools_save_to_this_directory)
                     );
                     directoryDialog.setSelectFolderListener(dir -> {
-                        // set sign image
-                        Bitmap bitmap = CBitmapUtil.decodeBitmap(digitalSignImagePath);
-                        ((CPDFSignatureWidget) pdfAnnotation).updateApWithBitmap(bitmap, CPDFImageScaleType.SCALETYPE_fitCenter);
-                        refresh();
-
-                        signDocument(cpdfSignatureWidget, styleData, certFilePath, certPassword, dir);
+                        signDocument(cpdfSignatureWidget, config, location, reason, certFilePath, certPassword, dir);
                     });
                     if (readerView.getContext() instanceof FragmentActivity) {
                         directoryDialog.show(((FragmentActivity) readerView.getContext()).getSupportFragmentManager(), "selectFolderDialog");
@@ -88,14 +86,25 @@ public class CDigitalSignatureWidgetImpl extends CPDFSignatureWidgetImpl {
     }
 
 
-    private void signDocument(CPDFSignatureWidget cpdfSignatureWidget, CDigitalSignStyleData styleData, String certFilePath, String certPassword, String saveDir) {
+    private void signDocument(CPDFSignatureWidget cpdfSignatureWidget,
+                              CPDFDigitalSigConfig config,
+                              String location,
+                              String reason,
+                              String certFilePath,
+                              String certPassword,
+                              String saveDir) {
         String uuid = UUID.randomUUID().toString().substring(0, 4);
         String fileName = readerView.getPDFDocument().getFileName();
         File saveFile = new File(saveDir + File.separator + fileName + "_" + uuid, readerView.getPDFDocument().getFileName());
         saveFile.getParentFile().mkdirs();
+
+        boolean updateSignApResult = cpdfSignatureWidget.updateApWithDigitalSigConfig(config);
+        if (!updateSignApResult){
+            return;
+        }
         // sign this pdf document
         boolean result = CertificateDigitalDatas.writeSignature(readerView.getPDFDocument(),
-                cpdfSignatureWidget, styleData,
+                cpdfSignatureWidget, location, reason,
                 certFilePath, certPassword, saveFile.getAbsolutePath());
         if (result) {
             CToastUtil.showToast(readerView.getContext(), readerView.getContext().getString(R.string.tools_digital_sign_success));
@@ -104,6 +113,8 @@ public class CDigitalSignatureWidgetImpl extends CPDFSignatureWidgetImpl {
                 CPDFViewCtrl pdfView = (CPDFViewCtrl) readerView.getParent();
                 pdfView.openPDF(saveFile.getAbsolutePath());
             }
+        } else {
+            CToastUtil.showToast(readerView.getContext(), "Signature Fail");
         }
     }
 }

+ 36 - 27
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/preview/CDigitalSignStylePreviewDialog.java

@@ -25,13 +25,14 @@ import androidx.appcompat.widget.AppCompatButton;
 import androidx.appcompat.widget.AppCompatCheckBox;
 import androidx.appcompat.widget.AppCompatImageView;
 import androidx.appcompat.widget.AppCompatTextView;
+import androidx.constraintlayout.widget.ConstraintLayout;
 
+import com.compdfkit.core.signature.CPDFDigitalSigConfig;
 import com.compdfkit.tools.R;
 import com.compdfkit.tools.annotation.pdfproperties.pdfsignature.data.CSignatureDatas;
 import com.compdfkit.tools.common.basic.fragment.CBasicBottomSheetDialogFragment;
 import com.compdfkit.tools.common.utils.viewutils.CViewUtils;
 import com.compdfkit.tools.common.views.CToolBar;
-import com.compdfkit.tools.signature.pdfproperties.pdfsign.CDigitalSignStyleData;
 import com.compdfkit.tools.signature.pdfproperties.pdfsign.CDigitalSignStylePreviewView;
 import com.compdfkit.tools.signature.preview.view.CSignStylePositionView;
 import com.compdfkit.tools.signature.preview.view.CSignStyleReasonView;
@@ -41,12 +42,13 @@ public class CDigitalSignStylePreviewDialog extends CBasicBottomSheetDialogFragm
 
     public static final String EXTRA_SIGN_IMAGE_PATH = "extra_sign_image_path";
     public static final String EXTRA_COMMON_NAME = "extra_common_name";
+    public static final String EXTRA_DIGTINGUISHABLE_NAME = "extra_dn";
 
     private CDigitalSignStylePreviewView previewView;
 
-    private AppCompatTextView tvPosition;
+    private ConstraintLayout clPosition;
 
-    private AppCompatTextView tvReason;
+    private ConstraintLayout clReason;
 
     private AppCompatTextView tvPositionDesc;
 
@@ -86,10 +88,11 @@ public class CDigitalSignStylePreviewDialog extends CBasicBottomSheetDialogFragm
 
     private COnResultDigitalSignListener resultDigitalSignListener;
 
-    public static CDigitalSignStylePreviewDialog newInstance(String signImagePath, String commonName) {
+    public static CDigitalSignStylePreviewDialog newInstance(String signImagePath, String commonName, String dn) {
         Bundle args = new Bundle();
         args.putString(EXTRA_SIGN_IMAGE_PATH, signImagePath);
         args.putString(EXTRA_COMMON_NAME, commonName);
+        args.putString(EXTRA_DIGTINGUISHABLE_NAME, dn);
         CDigitalSignStylePreviewDialog fragment = new CDigitalSignStylePreviewDialog();
         fragment.setArguments(args);
         return fragment;
@@ -140,8 +143,8 @@ public class CDigitalSignStylePreviewDialog extends CBasicBottomSheetDialogFragm
     @Override
     protected void onCreateView(View view) {
         previewView = view.findViewById(R.id.digital_sign_preview);
-        tvPosition = view.findViewById(R.id.tv_position);
-        tvReason = view.findViewById(R.id.tv_reason);
+        clPosition = view.findViewById(R.id.cl_position);
+        clReason = view.findViewById(R.id.cl_reason);
         tvPositionDesc = view.findViewById(R.id.tv_position_desc);
         tvReasonDesc = view.findViewById(R.id.tv_reason_desc);
         toolBar = view.findViewById(R.id.tool_bar);
@@ -168,8 +171,8 @@ public class CDigitalSignStylePreviewDialog extends CBasicBottomSheetDialogFragm
     }
 
     private void initListener(){
-        tvPosition.setOnClickListener(this);
-        tvReason.setOnClickListener(this);
+        clPosition.setOnClickListener(this);
+        clReason.setOnClickListener(this);
         toolBar.setBackBtnClickListener(this);
         btnSave.setOnClickListener(this);
         ivAlignmentLeft.setOnClickListener(this);
@@ -180,12 +183,12 @@ public class CDigitalSignStylePreviewDialog extends CBasicBottomSheetDialogFragm
             }else {
                 tvPositionDesc.setText(R.string.tools_close);
             }
-            previewView.setShowPosition(isChecked);
+            previewView.setShowLocation(isChecked);
         });
         positionView.setTextChangedListener((s, start, before, count) -> {
             if (positionView.isEnablePosition()){
                 tvPositionDesc.setText(s);
-                previewView.setPosition(TextUtils.isEmpty(s) ?"" : s.toString());
+                previewView.setLocation(TextUtils.isEmpty(s) ?"" : s.toString());
             }
         });
         reasonView.setOnCheckedChangeListener((buttonView, isChecked) -> {
@@ -212,14 +215,19 @@ public class CDigitalSignStylePreviewDialog extends CBasicBottomSheetDialogFragm
     }
 
     private void initData(){
-        String signImagePath = getArguments().getString(EXTRA_SIGN_IMAGE_PATH, "");
-        CDigitalSignStyleData data = CDigitalSignStyleData.defaultConfig(signImagePath);
-        if (getArguments() != null && !TextUtils.isEmpty(getArguments().getString(EXTRA_COMMON_NAME))) {
-            String commonName = getArguments().getString(EXTRA_COMMON_NAME);
-            data.setDigtinguishableName(commonName);
-            data.setName(commonName);
+        if (getArguments() != null) {
+            String signImagePath = getArguments().getString(EXTRA_SIGN_IMAGE_PATH, "");
+            tvAlignment.setVisibility(TextUtils.isEmpty(signImagePath) ? View.GONE : View.VISIBLE);
+            llAlignment.setVisibility(TextUtils.isEmpty(signImagePath) ? View.GONE : View.VISIBLE);
+            previewView.setSignImage(signImagePath);
+            if (!TextUtils.isEmpty(getArguments().getString(EXTRA_COMMON_NAME))){
+                String commonName = getArguments().getString(EXTRA_COMMON_NAME);
+                previewView.setCommonName(commonName);
+            }
+            if (!TextUtils.isEmpty(getArguments().getString(EXTRA_DIGTINGUISHABLE_NAME))){
+                previewView.setDistinguishableName(getArguments().getString(EXTRA_DIGTINGUISHABLE_NAME));
+            }
         }
-        previewView.setPreviewData(data);
         previewView.setShowName(cbName.isChecked());
         previewView.setShowDate(cbDate.isChecked());
         previewView.setShowLogo(cbLogo.isChecked());
@@ -227,38 +235,41 @@ public class CDigitalSignStylePreviewDialog extends CBasicBottomSheetDialogFragm
         previewView.setShowSDKVersion(cbSDKVersion.isChecked());
         previewView.setShowTab(cbTab.isChecked());
         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) {
+        if (v.getId() == R.id.cl_position) {
             positionView.setVisibility(View.VISIBLE);
+            btnSave.setVisibility(View.GONE);
             slMain.setVisibility(View.GONE);
-        } else if (v.getId() == R.id.tv_reason) {
+        } else if (v.getId() == R.id.cl_reason) {
             reasonView.setVisibility(View.VISIBLE);
+            btnSave.setVisibility(View.GONE);
             slMain.setVisibility(View.GONE);
         } else if (v.getId() == toolBar.getIvToolBarBackBtn().getId()){
+            CViewUtils.hideKeyboard(getDialog());
             if (positionView.getVisibility() == View.VISIBLE){
                 positionView.setVisibility(View.GONE);
                 slMain.setVisibility(View.VISIBLE);
+                btnSave.setVisibility(View.VISIBLE);
                 return;
             }
             if (reasonView.getVisibility() == View.VISIBLE){
                 reasonView.setVisibility(View.GONE);
                 slMain.setVisibility(View.VISIBLE);
+                btnSave.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);
+            previewView.setContentAlignLeft(false);
         } else if (v.getId() == R.id.iv_alignment_right) {
             ivAlignmentLeft.setSelected(false);
             ivAlignmentRight.setSelected(true);
-            previewView.setAlignment(CDigitalSignStylePreviewView.Alignment.right);
+            previewView.setContentAlignLeft(true);
         } else if (v.getId() == R.id.btn_save){
             CViewUtils.hideKeyboard(getDialog());
             if (positionView.getVisibility() == View.VISIBLE){
@@ -271,10 +282,8 @@ public class CDigitalSignStylePreviewDialog extends CBasicBottomSheetDialogFragm
                 slMain.setVisibility(View.VISIBLE);
                 return;
             }
-            Bitmap bitmap = previewView.getBitmap();
-            String imagePath = CSignatureDatas.saveSignatureBitmap(getContext(), bitmap);
             if (resultDigitalSignListener != null) {
-                resultDigitalSignListener.sign(imagePath, previewView.getPreviewData());
+                resultDigitalSignListener.sign(previewView.getConfig(), previewView.getLocation(), previewView.getReason());
             }
             dismiss();
         }
@@ -285,6 +294,6 @@ public class CDigitalSignStylePreviewDialog extends CBasicBottomSheetDialogFragm
     }
 
     public interface COnResultDigitalSignListener{
-        void sign(String digitalSignImagePath, CDigitalSignStyleData styleData);
+        void sign(CPDFDigitalSigConfig config, String location, String reason);
     }
 }

+ 4 - 7
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/signature/verify/CVerifySignStatusView.java

@@ -72,13 +72,10 @@ public class CVerifySignStatusView extends FrameLayout {
         tvStatus = findViewById(R.id.tv_status);
         btnDetails = findViewById(R.id.btn_details);
         progressBar = findViewById(R.id.progress_bar);
-        btnDetails.setOnClickListener(v -> {
-            if (getContext() instanceof FragmentActivity) {
-                CPDFCertDigitalSignListDialog signListDialog = CPDFCertDigitalSignListDialog.newInstance();
-                signListDialog.initWithPDFView(pdfView);
-                signListDialog.show(((FragmentActivity) getContext()).getSupportFragmentManager(), "signListDialog");
-            }
-        });
+    }
+
+    public AppCompatButton getBtnDetails() {
+        return btnDetails;
     }
 
     private void initAttr(Context context, AttributeSet attrs) {

+ 0 - 2
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/viewer/pdfsearch/data/CPDFSearchKeywordsDatas.java

@@ -52,10 +52,8 @@ public class CPDFSearchKeywordsDatas {
                 searchTextInfoList.addAll(searchPageContent);
             }
             if (searchTextInfoList.size() >= searchCount) {
-                page.close();
                 return searchTextInfoList;
             }
-            page.close();
         }
         return searchTextInfoList;
     }

BIN
ComPDFKit_Tools/src/main/res/drawable/tools_logo.png


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

@@ -16,6 +16,18 @@
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent" />
 
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_title_1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        android:text="*"
+        android:visibility="gone"
+        app:layout_constraintBaseline_toBaselineOf="@id/tv_title"
+        app:layout_constraintStart_toEndOf="@id/tv_title"
+        android:textColor="@color/tools_error"
+        app:layout_constraintTop_toTopOf="parent" />
+
 
     <androidx.appcompat.widget.AppCompatEditText
         android:id="@+id/edit_text"

+ 2 - 0
ComPDFKit_Tools/src/main/res/layout/tools_sign_certificate_attributes_list_trusted_cert_item.xml

@@ -32,6 +32,7 @@
         android:paddingStart="8dp"
         android:text="@string/tools_trusted_1"
         app:layout_constrainedWidth="true"
+        android:textColor="@color/tools_text_color_primary"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintHorizontal_bias="0"
         app:layout_constraintStart_toStartOf="parent"
@@ -45,6 +46,7 @@
         android:layout_marginStart="24dp"
         android:focusable="false"
         android:layout_marginTop="8dp"
+        android:textColor="@color/tools_text_color_primary"
         android:clickable="false"
         android:button="@drawable/tools_ic_cert_trusted_checkbox_radio"
         android:paddingStart="8dp"

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

@@ -36,6 +36,7 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:hint="@string/tools_please_enter_your_name"
+        app:showKeyTag="true"
         android:imeOptions="actionNext"
         android:title="@string/tools_field_name" />
 
@@ -61,6 +62,7 @@
         android:layout_height="wrap_content"
         android:hint="@string/tools_email_address_hint"
         android:imeOptions="actionDone"
+        app:showKeyTag="true"
         android:title="@string/tools_email_address" />
 
     <androidx.appcompat.widget.AppCompatTextView

+ 4 - 1
ComPDFKit_Tools/src/main/res/layout/tools_sign_style_preview_dialog.xml

@@ -1,6 +1,7 @@
 <?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">
@@ -35,7 +36,9 @@
         android:layout_width="match_parent"
         android:layout_height="0dp"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/tool_bar" />
+        app:layout_constraintTop_toBottomOf="@id/tool_bar"
+        app:layout_constraintVertical_bias="0.0"
+        tools:layout_editor_absoluteX="0dp" />
 
     <com.compdfkit.tools.signature.preview.view.CSignStylePositionView
         android:id="@+id/view_position"

+ 77 - 43
ComPDFKit_Tools/src/main/res/layout/tools_sign_style_preview_main.xml

@@ -1,8 +1,8 @@
 <?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"
-    android:layout_width="match_parent"
     android:id="@+id/sl_main"
+    android:layout_width="match_parent"
     android:layout_height="wrap_content">
 
 
@@ -81,54 +81,88 @@
 
         </LinearLayout>
 
-
-        <androidx.appcompat.widget.AppCompatTextView
-            android:id="@+id/tv_position"
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:id="@+id/cl_position"
             android:layout_width="match_parent"
-            android:layout_height="48dp"
+            android:layout_height="wrap_content"
             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_location"
-            app:drawableTint="@color/tools_text_color_primary"
-            android:textColor="@color/tools_text_color_primary"
-            app:layout_constraintTop_toBottomOf="@id/tv_alignment" />
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            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_position"
+                android:layout_width="wrap_content"
+                android:layout_height="48dp"
+                android:gravity="center_vertical"
+                android:paddingStart="16dp"
+                android:paddingEnd="16dp"
+                android:text="@string/tools_location"
+                android:textColor="@color/tools_text_color_primary"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent" />
 
-        <androidx.appcompat.widget.AppCompatTextView
-            android:id="@+id/tv_reason"
+            <androidx.appcompat.widget.AppCompatTextView
+                android:id="@+id/tv_position_desc"
+                android:layout_width="wrap_content"
+                android:layout_height="0dp"
+                android:layout_marginEnd="16dp"
+                android:drawableEnd="@drawable/tools_ic_right_arrow"
+                android:drawablePadding="8dp"
+                android:ellipsize="end"
+                android:gravity="center_vertical|end"
+                android:maxLines="2"
+                android:text="@string/tools_close"
+                android:textColor="@color/tools_text_color_primary"
+                app:drawableTint="@color/tools_text_color_primary"
+                app:layout_constrainedWidth="true"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintHorizontal_bias="1"
+                app:layout_constraintStart_toEndOf="@id/tv_position"
+                app:layout_constraintTop_toTopOf="parent" />
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:id="@+id/cl_reason"
             android:layout_width="match_parent"
-            android:layout_height="48dp"
+            android:layout_height="wrap_content"
             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" />
+            app:layout_constraintTop_toBottomOf="@id/cl_position">
+
+            <androidx.appcompat.widget.AppCompatTextView
+                android:id="@+id/tv_reason"
+                android:layout_width="wrap_content"
+                android:layout_height="48dp"
+                android:gravity="center_vertical"
+                android:paddingStart="16dp"
+                android:paddingEnd="16dp"
+                android:text="@string/tools_reason"
+                android:textColor="@color/tools_text_color_primary"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent" />
+
+            <androidx.appcompat.widget.AppCompatTextView
+                android:id="@+id/tv_reason_desc"
+                android:layout_width="wrap_content"
+                android:layout_height="0dp"
+                android:layout_marginEnd="16dp"
+                android:drawableEnd="@drawable/tools_ic_right_arrow"
+                android:drawablePadding="8dp"
+                android:gravity="center_vertical|end"
+                android:text="@string/tools_close"
+                android:textColor="@color/tools_text_color_primary"
+                app:drawableTint="@color/tools_text_color_primary"
+                app:layout_constrainedWidth="true"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintHorizontal_bias="1"
+                app:layout_constraintStart_toEndOf="@id/tv_reason"
+                app:layout_constraintTop_toTopOf="parent" />
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
 
-        <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"
@@ -141,7 +175,7 @@
             android:text="@string/tools_include_text"
             android:textColor="@color/tools_text_color_primary"
             android:textSize="12sp"
-            app:layout_constraintTop_toBottomOf="@id/tv_reason" />
+            app:layout_constraintTop_toBottomOf="@id/cl_reason" />
 
         <androidx.constraintlayout.helper.widget.Flow
             android:layout_width="match_parent"

+ 7 - 5
ComPDFKit_Tools/src/main/res/layout/tools_sign_style_preview_view.xml

@@ -9,12 +9,14 @@
 
     <androidx.appcompat.widget.AppCompatImageView
         android:id="@+id/iv_logo"
-        android:layout_width="60dp"
-        android:layout_height="60dp"
-        app:layout_constraintBottom_toBottomOf="parent"
+        android:layout_width="0dp"
+        app:layout_constraintDimensionRatio="1:1"
+        android:paddingVertical="8dp"
+        android:layout_height="0dp"
+        app:layout_constraintBottom_toBottomOf="@id/cl_preview"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintTop_toTopOf="@id/cl_preview"
         app:srcCompat="@drawable/tools_ic_compdfkit_logo" />
 
     <androidx.constraintlayout.widget.ConstraintLayout
@@ -43,7 +45,7 @@
             android:id="@+id/tv_sign_info"
             android:layout_width="0dp"
             android:layout_height="match_parent"
-            android:gravity="center_vertical"
+            android:gravity="center_vertical|start"
             android:lineSpacingMultiplier="1.15"
             android:textColor="@color/tools_sign_preview_text_color"
             app:autoSizeMaxTextSize="28sp"

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

@@ -93,6 +93,7 @@
         <attr name="android:imeOptions"/>
         <attr name="android:inputType"/>
         <attr name="android:hint"/>
+        <attr name="showKeyTag" format="boolean"/>
     </declare-styleable>
 
     <declare-styleable name="CVerifySignStatusView" tools:ignore="ResourceName">

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

@@ -323,6 +323,7 @@
     <string name="tools_none">None</string>
     <string name="tools_include_text">Include Text</string>
     <string name="tools_distinguishable_name">Distinguishable name</string>
+    <string name="tools_dn">DN</string>
     <string name="tools_date">Date</string>
     <string name="tools_logo">Logo</string>
     <string name="tools_compdfkit_versions">ComPDFKit Version</string>

+ 11 - 2
DigitalSignature/src/main/java/com/compdfkit/digitalsignature/PDFSignaturesSampleActivity.java

@@ -15,6 +15,7 @@ import android.os.Bundle;
 import android.view.View;
 
 import androidx.activity.result.ActivityResultLauncher;
+import androidx.fragment.app.FragmentActivity;
 
 import com.compdfkit.core.annotation.form.CPDFSignatureWidget;
 import com.compdfkit.core.document.CPDFDocument;
@@ -34,6 +35,7 @@ import com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl;
 import com.compdfkit.tools.common.views.pdfview.CPreviewMode;
 import com.compdfkit.tools.signature.CertificateDigitalDatas;
 import com.compdfkit.tools.signature.bean.CPDFDocumentSignInfo;
+import com.compdfkit.tools.signature.info.signlist.CPDFCertDigitalSignListDialog;
 import com.compdfkit.tools.signature.pdfproperties.pdfsign.CDigitalSignatureWidgetImpl;
 import com.compdfkit.tools.viewer.pdfsearch.CSearchResultDialogFragment;
 import com.compdfkit.ui.reader.CPDFReaderView;
@@ -68,6 +70,7 @@ public class PDFSignaturesSampleActivity extends CBasicPDFActivity {
         setContentView(binding.getRoot());
         binding.pdfView.setViewMode(CPDFReaderView.ViewMode.VIEW);
         screenStatusManager = new CViewerScreenStatusManager(binding);
+        binding.pdfView.getCPdfReaderView().setFormFieldHighlight(true);
         initToolbarListener();
         initSearchBar();
         initSignatureToolbar();
@@ -194,6 +197,12 @@ public class PDFSignaturesSampleActivity extends CBasicPDFActivity {
 
     private void initSignatureToolbar() {
         binding.signStatusView.initWithPDFView(binding.pdfView);
+        binding.signStatusView.getBtnDetails().setOnClickListener(v -> {
+                CPDFCertDigitalSignListDialog signListDialog = CPDFCertDigitalSignListDialog.newInstance();
+                signListDialog.initWithPDFView(binding.pdfView);
+                signListDialog.setDialogDismissListener(this::verifyDocumentSignStatus);
+                signListDialog.show(getSupportFragmentManager(), "signListDialog");
+        });
         binding.signatureToolBar.initWithPDFView(binding.pdfView);
         binding.signatureToolBar.getVerifySignButton().setOnClickListener(v -> {
             verifyDocumentSignStatus();
@@ -219,8 +228,8 @@ public class PDFSignaturesSampleActivity extends CBasicPDFActivity {
             });
         } else {
             if (binding.signStatusView.getVisibility() == View.VISIBLE) {
-                screenStatusManager.manager.removeToolView(binding.signStatusView);
-                screenStatusManager.manager.hideFromTop(binding.signStatusView, 200);
+                screenStatusManager.manager.removeAndHideToolView(binding.signStatusView);
+                screenStatusManager.constraintHide(binding.signStatusView);
             }
         }
     }

+ 16 - 1
Samples/build.gradle

@@ -8,7 +8,7 @@ android {
 
     defaultConfig {
         applicationId "com.compdfkit.samples"
-        minSdk rootProject.ext.android.MINSDK
+        minSdk 26
         targetSdk rootProject.ext.android.TARGETSDK
         versionCode rootProject.ext.android.VERSIONCODE as int
         versionName rootProject.ext.sdk.COMPDFKit_SDK_VERSION
@@ -41,6 +41,20 @@ android {
         sourceCompatibility JavaVersion.VERSION_1_8
         targetCompatibility JavaVersion.VERSION_1_8
     }
+    packagingOptions {
+        pickFirst 'META-INF/spring.factories'
+        pickFirst 'META-INF/license.txt'
+        pickFirst 'META-INF/DEPENDENCIES'
+        pickFirst 'META-INF/web-fragment.xml'
+        pickFirst 'META-INF/LICENSE.md'
+        pickFirst 'META-INF/NOTICE.md'
+        pickFirst 'META-INF/spring.schemas'
+        pickFirst 'META-INF/spring.tooling'
+        pickFirst 'META-INF/spring.handlers'
+        pickFirst 'META-INF/spring-configuration-metadata.json'
+        pickFirst 'META-INF/additional-spring-configuration-metadata.json'
+        pickFirst 'META-INF/notice.txt'
+    }
 }
 
 dependencies {
@@ -55,4 +69,5 @@ dependencies {
     annotationProcessor 'com.github.bumptech.glide:compiler:4.15.1'
 
     api 'androidx.documentfile:documentfile:1.0.1'
+     api 'com.compdf:compdfkit-api-java:1.3.2.0'
 }

BIN
Samples/src/main/assets/Certificate.pfx


BIN
Samples/src/main/assets/CommonFivePage_Signed.pdf


BIN
Samples/src/main/assets/Signed.pdf


+ 2 - 0
Samples/src/main/java/com/compdfkit/samples/SampleApplication.java

@@ -17,6 +17,7 @@ import com.compdfkit.samples.samples.AnnotationTest;
 import com.compdfkit.samples.samples.BackgroundTest;
 import com.compdfkit.samples.samples.BatesTest;
 import com.compdfkit.samples.samples.BookmarkTest;
+import com.compdfkit.samples.samples.DigitalSignaturesTest;
 import com.compdfkit.samples.samples.DocumentInfoTest;
 import com.compdfkit.samples.samples.EncryptTest;
 import com.compdfkit.samples.samples.FlattenTest;
@@ -51,6 +52,7 @@ public class SampleApplication extends Application {
         super.onCreate();
         application = this;
         samplesList.clear();
+        samplesList.add(new DigitalSignaturesTest());
         samplesList.add(new BookmarkTest());
         samplesList.add(new OutlineTest());
         samplesList.add(new PDFToImageTest());

+ 1 - 0
Samples/src/main/java/com/compdfkit/samples/SampleListActivity.java

@@ -19,6 +19,7 @@ import androidx.recyclerview.widget.RecyclerView;
 import com.compdfkit.samples.util.FileUtils;
 
 import java.io.File;
+import java.io.FileNotFoundException;
 
 public class SampleListActivity extends AppCompatActivity {
 

+ 300 - 0
Samples/src/main/java/com/compdfkit/samples/samples/DigitalSignaturesTest.java

@@ -0,0 +1,300 @@
+/**
+ * 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.samples.samples;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.RectF;
+
+import com.compdfkit.core.annotation.CPDFAnnotation;
+import com.compdfkit.core.annotation.form.CPDFSignatureWidget;
+import com.compdfkit.core.annotation.form.CPDFWidget;
+import com.compdfkit.core.document.CPDFDocument;
+import com.compdfkit.core.page.CPDFPage;
+import com.compdfkit.core.signature.CPDFDigitalSigConfig;
+import com.compdfkit.core.signature.CPDFOwnerInfo;
+import com.compdfkit.core.signature.CPDFSignature;
+import com.compdfkit.core.signature.CPDFSigner;
+import com.compdfkit.core.signature.CPDFX509;
+import com.compdfkit.samples.PDFSamples;
+import com.compdfkit.samples.R;
+import com.compdfkit.samples.util.DateUtil;
+import com.compdfkit.samples.util.FileUtils;
+import com.compdfkit.samples.util.OutputListener;
+
+import java.io.File;
+
+
+public class DigitalSignaturesTest extends PDFSamples {
+
+    public DigitalSignaturesTest() {
+        setTitle(R.string.digital_signature_title);
+        setDescription(R.string.digital_signature_desc);
+    }
+
+    @Override
+    protected void run(OutputListener outputListener) {
+        super.run(outputListener);
+        printHead();
+        printDividingLine();
+
+        //---------
+        //Samples 0: Create a pfx format certificate for digital signature use
+        generateCertificate();
+
+        //--------
+        //Samples 1: Create form fields for digital signature and digital signature using created pfx format certificate
+        createSignature();
+
+        //--------
+        //Samples 2: Verify signature
+        verifySignatureInfo();
+
+        //--------
+        //Samples 3: Verify certificate
+        verifyCertificate();
+
+        //--------
+        //Samples 4: Print digital signature info
+        printDigitalSignatureInfo();
+
+        //--------
+        //Samples 5: Trust certificate
+        trustCertificate();
+
+        //--------
+        //Samples 6:Remove digital signature from PDF document
+        removeDigitalSignature();
+
+        printFooter();
+    }
+
+    /**
+     * Create pfx format certificate for digital signature use
+     *
+     * Password: ComPDFKit
+     * C=SG: This represents the country code "SG," which typically stands for Singapore.
+     * O=ComPDFKit: This is the Organization (O) field, indicating the name of the organization or entity,
+     *      in this case, "ComPDFKit."
+     * D=R&D Department: This is the Department (D) field,
+     *      indicating the specific department within the organization,
+     *      in this case, "R&D Department."
+     * CN=Alan: This is the Common Name (CN) field, which usually represents the name
+     *      of the individual or entity. In this case, it is "Alan."
+     *
+     *
+     */
+    private void generateCertificate() {
+        outputListener.println("generate certificate");
+        String password = "ComPDFKit";
+        CPDFOwnerInfo ownerInfo = new CPDFOwnerInfo();
+        ownerInfo.setCommonName("Alan");
+        ownerInfo.setOrgnize("ComPDFKit");
+        ownerInfo.setEmail("xxxx@example.com");
+        ownerInfo.setCountry("SG");
+        CPDFSignature.CertUsage flag = CPDFSignature.CertUsage.PDFDigSig;
+        File certFile = new File(outputDir(), "certificate/Certificate.pfx");
+        certFile.getParentFile().mkdirs();
+
+        boolean result = CPDFSignature.generatePKCS12Cert(ownerInfo, password, certFile.getAbsolutePath(), flag, true);
+        if (result) {
+            outputListener.println("Done. File saved in Certificate.pfx");
+            outputListener.println("Generate PKCS12 certificate done");
+        }
+        addFileList(certFile.getAbsolutePath());
+        printDividingLine();
+    }
+
+    private void createSignature() {
+        outputListener.println("Create digital signature.");
+
+        CPDFDocument document = new CPDFDocument(context);
+        document.open(FileUtils.getAssetsTempFile(context, "CommonFivePage.pdf"));
+        //Insert a Form Signature Widget (unsigned)
+        CPDFPage cpdfPage = document.pageAtIndex(0);
+        RectF pageSize = cpdfPage.getSize();
+        RectF signatureRect = new RectF(28, 420, 150, 370);
+        signatureRect = cpdfPage.convertRectToPage(false, pageSize.width(), pageSize.height(), signatureRect);
+        CPDFSignatureWidget signatureWidget = (CPDFSignatureWidget) cpdfPage.addFormWidget(CPDFWidget.WidgetType.Widget_SignatureFields);
+        signatureWidget.setFieldName("Signature1");
+        int fillColor = 0xFF96B4D2;
+        signatureWidget.setFillColor(fillColor);
+        signatureWidget.setRect(signatureRect);
+        signatureWidget.updateAp();
+
+
+        // Make a digital signature
+        String fileName = FileUtils.getNameWithoutExtension(document.getFileName()) + "_Signed.pdf";
+        File file = new File(outputDir(), "digitalSignature/" + fileName);
+        file.getParentFile().mkdirs();
+        String password = "ComPDFKit";
+
+        String certPath = FileUtils.getAssetsTempFile(context, "Certificate.pfx");
+        CPDFX509 cpdfx509 = CPDFSignature.getX509ByPKCS12Cert(certPath, password);
+        String location = cpdfx509.getCertInfo().getSubject().getCountry();
+        String reason = "I am the owner of the document.";
+
+        Bitmap bitmap = BitmapFactory.decodeFile(FileUtils.getAssetsTempFile(context, "ComPDFKit.png"));
+        // Describe signature appearance information
+        CPDFDigitalSigConfig sigConfig = new CPDFDigitalSigConfig();
+        sigConfig.setText(cpdfx509.getCertInfo().getSubject().getCommonName());
+        sigConfig.setTextColor(0xFF000000);
+        sigConfig.setContentColor(0xFF000000);
+        sigConfig.setLogo(bitmap);
+        StringBuilder builder = new StringBuilder();
+        builder.append("Name: ").append(cpdfx509.getCertInfo().getSubject().getCommonName()).append("\n")
+                        .append("Date: ").append(DateUtil.getDataTime("yyyy.MM.dd HH:mm:ss")).append("\n")
+                        .append("Reason: ").append(reason).append("\n")
+                        .append("Location: ").append(location).append("\n")
+                        .append("DN: ").append(cpdfx509.getCertInfo().getSubject());
+        sigConfig.setContent(builder.toString());
+        sigConfig.setContentAlginLeft(false);
+        sigConfig.setDrawLogo(true);
+
+        boolean updateSignAp = signatureWidget.updateApWithDigitalSigConfig(sigConfig);
+        if (updateSignAp){
+            boolean writeSignResult = document.writeSignature(signatureWidget,
+                    file.getAbsolutePath(),
+                    certPath,
+                    password,
+                    location,
+                    reason,
+                    CPDFDocument.PDFDocMdpP.PDFDocMdpPForbidAllModify
+            );
+            if (writeSignResult) {
+                addFileList(file.getAbsolutePath());
+                outputListener.println("Done. File saved in " + fileName);
+                outputListener.println("Create digital signature done");
+            }
+        }
+
+        printDividingLine();
+    }
+
+    private void verifySignatureInfo() {
+        outputListener.println("Verify digital signature");
+        CPDFDocument document = new CPDFDocument(context);
+        document.open(FileUtils.getAssetsTempFile(context, "Signed.pdf"));
+        // Iterate through all digital signatures
+        for (int i = 0; i < document.getSignatureCount(); i++) {
+            CPDFSignature signature = document.getPdfSignature(i);
+            // Check if the signer array exists and is not empty
+            if (signature.getSignerArr() != null && signature.getSignerArr().length > 0) {
+                CPDFSigner signer = signature.getSignerArr()[0];
+
+                // Verify the validity of the signature
+                boolean verifyValid = signature.verify(document);
+
+                // Verify if the document has not been modified
+                boolean unmodified = signature.verifyDocument(document);
+
+                // Determine if the signature is valid and the document is unmodified
+                boolean isSignVerified = verifyValid && unmodified;
+
+                // Check if the certificate is trusted
+                boolean certChainTrusted = signer.getCert().verifyGetChain(document.getContext(), signature);
+                boolean certificateIsTrusted = signer.getCert().checkCertificateIsTrusted(document.getContext());
+                boolean certIsTrusted = certChainTrusted || certificateIsTrusted;
+
+                // Check if the certificate has expired
+                boolean isExpired = signer.getCert().isExpired();
+
+                // Take appropriate actions based on the verification results
+                if (isSignVerified && certIsTrusted) {
+                    // Signature is valid and the certificate is trusted
+                    // Perform corresponding actions
+
+                } else if (isSignVerified && !certIsTrusted) {
+                    // Signature is valid but the certificate is not trusted
+                    // Perform corresponding actions
+                } else {
+                    // Signature is invalid
+                    // Perform corresponding actions
+                }
+                outputListener.println("Is the certificate trusted: " + certIsTrusted);
+                outputListener.println("Is the signature verified: " + isSignVerified);
+            }
+        }
+        outputListener.println("Verify digital signature done.");
+        printDividingLine();
+    }
+
+    private void verifyCertificate() {
+        outputListener.println("verify certificate");
+        // Verify whether the specified certificate file is trusted
+        String certFilePath = FileUtils.getAssetsTempFile(context, "Certificate.pfx");
+        String password = "ComPDFKit";
+        if (CPDFSignature.checkPKCS12Password(certFilePath, password)) {
+            CPDFX509 x509 = CPDFSignature.getX509ByPKCS12Cert(certFilePath, password);
+            boolean result = x509.addToTrustedCertificates(context);
+            boolean isTrusted = x509.checkCertificateIsTrusted(context);
+            if (isTrusted) {
+                outputListener.println("Certificate is trusted");
+            } else {
+                outputListener.println("Certificate is not trusted");
+            }
+            outputListener.println("Verify certificate done.");
+        }
+        printDividingLine();
+    }
+
+    private void printDigitalSignatureInfo() {
+        outputListener.println("Print digital signature info.");
+        CPDFDocument document = new CPDFDocument(context);
+        document.open(FileUtils.getAssetsTempFile(context, "Signed.pdf"));
+        for (int i = 0; i < document.getSignatureCount(); i++) {
+            CPDFSignature signature = document.getPdfSignature(i);
+            // Check if the signer array exists and is not empty
+            if (signature.getSignerArr() != null && signature.getSignerArr().length > 0) {
+                CPDFSigner signer = signature.getSignerArr()[0];
+                CPDFOwnerInfo subject = signer.getCert().getCertInfo().getSubject();
+                outputListener.println("Name: " + signature.getName());
+                outputListener.println("Location: " + signature.getLocation());
+                outputListener.println("Reason: " + signature.getReason());
+                outputListener.println("Date: " + DateUtil.transformPDFDate(signature.getDate()));
+                outputListener.println("Subject: " + subject.toString());
+            }
+        }
+        outputListener.println("Print digital signature info done.");
+        printDividingLine();
+    }
+
+    private void trustCertificate(){
+        outputListener.println("Trust certificate");
+        CPDFDocument document = new CPDFDocument(context);
+        document.open(FileUtils.getAssetsTempFile(context, "Signed.pdf"));
+        CPDFSignature signature = document.getPdfSignature(0);
+        CPDFSigner signer = signature.getSignerArr()[0];
+        CPDFX509 cpdfx509 = signer.getCert();
+        outputListener.println("Certificate trusted status: " + cpdfx509.checkCertificateIsTrusted(context));
+        outputListener.println("---Begin trusted---");
+        cpdfx509.addToTrustedCertificates(context);
+        outputListener.println("Certificate trusted status: " + cpdfx509.checkCertificateIsTrusted(context));
+        outputListener.println("Trust certificate done.");
+        printDividingLine();
+    }
+
+    private void removeDigitalSignature() {
+        outputListener.println("Remove digital signature");
+        CPDFDocument document = new CPDFDocument(context);
+        document.open(FileUtils.getAssetsTempFile(context, "Signed.pdf"));
+        for (int i = 0; i < document.getSignatureCount(); i++) {
+            CPDFSignature signature = document.getPdfSignature(i);
+            if (i == 0) {
+                document.removeSignature(signature, true, null);
+            }
+        }
+        String fileName = FileUtils.getNameWithoutExtension(document.getFileName()) + "_RemoveSign.pdf";
+        File file = new File(outputDir(), "digitalSignature/" + fileName);
+        saveSamplePDF(document, file, true);
+        outputListener.println("Done. File saved in " + fileName);
+        printDividingLine();
+    }
+}

+ 8 - 0
Samples/src/main/java/com/compdfkit/samples/util/DateUtil.java

@@ -11,6 +11,9 @@ package com.compdfkit.samples.util;
 
 import android.text.TextUtils;
 
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
 
 public class DateUtil {
 
@@ -31,4 +34,9 @@ public class DateUtil {
             return inputDate;
         }
     }
+
+    public static String getDataTime(String format) {
+        SimpleDateFormat df = new SimpleDateFormat(format);
+        return df.format(new Date());
+    }
 }

+ 1 - 1
Samples/src/main/java/com/compdfkit/samples/util/FileUtils.java

@@ -27,7 +27,7 @@ public class FileUtils {
 
     public static void shareFile(Context context, String title, String type, File file) {
         try {
-            Intent intent = new Intent(Intent.ACTION_VIEW);
+            Intent intent = new Intent(Intent.ACTION_SEND);
             intent.putExtra(Intent.EXTRA_SUBJECT, title);
             Uri uri = getUriBySystem(context, file);
             intent.putExtra(Intent.EXTRA_STREAM, uri);

+ 6 - 0
Samples/src/main/res/values/strings.xml

@@ -62,6 +62,12 @@
     <string name="annotation_import_export_test_title">AnnotationImportExport</string>
     <string name="annotation_import_export_test_desc">This sample shows how to set up the export and import of annotations. The document from which the annotations are exported is an xfdf file</string>
 
+    <string name="annotation_content_edit_title">TextEditTest</string>
+    <string name="annotation_content_edit_desc">PDF Document Text Edit(insert,delete,replace)</string>
+
+    <string name="digital_signature_title">DigitalSignature</string>
+    <string name="digital_signature_desc">DigitalSignature Description</string>
+
     <string name="tools_allowed">Allowed</string>
     <string name="tools_not_allowed">Not Allowed</string>
 

+ 3 - 1
Samples_kotlin/src/main/java/com/compdfkit/samples/SampleDetailActivity.kt

@@ -91,4 +91,6 @@ open class SampleDetailActivity : AppCompatActivity() {
             })
         }
     }
-}
+}
+
+

+ 1 - 0
build.gradle

@@ -2,6 +2,7 @@
 plugins {
     id 'com.android.application' version '7.3.1' apply false
     id 'com.android.library' version '7.3.1' apply false
+    id 'org.jetbrains.kotlin.android' version '1.8.0' apply false
 }
 
 apply from: "config.gradle"

+ 1 - 0
settings.gradle

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