浏览代码

PDFTool(Android) - 图形属性弹窗预览云朵效果,导出注释刷新数据库,无注释时置灰菜单

liuxiaolong 3 天之前
父节点
当前提交
ba2c8adaf8
共有 22 个文件被更改,包括 462 次插入272 次删除
  1. 二进制
      ComPDFKit_Repo/compdfkit-ui/ComPDFKit-UI.aar
  2. 二进制
      ComPDFKit_Repo/compdfkit/ComPDFKit.aar
  3. 0 2
      ComPDFKit_Tools/build.gradle
  4. 4 3
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/annotation/pdfannotationlist/CPDFAnnotationListFragment.java
  5. 7 1
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/annotation/pdfannotationlist/data/CPDFAnnotDatas.java
  6. 1 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfshape/CShapeStyleFragment.java
  7. 7 1
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/pdf/CPDFDocumentFragment.java
  8. 11 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/utils/CFileUtils.java
  9. 7 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/utils/window/CPopupMenuWindow.java
  10. 393 197
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/preview/CAnnotShapePreviewView.java
  11. 5 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/preview/CBasicAnnotPreviewView.java
  12. 9 2
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/preview/CStylePreviewView.java
  13. 1 1
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/views/pdfview/CPDFViewCtrl.java
  14. 1 0
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/compress/CPDFCompressDialog.java
  15. 0 42
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/contenteditor/pdfproperties/CEditTextProperFragment.java
  16. 1 1
      ComPDFKit_Tools/src/main/java/com/compdfkit/tools/docseditor/pdfpageedit/CPDFPageEditDialogFragment.java
  17. 1 0
      ComPDFKit_Tools/src/main/res/color/tools_icon_status_color.xml
  18. 5 0
      ComPDFKit_Tools/src/main/res/color/tools_normal_text_view_status_color_dark.xml
  19. 5 0
      ComPDFKit_Tools/src/main/res/color/tools_normal_text_view_status_color_light.xml
  20. 二进制
      ComPDFKit_Tools/src/main/res/drawable/tools_rotate.png
  21. 2 20
      ComPDFKit_Tools/src/main/res/layout/tools_edit_text_property_fragment.xml
  22. 2 2
      ComPDFKit_Tools/src/main/res/values/tools_themes.xml

二进制
ComPDFKit_Repo/compdfkit-ui/ComPDFKit-UI.aar


二进制
ComPDFKit_Repo/compdfkit/ComPDFKit.aar


+ 0 - 2
ComPDFKit_Tools/build.gradle

@@ -57,8 +57,6 @@ dependencies {
     // or use
 //    api ('com.compdf:compdfkit:2.1.4')
 //    api ('com.compdf:compdfkit-ui:2.2.0-SNAPSHOT')
-//    api project(path: ':ComPDFKit')
-//    api project(path: ':ComPDFKit-UI')
     api 'com.github.bumptech.glide:glide:4.15.1'
     annotationProcessor 'com.github.bumptech.glide:compiler:4.15.1'
     api 'androidx.documentfile:documentfile:1.0.1'

+ 4 - 3
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/annotation/pdfannotationlist/CPDFAnnotationListFragment.java

@@ -183,8 +183,9 @@ public class CPDFAnnotationListFragment extends Fragment {
      */
     public void showAnnotationMenu(View anchorView) {
         CPopupMenuWindow menuWindow = new CPopupMenuWindow(getContext());
+        boolean hasAnnotations = !listAdapter.list.isEmpty();
         menuWindow.addItem(R.string.tools_import_annotations, v -> importAnnotFileLauncher.launch(CFileUtils.getIntent("application/octet-stream")));
-        menuWindow.addItem(R.string.tools_export_annotations, v -> {
+        menuWindow.addItem(R.string.tools_export_annotations,hasAnnotations,  v -> {
             // Select the directory to export the annotation files
             String dirPath = Environment.getExternalStorageDirectory().getAbsolutePath();
             CFileDirectoryDialog directoryDialog = CFileDirectoryDialog.newInstance(dirPath, getString(R.string.tools_saving_path), getString(R.string.tools_okay));
@@ -197,8 +198,8 @@ public class CPDFAnnotationListFragment extends Fragment {
             });
             directoryDialog.show(getChildFragmentManager(), "dirDialog");
         });
-        menuWindow.addItem(R.string.tools_delete_all_annotations, v -> deleteAllAnnotations());
-        menuWindow.addItem(R.string.tools_delete_all_replies, v -> {
+        menuWindow.addItem(R.string.tools_delete_all_annotations, hasAnnotations, v -> deleteAllAnnotations());
+        menuWindow.addItem(R.string.tools_delete_all_replies,hasAnnotations,  v -> {
             CPDFDocument document = pdfView.getCPdfReaderView().getPDFDocument();
             CPDFAnnotDatas.removeAllAnnotationReply(document);
             updateAnnotationList();

+ 7 - 1
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/annotation/pdfannotationlist/data/CPDFAnnotDatas.java

@@ -204,9 +204,15 @@ public class CPDFAnnotDatas {
         File cacheFile = new File(document.getContext().getCacheDir(), "annotationExportCache");
         cacheFile.mkdirs();
         CLog.e("ComPDFKit", "Annotation export path:" + saveFile.getAbsolutePath());
-        return document.exportAnnotations(saveFile.getAbsolutePath(), cacheFile.getAbsolutePath());
+        boolean result = document.exportAnnotations(saveFile.getAbsolutePath(), cacheFile.getAbsolutePath());
+        if (result){
+            CFileUtils.notifyMediaStore(document.getContext(), saveFile.getAbsolutePath());
+        }
+        return result;
     }
 
+
+
     /**
      * Import annotations in xfdf file
      * @param document the document

+ 1 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfshape/CShapeStyleFragment.java

@@ -194,6 +194,7 @@ public class CShapeStyleFragment extends CBasicPropertiesFragment {
                 CPDFAnnotation.CPDFBorderEffectType bordEffectType = bordEffectTypeAdapter.list.get(position);
                 viewModel.getStyle().setBordEffectType(bordEffectType);
                 enableDashSeekBar(bordEffectType == CPDFAnnotation.CPDFBorderEffectType.CPDFBorderEffectTypeSolid);
+                stylePreviewView.setBorderEffectType(bordEffectType);
             }
 
             @Override

+ 7 - 1
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/pdf/CPDFDocumentFragment.java

@@ -304,6 +304,12 @@ public class CPDFDocumentFragment extends CBasicPDFFragment {
                 if (!cpdfConfiguration.modeConfig.readerOnly) {
                     //Use the CFillScreenManager.class to manage fullscreen switching.
                     screenManager.fillScreenChange();
+                    CPDFReaderView readerView = pdfView.getCPdfReaderView();
+                    if (!readerView.isContinueMode() && CViewUtils.isLandScape(getContext()) && !readerView.isVerticalMode()){
+                        readerView.postDelayed(()->{
+                            readerView.setScale(1F);
+                        }, 200);
+                    }
                 }
             }
 
@@ -553,7 +559,7 @@ public class CPDFDocumentFragment extends CBasicPDFFragment {
                 .setScreenshotBorderColor(ContextCompat.getColor(getContext(), R.color.tools_color_accent))
                 .setScreenshotBorderDash(new float[]{8.0F, 4F})
                 .setFormPreviewPaint(paint)
-                .setRotateAnnotationDrawableRes(R.drawable.tools_ic_watermark_control)
+                .setRotateAnnotationDrawableRes(R.drawable.tools_rotate)
                 .build();
         pdfView.getCPdfReaderView().getEditManager().updateEditConfig(editConfig);
 

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

@@ -297,6 +297,17 @@ public class CFileUtils {
         return intent;
     }
 
+    public static void notifyMediaStore(Context context, String filePath) {
+        try{
+            Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
+            Uri uri = Uri.fromFile(new File(filePath));
+            intent.setData(uri);
+            context.sendBroadcast(intent);
+        }catch (Exception e){
+
+        }
+    }
+
     public static Intent selectSystemDir(boolean isOnlyLocal) {
         Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
         intent.putExtra("android.content.extra.SHOW_ADVANCED", isOnlyLocal);

+ 7 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/utils/window/CPopupMenuWindow.java

@@ -73,11 +73,18 @@ public class CPopupMenuWindow extends CBasePopupWindow {
     }
 
     public void addItem(@StringRes int stringResId, View.OnClickListener clickListener){
+        addItem(stringResId, true, clickListener);
+    }
+
+    public void addItem(@StringRes int stringResId,boolean enable, View.OnClickListener clickListener){
         View itemView = LayoutInflater.from(mContext).inflate(R.layout.tools_menu_window_item, null);
         AppCompatImageView ivIcon = itemView.findViewById(R.id.iv_menu_icon);
         AppCompatTextView tvTitle = itemView.findViewById(R.id.tv_menu_title);
         ivIcon.setVisibility(View.GONE);
+        ivIcon.setEnabled(enable);
         tvTitle.setText(stringResId);
+        tvTitle.setEnabled(enable);
+        itemView.setEnabled(enable);
         itemView.findViewById(R.id.ll_root).setOnClickListener(v -> {
             if (clickListener != null) {
                 clickListener.onClick(v);

+ 393 - 197
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/preview/CAnnotShapePreviewView.java

@@ -1,10 +1,10 @@
 /**
  * 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.
+ * 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.views.pdfproperties.preview;
@@ -14,268 +14,464 @@ import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.DashPathEffect;
 import android.graphics.Paint;
+import android.graphics.Paint.Join;
+import android.graphics.Paint.Style;
+import android.graphics.Path;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.View;
 
 import androidx.annotation.ColorInt;
 import androidx.annotation.IntRange;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import com.compdfkit.core.annotation.CPDFAnnotation.CPDFBorderEffectType;
 
 
 public class CAnnotShapePreviewView extends CBasicAnnotPreviewView {
 
-    private CShapeView shapeView;
+  private CShapeView shapeView;
 
-    public CAnnotShapePreviewView(@NonNull Context context) {
-        super(context);
+  public CAnnotShapePreviewView(@NonNull Context context) {
+    super(context);
+  }
+
+  public CAnnotShapePreviewView(@NonNull Context context, @Nullable AttributeSet attrs) {
+    super(context, attrs);
+  }
+
+  public CAnnotShapePreviewView(@NonNull Context context, @Nullable AttributeSet attrs,
+      int defStyleAttr) {
+    super(context, attrs, defStyleAttr);
+  }
+
+  @Override
+  protected void bindView() {
+    shapeView = new CShapeView(getContext());
+    addView(shapeView);
+  }
+
+  @Override
+  protected void initView() {
+
+  }
+
+  @Override
+  public void setColor(int color) {
+    super.setColor(color);
+    if (shapeView != null) {
+      shapeView.setFillColor(color);
     }
+  }
 
-    public CAnnotShapePreviewView(@NonNull Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
+  @Override
+  public void setOpacity(int opacity) {
+    super.setOpacity(opacity);
+    if (shapeView != null) {
+      shapeView.setFillColorOpacity(opacity);
     }
+  }
 
-    public CAnnotShapePreviewView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
+  @Override
+  public void setBorderColor(int color) {
+    super.setBorderColor(color);
+    if (shapeView != null) {
+      shapeView.setBorderColor(color);
     }
+  }
 
-    @Override
-    protected void bindView() {
-        shapeView = new CShapeView(getContext());
-        addView(shapeView);
+  @Override
+  public void setBorderColorOpacity(int opacity) {
+    super.setBorderColorOpacity(opacity);
+    if (shapeView != null) {
+      shapeView.setBorderColorOpacity(opacity);
     }
+  }
 
-    @Override
-    protected void initView() {
+  @Override
+  public void setBorderWidth(int borderWidth) {
+    super.setBorderWidth(borderWidth);
+    if (shapeView != null) {
+      shapeView.setBorderWidth(borderWidth);
+    }
+  }
 
+  @Override
+  public void setDashedGsp(int dashedGap) {
+    if (shapeView != null) {
+      shapeView.setDashGap(dashedGap);
     }
+  }
 
-    @Override
-    public void setColor(int color) {
-        super.setColor(color);
-        if (shapeView != null) {
-            shapeView.setFillColor(color);
-        }
+  @Override
+  public void setShapeType(CShapeView.ShapeType shapeType) {
+    if (shapeView != null) {
+      shapeView.setShapeType(shapeType);
     }
+  }
 
-    @Override
-    public void setOpacity(int opacity) {
-        super.setOpacity(opacity);
-        if (shapeView != null) {
-            shapeView.setFillColorOpacity(opacity);
-        }
+  @Override
+  public void setBorderEffectType(CPDFBorderEffectType type) {
+    if (shapeView != null) {
+      shapeView.setBorderEffectType(type);
     }
+  }
 
-    @Override
-    public void setBorderColor(int color) {
-        super.setBorderColor(color);
-        if (shapeView != null) {
-            shapeView.setBorderColor(color);
-        }
+  static class CShapeView extends View {
+
+    enum ShapeType {
+      SQUARE,
+      CIRCLE,
+      LINE,
+      ARROW,
     }
 
-    @Override
-    public void setBorderColorOpacity(int opacity) {
-        super.setBorderColorOpacity(opacity);
-        if (shapeView != null) {
-            shapeView.setBorderColorOpacity(opacity);
-        }
+    public static final float SQUARE_RATIO = 27F / 20F;
+    private Paint borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+    private Paint fillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+    private ShapeType shapeType = ShapeType.SQUARE;
+
+    private int borderColor = Color.BLACK;
+
+    private int fillColor = Color.GRAY;
+
+    private int borderColorOpacity = 255;
+
+    private int fillColorOpacity = 255;
+
+    private int borderWidth = 0;
+
+    private RectF borderRectF = new RectF();
+
+    private RectF fillRectF = new RectF();
+
+    private int mDashWidth = 8;
+
+    private int mDashGap = 0;
+
+    private Rect sizeRect = new Rect();
+
+    private CPDFBorderEffectType effectType = CPDFBorderEffectType.CPDFBorderEffectTypeSolid;
+
+    private int diameter = 20;
+
+    public CShapeView(Context context) {
+      this(context, null);
     }
 
-    @Override
-    public void setBorderWidth(int borderWidth) {
-        super.setBorderWidth(borderWidth);
-        if (shapeView != null) {
-            shapeView.setBorderWidth(borderWidth);
-        }
+    public CShapeView(Context context, @Nullable AttributeSet attrs) {
+      this(context, attrs, 0);
     }
 
-    @Override
-    public void setDashedGsp(int dashedGap) {
-        if (shapeView != null) {
-            shapeView.setDashGap(dashedGap);
-        }
+    public CShapeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+      super(context, attrs, defStyleAttr);
+      init(context);
     }
 
-    @Override
-    public void setShapeType(CShapeView.ShapeType shapeType){
-        if (shapeView != null){
-            shapeView.setShapeType(shapeType);
-        }
+    private void init(Context context) {
+      setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+      borderPaint.setColor(borderColor);
+      borderPaint.setAlpha(borderColorOpacity);
+      borderPaint.setStyle(Paint.Style.STROKE);
+      borderPaint.setStrokeWidth(borderWidth);
+      borderPaint.setStrokeCap(Paint.Cap.SQUARE);
+      borderPaint.setDither(true);
+      borderPaint.setXfermode(new PorterDuffXfermode(Mode.SRC));
+      if (mDashGap != 0) {
+        borderPaint.setPathEffect(
+            new DashPathEffect(new float[]{mDashWidth, mDashGap + borderWidth}, 0));
+      }
+
+      fillPaint.setColor(fillColor);
+      fillPaint.setAlpha(fillColorOpacity);
+      fillPaint.setStyle(Paint.Style.FILL_AND_STROKE);
     }
 
-    static class CShapeView extends View {
+    public void setBorderColor(@ColorInt int color) {
+      this.borderColor = color;
+      borderPaint.setColor(color);
+      borderPaint.setAlpha(borderColorOpacity);
+      invalidate();
+    }
 
-        enum ShapeType {
-            SQUARE,
-            CIRCLE,
-            LINE,
-            ARROW,
-        }
+    public void setBorderColorOpacity(@IntRange(from = 0, to = 255) int opacity) {
+      this.borderColorOpacity = opacity;
+      borderPaint.setAlpha(borderColorOpacity);
+      invalidate();
+    }
 
-        public static final float SQUARE_RATIO = 27F / 20F;
-        private Paint borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+    public void setFillColor(@ColorInt int color) {
+      this.fillColor = color;
+      fillPaint.setColor(fillColor);
+      fillPaint.setAlpha(fillColorOpacity);
+      invalidate();
+    }
 
-        private Paint fillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+    public void setFillColorOpacity(@IntRange(from = 0, to = 255) int opacity) {
+      this.fillColorOpacity = opacity;
+      fillPaint.setAlpha(fillColorOpacity);
+      invalidate();
+    }
 
-        private ShapeType shapeType = ShapeType.SQUARE;
+    public void setDashGap(@IntRange(from = 0, to = 8) int dashGap) {
+      this.mDashGap = dashGap;
+      if (dashGap == 0) {
+        borderPaint.setStyle(Paint.Style.STROKE);
+        borderPaint.setPathEffect(null);
+      } else {
+        borderPaint.setPathEffect(
+            new DashPathEffect(new float[]{mDashWidth, mDashGap + borderWidth}, 0));
+      }
+      invalidate();
+    }
 
-        private int borderColor = Color.BLACK;
+    public void setBorderWidth(int borderWidth) {
+      this.borderWidth = borderWidth;
+      borderPaint.setStrokeWidth(borderWidth);
+      if (mDashGap == 0) {
+        borderPaint.setPathEffect(null);
+      } else {
+        borderPaint.setPathEffect(
+            new DashPathEffect(new float[]{mDashWidth, mDashGap + borderWidth}, 0));
+      }
+      invalidate();
+    }
 
-        private int fillColor = Color.GRAY;
+    public void setBorderEffectType(CPDFBorderEffectType effectType) {
+      this.effectType = effectType;
+      invalidate();
+    }
 
-        private int borderColorOpacity = 255;
 
-        private int fillColorOpacity = 255;
+    public void setShapeType(ShapeType shapeType) {
+      this.shapeType = shapeType;
+      invalidate();
+    }
 
-        private int borderWidth = 0;
+    @Override
+    protected void onDraw(Canvas canvas) {
+      super.onDraw(canvas);
+      switch (shapeType) {
+        case SQUARE:
+          if (effectType == CPDFBorderEffectType.CPDFBorderEffectTypeCloudy) {
+            drawCloudySquare(canvas);
+          } else {
+            drawSolidSquare(canvas);
+          }
+          break;
+
+        case CIRCLE:
+          if (effectType == CPDFBorderEffectType.CPDFBorderEffectTypeCloudy) {
+            drawCloudyCircle(canvas);
+          } else {
+            drawSolidCircle(canvas);
+          }
+
+          break;
+        case LINE:
+          float lineWidth = getHeight();
+          float startX = (float) getWidth() / 2F - (lineWidth / 2);
+          float startY = (getHeight() / 2F) + borderWidth;
+          float stopX = startX + getHeight();
+          float stopY = (getHeight() / 2F) + borderWidth;
+          canvas.drawLine(startX, startY, stopX, stopY, borderPaint);
+          break;
+        case ARROW:
+
+          break;
+        default:
+          break;
+      }
+    }
 
-        private RectF borderRectF = new RectF();
+    private void drawSolidSquare(Canvas canvas) {
+      float width = getHeight() * SQUARE_RATIO;
+      float left = (float) getWidth() / 2F - (width / 2);
 
-        private RectF fillRectF = new RectF();
+      sizeRect.set((int) left,
+          0,
+          (int) (left + width),
+          getHeight());
 
-        private int mDashWidth = 8;
+      fillRectF.set(sizeRect.left + borderWidth, sizeRect.top + borderWidth,
+          sizeRect.right - borderWidth, sizeRect.bottom - borderWidth);
+      canvas.drawRect(fillRectF, fillPaint);
 
-        private int mDashGap = 0;
+      borderRectF.set(fillRectF.left - (borderWidth / 2F),
+          fillRectF.top - (borderWidth / 2F),
+          fillRectF.right + (borderWidth / 2F),
+          fillRectF.bottom + (borderWidth / 2F));
+      canvas.drawRect(borderRectF, borderPaint);
+    }
 
-        private Rect sizeRect = new Rect();
+    private void drawCloudySquare(Canvas canvas) {
+      float width = getHeight() * SQUARE_RATIO;
+      float left = (float) getWidth() / 2F - (width / 2);
 
-        public CShapeView(Context context) {
-            this(context, null);
-        }
+      sizeRect.set((int) left,
+          0,
+          (int) (left + width),
+          getHeight());
 
-        public CShapeView(Context context, @Nullable AttributeSet attrs) {
-            this(context, attrs, 0);
-        }
+      fillRectF.set(sizeRect.left + borderWidth, sizeRect.top + borderWidth,
+          sizeRect.right - borderWidth, sizeRect.bottom - borderWidth);
+      canvas.drawRect(fillRectF, fillPaint);
 
-        public CShapeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-            super(context, attrs, defStyleAttr);
-            init(context);
-        }
+      borderRectF.set(fillRectF.left,
+          fillRectF.top,
+          fillRectF.right,
+          fillRectF.bottom);
 
-        private void init(Context context) {
+      drawRoundedCorner(canvas, borderRectF.left, borderRectF.top, 90, 270); // 左上角
+      drawRoundedCorner(canvas, borderRectF.left, borderRectF.bottom - diameter, 0, 270); // 左下角
+      drawRoundedCorner(canvas, borderRectF.right - diameter, borderRectF.top, 180, 270); // 右上角
+      drawRoundedCorner(canvas, borderRectF.right - diameter, borderRectF.bottom - diameter, 270,
+          270); // 右下角
 
-            borderPaint.setColor(borderColor);
-            borderPaint.setAlpha(borderColorOpacity);
-            borderPaint.setStyle(Paint.Style.STROKE);
-            borderPaint.setStrokeWidth(borderWidth);
-            borderPaint.setStrokeCap(Paint.Cap.SQUARE);
-            if (mDashGap != 0){
-                borderPaint.setPathEffect(new DashPathEffect(new float[]{mDashWidth, mDashGap + borderWidth}, 0));
-            }
+      int verRectCount = (int) (borderRectF.height() - (diameter * 2) / this.diameter);
+      float leftRectStartPoint = borderRectF.left;
+      float leftRectEndPoint = borderRectF.left + diameter;
+      float leftRectTopPoint = borderRectF.top + diameter;
 
-            fillPaint.setColor(fillColor);
-            fillPaint.setAlpha(fillColorOpacity);
-            fillPaint.setStyle(Paint.Style.FILL_AND_STROKE);
-        }
+      float rightRectStartPoint = borderRectF.right - diameter;
+      float rightRectEndPoint = borderRectF.right;
 
-        public void setBorderColor(@ColorInt int color) {
-            this.borderColor = color;
-            borderPaint.setColor(color);
-            borderPaint.setAlpha(borderColorOpacity);
-            invalidate();
-        }
+      for (int i = 0; i < verRectCount; i++) {
+        float currentTop = leftRectTopPoint + (i * this.diameter);
+        float currentBottom = Math.min(borderRectF.bottom - diameter, currentTop + this.diameter);
 
-        public void setBorderColorOpacity(@IntRange(from = 0, to = 255) int opacity) {
-            this.borderColorOpacity = opacity;
-            borderPaint.setAlpha(borderColorOpacity);
-            invalidate();
+        if (currentBottom - currentTop < 5) {
+          continue;
         }
 
-        public void setFillColor(@ColorInt int color) {
-            this.fillColor = color;
-            fillPaint.setColor(fillColor);
-            fillPaint.setAlpha(fillColorOpacity);
-            invalidate();
+        RectF leftCloudyRectF = new RectF(leftRectStartPoint, currentTop, leftRectEndPoint,
+            currentBottom);
+        canvas.drawArc(leftCloudyRectF, 90, 180, false, borderPaint);
+
+        RectF rightCloudyRectF = new RectF(rightRectStartPoint, currentTop, rightRectEndPoint,
+            currentBottom);
+        canvas.drawArc(rightCloudyRectF, 270, 180, false, borderPaint);
+      }
+      int horRectCount = (int) ((borderRectF.width() - (diameter)) / diameter);
+      float topRectTopPoint = borderRectF.top;
+      float topRectBottomPoint = topRectTopPoint + diameter;
+
+      float bottomRectTopPoint = borderRectF.bottom - diameter;
+      float bottomRectBottomPoint = borderRectF.bottom;
+
+      for (int i = 0; i < horRectCount; i++) {
+        float currentLeft = borderRectF.left + diameter + (i * diameter);
+        float currentRight = Math.min(borderRectF.right - diameter, currentLeft + diameter);
+        if (currentRight - currentLeft < 5) {
+          continue;
         }
+        RectF topCloudyRectF = new RectF(currentLeft, topRectTopPoint, currentRight,
+            topRectBottomPoint);
+        canvas.drawArc(topCloudyRectF, 180, 180, false, borderPaint);
 
-        public void setFillColorOpacity(@IntRange(from = 0, to = 255) int opacity) {
-            this.fillColorOpacity = opacity;
-            fillPaint.setAlpha(fillColorOpacity);
-            invalidate();
-        }
+        RectF bottomCloudyRectF = new RectF(currentLeft, bottomRectTopPoint, currentRight,
+            bottomRectBottomPoint);
+        canvas.drawArc(bottomCloudyRectF, 0, 180, false, borderPaint);
+      }
 
-        public void setDashGap(@IntRange(from = 0, to = 8) int dashGap) {
-            this.mDashGap = dashGap;
-            if (dashGap == 0) {
-                borderPaint.setStyle(Paint.Style.STROKE);
-                borderPaint.setPathEffect(null);
-            } else {
-                borderPaint.setPathEffect(new DashPathEffect(new float[]{mDashWidth, mDashGap + borderWidth}, 0));
-            }
-            invalidate();
-        }
+    }
 
-        public void setBorderWidth(int borderWidth) {
-            this.borderWidth = borderWidth;
-            borderPaint.setStrokeWidth(borderWidth);
-            if (mDashGap == 0){
-                borderPaint.setPathEffect(null);
-            }else {
-                borderPaint.setPathEffect(new DashPathEffect(new float[]{mDashWidth, mDashGap + borderWidth}, 0));
-            }
-            invalidate();
-        }
+    private void drawRoundedCorner(Canvas canvas, float left, float top, float startAngle,
+        float sweepAngle) {
+      RectF cornerRect = new RectF(left, top, left + diameter, top + diameter);
+      canvas.drawArc(cornerRect, startAngle, sweepAngle, false, borderPaint);
+    }
 
-        public void setShapeType(ShapeType shapeType) {
-            this.shapeType = shapeType;
-            invalidate();
-        }
 
-        @Override
-        protected void onDraw(Canvas canvas) {
-            super.onDraw(canvas);
-            switch (shapeType) {
-                case SQUARE:
-                    float width = getHeight() * SQUARE_RATIO;
-                    float left = (float) getWidth() / 2F - (width / 2);
-
-                    sizeRect.set((int) left,
-                            0,
-                            (int) (left + width),
-                            getHeight());
-
-                    fillRectF.set(sizeRect.left + borderWidth, sizeRect.top + borderWidth, sizeRect.right - borderWidth, sizeRect.bottom - borderWidth);
-                    canvas.drawRect(fillRectF, fillPaint);
-
-                    borderRectF.set(fillRectF.left - (borderWidth / 2F),
-                            fillRectF.top - (borderWidth / 2F),
-                            fillRectF.right + (borderWidth / 2F),
-                            fillRectF.bottom + (borderWidth / 2F));
-                    canvas.drawRect(borderRectF, borderPaint);
-                    break;
-
-                case CIRCLE:
-                    float circleWidth = getHeight();
-                    float circleLeft = (float) getWidth() / 2F - (circleWidth / 2);
-                    sizeRect.set((int) circleLeft,
-                            0,
-                            (int) (circleLeft + circleWidth),
-                            getHeight());
-                    fillRectF.set(sizeRect.left + borderWidth, sizeRect.top + borderWidth, sizeRect.right - borderWidth, sizeRect.bottom - borderWidth);
-                    canvas.drawOval(fillRectF, fillPaint);
-                    borderRectF.set(fillRectF.left - (borderWidth / 2F),
-                            fillRectF.top - (borderWidth / 2F),
-                            fillRectF.right + (borderWidth / 2F),
-                            fillRectF.bottom + (borderWidth / 2F));
-                    canvas.drawOval(borderRectF, borderPaint);
-                    break;
-                case LINE:
-                    float lineWidth = getHeight();
-                    float startX = (float) getWidth() / 2F - (lineWidth / 2);
-                    float startY = (getHeight() / 2F) + borderWidth;
-                    float stopX = startX + getHeight();
-                    float stopY = (getHeight() / 2F) + borderWidth;
-                    canvas.drawLine(startX, startY, stopX, stopY, borderPaint);
-                    break;
-                case ARROW:
-
-                    break;
-                default:
-                    break;
-            }
-        }
+    private void drawSolidCircle(Canvas canvas) {
+      int padding = 10;
+      float circleWidth = getHeight() - padding;
+      float circleLeft = (float) getWidth() / 2F - (circleWidth / 2);
+      sizeRect.set((int) circleLeft,
+          padding / 2,
+          (int) (circleLeft + circleWidth),
+          getHeight() - (padding /2));
+      fillRectF.set(sizeRect.left + borderWidth, sizeRect.top + borderWidth,
+          sizeRect.right - borderWidth, sizeRect.bottom - borderWidth);
+      canvas.drawOval(fillRectF, fillPaint);
+      borderRectF.set(fillRectF.left - (borderWidth / 2F),
+          fillRectF.top - (borderWidth / 2F),
+          fillRectF.right + (borderWidth / 2F),
+          fillRectF.bottom + (borderWidth / 2F));
+      canvas.drawOval(borderRectF, borderPaint);
+
     }
+
+
+
+    private void drawCloudyCircle(Canvas canvas) {
+      int padding = 10;
+      float circleWidth = getHeight() - padding;
+      float circleLeft = (float) getWidth() / 2F - (circleWidth / 2);
+      sizeRect.set((int) circleLeft,
+          padding / 2,
+          (int) (circleLeft + circleWidth),
+          getHeight() - (padding /2));
+      fillRectF.set(sizeRect.left + borderWidth, sizeRect.top + borderWidth,
+          sizeRect.right - borderWidth, sizeRect.bottom - borderWidth);
+      canvas.drawOval(fillRectF, fillPaint);
+      borderRectF.set(fillRectF.left - (borderWidth / 2F),
+          fillRectF.top - (borderWidth / 2F),
+          fillRectF.right + (borderWidth / 2F),
+          fillRectF.bottom + (borderWidth / 2F));
+
+      drawCirclesOnBorder(canvas);
+    }
+
+    private void drawCirclesOnBorder(Canvas canvas) {
+
+      float smallCircleDiameter = diameter;
+      float smallCircleRadius = smallCircleDiameter / 2;
+      RectF borderRectF = new RectF(
+          fillRectF.left + smallCircleRadius,
+          fillRectF.top + smallCircleRadius ,
+          fillRectF.right -smallCircleRadius,
+          fillRectF.bottom - smallCircleRadius
+      );
+
+      float circleWidth = borderRectF.width();
+      float centerX = borderRectF.centerX();
+      float centerY = borderRectF.centerY();
+      float radius = circleWidth / 2;
+
+      float borderWidth = this.borderWidth;
+      float borderRadius = radius + (borderWidth / 2);
+
+      double circumference = 2 * Math.PI * borderRadius;
+
+      int numberOfCircles = (int) (circumference / smallCircleDiameter);
+
+      float angleInterval = 360f / numberOfCircles;
+
+      for (int i = 0; i < numberOfCircles; i++) {
+        float angle = angleInterval * i;
+        float x = centerX + borderRadius * (float) Math.cos(Math.toRadians(angle));
+        float y = centerY + borderRadius * (float) Math.sin(Math.toRadians(angle));
+
+        RectF smallCircleRect = new RectF(
+            x - smallCircleRadius,
+            y - smallCircleRadius,
+            x + smallCircleRadius,
+            y + smallCircleRadius
+        );
+        float startAngle = 280 + angle;
+        canvas.drawArc(smallCircleRect, startAngle, 170, false, borderPaint);
+      }
+    }
+
+  }
+
+
 }

+ 5 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/preview/CBasicAnnotPreviewView.java

@@ -20,6 +20,7 @@ import androidx.annotation.IntRange;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.compdfkit.core.annotation.CPDFAnnotation.CPDFBorderEffectType;
 import com.compdfkit.core.annotation.CPDFLineAnnotation;
 import com.compdfkit.tools.common.views.pdfproperties.pdfstyle.CAnnotStyle;
 
@@ -89,4 +90,8 @@ abstract class CBasicAnnotPreviewView extends FrameLayout {
     public void setFontPsName(String fontPsName){}
 
     public void setImage(Bitmap bitmap){}
+
+    public void setBorderEffectType(CPDFBorderEffectType type){
+
+    }
 }

+ 9 - 2
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/preview/CStylePreviewView.java

@@ -21,6 +21,7 @@ import androidx.annotation.ColorInt;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.compdfkit.core.annotation.CPDFAnnotation.CPDFBorderEffectType;
 import com.compdfkit.core.annotation.CPDFLineAnnotation;
 import com.compdfkit.tools.R;
 import com.compdfkit.tools.common.utils.viewutils.CDimensUtils;
@@ -158,6 +159,12 @@ public class CStylePreviewView extends FrameLayout {
         }
     }
 
+    public void setBorderEffectType(CPDFBorderEffectType effectType){
+        if (previewView != null){
+            previewView.setBorderEffectType(effectType);
+        }
+    }
+
     private void updatePreview() {
         removeAllViews();
         previewView = null;
@@ -183,13 +190,13 @@ public class CStylePreviewView extends FrameLayout {
             case ANNOT_SQUARE:
                 previewView = new CAnnotShapePreviewView(getContext());
                 previewView.setShapeType(CAnnotShapePreviewView.CShapeView.ShapeType.SQUARE);
-                layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, CDimensUtils.dp2px(getContext(), 30));
+                layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, CDimensUtils.dp2px(getContext(), 50));
                 layoutParams.gravity = Gravity.CENTER;
                 break;
             case ANNOT_CIRCLE:
                 previewView = new CAnnotShapePreviewView(getContext());
                 previewView.setShapeType(CAnnotShapePreviewView.CShapeView.ShapeType.CIRCLE);
-                layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, CDimensUtils.dp2px(getContext(), 40));
+                layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, CDimensUtils.dp2px(getContext(), 60));
                 layoutParams.gravity = Gravity.CENTER;
                 break;
             case ANNOT_LINE:

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

@@ -202,7 +202,7 @@ public class CPDFViewCtrl extends ConstraintLayout implements IReaderViewCallbac
 
 
     private void initCPDFReaderView() {
-        cPdfReaderView = new com.compdfkit.ui.reader.CPDFReaderView(getContext());
+        cPdfReaderView = new CPDFReaderView(getContext());
         cPdfReaderView.setDoublePageMode(false);
         cPdfReaderView.setReaderViewCallback(this);
         cPdfReaderView.setOnFocusedTypeChangedListener(this);

+ 1 - 0
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/compress/CPDFCompressDialog.java

@@ -156,6 +156,7 @@ public class CPDFCompressDialog extends CBasicBottomSheetDialogFragment implemen
     btnCancel.setOnClickListener(this);
     savePathView.setOnClickListener(this);
     toolBar.setBackBtnClickListener(v -> {
+      CViewUtils.hideKeyboard(etCustomQuality);
       dismiss();
     });
     rbQualityLow.setOnCheckedChangeListener(this);

+ 0 - 42
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/contenteditor/pdfproperties/CEditTextProperFragment.java

@@ -12,7 +12,6 @@ import androidx.appcompat.widget.AppCompatImageView;
 
 import com.compdfkit.core.annotation.CPDFTextAttribute;
 import com.compdfkit.tools.R;
-import com.compdfkit.tools.common.utils.CLog;
 import com.compdfkit.tools.common.utils.view.colorpicker.CColorPickerFragment;
 import com.compdfkit.tools.common.utils.view.colorpicker.widget.ColorPickerView;
 import com.compdfkit.tools.common.utils.view.sliderbar.CSliderBar;
@@ -21,7 +20,6 @@ import com.compdfkit.tools.common.views.pdfproperties.colorlist.ColorListView;
 import com.compdfkit.tools.common.views.pdfproperties.font.CPDFFontView;
 import com.compdfkit.tools.common.views.pdfproperties.pdfstyle.CAnnotStyle;
 import com.compdfkit.tools.common.views.pdfproperties.pdfstyle.CStyleFragmentDatas;
-import com.compdfkit.tools.common.views.pdfproperties.preview.CStylePreviewView;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -29,8 +27,6 @@ import java.util.List;
 public class CEditTextProperFragment extends CBasicPropertiesFragment
         implements View.OnClickListener, ColorPickerView.COnColorChangeListener, ColorPickerView.COnColorAlphaChangeListener {
 
-    private CStylePreviewView previewView;
-
     private ColorListView colorListView;
 
     private CSliderBar opacitySliderBar;
@@ -67,7 +63,6 @@ public class CEditTextProperFragment extends CBasicPropertiesFragment
 
     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
         View rootView = inflater.inflate(R.layout.tools_edit_text_property_fragment, container, false);
-        previewView = rootView.findViewById(R.id.style_preview);
         colorListView = rootView.findViewById(R.id.border_color_list_view);
         opacitySliderBar = rootView.findViewById(R.id.slider_bar);
         llAlignment = rootView.findViewById(R.id.ll_alignment_type);
@@ -104,12 +99,6 @@ public class CEditTextProperFragment extends CBasicPropertiesFragment
         super.onViewCreated(view, savedInstanceState);
         CAnnotStyle annotStyle = viewModel.getStyle();
         if (annotStyle != null) {
-            previewView.setTextColor(annotStyle.getTextColor());
-            previewView.setTextAlignment(annotStyle.getAlignment());
-            previewView.setTextColorOpacity(annotStyle.getTextColorOpacity());
-            previewView.setFontSize(annotStyle.getFontSize());
-            previewView.setFontPsName(annotStyle.getExternFontName());
-
             fontView.initFont(annotStyle.getExternFontName());
 
             colorListView.setSelectColor(annotStyle.getTextColor());
@@ -143,10 +132,6 @@ public class CEditTextProperFragment extends CBasicPropertiesFragment
                 setUpdatePropertyType(CAnnotStyle.EditUpdatePropertyType.TextColorOpacity);
                 opacity(progress);
                 setUpdatePropertyType(CAnnotStyle.EditUpdatePropertyType.All);
-            } else {
-                if (previewView != null) {
-                    previewView.setTextColorOpacity(progress);
-                }
             }
         });
         fontSizeSliderBar.setChangeListener((progress, percentageValue, isStop) -> {
@@ -234,9 +219,6 @@ public class CEditTextProperFragment extends CBasicPropertiesFragment
                 colorListView.setSelectColor(textColor);
             }
         }
-        if (previewView != null) {
-            previewView.setTextColor(textColor);
-        }
     }
 
     @Override
@@ -246,30 +228,6 @@ public class CEditTextProperFragment extends CBasicPropertiesFragment
                 opacitySliderBar.setProgress(textColorOpacity);
             }
         }
-        if (previewView != null) {
-            previewView.setTextColorOpacity(textColorOpacity);
-        }
-    }
-
-    @Override
-    public void onChangeAnnotExternFontType(String fontName) {
-        if (previewView != null) {
-            previewView.setFontPsName(fontName);
-        }
-    }
-
-    @Override
-    public void onChangeFontSize(int fontSize) {
-        if (previewView != null) {
-            previewView.setFontSize(fontSize);
-        }
-    }
-
-    @Override
-    public void onChangeTextAlignment(CAnnotStyle.Alignment alignment) {
-        if (previewView != null) {
-            previewView.setTextAlignment(alignment);
-        }
     }
 
 }

+ 1 - 1
ComPDFKit_Tools/src/main/java/com/compdfkit/tools/docseditor/pdfpageedit/CPDFPageEditDialogFragment.java

@@ -433,7 +433,7 @@ public class CPDFPageEditDialogFragment extends CBasicBottomSheetDialogFragment
         try {
             res &= newDocument.saveAs(filePath, false, false, pdfView.isSaveFileExtraFontSubset());
         } catch (Exception e) {
-
+            e.printStackTrace();
         }
         return res == true ? filePath : "";
     }

+ 1 - 0
ComPDFKit_Tools/src/main/res/color/tools_icon_status_color.xml

@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="@color/tools_icon_enable_color" android:state_enabled="false"/>
     <item android:color="?attr/colorAccent" android:state_selected="true"/>
     <item android:color="?attr/colorOnPrimary"/>
 </selector>

+ 5 - 0
ComPDFKit_Tools/src/main/res/color/tools_normal_text_view_status_color_dark.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="?attr/compdfkit_textColorPrimaryNoEnable" android:state_enabled="false"/>
+    <item android:color="@color/tools_dark_subtitle_1_color"/>
+</selector>

+ 5 - 0
ComPDFKit_Tools/src/main/res/color/tools_normal_text_view_status_color_light.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="?attr/compdfkit_textColorPrimaryNoEnable" android:state_enabled="false"/>
+    <item android:color="?android:attr/textColorPrimary"/>
+</selector>

二进制
ComPDFKit_Tools/src/main/res/drawable/tools_rotate.png


+ 2 - 20
ComPDFKit_Tools/src/main/res/layout/tools_edit_text_property_fragment.xml

@@ -10,32 +10,13 @@
         android:layout_height="wrap_content"
         android:animateLayoutChanges="true">
 
-        <com.compdfkit.tools.common.views.pdfproperties.preview.CStylePreviewView
-            android:id="@+id/style_preview"
-            android:layout_width="228dp"
-            android:layout_height="80dp"
-            android:layout_marginTop="10dp"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toTopOf="parent"
-            app:tools_annot_type="freetext" />
-
-        <View
-            android:id="@+id/line"
-            style="@style/tools_style_fragment_line"
-            android:layout_width="match_parent"
-            android:layout_marginTop="10dp"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@id/style_preview" />
-
         <com.compdfkit.tools.common.views.pdfproperties.colorlist.ColorListView
             android:id="@+id/border_color_list_view"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@id/line"
+            app:layout_constraintTop_toTopOf="parent"
             android:title="@string/tools_text_color" />
 
         <com.compdfkit.tools.common.utils.view.sliderbar.CSliderBar
@@ -187,6 +168,7 @@
             android:layout_marginTop="16dp"
             android:max="100"
             android:progress="1"
+            android:min="1"
             app:layout_constraintTop_toBottomOf="@id/tv_text_style"
             app:tools_slider_bar_value_show_type="source"
             android:title="@string/tools_annot_font_size" />

+ 2 - 2
ComPDFKit_Tools/src/main/res/values/tools_themes.xml

@@ -103,11 +103,11 @@
     </style>
 
     <style name="ComPDFKit.Theme.TextAppearance.Subtitle1.Dark" tools:ignore="ResourceName">
-        <item name="android:textColor">@color/tools_dark_subtitle_1_color</item>
+        <item name="android:textColor">@color/tools_normal_text_view_status_color_dark</item>
     </style>
 
     <style name="ComPDFKit.Theme.TextAppearance.Subtitle1.Light" tools:ignore="ResourceName">
-        <item name="android:textColor">@color/tools_subtitle_1_color</item>
+        <item name="android:textColor">@color/tools_normal_text_view_status_color_light</item>
     </style>