Browse Source

Merge branch 'compdfkit_demo_win_dev' into compdfkit_demo_win_dev_pdftech

# Conflicts:
#	Demo/Examples/ComPDFKit.Tool/CPDFToolManager.cs
#	Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.Annot.cs
#	Demo/Examples/ComPDFKit.Tool/DrawTool/CreateAnnotTool.cs
#	Demo/Examples/ComPDFKit.Tool/DrawTool/SelectedRect.cs
#	Demo/Examples/ComPDFKit.Tool/UndoManger/AnnotHistory.cs
#	Demo/Examples/ComPDFKit.Tool/UndoManger/GroupHistory.cs
#	Demo/Examples/ComPDFKit.Tool/UndoManger/MultiAnnotHistory.cs
#	Demo/Examples/ComPDFKit.Tool/UndoManger/PDFEditHistory/PDFEditHistory.cs
liyijie 1 month ago
parent
commit
c82ea76972
100 changed files with 9492 additions and 2061 deletions
  1. 1 1
      Demo/Examples/Annotations/MainWindow.xaml
  2. 2 2
      Demo/Examples/Annotations/Properties/AssemblyInfo.cs
  3. 139 1
      Demo/Examples/ComPDFKit.Tool/AlignmentsHelp.cs
  4. 444 81
      Demo/Examples/ComPDFKit.Tool/CPDFToolManager.cs
  5. 38 13
      Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.Annot.cs
  6. 1136 0
      Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.AnnotSelector.cs
  7. 161 18
      Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.Command.cs
  8. 2 0
      Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.CustomizeTool.cs
  9. 29 30
      Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.DataMethod.cs
  10. 6 0
      Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.FindReplace.cs
  11. 108 37
      Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.MultiSelectedRect.cs
  12. 131 0
      Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.PDFCompareEffect.cs
  13. 35 7
      Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.SelectImage.cs
  14. 4 1
      Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.SelectText.cs
  15. 17 1
      Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.SelectedRect.cs
  16. 1196 59
      Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.TextEdit.cs
  17. 10 0
      Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.WidgetTool.cs
  18. 2 4
      Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.xaml
  19. 232 26
      Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.xaml.cs
  20. 26 1
      Demo/Examples/ComPDFKit.Tool/ComPDFKit.Tool.csproj
  21. 195 116
      Demo/Examples/ComPDFKit.Tool/DrawTool/AnnotEdit.cs
  22. 210 0
      Demo/Examples/ComPDFKit.Tool/DrawTool/AnnotSelector.cs
  23. 61 18
      Demo/Examples/ComPDFKit.Tool/DrawTool/CreateAnnotTool.cs
  24. 16 1
      Demo/Examples/ComPDFKit.Tool/DrawTool/CreateCustomizeTool.cs
  25. 47 0
      Demo/Examples/ComPDFKit.Tool/DrawTool/DashBorder.cs
  26. 450 0
      Demo/Examples/ComPDFKit.Tool/DrawTool/FrameSelectTool.cs
  27. 193 17
      Demo/Examples/ComPDFKit.Tool/DrawTool/MultiSelectedRect.cs
  28. 301 19
      Demo/Examples/ComPDFKit.Tool/DrawTool/SelectedRect.cs
  29. 404 23
      Demo/Examples/ComPDFKit.Tool/DrawTool/SelectedRect.protected.cs
  30. 83 0
      Demo/Examples/ComPDFKit.Tool/Help/CommonHelper.cs
  31. 20 1
      Demo/Examples/ComPDFKit.Tool/Help/PDFHelp.cs
  32. 87 9
      Demo/Examples/ComPDFKit.Tool/Help/ParamConverter.cs
  33. 70 81
      Demo/Examples/ComPDFKit.Tool/PDFTextSearch.cs
  34. 9 1
      Demo/Examples/ComPDFKit.Tool/SettingParam/AnnotParam/FreeTextParam.cs
  35. 9 2
      Demo/Examples/ComPDFKit.Tool/SettingParam/AnnotParam/InkParam.cs
  36. 23 18
      Demo/Examples/ComPDFKit.Tool/SettingParam/AnnotParam/LineMeasureParam.cs
  37. 5 1
      Demo/Examples/ComPDFKit.Tool/SettingParam/AnnotParam/StampParam.cs
  38. 3 0
      Demo/Examples/ComPDFKit.Tool/SettingParam/AnnotParam/StickyNoteParam.cs
  39. 18 0
      Demo/Examples/ComPDFKit.Tool/SettingParam/DefaultSettingParam.cs
  40. 2 2
      Demo/Examples/ComPDFKit.Tool/UndoManger/AnnotHistory.cs
  41. 18 26
      Demo/Examples/ComPDFKit.Tool/UndoManger/AnnotHistory/FreeTextAnnotHistory.cs
  42. 15 0
      Demo/Examples/ComPDFKit.Tool/UndoManger/AnnotHistory/InkAnnotHistory.cs
  43. 14 10
      Demo/Examples/ComPDFKit.Tool/UndoManger/AnnotHistory/LineMeasureAnnotHistory.cs
  44. 1 1
      Demo/Examples/ComPDFKit.Tool/UndoManger/AnnotHistory/PolyLineMeasureAnnotHistory.cs
  45. 1 1
      Demo/Examples/ComPDFKit.Tool/UndoManger/AnnotHistory/PolygonMeasureAnnotHistory.cs
  46. 242 9
      Demo/Examples/ComPDFKit.Tool/UndoManger/AnnotHistory/StampAnnotHistory.cs
  47. 13 2
      Demo/Examples/ComPDFKit.Tool/UndoManger/AnnotHistory/StickyNoteAnnotHistory.cs
  48. 4 28
      Demo/Examples/ComPDFKit.Tool/UndoManger/FormHistory/ComboBoxHistory.cs
  49. 4 29
      Demo/Examples/ComPDFKit.Tool/UndoManger/FormHistory/ListBoxHistory.cs
  50. 4 28
      Demo/Examples/ComPDFKit.Tool/UndoManger/FormHistory/PushButtonHistory.cs
  51. 4 28
      Demo/Examples/ComPDFKit.Tool/UndoManger/FormHistory/TextBoxHistory.cs
  52. 8 7
      Demo/Examples/ComPDFKit.Tool/UndoManger/GroupHistory.cs
  53. 1 1
      Demo/Examples/ComPDFKit.Tool/UndoManger/MultiAnnotHistory.cs
  54. 28 21
      Demo/Examples/ComPDFKit.Tool/UndoManger/PDFEditHistory/PDFEditHistory.cs
  55. 1 1
      Demo/Examples/Compdfkit.Controls/Annotation/CPDFAnnotationPreviewerControl.xaml.cs
  56. 6 1
      Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationData/CPDFAnnotationData.cs
  57. 65 1
      Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationList/PDFAnnotationListControl/CPDFAnnotationListControl.xaml
  58. 203 18
      Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationList/PDFAnnotationListControl/CPDFAnnotationListControl.xaml.cs
  59. 134 0
      Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationList/PDFAnnotationListUI/AnnotationReplyListControl.xaml
  60. 215 0
      Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationList/PDFAnnotationListUI/AnnotationReplyListControl.xaml.cs
  61. 0 239
      Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationList/PDFAnnotationListUI/CPDFAnnoationListUI.xaml.cs
  62. 121 24
      Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationList/PDFAnnotationListUI/CPDFAnnoationListUI.xaml
  63. 690 0
      Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationList/PDFAnnotationListUI/CPDFAnnotationListUI.xaml.cs
  64. 71 0
      Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationList/PDFAnnotationListUI/ReplyStatusControl.xaml
  65. 175 0
      Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationList/PDFAnnotationListUI/ReplyStatusControl.xaml.cs
  66. 8 4
      Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationPanel/PDFAnnotationControl/CPDFAnnotationControl.xaml.cs
  67. 1 0
      Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationPanel/PDFAnnotationUI/CPDFSignatureUI.xaml.cs
  68. 1 1
      Demo/Examples/Compdfkit.Controls/Asset/Styles/ComboBoxStyle.xaml
  69. 0 2
      Demo/Examples/Compdfkit.Controls/Asset/Styles/ListBoxItemStyle.xaml
  70. 4 0
      Demo/Examples/Compdfkit.Controls/Common/BarControl/CPDFTitleBarControl.xaml
  71. 7 1
      Demo/Examples/Compdfkit.Controls/Common/BarControl/CPDFTitleBarControl.xaml.cs
  72. 2 4
      Demo/Examples/Compdfkit.Controls/Common/BaseControl/PageNumberControl.xaml
  73. 3 3
      Demo/Examples/Compdfkit.Controls/Common/Convert/AnnotArgsTypeToVisibilityConverter.cs
  74. 25 0
      Demo/Examples/Compdfkit.Controls/Common/Convert/AntiVisibilityConverter.cs
  75. 8 10
      Demo/Examples/Compdfkit.Controls/Common/Convert/LanguageResourceConverter.cs
  76. 28 0
      Demo/Examples/Compdfkit.Controls/Common/Convert/SubtractionConverter.cs
  77. 1 1
      Demo/Examples/Compdfkit.Controls/Common/PropertyControl/PDFFont/CPDFFontControl.xaml.cs
  78. 48 7
      Demo/Examples/Compdfkit.Controls/Compdfkit.Controls.csproj
  79. 3 1
      Demo/Examples/Compdfkit.Controls/DigitalSignature/DigitalSignatureControl/DigitalSignatureControl.xaml.cs
  80. 102 36
      Demo/Examples/Compdfkit.Controls/Edit/ContentEditCOntrol/ContentEditControl.xaml.cs
  81. 4 2
      Demo/Examples/Compdfkit.Controls/Edit/PDFContentEditControl.xaml.cs
  82. 90 96
      Demo/Examples/Compdfkit.Controls/Edit/PDFImageEdit/PDFImageEditControl/PDFImageEditControl.xaml
  83. 267 140
      Demo/Examples/Compdfkit.Controls/Edit/PDFImageEdit/PDFImageEditControl/PDFImageEditControl.xaml.cs
  84. 53 44
      Demo/Examples/Compdfkit.Controls/Edit/PDFTextEdit/PDFTextEditControl/PDFTextEditControl.xaml
  85. 360 151
      Demo/Examples/Compdfkit.Controls/Edit/PDFTextEdit/PDFTextEditControl/PDFTextEditControl.xaml.cs
  86. 80 77
      Demo/Examples/Compdfkit.Controls/Form/Property/CheckBoxProperty.xaml
  87. 104 101
      Demo/Examples/Compdfkit.Controls/Form/Property/ComboBoxProperty.xaml
  88. 1 1
      Demo/Examples/Compdfkit.Controls/Form/Property/ComboBoxProperty.xaml.cs
  89. 104 101
      Demo/Examples/Compdfkit.Controls/Form/Property/ListBoxProperty.xaml
  90. 1 1
      Demo/Examples/Compdfkit.Controls/Form/Property/ListBoxProperty.xaml.cs
  91. 90 88
      Demo/Examples/Compdfkit.Controls/Form/Property/PushButtonProperty.xaml
  92. 1 1
      Demo/Examples/Compdfkit.Controls/Form/Property/PushButtonProperty.xaml.cs
  93. 3 1
      Demo/Examples/Compdfkit.Controls/Form/Property/RadioButtonProperty.xaml
  94. 29 26
      Demo/Examples/Compdfkit.Controls/Form/Property/SignatureProperty.xaml
  95. 91 88
      Demo/Examples/Compdfkit.Controls/Form/Property/TextFieldProperty.xaml
  96. 1 1
      Demo/Examples/Compdfkit.Controls/Form/Property/TextFieldProperty.xaml.cs
  97. 2 2
      Demo/Examples/Compdfkit.Controls/Measure/MeasureControl.xaml.cs
  98. 3 3
      Demo/Examples/Compdfkit.Controls/Measure/MeasureSettingPanel.xaml.cs
  99. 4 1
      Demo/Examples/Compdfkit.Controls/PDFView/PDFDisplaySettings/PDFDisplaySettingsControl/CPDFDisplaySettingsControl.xaml
  100. 0 0
      Demo/Examples/Compdfkit.Controls/PDFView/PDFSearch/PDFSearchControl/CPDFSearchControl.xaml.cs

+ 1 - 1
Demo/Examples/Annotations/MainWindow.xaml

@@ -148,7 +148,7 @@
                         <ToggleButton.Content>
                         <ToggleButton.Content>
                             <Path Fill="#43474D" Width="30" Height="30">
                             <Path Fill="#43474D" Width="30" Height="30">
                                 <Path.Data>
                                 <Path.Data>
-                                    M22.5 8.5H7.5V12.25H13H22.5V8.5ZM12.25 13.75H7.5V21.5H12.25V13.75ZM13.75 21.5V13.75H22.5V21.5H13.75ZM7.5 7H6V8.5V21.5V23H7.5H22.5H24V21.5V8.5V7H22.5H7.5Z
+                                    M7.5 8.5H22.5V12.25H17H7.5V8.5ZM17.75 13.75H22.5V21.5H17.75V13.75ZM16.25 21.5V13.75H7.5V21.5H16.25ZM22.5 7H24V8.5V21.5V23H22.5H7.5H6V21.5V8.5V7H7.5H22.5Z
                                 </Path.Data>
                                 </Path.Data>
                             </Path>
                             </Path>
                         </ToggleButton.Content>
                         </ToggleButton.Content>

+ 2 - 2
Demo/Examples/Annotations/Properties/AssemblyInfo.cs

@@ -51,5 +51,5 @@ using System.Windows;
 // You can specify all the values or you can default the Build and Revision Numbers
 // You can specify all the values or you can default the Build and Revision Numbers
 // by using the '*' as shown below:
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.13.0.0")]
-[assembly: AssemblyFileVersion("1.13.0.0")]
+[assembly: AssemblyVersion("2.1.0.0")]
+[assembly: AssemblyFileVersion("2.1.0.0")]

+ 139 - 1
Demo/Examples/ComPDFKit.Tool/AlignmentsHelp.cs

@@ -2,6 +2,7 @@
 using System.Collections;
 using System.Collections;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
+using System.Runtime.CompilerServices;
 using System.Text;
 using System.Text;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using System.Windows;
 using System.Windows;
@@ -44,7 +45,7 @@ namespace ComPDFKit.Tool
         /// <returns>
         /// <returns>
         /// X Y direction distance required for alignment of the source rectangle
         /// X Y direction distance required for alignment of the source rectangle
         /// </returns>
         /// </returns>
-        public static Point SetAlignHorizonCenter (Rect src, Rect dst)
+        public static Point SetAlignHorizonCenter(Rect src, Rect dst)
         {
         {
             Point movePoint = new Point((dst.Left + dst.Right - src.Left - src.Right) / 2, 0);
             Point movePoint = new Point((dst.Left + dst.Right - src.Left - src.Right) / 2, 0);
             return movePoint;
             return movePoint;
@@ -214,6 +215,143 @@ namespace ComPDFKit.Tool
             return dictionary;
             return dictionary;
         }
         }
 
 
+        /// <summary>
+        /// Set the source rectangle to a horizontal distribution and align it within the target rectangle to maintain consistent gaps
+        /// </summary>
+        /// <param name="src">
+        /// Array of source rectangles needed
+        /// </param>
+        /// <param name="dst">
+        /// Target rectangle
+        /// </param>
+        /// <returns>
+        /// Dictionary of XY direction distance required for alignment of each source rectangle
+        /// </returns>
+        public static Dictionary<Rect, Point> SetGapDistributeHorizontal(List<Rect> src, Rect dst)
+        {
+            Dictionary<Rect, Point> dictionary = new Dictionary<Rect, Point>();
+            List<double> Leftlist = new List<double>();
+
+            // Sort the data according to the leftmost position of each rectangle, not the array order
+            double weight = 0;
+            foreach (Rect srcRect in src)
+            {
+                double left = srcRect.Left;
+                if (Leftlist.Contains(left))
+                {
+                    left += src.IndexOf(srcRect) * 0.01;
+                }
+                Leftlist.Add(left);
+                weight += srcRect.Width;
+            }
+            double[] datalist = Leftlist.ToArray();
+            Sort(datalist, 0, Leftlist.Count - 1);
+
+            double startX = dst.Left;
+            double endX = dst.Right;
+            double interval = ((endX - startX) - weight) / (Leftlist.Count - 1);
+            for (int i = 0; i < datalist.Count(); i++)
+            {
+                int index = Leftlist.IndexOf(datalist[i]);
+                Point movePoint = new Point();
+                if (i == 0 || i == datalist.Count() - 1)
+                {
+                    movePoint = new Point(0, 0);
+                }
+                else
+                {
+                    double width = 0;
+                    for (int f = 0; f < i; f++)
+                    {
+                        int index2 = 0;
+                        if (f != 0)
+                        {
+                            index2 = Leftlist.IndexOf(datalist[i - 1]);
+                            width += src[index2].Width;
+                        }
+                        int index0 = Leftlist.IndexOf(datalist[0]);
+                        if (f == 0)
+                        {
+                            width += src[index0].Right;
+                        }
+                        width += interval;
+
+                    }
+                    movePoint = new Point(width - src[index].X , 0);
+                }
+                dictionary.Add(src[index], movePoint);
+            }
+            return dictionary;
+        }
+
+        /// <summary>
+        /// Vertically distribute source rectangles within the target rectangle to maintain consistent gaps (sorted by the leftmost position of each rectangle, rather than array order)
+        /// </summary>
+        /// <param name="src">
+        /// Array of source rectangles needed
+        /// </param>
+        /// <param name="dst">
+        /// Target rectangle
+        /// </param>
+        /// <returns>
+        /// Dictionary of XY direction distance required for alignment of each source rectangle
+        /// </returns>
+        public static Dictionary<Rect, Point> SetGapDistributeVertical(List<Rect> src, Rect dst)
+        {
+            Dictionary<Rect, Point> dictionary = new Dictionary<Rect, Point>();
+            List<double> Leftlist = new List<double>();
+
+            // Sort the data according to the leftmost position of each rectangle, not the array order
+            double tall = 0;
+            foreach (Rect srcRect in src)
+            {
+                double top = srcRect.Top;
+                if (Leftlist.Contains(top)) {
+                    top += src.IndexOf(srcRect)*0.01;
+                }
+                Leftlist.Add(top);
+                tall += srcRect.Height;
+            }
+            double[] datalist = Leftlist.ToArray();
+            Sort(datalist, 0, Leftlist.Count - 1);
+
+            double startY = dst.Top;
+            double endY = dst.Bottom;
+            double interval = ((endY - startY) - tall) / (Leftlist.Count - 1);
+            for (int i = 0; i < datalist.Count(); i++)
+            {
+                int index = Leftlist.IndexOf(datalist[i]);
+                Point movePoint = new Point();
+                if (i == 0 || i == datalist.Count() - 1)
+                {
+                    movePoint = new Point(0, 0);
+                }
+                else
+                {
+                    double height = 0;
+                    for (int f = 0; f < i; f++)
+                    {
+                        int index2 = 0;
+                        if (f != 0)
+                        {
+                            index2 = Leftlist.IndexOf(datalist[i - 1]);
+                            height += src[index2].Height;
+                        }
+                        int index0 = Leftlist.IndexOf(datalist[0]);
+                        if (f == 0)
+                        {
+                            height += src[index0].Bottom;
+                        }
+                        height +=interval;
+
+                    }
+                    movePoint = new Point(0, height - src[index].Y);
+                }
+                dictionary.Add(src[index], movePoint);
+            }
+            return dictionary;
+        }
+
         #region Quick sort
         #region Quick sort
 
 
         private static int SortUnit(double[] array, int low, int high)
         private static int SortUnit(double[] array, int low, int high)

+ 444 - 81
Demo/Examples/ComPDFKit.Tool/CPDFToolManager.cs

@@ -20,9 +20,12 @@ using ComPDFKit.Tool.Help;
 using ComPDFKit.Measure;
 using ComPDFKit.Measure;
 using System.Dynamic;
 using System.Dynamic;
 using System.Globalization;
 using System.Globalization;
-using System.Windows.Controls;
+using ComPDFKitViewer.Layer;
 using ComPDFKitViewer;
 using ComPDFKitViewer;
-using System.Reflection;
+using ComPDFKitViewer.Annot;
+using System.Windows.Annotations;
+using ComPDFKit.Viewer.Annot;
+using System.Windows.Controls;
 using ComPDFKit.PDFDocument.Action;
 using ComPDFKit.PDFDocument.Action;
 
 
 namespace ComPDFKit.Tool
 namespace ComPDFKit.Tool
@@ -74,6 +77,24 @@ namespace ComPDFKit.Tool
         /// </summary>
         /// </summary>
         private string createImagePath = string.Empty;
         private string createImagePath = string.Empty;
 
 
+        private bool isActiveCropping = true;
+
+        /// <summary>
+        ///  add TextEdit Cursor
+        /// </summary>
+        private Cursor addTextEditCursor = Cursors.IBeam;
+
+        /// <summary>
+        /// add ImageEdit Cursor 
+        /// </summary>
+        private Cursor addImageEditCursor = Cursors.Arrow;
+
+        public bool SaveEmptyStickyAnnot { get; set; } = true;
+        public void SetActiveCropping(bool isActiveCropping)
+        {
+            this.isActiveCropping = isActiveCropping;
+        }
+
         public CPDFToolManager(CPDFViewerTool cPDFTool) : base()
         public CPDFToolManager(CPDFViewerTool cPDFTool) : base()
         {
         {
             viewerTool = cPDFTool;
             viewerTool = cPDFTool;
@@ -326,19 +347,17 @@ namespace ComPDFKit.Tool
                 default:
                 default:
                     break;
                     break;
             }
             }
+
             if (oldToolType == ToolType.ContentEdit)
             if (oldToolType == ToolType.ContentEdit)
             {
             {
-                viewerTool.GetCPDFViewer().GetDocument().ReleasePages();
-
-                viewerTool.GetCPDFViewer().UndoManager.RemoveRedoHistoryForType(typeof(PDFEditHistory));
-                viewerTool.GetCPDFViewer().UndoManager.RemoveUndoHistoryForType(typeof(PDFEditHistory));
+                viewerTool.GetCPDFViewer().GetDocument()?.ReleasePages();
+                //Undo delete logic
+                viewerTool.GetCPDFViewer().UndoManager.ClearHistory();
+                // viewerTool.GetCPDFViewer().UndoManager.RemoveRedoHistoryForType(typeof(PDFEditHistory));
+                //viewerTool.GetCPDFViewer().UndoManager.RemoveUndoHistoryForType(typeof(PDFEditHistory));
                 viewerTool.GetCPDFViewer().UpdateVirtualNodes();
                 viewerTool.GetCPDFViewer().UpdateVirtualNodes();
                 viewerTool.GetCPDFViewer().UpdateRenderFrame();
                 viewerTool.GetCPDFViewer().UpdateRenderFrame();
             }
             }
-            else
-            {
-                viewerTool.GetCPDFViewer().UpdateRenderFrame();
-            }
         }
         }
 
 
         public CPDFEditArea GetSelectedEditAreaObject(ref int pageIndex)
         public CPDFEditArea GetSelectedEditAreaObject(ref int pageIndex)
@@ -355,6 +374,37 @@ namespace ComPDFKit.Tool
             return editAreaObject?.cPDFEditArea;
             return editAreaObject?.cPDFEditArea;
         }
         }
 
 
+        /// <summary>
+        /// Get the index of the multi choice comment list
+        /// </summary>
+        /// <param name="pageIndexs"></param>
+        /// <returns></returns>
+        public List<CPDFEditArea> GetSelectedEditAreaListObject(ref List<int> pageIndexs)
+        {
+            List<CPDFEditArea> editAreaObjectlist = new List<CPDFEditArea>();
+            MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(viewerTool.PDFViewer.GetViewForTag(viewerTool.MultiSelectedRectViewTag));
+            if (multiSelectedRect != null && multiSelectedRect.Children.Count > 0)
+            {
+                foreach (SelectedRect selectedRect in multiSelectedRect.Children)
+                {
+                    EditAreaObject editAreaObject = viewerTool.GetEditAreaObjectListForRect(selectedRect);
+                    if (editAreaObject == null)
+                    {
+                        //pageIndexs.Add(-1);
+                    }
+                    else
+                    {
+                        if (!editAreaObjectlist.Contains(editAreaObject?.cPDFEditArea))
+                        {
+                            pageIndexs.Add(editAreaObject.PageIndex);
+                            editAreaObjectlist.Add(editAreaObject?.cPDFEditArea);
+                        }
+                    }
+                }
+            }
+            return editAreaObjectlist;
+        }
+
         public CPDFAnnotation GetCPDFAnnotation()
         public CPDFAnnotation GetCPDFAnnotation()
         {
         {
             return cPDFAnnotation;
             return cPDFAnnotation;
@@ -435,20 +485,24 @@ namespace ComPDFKit.Tool
             {
             {
                 case C_ANNOTATION_TYPE.C_ANNOTATION_WIDGET:
                 case C_ANNOTATION_TYPE.C_ANNOTATION_WIDGET:
                     {
                     {
-                    currentParam = ParamConverter.WidgetConverter(viewerTool.GetCPDFViewer().GetDocument(), e.annotData.Annot);
-                    (e.annotData.Annot as CPDFWidget).UpdateFormAp();
-                    break;
+                        currentParam = ParamConverter.WidgetConverter(viewerTool.GetCPDFViewer().GetDocument(), e.annotData.Annot);
+                        (e.annotData.Annot as CPDFWidget).UpdateFormAp();
+                        break;
                     }
                     }
 
 
                 default:
                 default:
                     {
                     {
-                    currentParam = ParamConverter.AnnotConverter(viewerTool.GetCPDFViewer().GetDocument(), e.annotData.Annot);
+                        currentParam = ParamConverter.AnnotConverter(viewerTool.GetCPDFViewer().GetDocument(), e.annotData.Annot);
                         if (e.annotData.AnnotType != C_ANNOTATION_TYPE.C_ANNOTATION_SOUND)
                         if (e.annotData.AnnotType != C_ANNOTATION_TYPE.C_ANNOTATION_SOUND)
                         {
                         {
-                    e.annotData.Annot.UpdateAp();
+                            e.annotData.Annot.UpdateAp();
+                            if(e.annotData.Annot is CPDFTextAnnotation)
+                            {
+                                CommonHelper.UpdateStickyAP(e.annotData.Annot as CPDFTextAnnotation);
+                            }
                         }
                         }
-                    break;
-            }
+                        break;
+                    }
             }
             }
 
 
             annotHistory.PreviousParam = previousParam;
             annotHistory.PreviousParam = previousParam;
@@ -456,7 +510,7 @@ namespace ComPDFKit.Tool
             annotHistory.CurrentParam = currentParam;
             annotHistory.CurrentParam = currentParam;
             annotHistory.Action = HistoryAction.Update;
             annotHistory.Action = HistoryAction.Update;
             viewerTool.GetCPDFViewer().UndoManager.AddHistory(annotHistory);
             viewerTool.GetCPDFViewer().UndoManager.AddHistory(annotHistory);
-            viewerTool.GetCPDFViewer().UpdateRenderFrame();
+            viewerTool.GetCPDFViewer().UpdateAnnotFrame();
             AnnotDefaultEditedHandler?.Invoke(this, e);
             AnnotDefaultEditedHandler?.Invoke(this, e);
         }
         }
 
 
@@ -488,8 +542,9 @@ namespace ComPDFKit.Tool
             CPDFDocument cPDFDocument = viewerTool.GetCPDFViewer().GetDocument();
             CPDFDocument cPDFDocument = viewerTool.GetCPDFViewer().GetDocument();
             CPDFPage cPDFPage = cPDFDocument.PageAtIndex(e.PageIndex);
             CPDFPage cPDFPage = cPDFDocument.PageAtIndex(e.PageIndex);
             CPDFEditPage cPDFEditPage = cPDFPage.GetEditPage();
             CPDFEditPage cPDFEditPage = cPDFPage.GetEditPage();
-            cPDFEditPage.BeginEdit(CPDFEditType.EditText | CPDFEditType.EditImage);
-            List<CPDFEditArea> cPDFEditAreas = cPDFEditPage.GetEditAreaList(true);
+            //cPDFEditPage.BeginEdit(CPDFEditType.EditText | CPDFEditType.EditImage);
+            List<CPDFEditArea> cPDFEditAreas = cPDFEditPage.GetEditAreaList(false);
+            float zoom = (float)viewerTool.PDFViewer.GetZoom();
             for (int i = 0; i < e.MultiObjectIndex.Count; i++)
             for (int i = 0; i < e.MultiObjectIndex.Count; i++)
             {
             {
                 if (e.MultiObjectIndex[i] < cPDFEditAreas.Count)
                 if (e.MultiObjectIndex[i] < cPDFEditAreas.Count)
@@ -498,20 +553,66 @@ namespace ComPDFKit.Tool
                     pDFEditHistory.PageIndex = e.PageIndex;
                     pDFEditHistory.PageIndex = e.PageIndex;
                     pDFEditHistory.EditPage = cPDFEditPage;
                     pDFEditHistory.EditPage = cPDFEditPage;
                     CRect cRect = cPDFEditAreas[e.MultiObjectIndex[i]].GetFrame();
                     CRect cRect = cPDFEditAreas[e.MultiObjectIndex[i]].GetFrame();
+                    if (cPDFEditAreas[e.MultiObjectIndex[i]].Type == CPDFEditType.EditImage)
+                    {
+                        cRect = (cPDFEditAreas[e.MultiObjectIndex[i]] as CPDFEditImageArea).GetClipRect();
+                    }
                     Point point = DpiHelper.StandardPointToPDFPoint(e.MoveOffset);
                     Point point = DpiHelper.StandardPointToPDFPoint(e.MoveOffset);
-                    cRect.left += (float)point.X;
-                    cRect.right += (float)point.X;
-                    cRect.top += (float)point.Y;
-                    cRect.bottom += (float)point.Y;
+                    point.X = point.X / zoom;
+                    point.Y = point.Y / zoom;
+                    if (point.X != 0 && point.Y != 0 && e.ZoomX == 1 && e.ZoomY == 1)
+                    {
+                        cRect.left += (float)point.X;
+                        cRect.right += (float)point.X;
+                        cRect.top += (float)point.Y;
+                        cRect.bottom += (float)point.Y;
+                    }
+                    else
+                    {
+                        //Mobile scaling ratio logic
+                        if ((float)point.X == 0)
+                        {
+                            cRect.left += (float)point.X;
+                            cRect.right = cRect.left + (cRect.right - cRect.left) + (float)DpiHelper.StandardNumToPDFNum(e.ChangeX) / zoom;
+                        }
+                        else
+                        {
+                            cRect.left += (float)point.X;
+                            if (e.ZoomX == 1)
+                            {
+                                cRect.right += (float)point.X;
+                            }
+                        }
+                        if ((float)point.Y == 0)
+                        {
+                            cRect.top += (float)point.Y;
+                            cRect.bottom = cRect.top + (cRect.bottom - cRect.top) + (float)DpiHelper.StandardNumToPDFNum(e.ChangeY) / zoom;
+                        }
+                        else
+                        {
 
 
-                    cRect.right = cRect.right * e.ZoomX;
-                    cRect.bottom = cRect.bottom * e.ZoomY;
+                            cRect.top += (float)point.Y;
+                            if (e.ZoomY == 1)
+                            {
+                                cRect.bottom += (float)point.Y;
+                            }
+                        }
+                    }
+                    //Original Logic
+                    //cRect.left += (float)point.X;
+                    //cRect.right += (float)point.X;
+                    //cRect.top += (float)point.Y;
+                    //cRect.bottom += (float)point.Y;
+
+                    //cRect.right = cRect.right* e.ZoomX;
+                    //cRect.bottom = cRect.bottom * e.ZoomY;
                     cPDFEditAreas[e.MultiObjectIndex[i]].SetFrame(cRect);
                     cPDFEditAreas[e.MultiObjectIndex[i]].SetFrame(cRect);
                     groupHistory.Histories.Add(pDFEditHistory);
                     groupHistory.Histories.Add(pDFEditHistory);
                 }
                 }
             }
             }
+            //Add end edit
+            cPDFEditPage.EndEdit();
             viewerTool.GetCPDFViewer().UndoManager.AddHistory(groupHistory);
             viewerTool.GetCPDFViewer().UndoManager.AddHistory(groupHistory);
-
             viewerTool.GetCPDFViewer().UpdateRenderFrame();
             viewerTool.GetCPDFViewer().UpdateRenderFrame();
         }
         }
 
 
@@ -546,7 +647,7 @@ namespace ComPDFKit.Tool
             switch (e.annotData.AnnotType)
             switch (e.annotData.AnnotType)
             {
             {
                 case C_ANNOTATION_TYPE.C_ANNOTATION_LINE:
                 case C_ANNOTATION_TYPE.C_ANNOTATION_LINE:
-                    if ((e.annotData.Annot as CPDFLineAnnotation).IsMersured())
+                    if ((e.annotData.Annot as CPDFLineAnnotation).IsMeasured())
                     {
                     {
                         List<Point> cPoints = new List<Point>();
                         List<Point> cPoints = new List<Point>();
                         for (int i = 0; i < e.Points.Count; i++)
                         for (int i = 0; i < e.Points.Count; i++)
@@ -611,7 +712,7 @@ namespace ComPDFKit.Tool
                         }
                         }
                         lineMeasure.UpdateAnnotMeasure();
                         lineMeasure.UpdateAnnotMeasure();
                         annotLine.UpdateAp();
                         annotLine.UpdateAp();
-                        if (annotLine.IsMersured())
+                        if (annotLine.IsMeasured())
                         {
                         {
                             PostMeasureInfo(this, annotLine);
                             PostMeasureInfo(this, annotLine);
                         }
                         }
@@ -661,7 +762,7 @@ namespace ComPDFKit.Tool
                             (float)top));
                             (float)top));
                         annotLine.GetAreaMeasure().UpdateAnnotMeasure();
                         annotLine.GetAreaMeasure().UpdateAnnotMeasure();
                         annotLine.UpdateAp();
                         annotLine.UpdateAp();
-                        if (annotLine.IsMersured())
+                        if (annotLine.IsMeasured())
                         {
                         {
                             PostMeasureInfo(this, annotLine);
                             PostMeasureInfo(this, annotLine);
                         }
                         }
@@ -693,7 +794,7 @@ namespace ComPDFKit.Tool
 
 
                         annotLine.GetPerimeterMeasure().UpdateAnnotMeasure();
                         annotLine.GetPerimeterMeasure().UpdateAnnotMeasure();
                         annotLine.UpdateAp();
                         annotLine.UpdateAp();
-                        if (annotLine.IsMersured())
+                        if (annotLine.IsMeasured())
                         {
                         {
                             PostMeasureInfo(this, annotLine);
                             PostMeasureInfo(this, annotLine);
                         }
                         }
@@ -728,7 +829,14 @@ namespace ComPDFKit.Tool
             annotHistory.CurrentParam = currentParam;
             annotHistory.CurrentParam = currentParam;
             annotHistory.Action = HistoryAction.Update;
             annotHistory.Action = HistoryAction.Update;
             viewerTool.GetCPDFViewer().UndoManager.AddHistory(annotHistory);
             viewerTool.GetCPDFViewer().UndoManager.AddHistory(annotHistory);
-            viewerTool.GetCPDFViewer().UpdateRenderFrame();
+            if (e.annotData.Annot.IsMeasured())
+            {
+                viewerTool.GetCPDFViewer().UpdateRenderFrame();
+            }
+            else
+            {
+                viewerTool.GetCPDFViewer().UpdateAnnotFrame();
+            }
         }
         }
 
 
         private void ViewerTool_MouseLeftButtonUpHandler(object sender, MouseEventObject e)
         private void ViewerTool_MouseLeftButtonUpHandler(object sender, MouseEventObject e)
@@ -739,7 +847,7 @@ namespace ComPDFKit.Tool
             viewerTool.DrawEndSelectedMultiRect();
             viewerTool.DrawEndSelectedMultiRect();
             viewerTool.DrawEndPageSelectedRect();
             viewerTool.DrawEndPageSelectedRect();
             if (currentToolType != ToolType.SelectedPage &&
             if (currentToolType != ToolType.SelectedPage &&
-                viewerTool.IsCanSave()&&
+                viewerTool.IsCanSave() &&
                 cPDFAnnotation?.Type != C_ANNOTATION_TYPE.C_ANNOTATION_FREETEXT)
                 cPDFAnnotation?.Type != C_ANNOTATION_TYPE.C_ANNOTATION_FREETEXT)
             {
             {
                 viewerTool.PDFViewer.EnableZoom(true);
                 viewerTool.PDFViewer.EnableZoom(true);
@@ -752,9 +860,9 @@ namespace ComPDFKit.Tool
             {
             {
                 viewerTool.PDFViewer.Cursor = viewerTool.Cursor = Cursors.IBeam;
                 viewerTool.PDFViewer.Cursor = viewerTool.Cursor = Cursors.IBeam;
             }
             }
-            else if(currentToolType == ToolType.ContentEdit)
+            else if (currentToolType == ToolType.ContentEdit)
             {
             {
-                if(createContentEditType == CPDFEditType.EditText)
+                if (createContentEditType == CPDFEditType.EditText)
                     viewerTool.PDFViewer.Cursor = viewerTool.Cursor = Cursors.IBeam;
                     viewerTool.PDFViewer.Cursor = viewerTool.Cursor = Cursors.IBeam;
                 else
                 else
                     viewerTool.PDFViewer.Cursor = viewerTool.Cursor = viewerTool.DrawMoveTest(viewerTool.GetLastSelectedRect());
                     viewerTool.PDFViewer.Cursor = viewerTool.Cursor = viewerTool.DrawMoveTest(viewerTool.GetLastSelectedRect());
@@ -763,7 +871,7 @@ namespace ComPDFKit.Tool
             {
             {
                 viewerTool.PDFViewer.Cursor = viewerTool.Cursor = Cursors.Arrow;
                 viewerTool.PDFViewer.Cursor = viewerTool.Cursor = Cursors.Arrow;
             }
             }
-            
+
             if (currentToolType == ToolType.Customize)
             if (currentToolType == ToolType.Customize)
             {
             {
                 viewerTool.CleanCustomizeTool();
                 viewerTool.CleanCustomizeTool();
@@ -811,7 +919,7 @@ namespace ComPDFKit.Tool
                             annotHistory.CurrentParam = annotParam;
                             annotHistory.CurrentParam = annotParam;
                             annotHistory.PDFDoc = cPDFDocument;
                             annotHistory.PDFDoc = cPDFDocument;
                             viewerTool.GetCPDFViewer().UndoManager.AddHistory(annotHistory);
                             viewerTool.GetCPDFViewer().UndoManager.AddHistory(annotHistory);
-                            viewerTool.GetCPDFViewer().UpdateRenderFrame();
+                            viewerTool.GetCPDFViewer().UpdateAnnotFrame();
                             e.annotType = cPDFAnnotation.Type;
                             e.annotType = cPDFAnnotation.Type;
                             e.IsCreate = true;
                             e.IsCreate = true;
                             dynamic expandData = new ExpandoObject();
                             dynamic expandData = new ExpandoObject();
@@ -827,7 +935,21 @@ namespace ComPDFKit.Tool
                     {
                     {
                         if (viewerTool.GetLastSelectedRect() != null)
                         if (viewerTool.GetLastSelectedRect() != null)
                         {
                         {
-                            viewerTool.DrawEndTextEdit(viewerTool.GetLastSelectedRect());
+                            //Crop Save Processing
+                            if (!viewerTool.GetIsCropMode())
+                            {
+                                viewerTool.DrawEndTextEdit(viewerTool.GetLastSelectedRect());
+                            }
+                            else
+                            {
+                                if (isActiveCropping)
+                                {
+                                    CropSelectRect();
+                                    viewerTool.SetClipThickness();
+                                }
+                                //Originally saved cropping logic
+                            }
+
                             editSelected = false;
                             editSelected = false;
                         }
                         }
                         else
                         else
@@ -872,10 +994,17 @@ namespace ComPDFKit.Tool
                             }
                             }
                             else if (createContentEditType == CPDFEditType.EditText)
                             else if (createContentEditType == CPDFEditType.EditText)
                             {
                             {
-                                e.IsCreate = viewerTool.DrawEndTest();
+                                if (viewerTool.CanAddTextEdit)
+                                {
+                                    e.IsCreate = viewerTool.DrawEndTest();
+                                }
                             }
                             }
                             else
                             else
                             {
                             {
+                                //Draw a box to select multiple boxes
+                                Rect rectFrameSelect = viewerTool.DrawEndFrameSelect();
+                                viewerTool.FrameSelectAddRect(rectFrameSelect);
+
                                 e.IsCreate = true;
                                 e.IsCreate = true;
                             }
                             }
                         }
                         }
@@ -898,6 +1027,25 @@ namespace ComPDFKit.Tool
             }
             }
         }
         }
 
 
+        /// <summary>
+        /// Create cropping logic
+        /// </summary>
+        public void CropSelectRect()
+        {
+            if (viewerTool.GetLastSelectedRect() != null)
+            {
+                if (viewerTool.GetIsCropMode())
+                {
+                    viewerTool.DrawEndTextEdit(viewerTool.GetLastSelectedRect());
+                }
+            }
+            viewerTool.DrawEndSelectText();
+            if (viewerTool.IsCanSave())
+            {
+                cPDFAnnotation = null;
+            }
+        }
+
         private void SaveCurrentAnnot()
         private void SaveCurrentAnnot()
         {
         {
             viewerTool.SetIsCanSave(true);
             viewerTool.SetIsCanSave(true);
@@ -932,7 +1080,7 @@ namespace ComPDFKit.Tool
                             annotHistory.CurrentParam = annotParam;
                             annotHistory.CurrentParam = annotParam;
                             annotHistory.PDFDoc = cPDFDocument;
                             annotHistory.PDFDoc = cPDFDocument;
                             viewerTool.GetCPDFViewer().UndoManager.AddHistory(annotHistory);
                             viewerTool.GetCPDFViewer().UndoManager.AddHistory(annotHistory);
-                            viewerTool.GetCPDFViewer().UpdateRenderFrame();
+                            viewerTool.GetCPDFViewer().UpdateAnnotFrame();
                             e.annotType = cPDFAnnotation.Type;
                             e.annotType = cPDFAnnotation.Type;
                             e.IsCreate = true;
                             e.IsCreate = true;
                             dynamic expandData = new ExpandoObject();
                             dynamic expandData = new ExpandoObject();
@@ -968,7 +1116,7 @@ namespace ComPDFKit.Tool
                 {
                 {
                     case C_ANNOTATION_TYPE.C_ANNOTATION_LINE:
                     case C_ANNOTATION_TYPE.C_ANNOTATION_LINE:
                         {
                         {
-                            if ((cPDFAnnotation as CPDFLineAnnotation).IsMersured())
+                            if ((cPDFAnnotation as CPDFLineAnnotation).IsMeasured())
                             {
                             {
                                 MeasureSetting measureSetting = viewerTool.GetMeasureSetting();
                                 MeasureSetting measureSetting = viewerTool.GetMeasureSetting();
                                 if (viewerTool.GetMoveLength() > measureSetting.MoveDetectionLength)
                                 if (viewerTool.GetMoveLength() > measureSetting.MoveDetectionLength)
@@ -979,7 +1127,7 @@ namespace ComPDFKit.Tool
                         }
                         }
                         break;
                         break;
                     case C_ANNOTATION_TYPE.C_ANNOTATION_POLYGON:
                     case C_ANNOTATION_TYPE.C_ANNOTATION_POLYGON:
-                        if ((cPDFAnnotation as CPDFPolygonAnnotation).IsMersured())
+                        if ((cPDFAnnotation as CPDFPolygonAnnotation).IsMeasured())
                         {
                         {
                             DefaultSettingParam defSetting = viewerTool.GetDefaultSettingParam();
                             DefaultSettingParam defSetting = viewerTool.GetDefaultSettingParam();
                             if (defSetting.IsCreateSquarePolygonMeasure)
                             if (defSetting.IsCreateSquarePolygonMeasure)
@@ -1061,7 +1209,7 @@ namespace ComPDFKit.Tool
                         e.IsCreate = true;
                         e.IsCreate = true;
                         e.annotType = C_ANNOTATION_TYPE.C_ANNOTATION_INK;
                         e.annotType = C_ANNOTATION_TYPE.C_ANNOTATION_INK;
                         e.Data = GetAnnotExpandObject(annotation);
                         e.Data = GetAnnotExpandObject(annotation);
-                        if (e.mouseButtonEventArgs!=null)
+                        if (e.mouseButtonEventArgs != null)
                         {
                         {
                             MouseLeftButtonUpHandler?.Invoke(this, e);
                             MouseLeftButtonUpHandler?.Invoke(this, e);
                         }
                         }
@@ -1078,7 +1226,7 @@ namespace ComPDFKit.Tool
                         return;
                         return;
                     case C_ANNOTATION_TYPE.C_ANNOTATION_LINE:
                     case C_ANNOTATION_TYPE.C_ANNOTATION_LINE:
                         {
                         {
-                            if ((annotation as CPDFLineAnnotation).IsMersured())
+                            if ((annotation as CPDFLineAnnotation).IsMeasured())
                             {
                             {
                                 if (measurepoints.Count > 1)
                                 if (measurepoints.Count > 1)
                                 {
                                 {
@@ -1122,31 +1270,52 @@ namespace ComPDFKit.Tool
                         break;
                         break;
                     case C_ANNOTATION_TYPE.C_ANNOTATION_POLYGON:
                     case C_ANNOTATION_TYPE.C_ANNOTATION_POLYGON:
                         {
                         {
-                            if ((annotation as CPDFPolygonAnnotation).IsMersured())
+                            if (measurepoints.Count >= 3)
                             {
                             {
-                                List<CPoint> cPoints = new List<CPoint>();
-                                foreach (Point item in measurepoints)
+                                if ((annotation as CPDFPolygonAnnotation).IsMeasured())
                                 {
                                 {
-                                    cPoints.Add(DataConversionForWPF.PointConversionForCPoint(DpiHelper.StandardPointToPDFPoint(item)));
-                                }
+                                    List<CPoint> cPoints = new List<CPoint>();
+                                    foreach (Point item in measurepoints)
+                                    {
+                                        cPoints.Add(DataConversionForWPF.PointConversionForCPoint(DpiHelper.StandardPointToPDFPoint(item)));
+                                    }
                                 (annotation as CPDFPolygonAnnotation).SetPoints(cPoints);
                                 (annotation as CPDFPolygonAnnotation).SetPoints(cPoints);
-                                (annotation as CPDFPolygonAnnotation).GetAreaMeasure().UpdateAnnotMeasure();
-                                PostMeasureInfo(this, annotation);
+                                    (annotation as CPDFPolygonAnnotation).GetAreaMeasure().UpdateAnnotMeasure();
+                                    PostMeasureInfo(this, annotation);
+                                }
+                            }
+                            else
+                            {
+                                annotation.RemoveAnnot();
+                                annotation = null;
+                                viewerTool.ClearDrawAnnot();
+                                return;
                             }
                             }
+
                         }
                         }
                         break;
                         break;
                     case C_ANNOTATION_TYPE.C_ANNOTATION_POLYLINE:
                     case C_ANNOTATION_TYPE.C_ANNOTATION_POLYLINE:
                         {
                         {
-                            if ((annotation as CPDFPolylineAnnotation).IsMersured())
+                            if(measurepoints.Count>=3)
                             {
                             {
-                                List<CPoint> cPoints = new List<CPoint>();
-                                foreach (Point item in measurepoints)
+                                if ((annotation as CPDFPolylineAnnotation).IsMeasured())
                                 {
                                 {
-                                    cPoints.Add(DataConversionForWPF.PointConversionForCPoint(DpiHelper.StandardPointToPDFPoint(item)));
+                                    List<CPoint> cPoints = new List<CPoint>();
+                                    foreach (Point item in measurepoints)
+                                    {
+                                        cPoints.Add(DataConversionForWPF.PointConversionForCPoint(DpiHelper.StandardPointToPDFPoint(item)));
+                                    }
+                               (annotation as CPDFPolylineAnnotation).SetPoints(cPoints);
+                                    (annotation as CPDFPolylineAnnotation).GetPerimeterMeasure().UpdateAnnotMeasure();
+                                    PostMeasureInfo(this, annotation);
                                 }
                                 }
-                                (annotation as CPDFPolylineAnnotation).SetPoints(cPoints);
-                                (annotation as CPDFPolylineAnnotation).GetPerimeterMeasure().UpdateAnnotMeasure();
-                                PostMeasureInfo(this, annotation);
+                            }
+                            else
+                            {
+                                annotation.RemoveAnnot();
+                                annotation = null;
+                                viewerTool.ClearDrawAnnot();
+                                return;
                             }
                             }
                         }
                         }
                         break;
                         break;
@@ -1167,6 +1336,7 @@ namespace ComPDFKit.Tool
                 {
                 {
                     switch (createAnnotType)
                     switch (createAnnotType)
                     {
                     {
+                        case C_ANNOTATION_TYPE.C_ANNOTATION_LINK:
                         case C_ANNOTATION_TYPE.C_ANNOTATION_HIGHLIGHT:
                         case C_ANNOTATION_TYPE.C_ANNOTATION_HIGHLIGHT:
                         case C_ANNOTATION_TYPE.C_ANNOTATION_UNDERLINE:
                         case C_ANNOTATION_TYPE.C_ANNOTATION_UNDERLINE:
                         case C_ANNOTATION_TYPE.C_ANNOTATION_SQUIGGLY:
                         case C_ANNOTATION_TYPE.C_ANNOTATION_SQUIGGLY:
@@ -1208,7 +1378,7 @@ namespace ComPDFKit.Tool
                                     }
                                     }
                                 }
                                 }
 
 
-                                if(createAnnotType == C_ANNOTATION_TYPE.C_ANNOTATION_REDACT && textSelectInfo.PageSelectPointList.Count ==0)
+                                if (createAnnotType == C_ANNOTATION_TYPE.C_ANNOTATION_REDACT && textSelectInfo.PageSelectPointList.Count == 0)
                                 {
                                 {
                                     viewerTool.GetCPDFViewer().UpdateAnnotFrame();
                                     viewerTool.GetCPDFViewer().UpdateAnnotFrame();
                                 }
                                 }
@@ -1328,7 +1498,7 @@ namespace ComPDFKit.Tool
                     annotation = null;
                     annotation = null;
                     return;
                     return;
                 }
                 }
-                //CRect cRect = new CRect((float)rect.Left + annotation.GetBorderWidth(), (float)rect.Bottom - annotation.GetBorderWidth(), (float)rect.Right - annotation.GetBorderWidth(), (float)rect.Top + annotation.GetBorderWidth());
+
                 CRect cRect = new CRect(
                 CRect cRect = new CRect(
                     (float)rect.Left,
                     (float)rect.Left,
                     (float)rect.Bottom,
                     (float)rect.Bottom,
@@ -1336,7 +1506,16 @@ namespace ComPDFKit.Tool
                     (float)rect.Top);
                     (float)rect.Top);
 
 
                 annotation.SetRect(cRect);
                 annotation.SetRect(cRect);
-                annotation.UpdateAp();
+                SaveSharpAnnotBoundText(annotation);
+                if (annotation.Type!=C_ANNOTATION_TYPE.C_ANNOTATION_TEXT)
+                {
+                    annotation.UpdateAp();
+                }
+                else
+                {
+                    CommonHelper.UpdateStickyAP(annotation as CPDFTextAnnotation);
+                }
+               
 
 
                 AnnotHistory annotHistory = ParamConverter.CreateHistory(annotation);
                 AnnotHistory annotHistory = ParamConverter.CreateHistory(annotation);
                 if (annotHistory == null)
                 if (annotHistory == null)
@@ -1356,10 +1535,25 @@ namespace ComPDFKit.Tool
                 annotHistory.CurrentParam = currentParam;
                 annotHistory.CurrentParam = currentParam;
                 annotHistory.Action = HistoryAction.Add;
                 annotHistory.Action = HistoryAction.Add;
                 annotHistory.PDFDoc = viewerTool.PDFViewer.GetDocument();
                 annotHistory.PDFDoc = viewerTool.PDFViewer.GetDocument();
-                viewerTool.GetCPDFViewer().UndoManager.AddHistory(annotHistory);
 
 
                 viewerTool.ClearDrawAnnot();
                 viewerTool.ClearDrawAnnot();
-                viewerTool.GetCPDFViewer().UpdateRenderFrame();
+                viewerTool.GetCPDFViewer().UpdateAnnotFrame();
+                viewerTool.GetCPDFViewer().UndoManager.AddHistory(annotHistory);
+
+                if (annotation.Type == C_ANNOTATION_TYPE.C_ANNOTATION_TEXT && SaveEmptyStickyAnnot == false)
+                {
+                    BaseLayer baseLayer1 = viewerTool.GetCPDFViewer().GetViewForTag(viewerTool.GetCPDFViewer().GetAnnotViewTag());
+                    int checkPageIndex = currentParam.PageIndex;
+                    int checkAnnotIndex = currentParam.AnnotIndex;
+                    BaseAnnot selectAnnot = (baseLayer1 as AnnotLayer).GetSelectedAnnot(ref checkPageIndex, ref checkAnnotIndex);
+                    if (selectAnnot != null)
+                    {
+                        StickyNoteAnnot stickyAnnot = selectAnnot as StickyNoteAnnot;
+                        StickyNoteAnnot.StickyPopupClosed -= StickyAnnot_StickyPopupClosed;
+                        StickyNoteAnnot.StickyPopupClosed += StickyAnnot_StickyPopupClosed;
+                        stickyAnnot.PopStickyNote();
+                    }
+                }
                 {
                 {
                     e.annotType = annotation.Type;
                     e.annotType = annotation.Type;
                     e.IsCreate = true;
                     e.IsCreate = true;
@@ -1369,9 +1563,71 @@ namespace ComPDFKit.Tool
                     expandData.AnnotParam = currentParam;
                     expandData.AnnotParam = currentParam;
                     e.Data = expandData;
                     e.Data = expandData;
                 }
                 }
+
             }
             }
         }
         }
 
 
+        private void SaveSharpAnnotBoundText(CPDFAnnotation boundAnnot)
+        {
+            if (boundAnnot == null || boundAnnot.Page == null || boundAnnot.Page.IsValid() == false)
+            {
+                return;
+            }
+
+            if (boundAnnot.Type != C_ANNOTATION_TYPE.C_ANNOTATION_CIRCLE && boundAnnot.Type != C_ANNOTATION_TYPE.C_ANNOTATION_SQUARE)
+            {
+                return;
+            }
+
+            CPDFTextPage textPage=  boundAnnot.Page.GetTextPage();
+            if (textPage == null || textPage.IsValid()==false)
+            {
+                return;
+            }
+
+            string boundText = textPage.GetBoundedText(boundAnnot.GetRect());
+            if(string.IsNullOrEmpty(boundText)==false)
+            {
+                boundAnnot.SetContent(boundText);
+            }
+        }
+
+        private void StickyAnnot_StickyPopupClosed(object sender, EventArgs e)
+        {
+            StickyNoteAnnot.StickyPopupClosed -= StickyAnnot_StickyPopupClosed;
+            StickyNoteAnnot stickyAnnot = sender as StickyNoteAnnot;
+            if (stickyAnnot == null)
+            {
+                return;
+            }
+            AnnotData annotData = stickyAnnot.GetAnnotData();
+            AnnotParam currentParam = ParamConverter.AnnotConverter(viewerTool.GetCPDFViewer().GetDocument(), annotData.Annot);
+            AnnotHistory annotHistory = ParamConverter.CreateHistory(annotData.Annot);
+            string content = annotData.Annot.GetContent();
+            if (string.IsNullOrEmpty(content))
+            {
+                if (annotData.Annot.RemoveAnnot())
+                {
+                    viewerTool.ClearDrawAnnot();
+                    viewerTool.GetCPDFViewer().UpdateAnnotFrame();
+                    viewerTool.SelectedAnnotForIndex(-1, -1);
+                    annotHistory.CurrentParam = currentParam;
+                    annotHistory.Action = HistoryAction.Remove;
+                    annotHistory.PDFDoc = viewerTool.PDFViewer.GetDocument();
+                    viewerTool.GetCPDFViewer().UndoManager.AddHistory(annotHistory);
+                }
+
+                return;
+            }
+            AnnotParam previousParam = ParamConverter.AnnotConverter(viewerTool.GetCPDFViewer().GetDocument(), annotData.Annot);
+            previousParam.Content = string.Empty;
+            annotHistory.PreviousParam = previousParam;
+            annotHistory.CurrentParam = currentParam;
+            annotHistory.Action = HistoryAction.Update;
+            annotHistory.PDFDoc = viewerTool.PDFViewer.GetDocument();
+            viewerTool.GetCPDFViewer().UndoManager.AddHistory(annotHistory);
+        }
+
         internal void PostMeasureInfo(object sender, CPDFAnnotation rawAnnot)
         internal void PostMeasureInfo(object sender, CPDFAnnotation rawAnnot)
         {
         {
             if (rawAnnot == null)
             if (rawAnnot == null)
@@ -1383,7 +1639,7 @@ namespace ComPDFKit.Tool
                 if (rawAnnot.Type == C_ANNOTATION_TYPE.C_ANNOTATION_LINE)
                 if (rawAnnot.Type == C_ANNOTATION_TYPE.C_ANNOTATION_LINE)
                 {
                 {
                     CPDFLineAnnotation lineAnnot = rawAnnot as CPDFLineAnnotation;
                     CPDFLineAnnotation lineAnnot = rawAnnot as CPDFLineAnnotation;
-                    if (lineAnnot.IsMersured() && lineAnnot.Points != null && lineAnnot.Points.Count() == 2)
+                    if (lineAnnot.IsMeasured() && lineAnnot.Points != null && lineAnnot.Points.Count() == 2)
                     {
                     {
                         CPDFDistanceMeasure lineMeasure = lineAnnot.GetDistanceMeasure();
                         CPDFDistanceMeasure lineMeasure = lineAnnot.GetDistanceMeasure();
                         CPDFMeasureInfo measureInfo = lineMeasure.MeasureInfo;
                         CPDFMeasureInfo measureInfo = lineMeasure.MeasureInfo;
@@ -1416,7 +1672,7 @@ namespace ComPDFKit.Tool
                 if (rawAnnot.Type == C_ANNOTATION_TYPE.C_ANNOTATION_POLYLINE)
                 if (rawAnnot.Type == C_ANNOTATION_TYPE.C_ANNOTATION_POLYLINE)
                 {
                 {
                     CPDFPolylineAnnotation polylineAnnot = rawAnnot as CPDFPolylineAnnotation;
                     CPDFPolylineAnnotation polylineAnnot = rawAnnot as CPDFPolylineAnnotation;
-                    if (polylineAnnot.IsMersured() && polylineAnnot.Points != null && polylineAnnot.Points.Count() >= 2)
+                    if (polylineAnnot.IsMeasured() && polylineAnnot.Points != null && polylineAnnot.Points.Count() >= 2)
                     {
                     {
                         double totalInch = 0;
                         double totalInch = 0;
                         for (int i = 0; i < polylineAnnot.Points.Count - 1; i++)
                         for (int i = 0; i < polylineAnnot.Points.Count - 1; i++)
@@ -1456,7 +1712,7 @@ namespace ComPDFKit.Tool
                 if (rawAnnot.Type == C_ANNOTATION_TYPE.C_ANNOTATION_POLYGON)
                 if (rawAnnot.Type == C_ANNOTATION_TYPE.C_ANNOTATION_POLYGON)
                 {
                 {
                     CPDFPolygonAnnotation polygonAnnot = rawAnnot as CPDFPolygonAnnotation;
                     CPDFPolygonAnnotation polygonAnnot = rawAnnot as CPDFPolygonAnnotation;
-                    if (polygonAnnot.IsMersured() && polygonAnnot.Points != null && polygonAnnot.Points.Count() >= 2)
+                    if (polygonAnnot.IsMeasured() && polygonAnnot.Points != null && polygonAnnot.Points.Count() >= 2)
                     {
                     {
                         double totalInch = 0;
                         double totalInch = 0;
                         for (int i = 0; i < polygonAnnot.Points.Count - 1; i++)
                         for (int i = 0; i < polygonAnnot.Points.Count - 1; i++)
@@ -1667,7 +1923,7 @@ namespace ComPDFKit.Tool
                 }
                 }
             }
             }
             viewerTool.ClearDrawAnnot();
             viewerTool.ClearDrawAnnot();
-            viewerTool.GetCPDFViewer().UpdateRenderFrame();
+            viewerTool.GetCPDFViewer().UpdateAnnotFrame();
             InkAnnotHistory inkAnnotHistory = new InkAnnotHistory();
             InkAnnotHistory inkAnnotHistory = new InkAnnotHistory();
             AnnotParam annotParam = ParamConverter.AnnotConverter(viewerTool.PDFViewer.GetDocument(), cPDFAnnotation);
             AnnotParam annotParam = ParamConverter.AnnotConverter(viewerTool.PDFViewer.GetDocument(), cPDFAnnotation);
             annotParam.AnnotIndex = cPDFAnnotation.Page.GetAnnotCount() - 1;
             annotParam.AnnotIndex = cPDFAnnotation.Page.GetAnnotCount() - 1;
@@ -1679,6 +1935,26 @@ namespace ComPDFKit.Tool
 
 
         #endregion
         #endregion
 
 
+        /// <summary>
+        /// Set mouse pattern when creating content editing
+        /// </summary>
+        /// <param name="AddTextEditCursor">add text</param>
+        /// <param name="AddImageEditCursor">add image</param>
+        public void SetAddContentEditCursor(Cursor AddTextEditCursor, Cursor AddImageEditCursor)
+        {
+            if (AddTextEditCursor == null)
+            {
+                AddTextEditCursor = Cursors.IBeam;
+            }
+            if (AddImageEditCursor == null)
+            {
+                AddImageEditCursor = Cursors.Arrow;
+            }
+            this.addTextEditCursor = AddTextEditCursor;
+            this.addImageEditCursor = AddImageEditCursor;
+
+        }
+
         private void ViewerTool_MouseMoveHandler(object sender, MouseEventObject e)
         private void ViewerTool_MouseMoveHandler(object sender, MouseEventObject e)
         {
         {
             if (viewerTool == null)
             if (viewerTool == null)
@@ -1733,7 +2009,7 @@ namespace ComPDFKit.Tool
                     if (currentToolType == ToolType.CreateAnnot)
                     if (currentToolType == ToolType.CreateAnnot)
                     {
                     {
                         if (!viewerTool.PDFViewer.GetIsShowStampMouse())
                         if (!viewerTool.PDFViewer.GetIsShowStampMouse())
-                        { 
+                        {
                             // Annotation drawing only occurs if the mouse is not set to stamp/data application mode.// Annotation drawing only occurs if the mouse is not set to stamp/data application mode.
                             // Annotation drawing only occurs if the mouse is not set to stamp/data application mode.// Annotation drawing only occurs if the mouse is not set to stamp/data application mode.
                             viewerTool.MoveDrawAnnot();
                             viewerTool.MoveDrawAnnot();
                         }
                         }
@@ -1793,12 +2069,14 @@ namespace ComPDFKit.Tool
                 if (createContentEditType != CPDFEditType.EditImage)
                 if (createContentEditType != CPDFEditType.EditImage)
                 {
                 {
                     Cursor cursor = Cursors.Arrow;
                     Cursor cursor = Cursors.Arrow;
+                    MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(viewerTool.PDFViewer.GetViewForTag(viewerTool.MultiSelectedRectViewTag));
+
                     if (viewerTool.GetLastSelectedRect() != null)
                     if (viewerTool.GetLastSelectedRect() != null)
                     {
                     {
                         if (editSelected)
                         if (editSelected)
                         {
                         {
                             viewerTool.DrawMoveTextEdit(viewerTool.GetLastSelectedRect(), clickEditSelected);
                             viewerTool.DrawMoveTextEdit(viewerTool.GetLastSelectedRect(), clickEditSelected);
-                            if(clickEditSelected)
+                            if (clickEditSelected)
                                 cursor = Cursors.IBeam;
                                 cursor = Cursors.IBeam;
                             else
                             else
                                 cursor = viewerTool.DrawMoveTest(viewerTool.GetLastSelectedRect());
                                 cursor = viewerTool.DrawMoveTest(viewerTool.GetLastSelectedRect());
@@ -1810,19 +2088,60 @@ namespace ComPDFKit.Tool
                     }
                     }
                     else
                     else
                     {
                     {
-                        viewerTool.HideDrawSelectedMultiRect();
                         cursor = viewerTool.DrawMoveTest(viewerTool.GetLastSelectedRect());
                         cursor = viewerTool.DrawMoveTest(viewerTool.GetLastSelectedRect());
+                        if (multiSelectedRect == null || multiSelectedRect.Children.Count == 0)
+                        {
+                            //Selection of mobile drawing logic
+                            if (e.mouseButtonEventArgs.LeftButton == MouseButtonState.Pressed && createContentEditType == CPDFEditType.None)
+                            {
+                                viewerTool.DrawMoveFrameSelect();
+                            }
+                        }
+
                     }
                     }
 
 
                     if (cursor == Cursors.Arrow && createContentEditType == CPDFEditType.EditText)
                     if (cursor == Cursors.Arrow && createContentEditType == CPDFEditType.EditText)
                     {
                     {
-                        cursor = Cursors.IBeam;
+                        cursor = addTextEditCursor;
                     }
                     }
                     viewerTool.Cursor = cursor;
                     viewerTool.Cursor = cursor;
                     viewerTool.PDFViewer.Cursor = cursor;
                     viewerTool.PDFViewer.Cursor = cursor;
                 }
                 }
                 else
                 else
                 {
                 {
+                    Cursor cursor = Cursors.Arrow;
+                    MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(viewerTool.PDFViewer.GetViewForTag(viewerTool.MultiSelectedRectViewTag));
+
+                    if (viewerTool.GetLastSelectedRect() != null)
+                    {
+                        if (editSelected)
+                        {
+                            viewerTool.DrawMoveTextEdit(viewerTool.GetLastSelectedRect(), clickEditSelected);
+                            if (clickEditSelected)
+                                cursor = Cursors.IBeam;
+                            else
+                                cursor = viewerTool.DrawMoveTest(viewerTool.GetLastSelectedRect());
+                        }
+                        else
+                        {
+                            cursor = viewerTool.DrawMoveTest(viewerTool.GetLastSelectedRect());
+                        }
+                    }
+                    else
+                    {
+                        cursor = viewerTool.DrawMoveTest(viewerTool.GetLastSelectedRect());
+                    }
+
+                    if (cursor == Cursors.Arrow && createContentEditType == CPDFEditType.EditText)
+                    {
+                        cursor = Cursors.IBeam;
+                    }
+                    if (cursor == Cursors.Arrow && createContentEditType == CPDFEditType.EditImage)
+                    {
+                        cursor = addImageEditCursor;
+                    }
+                    viewerTool.Cursor = cursor;
+                    viewerTool.PDFViewer.Cursor = cursor;
                     //viewerTool.Cursor = Cursors.None;
                     //viewerTool.Cursor = Cursors.None;
                     //viewerTool.PDFViewer.Cursor = Cursors.None;
                     //viewerTool.PDFViewer.Cursor = Cursors.None;
                 }
                 }
@@ -1882,6 +2201,7 @@ namespace ComPDFKit.Tool
                                                     viewerTool.EndDrawAnnot();
                                                     viewerTool.EndDrawAnnot();
                                                 }
                                                 }
                                                 break;
                                                 break;
+                                            case C_ANNOTATION_TYPE.C_ANNOTATION_LINK:
                                             case C_ANNOTATION_TYPE.C_ANNOTATION_REDACT:
                                             case C_ANNOTATION_TYPE.C_ANNOTATION_REDACT:
                                                 if (viewerTool.IsText())
                                                 if (viewerTool.IsText())
                                                 {
                                                 {
@@ -1896,7 +2216,7 @@ namespace ComPDFKit.Tool
                                                     CPDFLineAnnotation LineAnnotation = (cPDFAnnotation as CPDFLineAnnotation);
                                                     CPDFLineAnnotation LineAnnotation = (cPDFAnnotation as CPDFLineAnnotation);
                                                     if (LineAnnotation != null)
                                                     if (LineAnnotation != null)
                                                     {
                                                     {
-                                                        if (LineAnnotation.IsMersured())
+                                                        if (LineAnnotation.IsMeasured())
                                                         {
                                                         {
                                                             cansave = false;
                                                             cansave = false;
                                                         }
                                                         }
@@ -1908,10 +2228,10 @@ namespace ComPDFKit.Tool
                                                 {
                                                 {
                                                     bool cansave = true;
                                                     bool cansave = true;
                                                     CPDFPolygonAnnotation PolyAnnotation = (cPDFAnnotation as CPDFPolygonAnnotation);
                                                     CPDFPolygonAnnotation PolyAnnotation = (cPDFAnnotation as CPDFPolygonAnnotation);
-                                                    PolyAnnotation?.IsMersured();
+                                                    PolyAnnotation?.IsMeasured();
                                                     if (PolyAnnotation != null)
                                                     if (PolyAnnotation != null)
                                                     {
                                                     {
-                                                        if (PolyAnnotation.IsMersured())
+                                                        if (PolyAnnotation.IsMeasured())
                                                         {
                                                         {
                                                             cansave = false;
                                                             cansave = false;
                                                         }
                                                         }
@@ -1923,10 +2243,10 @@ namespace ComPDFKit.Tool
                                                 {
                                                 {
                                                     bool cansave = true;
                                                     bool cansave = true;
                                                     CPDFPolylineAnnotation PolyAnnotation = (cPDFAnnotation as CPDFPolylineAnnotation);
                                                     CPDFPolylineAnnotation PolyAnnotation = (cPDFAnnotation as CPDFPolylineAnnotation);
-                                                    PolyAnnotation?.IsMersured();
+                                                    PolyAnnotation?.IsMeasured();
                                                     if (PolyAnnotation != null)
                                                     if (PolyAnnotation != null)
                                                     {
                                                     {
-                                                        if (PolyAnnotation.IsMersured())
+                                                        if (PolyAnnotation.IsMeasured())
                                                         {
                                                         {
                                                             cansave = false;
                                                             cansave = false;
                                                         }
                                                         }
@@ -1941,7 +2261,7 @@ namespace ComPDFKit.Tool
                                     else
                                     else
                                     {
                                     {
                                         viewerTool.MultipleClick();
                                         viewerTool.MultipleClick();
-                                        e.IsDrawing=true;
+                                        e.IsDrawing = true;
                                     }
                                     }
                                     break;
                                     break;
                                 case 2:
                                 case 2:
@@ -1960,6 +2280,7 @@ namespace ComPDFKit.Tool
                         {
                         {
                             cPDFAnnotation = viewerTool.StartDrawWidget(createWidgetType);
                             cPDFAnnotation = viewerTool.StartDrawWidget(createWidgetType);
                             viewerTool.CreateDefaultWidget(cPDFAnnotation, createWidgetType, null);
                             viewerTool.CreateDefaultWidget(cPDFAnnotation, createWidgetType, null);
+                            viewerTool?.InvokeWidgetCreated(cPDFAnnotation);
                         }
                         }
                         else if (currentToolType == ToolType.Pan || currentToolType == ToolType.Viewer)
                         else if (currentToolType == ToolType.Pan || currentToolType == ToolType.Viewer)
                         {
                         {
@@ -2007,7 +2328,7 @@ namespace ComPDFKit.Tool
                         if (list.Contains(e.annotType))
                         if (list.Contains(e.annotType))
                         {
                         {
                             viewerTool.CleanSelectedRect();
                             viewerTool.CleanSelectedRect();
-                            if (!e.IsMersured||!list.Contains(createAnnotType))
+                            if (!e.IsMersured || !list.Contains(createAnnotType))
                             {
                             {
                                 viewerTool.StartDrawEditAnnot();
                                 viewerTool.StartDrawEditAnnot();
                             }
                             }
@@ -2045,6 +2366,15 @@ namespace ComPDFKit.Tool
                         clickEditSelected = true;
                         clickEditSelected = true;
                         switch ((e.mouseButtonEventArgs as MouseButtonEventArgs).ClickCount)
                         switch ((e.mouseButtonEventArgs as MouseButtonEventArgs).ClickCount)
                         {
                         {
+                            case 1:
+                                if (viewerTool.GetIsCropMode())
+                                {
+                                    //Preconditions for determining crop acquisition points
+                                    viewerTool.HandleTextSelectClick(viewerTool.GetLastSelectedRect(), true);
+                                    clickEditSelected = false;
+                                    MouseLeftButtonDownHandler?.Invoke(this, e);
+                                }
+                                break;
                             case 2:
                             case 2:
                                 viewerTool.HandleTextSelectClick(viewerTool.GetLastSelectedRect(), true);
                                 viewerTool.HandleTextSelectClick(viewerTool.GetLastSelectedRect(), true);
                                 clickEditSelected = false;
                                 clickEditSelected = false;
@@ -2063,8 +2393,19 @@ namespace ComPDFKit.Tool
                         viewerTool.HideDrawSelectedMultiRect();
                         viewerTool.HideDrawSelectedMultiRect();
                         if (viewerTool.GetLastSelectedRect() != null)
                         if (viewerTool.GetLastSelectedRect() != null)
                         {
                         {
+                            viewerTool.DrawEndFrameSelect();
                             Point point = Mouse.GetPosition(viewerTool);
                             Point point = Mouse.GetPosition(viewerTool);
-                            PointControlType pointControlType = viewerTool.GetLastSelectedRect().GetHitControlIndex(point);
+                            PointControlType pointControlType = PointControlType.None;
+                            if (viewerTool.GetIsCropMode())
+                            {
+                                //Crop acquisition point judgment
+                                pointControlType = viewerTool.GetLastSelectedRect().GetHitCropControlIndex(point);
+                            }
+                            else
+                            {
+                                pointControlType = viewerTool.GetLastSelectedRect().GetHitControlIndex(point);
+                            }
+
                             EditAreaObject editAreaObject = viewerTool.GetEditAreaObjectForRect(viewerTool.GetLastSelectedRect());
                             EditAreaObject editAreaObject = viewerTool.GetEditAreaObjectForRect(viewerTool.GetLastSelectedRect());
                             if (pointControlType != PointControlType.None &&
                             if (pointControlType != PointControlType.None &&
                                 (editAreaObject.cPDFEditArea.Type == CPDFEditType.EditImage || pointControlType != PointControlType.Body))
                                 (editAreaObject.cPDFEditArea.Type == CPDFEditType.EditImage || pointControlType != PointControlType.Body))
@@ -2094,12 +2435,23 @@ namespace ComPDFKit.Tool
                                     default:
                                     default:
                                         break;
                                         break;
                                 }
                                 }
-                                viewerTool.DrawStartTextEdit(viewerTool.GetLastSelectedRect());
+                                if (e.mouseButtonEventArgs.LeftButton == MouseButtonState.Pressed)
+                                {
+                                    viewerTool.DrawStartTextEdit(viewerTool.GetLastSelectedRect(), editAreaObject);
+                                }
+
                                 clickEditSelected = false;
                                 clickEditSelected = false;
                             }
                             }
                         }
                         }
                         else
                         else
                         {
                         {
+                            //If it is multiple selection, do not create a new input box
+                            MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(viewerTool.PDFViewer.GetViewForTag(viewerTool.MultiSelectedRectViewTag));
+                            if (multiSelectedRect != null && multiSelectedRect.Children.Count > 0)
+                            {
+                                viewerTool.PDFViewer.UpdateRenderFrame();
+                                return;
+                            }
                             Point point = Mouse.GetPosition(viewerTool);
                             Point point = Mouse.GetPosition(viewerTool);
                             viewerTool.GetCPDFViewer().GetPointPageInfo(point, out int index, out Rect paintRect, out Rect pageBound);
                             viewerTool.GetCPDFViewer().GetPointPageInfo(point, out int index, out Rect paintRect, out Rect pageBound);
                             if (index < 0)
                             if (index < 0)
@@ -2109,7 +2461,18 @@ namespace ComPDFKit.Tool
                             }
                             }
                             if (createContentEditType == CPDFEditType.EditText)
                             if (createContentEditType == CPDFEditType.EditText)
                             {
                             {
-                                viewerTool.DrawTest(pageBound, index);
+                                if (viewerTool.CanAddTextEdit)
+                                {
+                                    viewerTool.DrawTest(pageBound, index);
+                                }
+                            }
+                            if (createContentEditType == CPDFEditType.None)
+                            {
+                                viewerTool.DrawFrameSelect();
+                            }
+                            else
+                            {
+                                viewerTool.DrawEndFrameSelect();
                             }
                             }
                             clickEditSelected = false;
                             clickEditSelected = false;
                         }
                         }

+ 38 - 13
Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.Annot.cs

@@ -322,7 +322,7 @@ namespace ComPDFKit.Tool
             {
             {
                 return;
                 return;
             }
             }
-            (baseLayer as CreateAnnotTool).MultipleClick(point);
+            (baseLayer as CreateAnnotTool).MultipleClick(point, index);
         }
         }
 
 
         public void SetScrollAndZoomTypeForAnnot(C_ANNOTATION_TYPE annotType)
         public void SetScrollAndZoomTypeForAnnot(C_ANNOTATION_TYPE annotType)
@@ -462,7 +462,7 @@ namespace ComPDFKit.Tool
                     List<CRect> coreRectList = new List<CRect>();
                     List<CRect> coreRectList = new List<CRect>();
                     foreach (Rect copyRect in pageSelectRectList)
                     foreach (Rect copyRect in pageSelectRectList)
                     {
                     {
-                        coreRectList.Add(new CRect((float)copyRect.Left, (float)copyRect.Top, (float)copyRect.Right, (float)copyRect.Bottom));
+                        coreRectList.Add(new CRect((float)copyRect.Left, (float)copyRect.Bottom, (float)copyRect.Right, (float)copyRect.Top));
                     }
                     }
                     CreateDefaultAnnot(annotCore, annotType, null);
                     CreateDefaultAnnot(annotCore, annotType, null);
                     string markupContent = textSelectInfo.PageSelectText[pageIndex];
                     string markupContent = textSelectInfo.PageSelectText[pageIndex];
@@ -557,6 +557,17 @@ namespace ComPDFKit.Tool
                                 historyGroup.Histories.Add(redactHistory);
                                 historyGroup.Histories.Add(redactHistory);
                             }
                             }
                             break;
                             break;
+                        case C_ANNOTATION_TYPE.C_ANNOTATION_LINK:
+                            {
+                                LinkAnnotHistory linkHistory = new LinkAnnotHistory();
+                                AnnotParam annotParam = ParamConverter.AnnotConverter(cPDFDocument, annotCore);
+                                linkHistory.Action = HistoryAction.Add;
+                                linkHistory.CurrentParam = (LinkParam)annotParam;
+                                linkHistory.PDFDoc = cPDFDocument;
+                                linkHistory.Action = HistoryAction.Add;
+                                historyGroup.Histories.Add(linkHistory);
+                            }
+                            break;
                         default:
                         default:
                             break;
                             break;
                     }
                     }
@@ -636,7 +647,7 @@ namespace ComPDFKit.Tool
                 {
                 {
                     return;
                     return;
                 }
                 }
-                AnnotData annotData = currentAnnot.GetAnnotData(); 
+                AnnotData annotData = currentAnnot.GetAnnotData();
 
 
                 if (annotData.PaintRect == Rect.Empty)
                 if (annotData.PaintRect == Rect.Empty)
                 {
                 {
@@ -676,7 +687,7 @@ namespace ComPDFKit.Tool
                     double Height = DpiHelper.PDFNumToStandardNum(drawRect.height());
                     double Height = DpiHelper.PDFNumToStandardNum(drawRect.height());
                     textui = new TextBox();
                     textui = new TextBox();
                     textui.Name = "PdfViewerTextBox";
                     textui.Name = "PdfViewerTextBox";
-                    textBorder = new Border();
+                    textBorder = new DashedBorder();
                     textBorder.Child = textui;
                     textBorder.Child = textui;
                     textBorder.MinWidth = Width * PDFViewer.GetZoom();
                     textBorder.MinWidth = Width * PDFViewer.GetZoom();
                     textBorder.MinHeight = Height * PDFViewer.GetZoom();
                     textBorder.MinHeight = Height * PDFViewer.GetZoom();
@@ -714,15 +725,27 @@ namespace ComPDFKit.Tool
 
 
                     textBorder.Padding = new Thickness(0);
                     textBorder.Padding = new Thickness(0);
                     textBorder.BorderBrush = new SolidColorBrush(borderColor);
                     textBorder.BorderBrush = new SolidColorBrush(borderColor);
-                    textBorder.BorderThickness = new Thickness(DpiHelper.PDFNumToStandardNum(textWidget.GetBorderWidth() * annotData.CurrentZoom));
+                    double rawWidth = textWidget.GetBorderWidth();
+                    double drawWidth = DpiHelper.PDFNumToStandardNum(rawWidth * annotData.CurrentZoom);
+                    textBorder.BorderThickness = new Thickness(drawWidth);
                     textui.BorderThickness = new Thickness(0);
                     textui.BorderThickness = new Thickness(0);
                     textui.Text = textWidget.Content;
                     textui.Text = textWidget.Content;
+                    if (textWidget.BorderStyle != C_BORDER_STYLE.BS_SOLID && textWidget.Dash != null && textWidget.Dash.Length > 0)
+                    {
+                        //补充保存虚线样式
+                        DashedBorder dashBorder = textBorder as DashedBorder;
+                        DoubleCollection dashCollection = new DoubleCollection();
+                        foreach (float num in textWidget.Dash)
+                        {
+                            dashCollection.Add(num);
+                        }
+                        dashBorder?.DrawDashBorder(true, drawWidth, rawWidth, dashCollection);
+                    }
 
 
-                    string fontName = string.Empty;
-                    string fontFamily = string.Empty;
-                    CPDFFont.GetFamilyStyleName(textWidget.FreeTextDa.FontName, ref fontFamily, ref fontName);
-                    textui.FontFamily = new FontFamily(fontFamily);
-
+                    //string fontName = string.Empty;
+                    //string fontFamily = string.Empty;
+                    //CPDFFont.GetFamilyStyleName(textWidget.FreeTextDa.FontName, ref fontFamily, ref fontName);
+                    textui.FontFamily = new FontFamily(textWidget.FreeTextDa.FontName + ",Microsoft YaHei");
                     textui.AcceptsReturn = true;
                     textui.AcceptsReturn = true;
                     textui.TextWrapping = TextWrapping.Wrap;
                     textui.TextWrapping = TextWrapping.Wrap;
                     textui.TextAlignment = TextAlignment.Left;
                     textui.TextAlignment = TextAlignment.Left;
@@ -830,7 +853,7 @@ namespace ComPDFKit.Tool
                                 viewer.UpdateAnnotFrame();
                                 viewer.UpdateAnnotFrame();
                             }
                             }
                             RemovePopTextUI();
                             RemovePopTextUI();
-                        } 
+                        }
                     };
                     };
 
 
                     BaseLayer createAnnotTool = PDFViewer?.GetView(createAnnotTag) as CreateAnnotTool;
                     BaseLayer createAnnotTool = PDFViewer?.GetView(createAnnotTag) as CreateAnnotTool;
@@ -900,8 +923,10 @@ namespace ComPDFKit.Tool
                     textBorder.BorderBrush = new SolidColorBrush(borderColor);
                     textBorder.BorderBrush = new SolidColorBrush(borderColor);
                     textBorder.BorderThickness = new Thickness(DpiHelper.PDFNumToStandardNum(textWidget.GetBorderWidth() * annotData.CurrentZoom));
                     textBorder.BorderThickness = new Thickness(DpiHelper.PDFNumToStandardNum(textWidget.GetBorderWidth() * annotData.CurrentZoom));
                     textui.BorderThickness = new Thickness(0);
                     textui.BorderThickness = new Thickness(0);
-                    textui.Text = textWidget.Content;
-
+                    if (string.IsNullOrEmpty(textui.Text) == false)
+                    {
+                        textui.CaretIndex = textui.Text.Length;
+                    }
                     textui.FontFamily = new FontFamily(GetFontName(textAttribute.FontName));
                     textui.FontFamily = new FontFamily(GetFontName(textAttribute.FontName));
                     textui.FontWeight = IsBold(textAttribute.FontName) ? FontWeights.Bold : FontWeights.Normal;
                     textui.FontWeight = IsBold(textAttribute.FontName) ? FontWeights.Bold : FontWeights.Normal;
                     textui.FontStyle = IsItalic(textAttribute.FontName) ? FontStyles.Italic : FontStyles.Normal;
                     textui.FontStyle = IsItalic(textAttribute.FontName) ? FontStyles.Italic : FontStyles.Normal;

File diff suppressed because it is too large
+ 1136 - 0
Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.AnnotSelector.cs


+ 161 - 18
Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.Command.cs

@@ -16,6 +16,7 @@ using ComPDFKitViewer.Widget;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Dynamic;
 using System.Dynamic;
+using System.Linq;
 using System.Text;
 using System.Text;
 using System.Windows;
 using System.Windows;
 using System.Windows.Input;
 using System.Windows.Input;
@@ -161,10 +162,19 @@ namespace ComPDFKit.Tool
                         CheckViewerCommandStatus(uiCommand, e);
                         CheckViewerCommandStatus(uiCommand, e);
                         break;
                         break;
                     case ToolType.CreateAnnot:
                     case ToolType.CreateAnnot:
-                    case ToolType.WidgetEdit:
                     case ToolType.Pan:
                     case ToolType.Pan:
                         CheckAnnotCommandStatus(uiCommand, e);
                         CheckAnnotCommandStatus(uiCommand, e);
                         break;
                         break;
+                    case ToolType.WidgetEdit:
+                        if (AnnotSelectCommandSupport(uiCommand))
+                        {
+                            e.CanExecute = true;
+                        }
+                        else
+                        {
+                            CheckAnnotCommandStatus(uiCommand, e);
+                        }
+                        break;
                     case ToolType.Customize:
                     case ToolType.Customize:
                         break;
                         break;
                     case ToolType.ContentEdit:
                     case ToolType.ContentEdit:
@@ -206,10 +216,19 @@ namespace ComPDFKit.Tool
                             ExecuteViewerCommand(uiCommand);
                             ExecuteViewerCommand(uiCommand);
                             break;
                             break;
                         case ToolType.CreateAnnot:
                         case ToolType.CreateAnnot:
-                        case ToolType.WidgetEdit:
                         case ToolType.Pan:
                         case ToolType.Pan:
                             ExecuteAnnotCommand(uiCommand);
                             ExecuteAnnotCommand(uiCommand);
                             break;
                             break;
+                        case ToolType.WidgetEdit:
+                            if(AnnotSelectCommandSupport(uiCommand))
+                            {
+                                AnnotSelectCommandExecute(uiCommand);
+                            }
+                            else
+                            {
+                                ExecuteAnnotCommand(uiCommand);
+                            }
+                            break;
                         case ToolType.ContentEdit:
                         case ToolType.ContentEdit:
                             {
                             {
                                 ExecutePDFEditCommand(uiCommand, out editType);
                                 ExecutePDFEditCommand(uiCommand, out editType);
@@ -225,8 +244,8 @@ namespace ComPDFKit.Tool
                     commandData.CurrentParam = PasteParam;
                     commandData.CurrentParam = PasteParam;
                     CommandExecutedHandler?.Invoke(this, commandData);
                     CommandExecutedHandler?.Invoke(this, commandData);
                 }
                 }
-                catch (Exception ex) 
-                { 
+                catch (Exception ex)
+                {
 
 
                 }
                 }
             }
             }
@@ -252,6 +271,12 @@ namespace ComPDFKit.Tool
                         {
                         {
                             e.CanExecute = true;
                             e.CanExecute = true;
                         }
                         }
+                        //Add multi status
+                        MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(PDFViewer.GetViewForTag(MultiSelectedRectViewTag));
+                        if (multiSelectedRect != null && multiSelectedRect.Children.Count > 0)
+                        {
+                            e.CanExecute = true;
+                        }
                         break;
                         break;
                     }
                     }
                 case "Paste":
                 case "Paste":
@@ -465,6 +490,70 @@ namespace ComPDFKit.Tool
                         }
                         }
                     }
                     }
                 }
                 }
+                else
+                {
+                    //Add multi status
+                    MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(PDFViewer.GetViewForTag(MultiSelectedRectViewTag));
+                    if (multiSelectedRect != null && multiSelectedRect.Children.Count > 0)
+                    {
+                        foreach (SelectedRect selectedRect in multiSelectedRect.Children)
+                        {
+                            EditAreaObject editAreaObject = GetEditAreaObjectListForRect(selectedRect);
+                            if (editAreaObject != null)
+                            {
+
+                                PDFEditCommandData commandData = new PDFEditCommandData();
+                                if (editAreaObject.cPDFEditArea.Type == CPDFEditType.EditText)
+                                {
+                                    editType = CPDFEditType.EditText;
+                                    CPDFEditTextArea editTextArea = editAreaObject.cPDFEditArea as CPDFEditTextArea;
+                                    commandData.TextContent = editTextArea.SelectText;
+                                    if (!string.IsNullOrEmpty(commandData.TextContent))
+                                    {
+                                        CPDFEditPage editPage = editAreaObject.cPDFEditPage;
+                                        commandData.EditType = CPDFEditType.EditText;
+                                        commandData.EditAreaCopied = editPage.CopyEditArea(editAreaObject.cPDFEditArea);
+                                        if (commandData.EditAreaCopied)
+                                        {
+                                            List<CPDFCopyEditArea> copyList = editPage.GetCopyEditAreaList();
+                                            CPDFCopyEditArea CopyArea = copyList[copyList.Count - 1];
+                                            commandData.TextContent = CopyArea.GetCopyTextAreaContent();
+                                            commandData.CopyArea = CopyArea;
+                                            commandData.EditPage = editPage;
+                                        }
+                                    }
+                                    try
+                                    {
+                                        Clipboard.Clear();
+                                        Clipboard.SetText(commandData.TextContent);
+                                        Clipboard.Flush();
+                                    }
+                                    catch (Exception)
+                                    {
+
+                                    }
+                                    commandData.PDFRect = DataConversionForWPF.CRectConversionForRect(editAreaObject.cPDFEditArea.GetFrame());
+                                    lastPDFEditArgsList.Add(commandData);
+                                }
+                                if (editAreaObject.cPDFEditArea.Type == CPDFEditType.EditImage)
+                                {
+                                    editType = CPDFEditType.EditImage;
+                                    CPDFEditPage editPage = editAreaObject.cPDFEditPage;
+                                    commandData.PDFRect = DataConversionForWPF.CRectConversionForRect(editAreaObject.cPDFEditArea.GetFrame());
+                                    commandData.EditAreaCopied = editPage.CopyEditArea(editAreaObject.cPDFEditArea);
+                                    commandData.EditType = CPDFEditType.EditImage;
+                                    if (commandData.EditAreaCopied)
+                                    {
+                                        List<CPDFCopyEditArea> copyList = editPage.GetCopyEditAreaList();
+                                        commandData.CopyArea = copyList[copyList.Count - 1];
+                                        commandData.EditPage = editPage;
+                                        lastPDFEditArgsList.Add(commandData);
+                                    }
+                                }
+                            }
+                        } 
+                    }
+                }
             }
             }
             catch
             catch
             {
             {
@@ -487,35 +576,77 @@ namespace ComPDFKit.Tool
                     editType = CPDFEditType.EditText;
                     editType = CPDFEditType.EditText;
                     CPDFEditTextArea editTextArea = currentEditAreaObject.cPDFEditArea as CPDFEditTextArea;
                     CPDFEditTextArea editTextArea = currentEditAreaObject.cPDFEditArea as CPDFEditTextArea;
                     string selectContent = editTextArea.SelectText;
                     string selectContent = editTextArea.SelectText;
-                    if (string.IsNullOrEmpty(selectContent) == false && !selectAllCharsForLine)
+                    if (!selectAllCharsForLine)
                     {
                     {
                         DeleteChars();
                         DeleteChars();
-                        EndEdit();
                     }
                     }
                     else
                     else
                     {
                     {
-                        if (string.IsNullOrEmpty(selectContent))
-                        {
-                            editTextArea.SelectAllChars();
-                        }
                         RemoveTextBlock();
                         RemoveTextBlock();
                     }
                     }
-                    PDFEditHistory deleteHistory = new PDFEditHistory();
-                    deleteHistory.EditPage = currentEditAreaObject.cPDFEditPage;
-                    deleteHistory.PageIndex = currentEditAreaObject.PageIndex;
-                    groupHistory.Histories.Add(deleteHistory);
                 }
                 }
+
                 if (currentEditAreaObject.cPDFEditArea.Type == CPDFEditType.EditImage)
                 if (currentEditAreaObject.cPDFEditArea.Type == CPDFEditType.EditImage)
                 {
                 {
                     editType = CPDFEditType.EditImage;
                     editType = CPDFEditType.EditImage;
                     RemoveImageBlock();
                     RemoveImageBlock();
                 }
                 }
 
 
-                //After removing the data, you need to get the data again.
-                PDFViewer.UpdateRenderFrame();
                 if (PDFViewer != null && PDFViewer.UndoManager != null)
                 if (PDFViewer != null && PDFViewer.UndoManager != null)
                 {
                 {
                     PDFViewer.UndoManager.AddHistory(groupHistory);
                     PDFViewer.UndoManager.AddHistory(groupHistory);
+                    //After removing the data, you need to get the data again.
+                    PDFViewer.UpdateRenderFrame();
+                }
+            }
+            else
+            {
+                //Add multi status
+                MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(PDFViewer.GetViewForTag(MultiSelectedRectViewTag));
+                if (multiSelectedRect != null && multiSelectedRect.Children.Count > 0)
+                {
+                    List<EditAreaObject> editAreaObjectList = new List<EditAreaObject>();
+                    foreach (SelectedRect selectedRect in multiSelectedRect.Children)
+                    {
+                        EditAreaObject editAreaObject = GetEditAreaObjectListForRect(selectedRect);
+                        editAreaObjectList.Add(editAreaObject);
+                    }
+
+                    if (editAreaObjectList != null && editAreaObjectList.Count > 0)
+                    {
+                        editAreaObjectList = editAreaObjectList.OrderByDescending(x => x.EditAreaIndex).ToList();
+                        GroupHistory groupHistory = new GroupHistory();
+                        foreach (EditAreaObject editareaobject in editAreaObjectList)
+                        {
+                            PDFEditHistory editHistory = new PDFEditHistory();
+                            editHistory.EditPage = editareaobject.cPDFEditPage;
+                            editHistory.PageIndex = editareaobject.PageIndex;
+                            groupHistory.Histories.Add(editHistory);
+                            if (editareaobject.cPDFEditArea.Type == CPDFEditType.EditText)
+                            {
+                                editType = CPDFEditType.EditText;
+                                CPDFEditTextArea editTextArea = editareaobject.cPDFEditArea as CPDFEditTextArea;
+                                string selectContent = editTextArea.SelectText;
+                                RemoveTextBlock(editareaobject);
+                            }
+
+                            if (editareaobject.cPDFEditArea.Type == CPDFEditType.EditImage)
+                            {
+                                editType = CPDFEditType.EditImage;
+                                RemoveImageBlock(editareaobject);
+                            }
+                        }
+
+                        if (PDFViewer != null && PDFViewer.UndoManager != null)
+                        {
+                            PDFViewer.UndoManager.AddHistory(groupHistory);
+                            //After removing the data, you need to get the data again.
+                            PDFViewer.UpdateRenderFrame();
+                        }
+                    }
+
+                    CleanSelectedMultiRect();
+                    OpenSelectedMulti(false);
                 }
                 }
             }
             }
         }
         }
@@ -814,7 +945,6 @@ namespace ComPDFKit.Tool
 
 
         #endregion
         #endregion
 
 
-
         #region Annot
         #region Annot
 
 
         private bool CheckCacheHitTestAnnot(string cmdName = "")
         private bool CheckCacheHitTestAnnot(string cmdName = "")
@@ -1099,7 +1229,7 @@ namespace ComPDFKit.Tool
                             CPDFAnnotation cPDFAnnotation = cPDFPage.CreateAnnot(item.CurrentType);
                             CPDFAnnotation cPDFAnnotation = cPDFPage.CreateAnnot(item.CurrentType);
                             CreateDefaultAnnot(cPDFAnnotation, item.CurrentType, item);
                             CreateDefaultAnnot(cPDFAnnotation, item.CurrentType, item);
                             cPDFAnnotation.SetRect(setRect);
                             cPDFAnnotation.SetRect(setRect);
-                            cPDFAnnotation.UpdateAp();
+                            CommonHelper.UpdateStickyAP(cPDFAnnotation as CPDFTextAnnotation);
                             AnnotParam annotParam = ParamConverter.AnnotConverter(cPDFDocument, cPDFAnnotation);
                             AnnotParam annotParam = ParamConverter.AnnotConverter(cPDFDocument, cPDFAnnotation);
                             (annotHistory as StickyNoteAnnotHistory).CurrentParam = (StickyNoteParam)annotParam;
                             (annotHistory as StickyNoteAnnotHistory).CurrentParam = (StickyNoteParam)annotParam;
                         }
                         }
@@ -1285,6 +1415,13 @@ namespace ComPDFKit.Tool
                             CPDFAnnotation cPDFAnnotation = cPDFPage.CreateAnnot(item.CurrentType);
                             CPDFAnnotation cPDFAnnotation = cPDFPage.CreateAnnot(item.CurrentType);
                             CreateDefaultAnnot(cPDFAnnotation, item.CurrentType, item);
                             CreateDefaultAnnot(cPDFAnnotation, item.CurrentType, item);
                             cPDFAnnotation.SetRect(setRect);
                             cPDFAnnotation.SetRect(setRect);
+                            CPDFTextPage textPage = cPDFPage.GetTextPage();
+                            if (textPage != null)
+                            {
+                                string newContent = textPage.GetBoundedText(setRect);
+                                cPDFAnnotation.SetContent(newContent);
+                            }
+
                             cPDFAnnotation.UpdateAp();
                             cPDFAnnotation.UpdateAp();
                             AnnotParam annotParam = ParamConverter.AnnotConverter(cPDFDocument, cPDFAnnotation);
                             AnnotParam annotParam = ParamConverter.AnnotConverter(cPDFDocument, cPDFAnnotation);
                             (annotHistory as SquareAnnotHistory).CurrentParam = (SquareParam)annotParam;
                             (annotHistory as SquareAnnotHistory).CurrentParam = (SquareParam)annotParam;
@@ -1329,6 +1466,12 @@ namespace ComPDFKit.Tool
                             CPDFAnnotation cPDFAnnotation = cPDFPage.CreateAnnot(item.CurrentType);
                             CPDFAnnotation cPDFAnnotation = cPDFPage.CreateAnnot(item.CurrentType);
                             CreateDefaultAnnot(cPDFAnnotation, item.CurrentType, item);
                             CreateDefaultAnnot(cPDFAnnotation, item.CurrentType, item);
                             cPDFAnnotation.SetRect(setRect);
                             cPDFAnnotation.SetRect(setRect);
+                            CPDFTextPage textPage = cPDFPage.GetTextPage();
+                            if (textPage != null)
+                            {
+                                string newContent = textPage.GetBoundedText(setRect);
+                                cPDFAnnotation.SetContent(newContent);
+                            }
                             cPDFAnnotation.UpdateAp();
                             cPDFAnnotation.UpdateAp();
                             AnnotParam annotParam = ParamConverter.AnnotConverter(cPDFDocument, cPDFAnnotation);
                             AnnotParam annotParam = ParamConverter.AnnotConverter(cPDFDocument, cPDFAnnotation);
                             (annotHistory as CircleAnnotHistory).CurrentParam = (CircleParam)annotParam;
                             (annotHistory as CircleAnnotHistory).CurrentParam = (CircleParam)annotParam;

+ 2 - 0
Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.CustomizeTool.cs

@@ -70,9 +70,11 @@ namespace ComPDFKit.Tool
             CPDFDocument cPDFDocument = PDFViewer.GetDocument();
             CPDFDocument cPDFDocument = PDFViewer.GetDocument();
             CPDFPage cPDFPage = cPDFDocument.PageAtIndex(index);
             CPDFPage cPDFPage = cPDFDocument.PageAtIndex(index);
             BaseLayer layer = PDFViewer.GetViewForTag(PDFViewer.GetAnnotViewTag());
             BaseLayer layer = PDFViewer.GetViewForTag(PDFViewer.GetAnnotViewTag());
+            (baseLayer as CreateCustomizeTool).ErasePageIndex = -1;
             if (ToolType == CustomizeToolType.kErase)
             if (ToolType == CustomizeToolType.kErase)
             {
             {
                 (baseLayer as CreateCustomizeTool).SetAnnotLayer(layer as AnnotLayer);
                 (baseLayer as CreateCustomizeTool).SetAnnotLayer(layer as AnnotLayer);
+                (baseLayer as CreateCustomizeTool).ErasePageIndex = index;
             }
             }
            (baseLayer as CreateCustomizeTool).StartDraw(point, cPDFPage, paintRect, pageBound, ToolType);
            (baseLayer as CreateCustomizeTool).StartDraw(point, cPDFPage, paintRect, pageBound, ToolType);
         }
         }

+ 29 - 30
Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.DataMethod.cs

@@ -183,6 +183,10 @@ namespace ComPDFKit.Tool
             }
             }
 
 
             TextAnnotation.SetColor(StickyNoteParamDef.StickyNoteColor);
             TextAnnotation.SetColor(StickyNoteParamDef.StickyNoteColor);
+            if(string.IsNullOrEmpty(StickyNoteParamDef.IconName)==false)
+            {
+                TextAnnotation.SetIconName(StickyNoteParamDef.IconName);
+            }
             DefaultAnnot(cPDFAnnotation, StickyNoteParamDef);
             DefaultAnnot(cPDFAnnotation, StickyNoteParamDef);
         }
         }
 
 
@@ -254,7 +258,6 @@ namespace ComPDFKit.Tool
             {
             {
                 freeTextAnnotation.SetLineColor(FreeTextParam.LineColor);
                 freeTextAnnotation.SetLineColor(FreeTextParam.LineColor);
             }
             }
-            freeTextAnnotation.SetBorderWidth(1);
             freeTextAnnotation.SetTransparency(FreeTextParam.Transparency);
             freeTextAnnotation.SetTransparency(FreeTextParam.Transparency);
             freeTextAnnotation.SetLineWidth((float)FreeTextParam.LineWidth);
             freeTextAnnotation.SetLineWidth((float)FreeTextParam.LineWidth);
 
 
@@ -262,6 +265,13 @@ namespace ComPDFKit.Tool
             {
             {
                 freeTextAnnotation.SetBgColor(FreeTextParam.BgColor);
                 freeTextAnnotation.SetBgColor(FreeTextParam.BgColor);
             }
             }
+
+            if(FreeTextParam.Dash!=null && FreeTextParam.Dash.Length>0)
+            {
+                //补充保存虚线样式
+                freeTextAnnotation.SetBorderStyle(C_BORDER_STYLE.BS_DASHDED, FreeTextParam.Dash);
+            }
+
             CTextAttribute textAttr = new CTextAttribute();
             CTextAttribute textAttr = new CTextAttribute();
             textAttr.FontColor = FreeTextParam.FontColor;
             textAttr.FontColor = FreeTextParam.FontColor;
             textAttr.FontSize = (float)FreeTextParam.FontSize;
             textAttr.FontSize = (float)FreeTextParam.FontSize;
@@ -625,7 +635,16 @@ namespace ComPDFKit.Tool
             }
             }
 
 
             InkAnnotation.SetThickness((float)inkParam.Thickness);
             InkAnnotation.SetThickness((float)inkParam.Thickness);
-            (cPDFAnnotation as CPDFInkAnnotation).SetInkPath(inkParam.InkPath);
+            CPDFInkAnnotation inkAnnot = cPDFAnnotation as CPDFInkAnnotation;
+            inkAnnot.SetInkPath(inkParam.InkPath);
+            if(inkParam.Dash!=null && inkParam.Dash.Length>0)
+            {
+                inkAnnot.SetBorderStyle(C_BORDER_STYLE.BS_DASHDED,inkParam.Dash);
+            }
+            else
+            {
+                inkAnnot.SetBorderStyle(C_BORDER_STYLE.BS_SOLID, new float[0]);
+            }
             DefaultAnnot(cPDFAnnotation, inkParam);
             DefaultAnnot(cPDFAnnotation, inkParam);
         }
         }
 
 
@@ -720,7 +739,7 @@ namespace ComPDFKit.Tool
             {
             {
                 return;
                 return;
             }
             }
-            if (!LineAnnotation.IsMersured() && annotParam != null)
+            if (!LineAnnotation.IsMeasured() && annotParam != null)
             {
             {
                 return;
                 return;
             }
             }
@@ -783,7 +802,7 @@ namespace ComPDFKit.Tool
             {
             {
                 return;
                 return;
             }
             }
-            if (!PolyAnnotation.IsMersured() && annotParam != null)
+            if (!PolyAnnotation.IsMeasured() && annotParam != null)
             {
             {
                 return;
                 return;
             }
             }
@@ -850,7 +869,7 @@ namespace ComPDFKit.Tool
             {
             {
                 return;
                 return;
             }
             }
-            if (!PolyAnnotation.IsMersured() && annotParam != null)
+            if (!PolyAnnotation.IsMeasured() && annotParam != null)
             {
             {
                 return;
                 return;
             }
             }
@@ -999,11 +1018,7 @@ namespace ComPDFKit.Tool
             CTextAttribute textAttr = new CTextAttribute();
             CTextAttribute textAttr = new CTextAttribute();
             textAttr.FontColor = pushButtonParam.FontColor;
             textAttr.FontColor = pushButtonParam.FontColor;
             textAttr.FontSize = (float)pushButtonParam.FontSize;
             textAttr.FontSize = (float)pushButtonParam.FontSize;
-            FontType checkFontType = CFontNameHelper.GetFontType(pushButtonParam.FontName);
-            textAttr.FontName = CFontNameHelper.ObtainFontName(
-                checkFontType == FontType.Unknown ? FontType.Helvetica : checkFontType,
-                pushButtonParam.IsBold,
-                 pushButtonParam.IsItalic);
+            textAttr.FontName = pushButtonParam.FontName;
             widget.SetTextAttribute(textAttr);
             widget.SetTextAttribute(textAttr);
 
 
             if (!string.IsNullOrEmpty(pushButtonParam.FieldName))
             if (!string.IsNullOrEmpty(pushButtonParam.FieldName))
@@ -1156,11 +1171,7 @@ namespace ComPDFKit.Tool
             CTextAttribute textAttr = new CTextAttribute();
             CTextAttribute textAttr = new CTextAttribute();
             textAttr.FontColor = textBoxParam.FontColor;
             textAttr.FontColor = textBoxParam.FontColor;
             textAttr.FontSize = (float)textBoxParam.FontSize;
             textAttr.FontSize = (float)textBoxParam.FontSize;
-            FontType checkFontType = CFontNameHelper.GetFontType(textBoxParam.FontName);
-            textAttr.FontName = CFontNameHelper.ObtainFontName(
-                checkFontType == FontType.Unknown ? FontType.Helvetica : checkFontType,
-                textBoxParam.IsBold,
-                 textBoxParam.IsItalic);
+            textAttr.FontName = textBoxParam.FontName;
             widget.SetTextAttribute(textAttr);
             widget.SetTextAttribute(textAttr);
 
 
             if (!string.IsNullOrEmpty(textBoxParam.FieldName))
             if (!string.IsNullOrEmpty(textBoxParam.FieldName))
@@ -1205,11 +1216,7 @@ namespace ComPDFKit.Tool
             CTextAttribute textAttr = new CTextAttribute();
             CTextAttribute textAttr = new CTextAttribute();
             textAttr.FontColor = comboBoxParam.FontColor;
             textAttr.FontColor = comboBoxParam.FontColor;
             textAttr.FontSize = (float)comboBoxParam.FontSize;
             textAttr.FontSize = (float)comboBoxParam.FontSize;
-            FontType checkFontType = CFontNameHelper.GetFontType(comboBoxParam.FontName);
-            textAttr.FontName = CFontNameHelper.ObtainFontName(
-                checkFontType == FontType.Unknown ? FontType.Helvetica : checkFontType,
-                comboBoxParam.IsBold,
-                 comboBoxParam.IsItalic);
+            textAttr.FontName = comboBoxParam.FontName;
             widget.SetTextAttribute(textAttr);
             widget.SetTextAttribute(textAttr);
 
 
             if (!string.IsNullOrEmpty(comboBoxParam.FieldName))
             if (!string.IsNullOrEmpty(comboBoxParam.FieldName))
@@ -1260,11 +1267,7 @@ namespace ComPDFKit.Tool
             CTextAttribute textAttr = new CTextAttribute();
             CTextAttribute textAttr = new CTextAttribute();
             textAttr.FontColor = listBoxParam.FontColor;
             textAttr.FontColor = listBoxParam.FontColor;
             textAttr.FontSize = (float)listBoxParam.FontSize;
             textAttr.FontSize = (float)listBoxParam.FontSize;
-            FontType checkFontType = CFontNameHelper.GetFontType(listBoxParam.FontName);
-            textAttr.FontName = CFontNameHelper.ObtainFontName(
-                checkFontType == FontType.Unknown ? FontType.Helvetica : checkFontType,
-                listBoxParam.IsBold,
-                 listBoxParam.IsItalic);
+            textAttr.FontName = listBoxParam.FontName;
             widget.SetTextAttribute(textAttr);
             widget.SetTextAttribute(textAttr);
 
 
             if (!string.IsNullOrEmpty(listBoxParam.FieldName))
             if (!string.IsNullOrEmpty(listBoxParam.FieldName))
@@ -1316,11 +1319,7 @@ namespace ComPDFKit.Tool
             textAttr.FontSize = (float)signatureParam.FontSize;
             textAttr.FontSize = (float)signatureParam.FontSize;
             bool isBold = IsBold(textAttr.FontName);
             bool isBold = IsBold(textAttr.FontName);
             bool isItalic = IsItalic(textAttr.FontName);
             bool isItalic = IsItalic(textAttr.FontName);
-            FontType checkFontType = CFontNameHelper.GetFontType(signatureParam.FontName);
-            textAttr.FontName = CFontNameHelper.ObtainFontName(
-                checkFontType == FontType.Unknown ? FontType.Helvetica : checkFontType,
-                isBold,
-                 isItalic);
+            textAttr.FontName = signatureParam.FontName;
             widget.SetTextAttribute(textAttr);
             widget.SetTextAttribute(textAttr);
 
 
             if (!string.IsNullOrEmpty(signatureParam.FieldName))
             if (!string.IsNullOrEmpty(signatureParam.FieldName))

+ 6 - 0
Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.FindReplace.cs

@@ -184,6 +184,12 @@ namespace ComPDFKit.Tool
                 }
                 }
             }
             }
 
 
+            if (currentSelectionIndex < 0 || (editTextFindSelectionList!=null && currentSelectionIndex >= editTextFindSelectionList.Count))
+            {
+                isOtherPage = false;
+                canLoop = true;
+                return false;
+            }
             editTextFindSelection = editTextFindSelectionList[currentSelectionIndex];
             editTextFindSelection = editTextFindSelectionList[currentSelectionIndex];
             GoToFoundDestination(editTextFindSelection);
             GoToFoundDestination(editTextFindSelection);
             isOtherPage = false;
             isOtherPage = false;

+ 108 - 37
Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.MultiSelectedRect.cs

@@ -1,12 +1,8 @@
 using ComPDFKit.Tool.DrawTool;
 using ComPDFKit.Tool.DrawTool;
 using ComPDFKit.Tool.Help;
 using ComPDFKit.Tool.Help;
 using ComPDFKit.Viewer.Layer;
 using ComPDFKit.Viewer.Layer;
-using ComPDFKitViewer.Layer;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 using System.Windows;
 using System.Windows;
 using System.Windows.Input;
 using System.Windows.Input;
 
 
@@ -31,15 +27,29 @@ namespace ComPDFKit.Tool
         public float ZoomX { get; set; }
         public float ZoomX { get; set; }
 
 
         public float ZoomY { get; set; }
         public float ZoomY { get; set; }
+
+        /// <summary>
+        /// Multiple selection of movement distance
+        /// </summary>
+        public float ChangeX { get; set; }
+
+        /// <summary>
+        /// Multiple selection of movement distance
+        /// </summary>
+        public float ChangeY { get; set; }
     }
     }
 
 
     public partial class CPDFViewerTool
     public partial class CPDFViewerTool
     {
     {
-        int multiSelectedRectViewTag = -1;
-        List<int> editAreaMultiIndex = new List<int>();
-        int multiPage = -1;
         public event EventHandler<MultiSelectedData> MultiDataChanging;
         public event EventHandler<MultiSelectedData> MultiDataChanging;
         public event EventHandler<MultiSelectedData> MultiDataChanged;
         public event EventHandler<MultiSelectedData> MultiDataChanged;
+        public int MultiSelectedRectViewTag { get; set; } = -1;
+
+        private List<int> editAreaMultiIndex = new List<int>();
+        private int multiPage = -1;
+        private bool isOpen = false;
+        private Key multiKey = Key.LeftCtrl;
+
         private void InsertMultiSelectedRectView()
         private void InsertMultiSelectedRectView()
         {
         {
             int selectedRectViewIndex = PDFViewer.GetMaxViewIndex();
             int selectedRectViewIndex = PDFViewer.GetMaxViewIndex();
@@ -50,18 +60,20 @@ namespace ComPDFKit.Tool
             multiSelectedRect.DataChanged += MultiSelectedRect_DataChanged;
             multiSelectedRect.DataChanged += MultiSelectedRect_DataChanged;
             multiSelectedRect.DataChanging += MultiSelectedRect_DataChanging;
             multiSelectedRect.DataChanging += MultiSelectedRect_DataChanging;
             PDFViewer.InsertView(selectedRectViewIndex, customizeLayer);
             PDFViewer.InsertView(selectedRectViewIndex, customizeLayer);
-            multiSelectedRectViewTag = customizeLayer.GetResTag();
+            MultiSelectedRectViewTag = customizeLayer.GetResTag();
             //multiSelectedRect.Children.Add(multiSelectedRect);
             //multiSelectedRect.Children.Add(multiSelectedRect);
         }
         }
 
 
         private void MultiSelectedRect_DataChanging(object sender, Point e)
         private void MultiSelectedRect_DataChanging(object sender, Point e)
         {
         {
             MultiSelectedData multiSelectedAnnotData = new MultiSelectedData();
             MultiSelectedData multiSelectedAnnotData = new MultiSelectedData();
-            MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(PDFViewer.GetViewForTag(multiSelectedRectViewTag));
+            MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(PDFViewer.GetViewForTag(MultiSelectedRectViewTag));
             if (isOpen && multiSelectedRect != null)
             if (isOpen && multiSelectedRect != null)
             {
             {
                 multiSelectedAnnotData.ZoomX = multiSelectedRect.GetZoomX();
                 multiSelectedAnnotData.ZoomX = multiSelectedRect.GetZoomX();
                 multiSelectedAnnotData.ZoomY = multiSelectedRect.GetZoomY();
                 multiSelectedAnnotData.ZoomY = multiSelectedRect.GetZoomY();
+                multiSelectedAnnotData.ChangeX = multiSelectedRect.GetChangeX();
+                multiSelectedAnnotData.ChangeY = multiSelectedRect.GetChangeY();
                 multiSelectedAnnotData.MoveOffset = e;
                 multiSelectedAnnotData.MoveOffset = e;
                 multiSelectedAnnotData.ObjectType = multiSelectedRect.GetSelectedType();
                 multiSelectedAnnotData.ObjectType = multiSelectedRect.GetSelectedType();
                 multiSelectedAnnotData.MultiObjectIndex = new List<int>();
                 multiSelectedAnnotData.MultiObjectIndex = new List<int>();
@@ -74,11 +86,13 @@ namespace ComPDFKit.Tool
         private void MultiSelectedRect_DataChanged(object sender, Point e)
         private void MultiSelectedRect_DataChanged(object sender, Point e)
         {
         {
             MultiSelectedData multiSelectedAnnotData = new MultiSelectedData();
             MultiSelectedData multiSelectedAnnotData = new MultiSelectedData();
-            MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(PDFViewer.GetViewForTag(multiSelectedRectViewTag));
+            MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(PDFViewer.GetViewForTag(MultiSelectedRectViewTag));
             if (isOpen && multiSelectedRect != null)
             if (isOpen && multiSelectedRect != null)
             {
             {
                 multiSelectedAnnotData.ZoomX = multiSelectedRect.GetZoomX();
                 multiSelectedAnnotData.ZoomX = multiSelectedRect.GetZoomX();
                 multiSelectedAnnotData.ZoomY = multiSelectedRect.GetZoomY();
                 multiSelectedAnnotData.ZoomY = multiSelectedRect.GetZoomY();
+                multiSelectedAnnotData.ChangeX = multiSelectedRect.GetChangeX();
+                multiSelectedAnnotData.ChangeY = multiSelectedRect.GetChangeY();
                 multiSelectedAnnotData.MoveOffset = e;
                 multiSelectedAnnotData.MoveOffset = e;
                 multiSelectedAnnotData.ObjectType = multiSelectedRect.GetSelectedType();
                 multiSelectedAnnotData.ObjectType = multiSelectedRect.GetSelectedType();
                 multiSelectedAnnotData.MultiObjectIndex = new List<int>();
                 multiSelectedAnnotData.MultiObjectIndex = new List<int>();
@@ -88,19 +102,23 @@ namespace ComPDFKit.Tool
             }
             }
         }
         }
 
 
-        bool isOpen = false;
-        public void OpenSelectedMulti(bool open)
+        /// <summary>
+        /// Set multiple selection shortcut keys
+        /// </summary>
+        /// <param name="multikey"></param>
+        public void SetMultiSelectKey(Key multikey)
+        {
+            multiKey = multikey;
+        }
+
+        private void OpenSelectedMulti(bool open)
         {
         {
-            if (!open)
-            {
-                CleanSelectedMultiRect();
-            }
             isOpen = open;
             isOpen = open;
         }
         }
 
 
         public bool HitTestMultiSelectedRect()
         public bool HitTestMultiSelectedRect()
         {
         {
-            MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(PDFViewer.GetViewForTag(multiSelectedRectViewTag));
+            MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(PDFViewer.GetViewForTag(MultiSelectedRectViewTag));
             if (isOpen && multiSelectedRect != null)
             if (isOpen && multiSelectedRect != null)
             {
             {
                 if (multiSelectedRect.GetHitControlIndex(Mouse.GetPosition(this)) != PointControlType.None)
                 if (multiSelectedRect.GetHitControlIndex(Mouse.GetPosition(this)) != PointControlType.None)
@@ -113,10 +131,16 @@ namespace ComPDFKit.Tool
 
 
         public void SelectedMultiRect(Rect selectedRects, Rect MaxRect, SelectedType type)
         public void SelectedMultiRect(Rect selectedRects, Rect MaxRect, SelectedType type)
         {
         {
-            MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(PDFViewer.GetViewForTag(multiSelectedRectViewTag));
-            if (isOpen && multiSelectedRect != null)
+            MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(PDFViewer.GetViewForTag(MultiSelectedRectViewTag));
+            bool open = isOpen;
+            if (!Keyboard.IsKeyDown(multiKey))
             {
             {
-
+                open = false;
+            }
+            if (open && multiSelectedRect != null)
+            {
+                lastSelectedRect.ClearDraw();
+                lastSelectedRect.HideDraw();
                 GetSelectedEditAreaForIndex(out int pageIndex, out int editAreaIndex);
                 GetSelectedEditAreaForIndex(out int pageIndex, out int editAreaIndex);
                 if (multiPage != pageIndex && editAreaMultiIndex.Count > 0)
                 if (multiPage != pageIndex && editAreaMultiIndex.Count > 0)
                 {
                 {
@@ -134,21 +158,64 @@ namespace ComPDFKit.Tool
                     multiPage = pageIndex;
                     multiPage = pageIndex;
                 }
                 }
                 multiPage = pageIndex;
                 multiPage = pageIndex;
-                editAreaMultiIndex.Add(editAreaIndex);
+                if (startSelectedRect != null && startSelectedPageIndex == multiPage && !editAreaMultiIndex.Contains(startSelectedIndex))
+                {
+                    //Add the first selected object
+                    editAreaMultiIndex.Add(startSelectedIndex);
 
 
+                    SelectedRect startselectedrect = new SelectedRect(GetDefaultDrawParam(), type);
+                    startselectedrect.SetEditPen(editPen, editHoverPen);
+                    startselectedrect.SetDrawMoveType(DrawMoveType.kReferenceLine);
+                    startselectedrect.SetRect(startSelectedRect.GetRect(), currentZoom);
+                    startselectedrect.SetMaxRect(MaxRect);
+                    editAreaList.Add(startselectedrect, startSelectedEditAreaObject);
+                    multiSelectedRect.Children.Add(startselectedrect);
+
+                    multiSelectedRect.SetMulitSelectedRect(startselectedrect, startSelectedEditAreaObject.PageIndex, startSelectedEditAreaObject.EditAreaIndex);
+                    multiSelectedRect.SetRect(startselectedrect.GetRect());
+                    multiSelectedRect.SetMaxRect(startselectedrect.GetMaxRect());
+                    multiSelectedRect.Draw();
+                }
+                startSelectedRect = null;
+                startSelectedIndex = -1;
+                startSelectedPageIndex = -1;
+                startSelectedEditAreaObject = null;
+                editAreaMultiIndex.Add(editAreaIndex);
                 multiSelectedRect.SetSelectedType(type);
                 multiSelectedRect.SetSelectedType(type);
                 SelectedRect selectedRect = new SelectedRect(GetDefaultDrawParam(), type);
                 SelectedRect selectedRect = new SelectedRect(GetDefaultDrawParam(), type);
+                selectedRect.SetEditPen(editPen, editHoverPen);
                 selectedRect.SetDrawMoveType(DrawMoveType.kReferenceLine);
                 selectedRect.SetDrawMoveType(DrawMoveType.kReferenceLine);
-                selectedRect.SetRect(selectedRects,currentZoom);
+                selectedRect.SetRect(selectedRects, currentZoom);
                 selectedRect.SetMaxRect(MaxRect);
                 selectedRect.SetMaxRect(MaxRect);
+                EditAreaObject editAreaObject = GetEditAreaObjectForRect(lastSelectedRect);
+                editAreaList.Add(selectedRect, editAreaObject);
                 multiSelectedRect.Children.Add(selectedRect);
                 multiSelectedRect.Children.Add(selectedRect);
-                multiSelectedRect.SetMulitSelectedRect(selectedRect);
+                multiSelectedRect.SetMulitSelectedRect(selectedRect, editAreaObject.PageIndex, editAreaObject.EditAreaIndex);
 
 
                 multiSelectedRect.SetRect(selectedRects);
                 multiSelectedRect.SetRect(selectedRects);
                 multiSelectedRect.SetMaxRect(MaxRect);
                 multiSelectedRect.SetMaxRect(MaxRect);
                 multiSelectedRect.Draw();
                 multiSelectedRect.Draw();
             }
             }
-
+            else
+            {
+                //Remember the first selected object
+                isOpen = false;
+                GetSelectedEditAreaForIndex(out int pageIndex, out int editAreaIndex);
+                SelectedRect selectedRect = new SelectedRect(GetDefaultDrawParam(), type);
+                selectedRect.SetEditPen(editPen, editHoverPen);
+                selectedRect.SetDrawMoveType(DrawMoveType.kReferenceLine);
+                selectedRect.SetRect(selectedRects, currentZoom);
+                selectedRect.SetMaxRect(MaxRect);
+                EditAreaObject editAreaObject = GetEditAreaObjectForRect(lastSelectedRect);
+                if (startSelectedIndex != editAreaIndex || startSelectedPageIndex != pageIndex)
+                {
+                    startSelectedIndex = editAreaIndex;
+                    startSelectedPageIndex = pageIndex;
+                    startSelectedEditAreaObject = editAreaObject;
+                    startSelectedRect = selectedRect;
+                    editAreaList.Add(startSelectedRect, editAreaObject);
+                }
+            }
         }
         }
 
 
         public void HideDrawSelectedMultiRect()
         public void HideDrawSelectedMultiRect()
@@ -165,18 +232,20 @@ namespace ComPDFKit.Tool
 
 
         public void CleanSelectedMultiRect()
         public void CleanSelectedMultiRect()
         {
         {
-            MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(PDFViewer.GetViewForTag(multiSelectedRectViewTag));
+            MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(PDFViewer.GetViewForTag(MultiSelectedRectViewTag));
             if (multiSelectedRect != null)
             if (multiSelectedRect != null)
             {
             {
                 multiSelectedRect.Children.Clear();
                 multiSelectedRect.Children.Clear();
                 multiSelectedRect.CleanMulitSelectedRect();
                 multiSelectedRect.CleanMulitSelectedRect();
                 editAreaMultiIndex.Clear();
                 editAreaMultiIndex.Clear();
+                //Delete Multiple Selection Record List
+                editAreaList.Clear();
             }
             }
         }
         }
 
 
         public void DrawStartSelectedMultiRect()
         public void DrawStartSelectedMultiRect()
         {
         {
-            MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(PDFViewer.GetViewForTag(multiSelectedRectViewTag));
+            MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(PDFViewer.GetViewForTag(MultiSelectedRectViewTag));
 
 
             if (multiSelectedRect != null)
             if (multiSelectedRect != null)
             {
             {
@@ -188,9 +257,9 @@ namespace ComPDFKit.Tool
 
 
         public void DrawMoveSelectedMultiRect()
         public void DrawMoveSelectedMultiRect()
         {
         {
-            MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(PDFViewer.GetViewForTag(multiSelectedRectViewTag));
+            MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(PDFViewer.GetViewForTag(MultiSelectedRectViewTag));
 
 
-            if (multiSelectedRect != null)
+            if (multiSelectedRect != null&& multiSelectedRect.Children.Count>0)
             {
             {
                 Point point = Mouse.GetPosition(this);
                 Point point = Mouse.GetPosition(this);
                 multiSelectedRect.OnMouseMove(point, out bool Tag, PDFViewer.ActualWidth, PDFViewer.ActualHeight);
                 multiSelectedRect.OnMouseMove(point, out bool Tag, PDFViewer.ActualWidth, PDFViewer.ActualHeight);
@@ -199,7 +268,7 @@ namespace ComPDFKit.Tool
 
 
         public void DrawEndSelectedMultiRect()
         public void DrawEndSelectedMultiRect()
         {
         {
-            MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(PDFViewer.GetViewForTag(multiSelectedRectViewTag));
+            MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(PDFViewer.GetViewForTag(MultiSelectedRectViewTag));
 
 
             if (multiSelectedRect != null)
             if (multiSelectedRect != null)
             {
             {
@@ -210,8 +279,8 @@ namespace ComPDFKit.Tool
 
 
         public void ReDrawSelectedMultiRect()
         public void ReDrawSelectedMultiRect()
         {
         {
-            MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(PDFViewer.GetViewForTag(multiSelectedRectViewTag));
-
+            MultiSelectedRect multiSelectedRect = CommonHelper.FindVisualChild<MultiSelectedRect>(PDFViewer.GetViewForTag(MultiSelectedRectViewTag));
+            DrawEndFrameSelect();
             if (multiSelectedRect != null)
             if (multiSelectedRect != null)
             {
             {
                 multiSelectedRect.ClearDraw();
                 multiSelectedRect.ClearDraw();
@@ -241,18 +310,20 @@ namespace ComPDFKit.Tool
 
 
         private void SelectPDFEdit(MultiSelectedRect multiSelectedRect)
         private void SelectPDFEdit(MultiSelectedRect multiSelectedRect)
         {
         {
+            //Delete Multiple Selection Box
             foreach (int item in editAreaMultiIndex)
             foreach (int item in editAreaMultiIndex)
             {
             {
                 SelectedRect OldRect = GetEditAreaForIndex(multiPage, item);
                 SelectedRect OldRect = GetEditAreaForIndex(multiPage, item);
                 if (OldRect != null)
                 if (OldRect != null)
                 {
                 {
                     multiSelectedRect.SetSelectedType(SelectedType.PDFEdit);
                     multiSelectedRect.SetSelectedType(SelectedType.PDFEdit);
-                    SelectedRect selectedRect = new SelectedRect(GetDefaultDrawParam(), SelectedType.PDFEdit);
-                    selectedRect.SetDrawMoveType(DrawMoveType.kReferenceLine);
-                    selectedRect.SetRect(OldRect.GetRect(),currentZoom);
-                    selectedRect.SetMaxRect(OldRect.GetMaxRect());
-                    multiSelectedRect.Children.Add(selectedRect);
-                    multiSelectedRect.SetMulitSelectedRect(selectedRect);
+                    //Optimize logic to prevent overlapping of multiple selected objects
+                    //SelectedRect selectedRect = new SelectedRect(GetDefaultDrawParam(), SelectedType.PDFEdit);
+                    //selectedRect.SetDrawMoveType(DrawMoveType.kReferenceLine);
+                    //selectedRect.SetRect(OldRect.GetRect(), currentZoom);
+                    //selectedRect.SetMaxRect(OldRect.GetMaxRect());
+                    //multiSelectedRect.Children.Add(selectedRect);
+                    multiSelectedRect.SetMulitSelectedRect(OldRect, multiPage,item);
                     multiSelectedRect.SetRect(OldRect.GetRect());
                     multiSelectedRect.SetRect(OldRect.GetRect());
                     multiSelectedRect.SetMaxRect(OldRect.GetMaxRect());
                     multiSelectedRect.SetMaxRect(OldRect.GetMaxRect());
                     OldRect.HideDraw();
                     OldRect.HideDraw();

+ 131 - 0
Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.PDFCompareEffect.cs

@@ -0,0 +1,131 @@
+using ComPDFKit.Tool.Help;
+using ComPDFKit.Viewer.Layer;
+using ComPDFKitViewer;
+using ComPDFKitViewer.Helper;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Media;
+
+namespace ComPDFKit.Tool
+{
+    public partial class CPDFViewerTool
+    {
+        private int PDFCompareViewID { get; set; } = -1;
+        private int PDFComparePageIndex {  get; set; } = -1;
+        private List<Rect> PDFCompareRectList {  get; set; }
+        private SolidColorBrush PDFCompareBrush { get; set; }
+        private Pen PDFComparePen { get; set; }
+        private CustomizeLayer GetPDFCompareDrawView()
+        {
+            if(PDFViewer==null)
+            {
+                return null;
+            }
+            if (PDFCompareViewID != -1)
+            {
+                return PDFViewer.GetViewForTag(PDFCompareViewID) as CustomizeLayer;
+            }
+            int maxId = PDFViewer.GetMaxViewIndex();
+            CustomizeLayer customizeLayer = new CustomizeLayer();
+            PDFViewer.InsertView(maxId, customizeLayer);
+            PDFCompareViewID = customizeLayer.GetResTag();
+            PDFViewer.DrawChanged -= DrawChangedNotify;
+            PDFViewer.DrawChanged += DrawChangedNotify;
+            return customizeLayer;
+        }
+
+        private void DrawPDFCompare()
+        {
+            if (PDFCompareViewID==-1)
+            {
+                return;
+            }
+            CustomizeLayer drawLayer = GetPDFCompareDrawView();
+            if (drawLayer == null)
+            {
+                return;
+            }
+
+            if (PDFViewer.CurrentRenderFrame == null)
+            {
+                return;
+            }
+
+            RenderFrame frame = PDFViewer.CurrentRenderFrame;
+            List<RenderData> drawDataList = frame.GetRenderDatas();
+            if (drawDataList == null || drawDataList.Count == 0)
+            {
+                return;
+            }
+
+            RenderData drawData = null;
+            foreach (RenderData data in drawDataList)
+            {
+                if (data.PageIndex == PDFComparePageIndex)
+                {
+                    drawData = data;
+                    break;
+                }
+            }
+
+          DrawingContext drawDC=  drawLayer.RenderOpen();
+
+            if (drawData != null && PDFCompareRectList != null)
+            {
+                foreach(Rect drawRect in PDFCompareRectList)
+                {
+                    Rect standRect = DpiHelper.PDFRectToStandardRect(drawRect);
+
+                    Rect paintRect = new Rect(
+                        standRect.Left * frame.ZoomFactor,
+                        standRect.Top * frame.ZoomFactor,
+                        standRect.Width * frame.ZoomFactor,
+                        standRect.Height * frame.ZoomFactor);
+
+                    Rect offsetRect = new Rect(
+                        paintRect.Left + drawData.PageBound.Left,
+                        paintRect.Top + drawData.PageBound.Top,
+                        paintRect.Width,
+                        paintRect.Height);
+
+                    drawDC.DrawRectangle(PDFCompareBrush,PDFComparePen,offsetRect);
+                }
+            }
+
+            drawDC.Close();
+        }
+
+        private void DrawChangedNotify(object sender, EventArgs e)
+        {
+            DrawPDFCompare();
+        }
+
+        public void SetPDFCompareView(SolidColorBrush FillBrush,Pen BorderPen,int PageIndex,List<Rect> PDFRectList)
+        {
+            PDFCompareRectList=PDFRectList;
+            PDFComparePageIndex = PageIndex;
+            PDFCompareBrush = FillBrush;
+            PDFComparePen = BorderPen;
+            if(PDFCompareViewID==-1)
+            {
+                GetPDFCompareDrawView();
+            }
+            DrawPDFCompare();
+        }
+
+        public void ClearPDFCompareView()
+        {
+            CustomizeLayer drawLayer = GetPDFCompareDrawView();
+            if (drawLayer != null && PDFViewer != null)
+            {
+                PDFViewer.RemoveView(drawLayer);
+                PDFCompareViewID = -1;
+            }
+        }
+    }
+}

+ 35 - 7
Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.SelectImage.cs

@@ -13,6 +13,8 @@ namespace ComPDFKit.Tool
     public partial class CPDFViewerTool
     public partial class CPDFViewerTool
     {
     {
         int selectImageTag = -1;
         int selectImageTag = -1;
+        private bool enableImageSelect = true;
+
         private void InsertSelectImageView()
         private void InsertSelectImageView()
         {
         {
             SelectImage createAnnotTool = new SelectImage();
             SelectImage createAnnotTool = new SelectImage();
@@ -20,10 +22,24 @@ namespace ComPDFKit.Tool
             PDFViewer.InsertView(SelectTextindex, createAnnotTool);
             PDFViewer.InsertView(SelectTextindex, createAnnotTool);
             selectImageTag = createAnnotTool.GetResTag();
             selectImageTag = createAnnotTool.GetResTag();
         }
         }
+
+        public void SetImageSelectEnable(bool enable)
+        {
+            enableImageSelect=enable;
+            if (enableImageSelect==false && PDFViewer!=null)
+            {
+                SelectImage imageLayer = PDFViewer.GetViewForTag(selectImageTag) as SelectImage;
+                if (imageLayer != null)
+                {
+                    imageLayer.CleanDraw(PDFViewer);
+                }
+            }
+        }
+
         public bool DrawMoveSelectImage()
         public bool DrawMoveSelectImage()
         {
         {
             bool isSelect = false;
             bool isSelect = false;
-            if (PDFViewer.CurrentRenderFrame == null)
+            if (PDFViewer.CurrentRenderFrame == null || enableImageSelect == false)
             {
             {
                 return isSelect;
                 return isSelect;
             }
             }
@@ -40,7 +56,7 @@ namespace ComPDFKit.Tool
         public bool DrawDownSelectImage(bool isNeedClear)
         public bool DrawDownSelectImage(bool isNeedClear)
         {
         {
             bool isSelect = false;
             bool isSelect = false;
-            if (PDFViewer.CurrentRenderFrame == null)
+            if (PDFViewer.CurrentRenderFrame == null || enableImageSelect == false)
             {
             {
                 return isSelect;
                 return isSelect;
             }
             }
@@ -57,24 +73,36 @@ namespace ComPDFKit.Tool
 
 
         public void ReDrawSelectImage()
         public void ReDrawSelectImage()
         {
         {
+            if(enableImageSelect == false)
+            {
+                return;
+            }
             BaseLayer baseLayer = PDFViewer.GetViewForTag(selectImageTag);
             BaseLayer baseLayer = PDFViewer.GetViewForTag(selectImageTag);
             (baseLayer as SelectImage).Draw(PDFViewer);
             (baseLayer as SelectImage).Draw(PDFViewer);
         }
         }
 
 
         public void CleanDrawSelectImage()
         public void CleanDrawSelectImage()
         {
         {
+            if (enableImageSelect == false)
+            {
+                return;
+            }
             BaseLayer baseLayer = PDFViewer.GetViewForTag(selectImageTag);
             BaseLayer baseLayer = PDFViewer.GetViewForTag(selectImageTag);
             (baseLayer as SelectImage).CleanDraw(PDFViewer);
             (baseLayer as SelectImage).CleanDraw(PDFViewer);
         }
         }
 
 
-        public PageImageItem GetSelectImage()
-        {
-            BaseLayer baseLayer = PDFViewer.GetViewForTag(selectImageTag);
-            return (baseLayer as SelectImage).GetHoverImageItem();
-        }
+        //public PageImageItem GetSelectImage()
+        //{
+        //    BaseLayer baseLayer = PDFViewer.GetViewForTag(selectImageTag);
+        //    return (baseLayer as SelectImage).GetHoverImageItem();
+        //}
 
 
         public Dictionary<int, List<PageImageItem>> GetSelectImageItems()
         public Dictionary<int, List<PageImageItem>> GetSelectImageItems()
         {
         {
+            if (enableImageSelect == false)
+            {
+                return new Dictionary<int, List<PageImageItem>>();
+            }
             BaseLayer baseLayer = PDFViewer.GetViewForTag(selectImageTag);
             BaseLayer baseLayer = PDFViewer.GetViewForTag(selectImageTag);
             return (baseLayer as SelectImage).GetSelectImageItems();
             return (baseLayer as SelectImage).GetSelectImageItems();
         }
         }

+ 4 - 1
Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.SelectText.cs

@@ -51,7 +51,10 @@ namespace ComPDFKit.Tool
             }
             }
             BaseLayer baseLayer = PDFViewer.GetViewForTag(selectTextTag);
             BaseLayer baseLayer = PDFViewer.GetViewForTag(selectTextTag);
             PDFViewer.GetMousePointToPage(out int pageindex, out Point pagepoint);
             PDFViewer.GetMousePointToPage(out int pageindex, out Point pagepoint);
-            (baseLayer as SelectText).MoveDraw(new Point(DpiHelper.StandardNumToPDFNum(pagepoint.X / PDFViewer.CurrentRenderFrame.ZoomFactor), DpiHelper.StandardNumToPDFNum(pagepoint.Y / PDFViewer.CurrentRenderFrame.ZoomFactor)), pageindex, PDFViewer, new Point(10, 10), DoubleClick);
+            if(pageindex>=0)
+            {
+                (baseLayer as SelectText).MoveDraw(new Point(DpiHelper.StandardNumToPDFNum(pagepoint.X / PDFViewer.CurrentRenderFrame.ZoomFactor), DpiHelper.StandardNumToPDFNum(pagepoint.Y / PDFViewer.CurrentRenderFrame.ZoomFactor)), pageindex, PDFViewer, new Point(10, 10), DoubleClick);
+            }
         }
         }
 
 
         public void DrawEndSelectText()
         public void DrawEndSelectText()

+ 17 - 1
Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.SelectedRect.cs

@@ -19,6 +19,7 @@ namespace ComPDFKit.Tool
     {
     {
         bool isDrawSelectRect = false;
         bool isDrawSelectRect = false;
         int selectedRectViewTag = -1;
         int selectedRectViewTag = -1;
+        private bool isOutSideScaling = false;
         public event EventHandler<SelectedAnnotData> SelectedDataChanging;
         public event EventHandler<SelectedAnnotData> SelectedDataChanging;
         public event EventHandler<SelectedAnnotData> SelectedDataChanged;
         public event EventHandler<SelectedAnnotData> SelectedDataChanged;
 
 
@@ -37,6 +38,15 @@ namespace ComPDFKit.Tool
             selectedRectViewTag= customizeLayer.GetResTag();
             selectedRectViewTag= customizeLayer.GetResTag();
         }
         }
 
 
+        /// <summary>
+        /// Set whether the border can be moved outside the border
+        /// </summary>
+        /// <param name="IsOutSideScaling"></param>
+        public void SetOutSideScaling(bool IsOutSideScaling)
+        {
+            isOutSideScaling = IsOutSideScaling;
+        }
+
         private void SelectedRect_DataChanging(object sender, SelectedAnnotData e)
         private void SelectedRect_DataChanging(object sender, SelectedAnnotData e)
         {
         {
             SelectedDataChanging?.Invoke(this, e);
             SelectedDataChanging?.Invoke(this, e);
@@ -89,6 +99,7 @@ namespace ComPDFKit.Tool
             SelectedRect selectedRect = CommonHelper.FindVisualChild<SelectedRect>(baseLayer as CustomizeLayer);
             SelectedRect selectedRect = CommonHelper.FindVisualChild<SelectedRect>(baseLayer as CustomizeLayer);
             if (selectedRect != null)
             if (selectedRect != null)
             {
             {
+                selectedRect.SetOutSideScaling(isOutSideScaling);
                 selectedRect.OnMouseMove(point, out DrawTag,PDFViewer.ActualWidth,PDFViewer.ActualHeight);
                 selectedRect.OnMouseMove(point, out DrawTag,PDFViewer.ActualWidth,PDFViewer.ActualHeight);
                 selectedRect.Draw();
                 selectedRect.Draw();
             }
             }
@@ -137,11 +148,16 @@ namespace ComPDFKit.Tool
             {
             {
                 return ;
                 return ;
             }
             }
+            SelectAnnot(cacheHitTestAnnot.GetAnnotData());
+        }
+
+        private void SelectAnnot(AnnotData selectData)
+        {
             BaseLayer baseLayer = PDFViewer.GetViewForTag(selectedRectViewTag);
             BaseLayer baseLayer = PDFViewer.GetViewForTag(selectedRectViewTag);
             SelectedRect selectedRect = CommonHelper.FindVisualChild<SelectedRect>(baseLayer as CustomizeLayer);
             SelectedRect selectedRect = CommonHelper.FindVisualChild<SelectedRect>(baseLayer as CustomizeLayer);
             if (selectedRect != null)
             if (selectedRect != null)
             {
             {
-                selectedRect.SetAnnotData(cacheHitTestAnnot.GetAnnotData());
+                selectedRect.SetAnnotData(selectData);
             }
             }
         }
         }
 
 

File diff suppressed because it is too large
+ 1196 - 59
Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.TextEdit.cs


+ 10 - 0
Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.WidgetTool.cs

@@ -39,6 +39,7 @@ namespace ComPDFKit.Tool
         public static DependencyProperty PopupAttachDataProperty = DependencyProperty.Register("PopupAttachData", typeof(BaseAnnot), typeof(CPDFViewerTool));
         public static DependencyProperty PopupAttachDataProperty = DependencyProperty.Register("PopupAttachData", typeof(BaseAnnot), typeof(CPDFViewerTool));
 
 
         public event EventHandler<WidgetClickArgs> WidgetActionHandler;
         public event EventHandler<WidgetClickArgs> WidgetActionHandler;
+        public event EventHandler<CPDFAnnotation> WidgetCreatedHandler;
 
 
         private CustomizeLayer formPopLayer=null;
         private CustomizeLayer formPopLayer=null;
         // Inner default pop-up control
         // Inner default pop-up control
@@ -162,6 +163,7 @@ namespace ComPDFKit.Tool
                     }
                     }
 
 
                     TextBox textui = new TextBox();
                     TextBox textui = new TextBox();
+                    textui.Name = "PdfViewerTextBox";
                     CTextAttribute textAttribute = textWidget.GetTextAttribute();
                     CTextAttribute textAttribute = textWidget.GetTextAttribute();
                     byte transparency = textWidget.GetTransparency();
                     byte transparency = textWidget.GetTransparency();
                     textui.FontSize = textAttribute.FontSize* annotData.CurrentZoom/72D*96D;
                     textui.FontSize = textAttribute.FontSize* annotData.CurrentZoom/72D*96D;
@@ -871,5 +873,13 @@ namespace ComPDFKit.Tool
                 }
                 }
             }
             }
         }
         }
+
+        internal void InvokeWidgetCreated(CPDFAnnotation annot)
+        {
+            if(annot!=null && annot.IsValid())
+            {
+                WidgetCreatedHandler?.Invoke(this, annot);
+            }
+        }
     }
     }
 }
 }

+ 2 - 4
Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.xaml

@@ -12,9 +12,7 @@
              >
              >
     <ScrollViewer Name="ScrollContainer" Focusable="False" CanContentScroll="True"
     <ScrollViewer Name="ScrollContainer" Focusable="False" CanContentScroll="True"
                   HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
                   HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
-                  MouseUp="ScrollViewer_MouseUp" MouseDown="ScrollViewer_MouseDown">
-        <compdfkitviewer:CPDFViewer x:Name="PDFViewer">
-
-        </compdfkitviewer:CPDFViewer>
+                  MouseUp="ScrollViewer_MouseUp" MouseDown="ScrollViewer_MouseDown" ScrollChanged="ScrollViewer_ScrollChanged">
+        <compdfkitviewer:CPDFViewer x:Name="PDFViewer"></compdfkitviewer:CPDFViewer>
     </ScrollViewer>
     </ScrollViewer>
 </UserControl>
 </UserControl>

+ 232 - 26
Demo/Examples/ComPDFKit.Tool/CPDFViewerTool.xaml.cs

@@ -1,10 +1,13 @@
-using ComPDFKit.PDFAnnotation;
+using ComPDFKit.Import;
+using ComPDFKit.PDFAnnotation;
 using ComPDFKit.PDFDocument;
 using ComPDFKit.PDFDocument;
 using ComPDFKit.PDFDocument.Action;
 using ComPDFKit.PDFDocument.Action;
 using ComPDFKit.PDFPage;
 using ComPDFKit.PDFPage;
 using ComPDFKit.Tool.DrawTool;
 using ComPDFKit.Tool.DrawTool;
+using ComPDFKit.Tool.Help;
 using ComPDFKit.Tool.SettingParam;
 using ComPDFKit.Tool.SettingParam;
 using ComPDFKit.Viewer.Helper;
 using ComPDFKit.Viewer.Helper;
+using ComPDFKit.Viewer.Layer;
 using ComPDFKitViewer;
 using ComPDFKitViewer;
 using ComPDFKitViewer.Annot;
 using ComPDFKitViewer.Annot;
 using ComPDFKitViewer.BaseObject;
 using ComPDFKitViewer.BaseObject;
@@ -48,6 +51,7 @@ namespace ComPDFKit.Tool
         ImageSelect,
         ImageSelect,
         MultiTextEdit,
         MultiTextEdit,
         SelectedPageRect,
         SelectedPageRect,
+        MultiSelector
     }
     }
 
 
     public enum ToolType
     public enum ToolType
@@ -94,8 +98,12 @@ namespace ComPDFKit.Tool
             InsertMultiSelectedRectView();
             InsertMultiSelectedRectView();
             InsertCustomizeToolView();
             InsertCustomizeToolView();
             InsertSelectTextView();
             InsertSelectTextView();
+            //Frame Select
+            InsertFrameSelectToolView();
             InsertTextEditView();
             InsertTextEditView();
             InsertPageSelectedRectView();
             InsertPageSelectedRectView();
+
+            AnnotSelectInsert();
         }
         }
 
 
         public void ReplaceCPDFViewer(CPDFViewer newViewer)
         public void ReplaceCPDFViewer(CPDFViewer newViewer)
@@ -130,6 +138,7 @@ namespace ComPDFKit.Tool
         public event EventHandler<MouseEventObject> MouseLeftButtonUpHandler;
         public event EventHandler<MouseEventObject> MouseLeftButtonUpHandler;
         public event EventHandler<MouseEventObject> MouseMoveHandler;
         public event EventHandler<MouseEventObject> MouseMoveHandler;
         public event EventHandler<MouseEventObject> MouseRightButtonDownHandler;
         public event EventHandler<MouseEventObject> MouseRightButtonDownHandler;
+        public event EventHandler<ScrollChangedEventArgs> ScrollChangedHandler;
         public event EventHandler DrawChanged;
         public event EventHandler DrawChanged;
         public event EventHandler DocumentModifiedChanged;
         public event EventHandler DocumentModifiedChanged;
         public event EventHandler<PopupControlInfo> PopUpControlHandler;
         public event EventHandler<PopupControlInfo> PopUpControlHandler;
@@ -146,6 +155,33 @@ namespace ComPDFKit.Tool
         private bool isMultiSelected;
         private bool isMultiSelected;
         private bool isDocumentModified = false;
         private bool isDocumentModified = false;
 
 
+
+
+        public bool CanAddTextEdit = true;
+
+        protected bool isContinueCreateTextEdit = false;
+
+        public bool GetIsMultiSelected()
+        {
+            return isMultiSelected;
+        }
+
+        /// <summary>
+        /// Set whether continuous text editing is required
+        /// </summary>
+        /// <param name="isContinueCreateTextEdit"></param>
+        public void SetContinueCreateTextEdit(bool isContinueCreateTextEdit)
+        {
+
+            this.isContinueCreateTextEdit = isContinueCreateTextEdit;
+            CanAddTextEdit = true;
+        }
+
+
+        /// <summary>
+        ///  Does it support multiple selection
+        /// </summary>
+        /// <param name="isMulti">true Can MultiSelected</param>
         public void SetIsMultiSelected(bool isMulti)
         public void SetIsMultiSelected(bool isMulti)
         {
         {
             isMultiSelected = isMulti;
             isMultiSelected = isMulti;
@@ -161,6 +197,22 @@ namespace ComPDFKit.Tool
             return defaultDrawParam;
             return defaultDrawParam;
         }
         }
 
 
+        /// <summary>
+        /// Set default painting parameters
+        /// </summary>
+        /// <param name="defaultDrawParam"></param>
+        public void SetDefaultDrawParam(DefaultDrawParam defaultDrawParam = null)
+        {
+            if (defaultDrawParam == null)
+            {
+                this.defaultDrawParam = new DefaultDrawParam();
+            }
+            else
+            {
+                this.defaultDrawParam = defaultDrawParam;
+            }
+        }
+
         public MeasureSetting GetMeasureSetting()
         public MeasureSetting GetMeasureSetting()
         {
         {
             return measureSetting;
             return measureSetting;
@@ -298,10 +350,24 @@ namespace ComPDFKit.Tool
 
 
         protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
         protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
         {
         {
+            if (isContinueCreateTextEdit)
+            {
+
+                if (lastSelectedRect != null)
+                {
+                    CanAddTextEdit = false;
+                }
+                else
+                {
+                    CanAddTextEdit = true;
+                }
+            }
+
             if (PDFViewer == null || PDFViewer.CurrentRenderFrame == null)
             if (PDFViewer == null || PDFViewer.CurrentRenderFrame == null)
             {
             {
                 return;
                 return;
             }
             }
+
             if (!HitTestBorder())
             if (!HitTestBorder())
             {
             {
                 RemovePopTextUI();
                 RemovePopTextUI();
@@ -326,7 +392,7 @@ namespace ComPDFKit.Tool
                         BuildPopTextUI(cacheHitTestAnnot);
                         BuildPopTextUI(cacheHitTestAnnot);
                         isDrawSelectRect = false;
                         isDrawSelectRect = false;
                         mouseEventObject.annotType = cacheHitTestAnnot.GetAnnotData().AnnotType;
                         mouseEventObject.annotType = cacheHitTestAnnot.GetAnnotData().AnnotType;
-                        mouseEventObject.IsMersured = cacheHitTestAnnot.GetAnnotData().Annot.IsMersured();
+                        mouseEventObject.IsMersured = cacheHitTestAnnot.GetAnnotData().Annot.IsMeasured();
                         MouseLeftButtonDownHandler?.Invoke(this, mouseEventObject);
                         MouseLeftButtonDownHandler?.Invoke(this, mouseEventObject);
                         return;
                         return;
                     }
                     }
@@ -340,7 +406,7 @@ namespace ComPDFKit.Tool
                 {
                 {
                     mouseEventObject.hitTestType = MouseHitTestType.SelectRect;
                     mouseEventObject.hitTestType = MouseHitTestType.SelectRect;
                     mouseEventObject.annotType = cacheHitTestAnnot.GetAnnotData().AnnotType;
                     mouseEventObject.annotType = cacheHitTestAnnot.GetAnnotData().AnnotType;
-                    mouseEventObject.IsMersured = cacheHitTestAnnot.GetAnnotData().Annot.IsMersured();
+                    mouseEventObject.IsMersured = cacheHitTestAnnot.GetAnnotData().Annot.IsMeasured();
                     MouseLeftButtonDownHandler?.Invoke(this, mouseEventObject);
                     MouseLeftButtonDownHandler?.Invoke(this, mouseEventObject);
                     return;
                     return;
                 }
                 }
@@ -357,7 +423,7 @@ namespace ComPDFKit.Tool
                 {
                 {
                     mouseEventObject.hitTestType = MouseHitTestType.SelectRect;
                     mouseEventObject.hitTestType = MouseHitTestType.SelectRect;
                     mouseEventObject.annotType = cacheHitTestAnnot.GetAnnotData().AnnotType;
                     mouseEventObject.annotType = cacheHitTestAnnot.GetAnnotData().AnnotType;
-                    mouseEventObject.IsMersured = cacheHitTestAnnot.GetAnnotData().Annot.IsMersured();
+                    mouseEventObject.IsMersured = cacheHitTestAnnot.GetAnnotData().Annot.IsMeasured();
                     MouseLeftButtonDownHandler?.Invoke(this, mouseEventObject);
                     MouseLeftButtonDownHandler?.Invoke(this, mouseEventObject);
                     return;
                     return;
                 }
                 }
@@ -389,7 +455,7 @@ namespace ComPDFKit.Tool
                         };
                         };
                         if (cacheHitTestAnnot != null && list.Contains(cacheHitTestAnnot.CurrentType))
                         if (cacheHitTestAnnot != null && list.Contains(cacheHitTestAnnot.CurrentType))
                         {
                         {
-                            mouseEventObject.IsMersured = cacheHitTestAnnot.GetAnnotData().Annot.IsMersured();
+                            mouseEventObject.IsMersured = cacheHitTestAnnot.GetAnnotData().Annot.IsMeasured();
                             SetEditAnnotObject();
                             SetEditAnnotObject();
                         }
                         }
                         else
                         else
@@ -420,7 +486,7 @@ namespace ComPDFKit.Tool
             }
             }
             else if ((currentModel == ToolType.Pan || currentModel == ToolType.Viewer))
             else if ((currentModel == ToolType.Pan || currentModel == ToolType.Viewer))
             {
             {
-                if (DrawDownSelectImage(true))
+                if (!IsText() && DrawDownSelectImage(true))
                 {
                 {
                     mouseEventObject.hitTestType = MouseHitTestType.ImageSelect;
                     mouseEventObject.hitTestType = MouseHitTestType.ImageSelect;
                 }
                 }
@@ -433,14 +499,29 @@ namespace ComPDFKit.Tool
             // Form creation mode
             // Form creation mode
             else if (currentModel == ToolType.WidgetEdit)
             else if (currentModel == ToolType.WidgetEdit)
             {
             {
-                if (AnnotWidgetHitTest())
+                if (!AnnotSelectAreaHitTest())
                 {
                 {
-                    cacheHitTestAnnot = PDFViewer?.AnnotHitTest() as BaseWidget;
-                    SelectedAnnot();
-                    mouseEventObject.hitTestType = MouseHitTestType.Annot;
+                    if (AnnotWidgetHitTest())
+                    {
+                        BaseWidget hitWidget = PDFViewer?.AnnotHitTest() as BaseWidget;
+                        cacheHitTestAnnot = null;
+                        if (AnnotSelectGetCount() == 0 && hitWidget != null)
+                        {
+                            AnnotSelectAddItem(hitWidget.GetAnnotData());
+                            cacheHitTestAnnot = hitWidget;
+                            SelectedAnnot();
+                        }
 
 
-                    mouseEventObject.annotType = cacheMoveWidget.GetAnnotData().AnnotType;
+                        mouseEventObject.hitTestType = MouseHitTestType.Annot;
+                        mouseEventObject.annotType = cacheMoveWidget.GetAnnotData().AnnotType;
+                    }
+                    else
+                    {
+                        AnnotSelectAreaHit();
+                    }
                 }
                 }
+
+                AnnotSelectMoveHit();
             }
             }
             // Content editing mode
             // Content editing mode
             else if (currentModel == ToolType.ContentEdit)
             else if (currentModel == ToolType.ContentEdit)
@@ -454,6 +535,30 @@ namespace ComPDFKit.Tool
 
 
                 if (lastSelectedRect != null)
                 if (lastSelectedRect != null)
                 {
                 {
+                    //Multi selection processing optimization, other click effects
+                    DrawEndFrameSelect();
+                    if (!Keyboard.IsKeyDown(multiKey) || !isMultiSelected)
+                    {
+                        CleanSelectedMultiRect();
+                        OpenSelectedMulti(false);
+                        if (PDFViewer.CurrentRenderFrame != null)
+                        {
+                            currentZoom = PDFViewer.CurrentRenderFrame.ZoomFactor;
+                            if (PDFViewer.CurrentRenderFrame.IsCacheEditPage == true && currentModel == ToolType.ContentEdit)
+                            {
+                                SetEditTextRect(PDFViewer.CurrentRenderFrame);
+                                if (selectedEditPageIndex != -1 && selectedEditAreaIndex != -1)
+                                {
+                                    DrawSelectedEditAreaForIndex();
+                                }
+                            }
+                        }
+                        ReDrawSelectedMultiRect();
+                    }
+                    if (lastSelectedRect == null)
+                    {
+                        return;
+                    }
                     SelectedMultiRect(lastSelectedRect.GetRect(), lastSelectedRect.GetMaxRect(), SelectedType.PDFEdit);
                     SelectedMultiRect(lastSelectedRect.GetRect(), lastSelectedRect.GetMaxRect(), SelectedType.PDFEdit);
                     HideDrawSelectedMultiRect();
                     HideDrawSelectedMultiRect();
                     lastSelectedRect.DataChanged -= SelectedRect_DataChanged;
                     lastSelectedRect.DataChanged -= SelectedRect_DataChanged;
@@ -461,14 +566,38 @@ namespace ComPDFKit.Tool
                 }
                 }
                 else
                 else
                 {
                 {
+                    if (Keyboard.IsKeyDown(multiKey) && isMultiSelected)
+                    {
+                        DelMultiSelectRect();
+                    }
+
                     if (HitTestMultiSelectedRect())
                     if (HitTestMultiSelectedRect())
                     {
                     {
                         mouseEventObject.hitTestType = MouseHitTestType.MultiTextEdit;
                         mouseEventObject.hitTestType = MouseHitTestType.MultiTextEdit;
                     }
                     }
                     else
                     else
                     {
                     {
-                        CleanSelectedMultiRect();
+                        //Clear the currently selected object
+                        startSelectedRect = null;
+                        startSelectedIndex = -1;
+                        startSelectedPageIndex = -1;
+                        startSelectedEditAreaObject = null;
 
 
+                        CleanSelectedMultiRect();
+                        OpenSelectedMulti(false);
+                        if (PDFViewer.CurrentRenderFrame != null)
+                        {
+                            currentZoom = PDFViewer.CurrentRenderFrame.ZoomFactor;
+                            if (PDFViewer.CurrentRenderFrame.IsCacheEditPage == true && currentModel == ToolType.ContentEdit)
+                            {
+                                SetEditTextRect(PDFViewer.CurrentRenderFrame);
+                                if (selectedEditPageIndex != -1 && selectedEditAreaIndex != -1)
+                                {
+                                    DrawSelectedEditAreaForIndex();
+                                }
+                            }
+                        }
+                        ReDrawSelectedMultiRect();
                     }
                     }
                 }
                 }
             }
             }
@@ -495,6 +624,46 @@ namespace ComPDFKit.Tool
             {
             {
                 return;
                 return;
             }
             }
+            if (currentModel == ToolType.WidgetEdit)
+            {
+                bool areaSelectAdd = AnnotSelectAreaSelect(true);
+                if (AnnotWidgetHitTest())
+                {
+                    BaseWidget checkItem = PDFViewer?.AnnotHitTest() as BaseWidget;
+                    AnnotSelectAddItem(checkItem?.GetAnnotData(), !AnnotSelectAreaHitTest());
+                }
+                if (AnnotSelectGetCount() > 1)
+                {
+                    CleanSelectedRect();
+                }
+                if (IsMoved == false && AnnotSelectAreaHitTest() == false && AnnotWidgetHitTest() == false)
+                {
+                    AnnotSelectClean();
+                }
+                if (AnnotSelectGetCount() == 1)
+                {
+                    cacheHitTestAnnot = AnnotSelectGetAnnot();
+                    if (cacheHitTestAnnot != null)
+                    {
+                        BaseLayer baseLayer = PDFViewer.GetViewForTag(selectedRectViewTag);
+                        SelectedRect selectedRect = CommonHelper.FindVisualChild<SelectedRect>(baseLayer as CustomizeLayer);
+                        if (selectedRect != null)
+                        {
+                            if (IsMoved && areaSelectAdd == false)
+                            {
+                                selectedRect.UpdateAnnotData(cacheHitTestAnnot.GetAnnotData());
+                            }
+                            else
+                            {
+                                selectedRect.SetAnnotData(cacheHitTestAnnot.GetAnnotData());
+                            }
+                            selectedRect.Draw();
+                        }
+                        isDrawSelectRect = true;
+                    }
+                }
+            }
+
             MouseEventObject mouseEventObject = new MouseEventObject
             MouseEventObject mouseEventObject = new MouseEventObject
             {
             {
                 mouseButtonEventArgs = e,
                 mouseButtonEventArgs = e,
@@ -502,6 +671,7 @@ namespace ComPDFKit.Tool
                 annotType = C_ANNOTATION_TYPE.C_ANNOTATION_NONE,
                 annotType = C_ANNOTATION_TYPE.C_ANNOTATION_NONE,
                 IsCreate = false
                 IsCreate = false
             };
             };
+
             if (isDrawSelectRect || IsDrawEditAnnot)
             if (isDrawSelectRect || IsDrawEditAnnot)
             {
             {
                 mouseEventObject.hitTestType = MouseHitTestType.SelectRect;
                 mouseEventObject.hitTestType = MouseHitTestType.SelectRect;
@@ -513,16 +683,23 @@ namespace ComPDFKit.Tool
                 {
                 {
                     mouseEventObject.annotType = C_ANNOTATION_TYPE.C_ANNOTATION_NONE;
                     mouseEventObject.annotType = C_ANNOTATION_TYPE.C_ANNOTATION_NONE;
                 }
                 }
-                MouseLeftButtonUpHandler?.Invoke(this, mouseEventObject);
-                ReleaseMouseCapture();
-                return;
             }
             }
             MouseLeftButtonUpHandler?.Invoke(this, mouseEventObject);
             MouseLeftButtonUpHandler?.Invoke(this, mouseEventObject);
             ReleaseMouseCapture();
             ReleaseMouseCapture();
+            if (currentModel == ToolType.WidgetEdit)
+            {
+                AnnotSelectUpdate();
+                AnnotSelectDraw();
+                AnnotSelectSave();
+                AreaMoveData = new AnnotSelectAreaData();
+            }
+            IsMoved = false;
         }
         }
 
 
         protected override void OnMouseMove(MouseEventArgs e)
         protected override void OnMouseMove(MouseEventArgs e)
         {
         {
+            IsMoved = e.LeftButton == MouseButtonState.Pressed;
+
             if (PDFViewer == null || PDFViewer.CurrentRenderFrame == null)
             if (PDFViewer == null || PDFViewer.CurrentRenderFrame == null)
             {
             {
                 return;
                 return;
@@ -574,7 +751,7 @@ namespace ComPDFKit.Tool
                     }
                     }
 
 
                     mouseEventObject.annotType = caheMoveAnnot.GetAnnotData().AnnotType;
                     mouseEventObject.annotType = caheMoveAnnot.GetAnnotData().AnnotType;
-                    mouseEventObject.IsMersured = caheMoveAnnot.GetAnnotData().Annot.IsMersured();
+                    mouseEventObject.IsMersured = caheMoveAnnot.GetAnnotData().Annot.IsMeasured();
                 }
                 }
                 else
                 else
                 {
                 {
@@ -588,7 +765,10 @@ namespace ComPDFKit.Tool
                     caheMoveAnnot = null;
                     caheMoveAnnot = null;
                     if ((currentModel == ToolType.Pan || currentModel == ToolType.Viewer))
                     if ((currentModel == ToolType.Pan || currentModel == ToolType.Viewer))
                     {
                     {
-                        DrawMoveSelectImage();
+                        if (GetTextSelectInfo() == null)
+                        {
+                            DrawMoveSelectImage();
+                        }
                     }
                     }
                 }
                 }
             }
             }
@@ -622,7 +802,7 @@ namespace ComPDFKit.Tool
                     if (cacheHitTestAnnot != null)
                     if (cacheHitTestAnnot != null)
                     {
                     {
                         mouseEventObject.annotType = cacheHitTestAnnot.GetAnnotData().AnnotType;
                         mouseEventObject.annotType = cacheHitTestAnnot.GetAnnotData().AnnotType;
-                        mouseEventObject.IsMersured = cacheHitTestAnnot.GetAnnotData().Annot.IsMersured();
+                        mouseEventObject.IsMersured = cacheHitTestAnnot.GetAnnotData().Annot.IsMeasured();
                     }
                     }
                     else
                     else
                     {
                     {
@@ -631,6 +811,15 @@ namespace ComPDFKit.Tool
                 }
                 }
             }
             }
 
 
+            if (currentModel == ToolType.WidgetEdit)
+            {
+                AnnotSelectAreaDraw();
+                if (!AnnotSelectMoveDraw())
+                {
+                    AnnotSelectAreaHover();
+                }
+            }
+
             MouseMoveHandler?.Invoke(this, mouseEventObject);
             MouseMoveHandler?.Invoke(this, mouseEventObject);
             PDFViewer.SetCustomMousePoint(Mouse.GetPosition(this).Y, Mouse.GetPosition(this).X);
             PDFViewer.SetCustomMousePoint(Mouse.GetPosition(this).Y, Mouse.GetPosition(this).X);
             if (oldCursor != newCursor)
             if (oldCursor != newCursor)
@@ -743,18 +932,26 @@ namespace ComPDFKit.Tool
             // Form creation mode
             // Form creation mode
             if (currentModel == ToolType.WidgetEdit)
             if (currentModel == ToolType.WidgetEdit)
             {
             {
-                if (AnnotWidgetHitTest())
+                if (!AnnotSelectAreaHitTest())
                 {
                 {
-                    cacheHitTestAnnot = PDFViewer?.AnnotHitTest() as BaseWidget;
-                    SelectedAnnot();
-                    DrawSelectedLayer();
-                    mouseEventObject.hitTestType = MouseHitTestType.Annot;
-
-                    mouseEventObject.annotType = cacheMoveWidget.GetAnnotData().AnnotType;
+                    if (AnnotWidgetHitTest())
+                    {
+                        cacheHitTestAnnot = PDFViewer?.AnnotHitTest() as BaseWidget;
+                        SelectedAnnot();
+                        DrawSelectedLayer();
+                        mouseEventObject.hitTestType = MouseHitTestType.Annot;
+                        mouseEventObject.annotType = cacheMoveWidget.GetAnnotData().AnnotType;
+                        AnnotSelectClean();
+                        AnnotSelectAddItem(cacheHitTestAnnot?.GetAnnotData());
+                    }
+                    else
+                    {
+                        CleanSelectedRect();
+                    }
                 }
                 }
                 else
                 else
                 {
                 {
-                    CleanSelectedRect();
+                    mouseEventObject.hitTestType = MouseHitTestType.MultiSelector;
                 }
                 }
             }
             }
 
 
@@ -809,6 +1006,8 @@ namespace ComPDFKit.Tool
                 {
                 {
                     lastSelectedRect.SetCurrentDrawPointType(DrawPointType.Crop);
                     lastSelectedRect.SetCurrentDrawPointType(DrawPointType.Crop);
                     ignoreList.Add(PointControlType.Body);
                     ignoreList.Add(PointControlType.Body);
+                    // Initialize ClipRect
+                    ClipThickness = new Thickness(0, 0, 0, 0);
                     if (editArea.TryGetValue(lastSelectedRect, out EditAreaObject editAreaObject))
                     if (editArea.TryGetValue(lastSelectedRect, out EditAreaObject editAreaObject))
                     {
                     {
                         cropIndex = editAreaObject.EditAreaIndex;
                         cropIndex = editAreaObject.EditAreaIndex;
@@ -890,6 +1089,8 @@ namespace ComPDFKit.Tool
         private void PDFViewer_DrawChanged(object sender, EventArgs e)
         private void PDFViewer_DrawChanged(object sender, EventArgs e)
         {
         {
             SizeChangeds();
             SizeChangeds();
+            AnnotSelectUpdate();
+            AnnotSelectDraw();
             DrawChanged?.Invoke(this, e);
             DrawChanged?.Invoke(this, e);
         }
         }
 
 
@@ -990,5 +1191,10 @@ namespace ComPDFKit.Tool
         {
         {
 
 
         }
         }
+
+        private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
+        {
+            ScrollChangedHandler?.Invoke(this, e);
+        }
     }
     }
 }
 }

+ 26 - 1
Demo/Examples/ComPDFKit.Tool/ComPDFKit.Tool.csproj

@@ -9,7 +9,7 @@
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <RootNamespace>ComPDFKit.Tool</RootNamespace>
     <RootNamespace>ComPDFKit.Tool</RootNamespace>
     <AssemblyName>ComPDFKit.Tool</AssemblyName>
     <AssemblyName>ComPDFKit.Tool</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <FileAlignment>512</FileAlignment>
     <Deterministic>true</Deterministic>
     <Deterministic>true</Deterministic>
     <TargetFrameworkProfile />
     <TargetFrameworkProfile />
@@ -106,6 +106,7 @@
     <Compile Include="AlignmentsHelp.cs" />
     <Compile Include="AlignmentsHelp.cs" />
     <Compile Include="CPDFViewerTool.Annot.cs" />
     <Compile Include="CPDFViewerTool.Annot.cs" />
     <Compile Include="CPDFViewerTool.AnnotEdit.cs" />
     <Compile Include="CPDFViewerTool.AnnotEdit.cs" />
+    <Compile Include="CPDFViewerTool.AnnotSelector.cs" />
     <Compile Include="CPDFViewerTool.Command.cs" />
     <Compile Include="CPDFViewerTool.Command.cs" />
     <Compile Include="CPDFViewerTool.CreateWidget.cs" />
     <Compile Include="CPDFViewerTool.CreateWidget.cs" />
     <Compile Include="CPDFViewerTool.CustomizeTool.cs" />
     <Compile Include="CPDFViewerTool.CustomizeTool.cs" />
@@ -113,6 +114,7 @@
     <Compile Include="CPDFViewerTool.FindReplace.cs" />
     <Compile Include="CPDFViewerTool.FindReplace.cs" />
     <Compile Include="CPDFViewerTool.MultiSelectedRect.cs" />
     <Compile Include="CPDFViewerTool.MultiSelectedRect.cs" />
     <Compile Include="CPDFViewerTool.PageSelected.cs" />
     <Compile Include="CPDFViewerTool.PageSelected.cs" />
+    <Compile Include="CPDFViewerTool.PDFCompareEffect.cs" />
     <Compile Include="CPDFViewerTool.SelectImage.cs" />
     <Compile Include="CPDFViewerTool.SelectImage.cs" />
     <Compile Include="CPDFViewerTool.WidgetTool.cs" />
     <Compile Include="CPDFViewerTool.WidgetTool.cs" />
     <Compile Include="CPDFViewerTool.SelectedRect.cs" />
     <Compile Include="CPDFViewerTool.SelectedRect.cs" />
@@ -123,10 +125,13 @@
     </Compile>
     </Compile>
     <Compile Include="CustomCommands.cs" />
     <Compile Include="CustomCommands.cs" />
     <Compile Include="DrawTool\AnnotEdit.cs" />
     <Compile Include="DrawTool\AnnotEdit.cs" />
+    <Compile Include="DrawTool\AnnotSelector.cs" />
     <Compile Include="DrawTool\CaretVisual.cs" />
     <Compile Include="DrawTool\CaretVisual.cs" />
     <Compile Include="DrawTool\CreateAnnotTool.cs" />
     <Compile Include="DrawTool\CreateAnnotTool.cs" />
     <Compile Include="DrawTool\CreateCustomizeTool.cs" />
     <Compile Include="DrawTool\CreateCustomizeTool.cs" />
     <Compile Include="DrawTool\CreateWidgetTool.cs" />
     <Compile Include="DrawTool\CreateWidgetTool.cs" />
+    <Compile Include="DrawTool\DashBorder.cs" />
+    <Compile Include="DrawTool\FrameSelectTool.cs" />
     <Compile Include="DrawTool\MultiSelectedRect.cs" />
     <Compile Include="DrawTool\MultiSelectedRect.cs" />
     <Compile Include="DrawTool\PageSelectedRect.cs" />
     <Compile Include="DrawTool\PageSelectedRect.cs" />
     <Compile Include="DrawTool\SelectedRect.cs" />
     <Compile Include="DrawTool\SelectedRect.cs" />
@@ -217,5 +222,25 @@
       <Name>ComPDFKit.Viewer</Name>
       <Name>ComPDFKit.Viewer</Name>
     </ProjectReference>
     </ProjectReference>
   </ItemGroup>
   </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\compdfkit_windows\ComPDFKit\ComPDFKitCSharp\ComPDFKit.NET.csproj">
+      <Project>{56e518ad-c126-4b48-9a09-0a64c87020e4}</Project>
+      <Name>ComPDFKit.NET</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\compdfkit_windows_rebuild\ComPDFKit.Viewer\ComPDFKit.Viewer.csproj">
+      <Project>{783263cf-0da3-4095-9df8-2c4a6b3ff908}</Project>
+      <Name>ComPDFKit.Viewer</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\compdfkit_windows\ComPDFKit\ComPDFKitCSharp\ComPDFKit.NET.csproj">
+      <Project>{56e518ad-c126-4b48-9a09-0a64c87020e4}</Project>
+      <Name>ComPDFKit.NET</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\compdfkit_windows_rebuild\ComPDFKit.Viewer\ComPDFKit.Viewer.csproj">
+      <Project>{783263cf-0da3-4095-9df8-2c4a6b3ff908}</Project>
+      <Name>ComPDFKit.Viewer</Name>
+    </ProjectReference>
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 </Project>
 </Project>

+ 195 - 116
Demo/Examples/ComPDFKit.Tool/DrawTool/AnnotEdit.cs

@@ -13,6 +13,7 @@ using System.Linq;
 using System.Net;
 using System.Net;
 using System.Windows;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Controls;
+using System.Windows.Input;
 using System.Windows.Media;
 using System.Windows.Media;
 using System.Windows.Media.TextFormatting;
 using System.Windows.Media.TextFormatting;
 using static ComPDFKit.Tool.Help.ImportWin32;
 using static ComPDFKit.Tool.Help.ImportWin32;
@@ -79,6 +80,7 @@ namespace ComPDFKit.Tool.DrawTool
         /// Move offset during movement
         /// Move offset during movement
         /// </summary>
         /// </summary>
         protected Point moveOffset { get; set; } = new Point(0, 0);
         protected Point moveOffset { get; set; } = new Point(0, 0);
+        private Point LineMeasureOffset { get; set; }= new Point(0, 0);
 
 
         /// <summary>
         /// <summary>
         /// Point size
         /// Point size
@@ -160,6 +162,7 @@ namespace ComPDFKit.Tool.DrawTool
                 case C_ANNOTATION_TYPE.C_ANNOTATION_FREETEXT:
                 case C_ANNOTATION_TYPE.C_ANNOTATION_FREETEXT:
                     break;
                     break;
                 case C_ANNOTATION_TYPE.C_ANNOTATION_LINE:
                 case C_ANNOTATION_TYPE.C_ANNOTATION_LINE:
+                    List<Point> sortPointList= new List<Point>();
                     for (int i = 0; i < (annotData.Annot as CPDFLineAnnotation).Points.Length; i++)
                     for (int i = 0; i < (annotData.Annot as CPDFLineAnnotation).Points.Length; i++)
                     {
                     {
                         Point point = DpiHelper.PDFPointToStandardPoint(new Point((annotData.Annot as CPDFLineAnnotation).Points[i].x, (annotData.Annot as CPDFLineAnnotation).Points[i].y));
                         Point point = DpiHelper.PDFPointToStandardPoint(new Point((annotData.Annot as CPDFLineAnnotation).Points[i].x, (annotData.Annot as CPDFLineAnnotation).Points[i].y));
@@ -167,9 +170,15 @@ namespace ComPDFKit.Tool.DrawTool
                             point.X * annotData.CurrentZoom + annotData.PaintOffset.X - annotData.CropLeft * annotData.CurrentZoom,
                             point.X * annotData.CurrentZoom + annotData.PaintOffset.X - annotData.CropLeft * annotData.CurrentZoom,
                             point.Y * annotData.CurrentZoom + annotData.PaintOffset.Y - annotData.CropTop * annotData.CurrentZoom
                             point.Y * annotData.CurrentZoom + annotData.PaintOffset.Y - annotData.CropTop * annotData.CurrentZoom
                             );
                             );
-                        activePoints.Add(point);
+                        sortPointList.Add(point);
+                    }
+                    sortPointList.Sort((a, b) => { if (a.X > b.X) return 1; else return 0; });
+                    foreach (Point checkPoint in sortPointList)
+                    {
+                        activePoints.Add(checkPoint);
                     }
                     }
-                    if ((annotData.Annot as CPDFLineAnnotation).IsMersured())
+                   
+                    if ((annotData.Annot as CPDFLineAnnotation).IsMeasured())
                     {
                     {
                         CRect rawRect = annotData.Annot.GetRect();
                         CRect rawRect = annotData.Annot.GetRect();
                         Rect rect = DataConversionForWPF.CRectConversionForRect(rawRect);
                         Rect rect = DataConversionForWPF.CRectConversionForRect(rawRect);
@@ -197,7 +206,7 @@ namespace ComPDFKit.Tool.DrawTool
                             );
                             );
                         activePoints.Add(point);
                         activePoints.Add(point);
                     }
                     }
-                    if ((annotData.Annot as CPDFPolygonAnnotation).IsMersured())
+                    if ((annotData.Annot as CPDFPolygonAnnotation).IsMeasured())
                     {
                     {
                         CRect rawRect = annotData.Annot.GetRect();
                         CRect rawRect = annotData.Annot.GetRect();
                         Rect rect = DataConversionForWPF.CRectConversionForRect(rawRect);
                         Rect rect = DataConversionForWPF.CRectConversionForRect(rawRect);
@@ -220,7 +229,7 @@ namespace ComPDFKit.Tool.DrawTool
                             );
                             );
                         activePoints.Add(point);
                         activePoints.Add(point);
                     }
                     }
-                    if ((annotData.Annot as CPDFPolylineAnnotation).IsMersured())
+                    if ((annotData.Annot as CPDFPolylineAnnotation).IsMeasured())
                     {
                     {
                         CRect rawRect = annotData.Annot.GetRect();
                         CRect rawRect = annotData.Annot.GetRect();
                         Rect rect = DataConversionForWPF.CRectConversionForRect(rawRect);
                         Rect rect = DataConversionForWPF.CRectConversionForRect(rawRect);
@@ -309,16 +318,16 @@ namespace ComPDFKit.Tool.DrawTool
             crossLine.Clear();
             crossLine.Clear();
             rightLine.Clear();
             rightLine.Clear();
             CPDFDistanceMeasure LineMeasure = Annot.GetDistanceMeasure();
             CPDFDistanceMeasure LineMeasure = Annot.GetDistanceMeasure();
-            double LeadLength = LineMeasure.GetLeadLength() / 72D * 96D;
-            double LeadOffset = LineMeasure.GetLeadOffset() / 72D * 96D;
-            double LeadExtension = LineMeasure.GetLeadExtension() / 72D * 96D;
+            double LeadLength = LineMeasure.GetLeadLength() / 72D * 96D * annotData.CurrentZoom;
+            double LeadOffset = LineMeasure.GetLeadOffset() / 72D * 96D * annotData.CurrentZoom;
+            double LeadExtension = LineMeasure.GetLeadExtension() / 72D * 96D * annotData.CurrentZoom;
 
 
             List<Point> orderPoints = activePoints.AsEnumerable().OrderBy(x => x.X).ToList();
             List<Point> orderPoints = activePoints.AsEnumerable().OrderBy(x => x.X).ToList();
-            Vector lineVector = (activePoints[1] - activePoints[0]) * annotData.CurrentZoom;
+            Vector lineVector = (activePoints[1] - activePoints[0]) ;
             lineVector.Normalize();
             lineVector.Normalize();
-            Vector leadEndVector = lineVector * (Math.Abs(LeadLength) + Math.Abs(LeadOffset) + Math.Abs(LeadExtension) * annotData.CurrentZoom);
-            Vector leadStartVector = lineVector * (Math.Abs(LeadOffset)) * annotData.CurrentZoom;
-            Vector leadCrossVector = lineVector * (Math.Abs(LeadLength)  * annotData.CurrentZoom + Math.Abs(LeadOffset));
+            Vector leadEndVector = lineVector * (Math.Abs(LeadLength) + Math.Abs(LeadOffset) + Math.Abs(LeadExtension));
+            Vector leadStartVector = lineVector * (Math.Abs(LeadOffset));
+            Vector leadCrossVector = lineVector * (Math.Abs(LeadLength) + Math.Abs(LeadOffset));
             Matrix rotateMatrix = new Matrix();
             Matrix rotateMatrix = new Matrix();
             double angle = LeadLength < 0 ? 90 : -90;
             double angle = LeadLength < 0 ? 90 : -90;
             rotateMatrix.Rotate(angle);
             rotateMatrix.Rotate(angle);
@@ -327,12 +336,12 @@ namespace ComPDFKit.Tool.DrawTool
             Point leftCrossPoint = rotateMatrix.Transform(leadCrossVector) + activePoints[0];
             Point leftCrossPoint = rotateMatrix.Transform(leadCrossVector) + activePoints[0];
 
 
             leftLine.Add(leftStartPoint);
             leftLine.Add(leftStartPoint);
-            leftLine.Add(leftCrossPoint);
+            leftLine.Add(leftEndPoint);
             crossLine.Add(leftCrossPoint);
             crossLine.Add(leftCrossPoint);
 
 
             lineVector = activePoints[1] - activePoints[0];
             lineVector = activePoints[1] - activePoints[0];
             rightLine.Add(leftStartPoint + lineVector);
             rightLine.Add(leftStartPoint + lineVector);
-            rightLine.Add(leftCrossPoint + lineVector);
+            rightLine.Add(leftEndPoint + lineVector);
             crossLine.Add(leftCrossPoint + lineVector);
             crossLine.Add(leftCrossPoint + lineVector);
             activePoints.Insert(1, new Point(
             activePoints.Insert(1, new Point(
                 (crossLine[0].X + crossLine[1].X) / 2,
                 (crossLine[0].X + crossLine[1].X) / 2,
@@ -348,6 +357,7 @@ namespace ComPDFKit.Tool.DrawTool
             hitIndex = -1;
             hitIndex = -1;
             mouseDownPoint = downPoint;
             mouseDownPoint = downPoint;
             moveOffset = new Point(0, 0);
             moveOffset = new Point(0, 0);
+            LineMeasureOffset=new Point(0, 0);
             HitTestResult hitResult = VisualTreeHelper.HitTest(this, downPoint);
             HitTestResult hitResult = VisualTreeHelper.HitTest(this, downPoint);
             if (hitResult != null && hitResult.VisualHit is DrawingVisual)
             if (hitResult != null && hitResult.VisualHit is DrawingVisual)
             {
             {
@@ -358,7 +368,7 @@ namespace ComPDFKit.Tool.DrawTool
         public virtual void OnMouseMove(Point mousePoint, out bool Tag)
         public virtual void OnMouseMove(Point mousePoint, out bool Tag)
         {
         {
             Tag = false;
             Tag = false;
-            if (isMouseDown)
+            if (Mouse.LeftButton==MouseButtonState.Pressed)
             {
             {
                 Tag = isMouseDown;
                 Tag = isMouseDown;
                 mouseEndDrawPoint = mousePoint;
                 mouseEndDrawPoint = mousePoint;
@@ -369,6 +379,7 @@ namespace ComPDFKit.Tool.DrawTool
                     );
                     );
 
 
                 Point movePoint = CheckMoveOffSet(activePoints.ToList(), maxRect, newOffset);
                 Point movePoint = CheckMoveOffSet(activePoints.ToList(), maxRect, newOffset);
+                LineMeasureOffset=newOffset;
                 if(movePoint.X==0)
                 if(movePoint.X==0)
                 {
                 {
                     newOffset.X=moveOffset.X;
                     newOffset.X=moveOffset.X;
@@ -389,7 +400,7 @@ namespace ComPDFKit.Tool.DrawTool
             Draw();
             Draw();
             if (annotData!=null&&annotData.AnnotType == C_ANNOTATION_TYPE.C_ANNOTATION_LINE)
             if (annotData!=null&&annotData.AnnotType == C_ANNOTATION_TYPE.C_ANNOTATION_LINE)
             {
             {
-                if ((annotData.Annot as CPDFLineAnnotation).IsMersured())
+                if ((annotData.Annot as CPDFLineAnnotation).IsMeasured())
                 {
                 {
                     activePoints.Clear();
                     activePoints.Clear();
 
 
@@ -443,7 +454,7 @@ namespace ComPDFKit.Tool.DrawTool
                 {
                 {
                     if (annotData.AnnotType == C_ANNOTATION_TYPE.C_ANNOTATION_LINE)
                     if (annotData.AnnotType == C_ANNOTATION_TYPE.C_ANNOTATION_LINE)
                     {
                     {
-                        if (!(annotData.Annot as CPDFLineAnnotation).IsMersured())
+                        if (!(annotData.Annot as CPDFLineAnnotation).IsMeasured())
                         {
                         {
                             currentPoint.X += moveOffset.X;
                             currentPoint.X += moveOffset.X;
                             currentPoint.Y += moveOffset.Y;
                             currentPoint.Y += moveOffset.Y;
@@ -486,7 +497,7 @@ namespace ComPDFKit.Tool.DrawTool
                 {
                 {
                     case C_ANNOTATION_TYPE.C_ANNOTATION_LINE:
                     case C_ANNOTATION_TYPE.C_ANNOTATION_LINE:
                         {
                         {
-                            if ((annotData.Annot as CPDFLineAnnotation).IsMersured())
+                            if ((annotData.Annot as CPDFLineAnnotation).IsMeasured())
                             {
                             {
                                 DrawLineMeasure(drawDC);
                                 DrawLineMeasure(drawDC);
                             }
                             }
@@ -625,23 +636,30 @@ namespace ComPDFKit.Tool.DrawTool
             }
             }
         }
         }
 
 
-        private void DrawLineMeasure(DrawingContext drawingContext)
+        private Point CalcRotateBound(Point rawPoint, Point moveOffset)
+        {
+            Point newPoint = rawPoint;
+            Rect checkRect = annotData.PaintOffset;
+            newPoint.X += moveOffset.X;
+            newPoint.Y += moveOffset.Y;
+            newPoint.X = Math.Max(checkRect.Left, newPoint.X);
+            newPoint.X = Math.Min(checkRect.Right, newPoint.X);
+            newPoint.Y = Math.Max(checkRect.Top, newPoint.Y);
+            newPoint.Y = Math.Min(checkRect.Bottom, newPoint.Y);
+
+            return newPoint;
+        }
+
+        private void DrawLineMeasure(DrawingContext drawDC)
         {
         {
-            foreach (Point controlPoint in activePoints)
-            {
-                Point drawPoint = new Point(
-                    controlPoint.X,
-                    controlPoint.Y);
-                if (hitIndex == -1)
-                {
-                    drawPoint.X += moveOffset.X;
-                    drawPoint.Y += moveOffset.Y;
-                }
-                drawingContext?.DrawEllipse(drawParam.EditControlLineBrush, drawParam.EditControlLinePen, (drawPoint), pointSize, pointSize);
-            }
             Rect drawRect = activeRect;
             Rect drawRect = activeRect;
             drawRect.X += moveOffset.X;
             drawRect.X += moveOffset.X;
             drawRect.Y += moveOffset.Y;
             drawRect.Y += moveOffset.Y;
+
+            Point[] drawLeftLine = leftLine.ToArray();
+            Point[] drawRightLine = rightLine.ToArray();
+            Point[] drawCrossLine = crossLine.ToArray();
+
             if (isMouseDown)
             if (isMouseDown)
             {
             {
                 PointCollection drawLeftPoints = new PointCollection();
                 PointCollection drawLeftPoints = new PointCollection();
@@ -650,44 +668,52 @@ namespace ComPDFKit.Tool.DrawTool
                 moveLeftLine = leftLine.ToArray();
                 moveLeftLine = leftLine.ToArray();
                 moveRightLine = rightLine.ToArray();
                 moveRightLine = rightLine.ToArray();
                 moveCrossLine = crossLine.ToArray();
                 moveCrossLine = crossLine.ToArray();
-                switch (hitIndex)
-                { 
-                    case 0://Left
-                        {
-                            moveLeftLine[0].X += moveOffset.X;
-                            moveLeftLine[0].Y += moveOffset.Y;
+                foreach(Point checkPoint in moveLeftLine)
+                {
+                    drawLeftPoints.Add(checkPoint);
+                }
 
 
-                            moveLeftLine[0].X = Math.Max(maxRect.Left, moveLeftLine[0].X);
-                            moveLeftLine[0].X = Math.Min(maxRect.Right, moveLeftLine[0].X);
-                            moveLeftLine[0].Y = Math.Max(maxRect.Top, moveLeftLine[0].Y);
-                            moveLeftLine[0].Y = Math.Min(maxRect.Bottom, moveLeftLine[0].Y);
+                foreach (Point checkPoint in moveRightLine)
+                {
+                    drawRightPoints.Add(checkPoint);
+                }
 
 
-                            Vector newVector = moveLeftLine[0] - rightLine[0];
-                            Vector leftVector = leftLine[1] - leftLine[0];
+                foreach (Point checkPoint in moveCrossLine)
+                {
+                    drawCrossPoints.Add(checkPoint);
+                }
 
 
-                            double angle = leftLine[0].Y < crossLine[0].Y ? -90 : 90;
+                switch (hitIndex)
+                {
+                    case 0:
+                        {
+                            moveLeftLine[0] = CalcRotateBound(drawLeftPoints[0], LineMeasureOffset);
+
+                            Vector newVector = moveLeftLine[0] - drawRightPoints[0];
+                            Vector leftVector = drawLeftPoints[1] - drawLeftPoints[0];
+                            double angle = drawLeftPoints[0].Y < drawCrossPoints[0].Y ? -90 : 90;
                             newVector.Normalize();
                             newVector.Normalize();
                             newVector = newVector * leftVector.Length;
                             newVector = newVector * leftVector.Length;
                             Matrix rotateMatrix = new Matrix();
                             Matrix rotateMatrix = new Matrix();
                             rotateMatrix.Rotate(angle);
                             rotateMatrix.Rotate(angle);
+                            moveRightLine[0] = drawRightPoints[0];
                             moveLeftLine[1] = moveLeftLine[0] + newVector * rotateMatrix;
                             moveLeftLine[1] = moveLeftLine[0] + newVector * rotateMatrix;
-                            moveRightLine[0] = rightLine[0];
                             moveRightLine[1] = moveRightLine[0] + newVector * rotateMatrix;
                             moveRightLine[1] = moveRightLine[0] + newVector * rotateMatrix;
+
                             moveCrossLine[0] = moveLeftLine[1];
                             moveCrossLine[0] = moveLeftLine[1];
                             moveCrossLine[1] = moveRightLine[1];
                             moveCrossLine[1] = moveRightLine[1];
+
+                            drawDC?.DrawLine(drawParam.EditLinePen, moveLeftLine[0], moveLeftLine[1]);
+                            drawDC?.DrawLine(drawParam.EditLinePen, moveRightLine[0], moveRightLine[1]);
+                            drawDC?.DrawLine(drawParam.EditLinePen, moveLeftLine[1], moveRightLine[1]);
                         }
                         }
                         break;
                         break;
-                    case 1:// Center
+                    case 1:
                         {
                         {
-                            Point centerPoint = new Point(
-                            (crossLine[0].X + crossLine[1].X) / 2,
-                            (crossLine[0].Y + crossLine[1].Y) / 2
-                            );
-                            Point movePoint = new Point(centerPoint.X, centerPoint.Y);
-                            movePoint.X += moveOffset.X;
-                            movePoint.Y += moveOffset.Y;
-                            Vector ruleVector = crossLine[1] - crossLine[0];
+                            Point centerPoint = new Point((drawCrossPoints[0].X + drawCrossPoints[1].X) / 2,(drawCrossPoints[0].Y + drawCrossPoints[1].Y) / 2);
 
 
+                            Point movePoint = CalcRotateBound(centerPoint, LineMeasureOffset);
+                            Vector ruleVector = drawCrossPoints[1] - drawCrossPoints[0];
                             bool rateMove = true;
                             bool rateMove = true;
                             if (ruleVector.X == 0)
                             if (ruleVector.X == 0)
                             {
                             {
@@ -699,6 +725,7 @@ namespace ComPDFKit.Tool.DrawTool
                                 movePoint.X = centerPoint.X;
                                 movePoint.X = centerPoint.X;
                                 rateMove = false;
                                 rateMove = false;
                             }
                             }
+
                             if (rateMove)
                             if (rateMove)
                             {
                             {
                                 Vector moveVector = movePoint - centerPoint;
                                 Vector moveVector = movePoint - centerPoint;
@@ -722,99 +749,151 @@ namespace ComPDFKit.Tool.DrawTool
                                 moveCrossLine[1] = SaveRight;
                                 moveCrossLine[1] = SaveRight;
                                 moveLeftLine[1] = saveLeft;
                                 moveLeftLine[1] = saveLeft;
                                 moveRightLine[1] = SaveRight;
                                 moveRightLine[1] = SaveRight;
-                                moveLeftLine[0] = leftLine[0];
-                                moveRightLine[0] = rightLine[0];
+                                moveLeftLine[0] = drawLeftPoints[0];
+                                moveRightLine[0] = drawRightPoints[0];
                             }
                             }
                             else
                             else
                             {
                             {
                                 Point moveOffset = new Point(
                                 Point moveOffset = new Point(
                                     movePoint.X - centerPoint.X,
                                     movePoint.X - centerPoint.X,
                                     movePoint.Y - centerPoint.Y);
                                     movePoint.Y - centerPoint.Y);
-                                moveCrossLine[0].X += moveOffset.X;
-                                moveCrossLine[0].Y += moveOffset.Y;
-                                moveCrossLine[1].X += moveOffset.X;
-                                moveCrossLine[1].Y += moveOffset.Y;
 
 
-                                moveLeftLine[1].X += moveOffset.X;
-                                moveLeftLine[1].Y += moveOffset.Y;
+                                moveCrossLine[0] = new Point(
+                                    drawCrossPoints[0].X + moveOffset.X,
+                                    drawCrossPoints[0].Y + moveOffset.Y);
+                                moveCrossLine[1] = new Point(
+                                    drawCrossPoints[1].X + moveOffset.X,
+                                    drawCrossPoints[1].Y + moveOffset.Y);
+
+                                moveLeftLine[0] = drawLeftPoints[0];
+                                moveRightLine[0] = drawRightPoints[0];
 
 
-                                moveRightLine[1].X += moveOffset.X;
-                                moveRightLine[1].Y += moveOffset.Y;
+                                moveLeftLine[1] = new Point(
+                                    drawLeftPoints[1].X + moveOffset.X,
+                                    drawLeftPoints[1].Y + moveOffset.Y);
+
+                                moveRightLine[1] = new Point(
+                                   drawRightPoints[1].X + moveOffset.X,
+                                   drawRightPoints[1].Y + moveOffset.Y);
                             }
                             }
 
 
+                            drawDC?.DrawLine(drawParam.EditLinePen, moveCrossLine[0], moveCrossLine[1]);
+                            drawDC?.DrawLine(drawParam.EditLinePen, moveCrossLine[0], moveLeftLine[0]);
+                            drawDC?.DrawLine(drawParam.EditLinePen, moveCrossLine[1], moveRightLine[0]);
                         }
                         }
                         break;
                         break;
-                    case 2://Right
+                    case 2:
                         {
                         {
-                            moveRightLine[0].X += moveOffset.X;
-                            moveRightLine[0].Y += moveOffset.Y;
-
-                            Vector newVector = moveRightLine[0] - leftLine[0];
-                            Vector leftVector = rightLine[1] - rightLine[0];
-
-                            double angle = (rightLine[0].Y + leftLine[0].Y) / 2 > (crossLine[0].Y + crossLine[1].Y) / 2 ? -90 : 90;
+                            moveRightLine[0] = CalcRotateBound(drawRightPoints[0], LineMeasureOffset);
+                            Vector newVector = moveRightLine[0] - drawLeftPoints[0];
+                            Vector rightVector = drawRightPoints[1] - drawRightPoints[0];
+                            double angle = (drawRightPoints[0].Y + drawLeftPoints[0].Y) / 2 > (drawCrossPoints[0].Y + drawCrossPoints[1].Y) / 2 ? -90 : 90;
                             newVector.Normalize();
                             newVector.Normalize();
-                            newVector = newVector * leftVector.Length;
+                            newVector = newVector * rightVector.Length;
                             Matrix rotateMatrix = new Matrix();
                             Matrix rotateMatrix = new Matrix();
                             rotateMatrix.Rotate(angle);
                             rotateMatrix.Rotate(angle);
+                            moveLeftLine[0] = drawLeftPoints[0];
                             moveLeftLine[1] = moveLeftLine[0] + newVector * rotateMatrix;
                             moveLeftLine[1] = moveLeftLine[0] + newVector * rotateMatrix;
-                            moveLeftLine[0] = leftLine[0];
                             moveRightLine[1] = moveRightLine[0] + newVector * rotateMatrix;
                             moveRightLine[1] = moveRightLine[0] + newVector * rotateMatrix;
+
                             moveCrossLine[0] = moveLeftLine[1];
                             moveCrossLine[0] = moveLeftLine[1];
                             moveCrossLine[1] = moveRightLine[1];
                             moveCrossLine[1] = moveRightLine[1];
+
+                            drawDC?.DrawLine(drawParam.EditLinePen, moveLeftLine[0], moveLeftLine[1]);
+                            drawDC?.DrawLine(drawParam.EditLinePen, moveRightLine[0], moveRightLine[1]);
+                            drawDC?.DrawLine(drawParam.EditLinePen, moveLeftLine[1], moveRightLine[1]);
                         }
                         }
                         break;
                         break;
                     case -1:
                     case -1:
-                        moveLeftLine[0].X += moveOffset.X;
-                        moveLeftLine[0].Y += moveOffset.Y;
-                        moveLeftLine[1].X += moveOffset.X;
-                        moveLeftLine[1].Y += moveOffset.Y;
-
-                        moveRightLine[0].X += moveOffset.X;
-                        moveRightLine[0].Y += moveOffset.Y;
-                        moveRightLine[1].X += moveOffset.X;
-                        moveRightLine[1].Y += moveOffset.Y;
-
-                        moveCrossLine[0] = moveLeftLine[1];
-                        moveCrossLine[1] = moveRightLine[1];
+                        {
+                            Rect moveRect = new Rect(moveLeftLine[0], moveRightLine[1]);
+                            moveRect.Union(moveLeftLine[1]);
+                            moveRect.Union(moveRightLine[0]);
+                            Point moveOffset = LineMeasureOffset;
+                            Rect pageBound = annotData.PaintOffset;
+                            if (moveRect.Left + LineMeasureOffset.X < pageBound.Left)
+                            {
+                                moveOffset.X = pageBound.Left - moveRect.Left;
+                            }
+                            if (moveRect.Right + moveOffset.X > pageBound.Right)
+                            {
+                                moveOffset.X = pageBound.Right - moveRect.Right;
+                            }
+                            if (moveRect.Top + moveOffset.Y < pageBound.Top)
+                            {
+                                moveOffset.Y = pageBound.Top - moveRect.Top;
+                            }
+                            if (moveRect.Bottom + moveOffset.Y > pageBound.Bottom)
+                            {
+                                moveOffset.Y = pageBound.Bottom - moveRect.Bottom;
+                            }
+
+                            moveLeftLine[0].X = moveLeftLine[0].X + moveOffset.X;
+                            moveLeftLine[0].Y = moveLeftLine[0].Y + moveOffset.Y;
+
+                            moveLeftLine[1].X = moveLeftLine[1].X + moveOffset.X;
+                            moveLeftLine[1].Y = moveLeftLine[1].Y + moveOffset.Y;
+
+                            moveRightLine[0].X = moveRightLine[0].X + moveOffset.X;
+                            moveRightLine[0].Y = moveRightLine[0].Y + moveOffset.Y;
+
+                            moveRightLine[1].X = moveRightLine[1].X + moveOffset.X;
+                            moveRightLine[1].Y = moveRightLine[1].Y + moveOffset.Y;
+
+                            moveCrossLine[0].X = moveCrossLine[0].X + moveOffset.X;
+                            moveCrossLine[0].Y = moveCrossLine[0].Y + moveOffset.Y;
+
+                            moveCrossLine[1].X = moveCrossLine[1].X + moveOffset.X;
+                            moveCrossLine[1].Y = moveCrossLine[1].Y + moveOffset.Y;
+
+                            drawDC?.DrawLine(drawParam.EditLinePen, moveLeftLine[0], moveLeftLine[1]);
+                            drawDC?.DrawLine(drawParam.EditLinePen, moveRightLine[0], moveRightLine[1]);
+                            drawDC?.DrawLine(drawParam.EditLinePen, moveCrossLine[0], moveCrossLine[1]);
+                        }
                         break;
                         break;
                     default:
                     default:
                         break;
                         break;
                 }
                 }
-                //Left
-                drawLeftPoints.Add(new Point(
-                    moveLeftLine[0].X,
-                    moveLeftLine[0].Y));
-                drawLeftPoints.Add(new Point(
-                   moveLeftLine[1].X,
-                   moveLeftLine[1].Y));
-
-                //Right
-                drawRightPoints.Add(new Point(
-                    moveRightLine[0].X,
-                    moveRightLine[0].Y));
-                drawRightPoints.Add(new Point(
-                   moveRightLine[1].X,
-                   moveRightLine[1].Y));
-
-                //Middle
-                drawCrossPoints.Add(new Point(
-                    moveCrossLine[0].X,
-                    moveCrossLine[0].Y));
-
-                drawCrossPoints.Add(new Point(
-                    moveCrossLine[1].X,
-                    moveCrossLine[1].Y));
-
-
-                drawingContext?.DrawLine(drawParam.EditLinePen, drawLeftPoints[0], drawLeftPoints[1]);
-                drawingContext?.DrawLine(drawParam.EditLinePen, drawRightPoints[0], drawRightPoints[1]);
-                drawingContext?.DrawLine(drawParam.EditLinePen, drawCrossPoints[0], drawCrossPoints[1]);
+
+
+                if (moveLeftLine[0].X > moveRightLine[0].X)
+                {
+                    Point tmpPoint = moveRightLine[0];
+                    moveRightLine[0] = moveLeftLine[0];
+                    moveLeftLine[0] = tmpPoint;
+                }
+
+                if (moveLeftLine[1].X > moveRightLine[1].X)
+                {
+                    Point tmpPoint = moveRightLine[1];
+                    moveRightLine[1] = moveLeftLine[1];
+                    moveLeftLine[1] = tmpPoint;
+                }
+
+                if (moveCrossLine[0].X > moveCrossLine[1].X)
+                {
+                    Point tmpPoint = moveCrossLine[1];
+                    moveCrossLine[1] = moveCrossLine[0];
+                    moveCrossLine[0] = tmpPoint;
+                }
+
+                drawLeftLine=moveLeftLine;
+                drawRightLine=moveRightLine;
+                drawCrossLine=moveCrossLine;
             }
             }
-            else
+
+            if(isMouseDown==false)
             {
             {
-                drawingContext?.DrawRectangle(null, drawParam.EditLinePen, drawRect);
+                drawDC?.DrawRectangle(null, drawParam.EditControlLinePen, activeRect);
             }
             }
+
+            Point moveCenterPoint = new Point(
+                (drawCrossLine[0].X + drawCrossLine[1].X) / 2,
+                (drawCrossLine[0].Y + drawCrossLine[1].Y) / 2
+                );
+            drawDC?.DrawEllipse(drawParam.EditControlLineBrush, drawParam.EditControlLinePen, drawLeftLine[0], pointSize, pointSize);
+            drawDC?.DrawEllipse(drawParam.EditControlLineBrush, drawParam.EditControlLinePen, drawRightLine[0], pointSize, pointSize);
+            drawDC?.DrawEllipse(drawParam.EditControlLineBrush, drawParam.EditControlLinePen, moveCenterPoint, pointSize, pointSize);
         }
         }
 
 
         private void DrawPolyLineMeasure(DrawingContext drawingContext)
         private void DrawPolyLineMeasure(DrawingContext drawingContext)

+ 210 - 0
Demo/Examples/ComPDFKit.Tool/DrawTool/AnnotSelector.cs

@@ -0,0 +1,210 @@
+using ComPDFKitViewer;
+using ComPDFKitViewer.Layer;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Media;
+
+namespace ComPDFKit.Tool.DrawTool
+{
+    internal class AnnotSelector:BaseLayer
+    {
+        public CPDFViewer PDFViewer { get; set; }
+        public List<AnnotData> SelectAnnots { get; set; } = new List<AnnotData>();
+        public Pen DrawPen { get; set; }
+        public Brush DrawBrush { get; set; }
+        private List<Point> ControlPoints { get; set; } = new List<Point>();
+        private double RectPadding = 4;
+        public AnnotSelector()
+        {
+            DrawPen = new Pen(new SolidColorBrush(Color.FromArgb(255, 71, 126, 222)), 2);
+            DrawBrush = new SolidColorBrush(Color.FromArgb(40, 119, 180, 227));
+        }
+        public override void Draw()
+        {
+            DrawingContext drawDC = Open();
+            DrawOutBound(drawDC);
+            DrawIndividual(drawDC);
+            DrawControlPoint(drawDC);
+            Present();
+        }
+
+        public int GetSelectCount()
+        {
+            if(SelectAnnots!=null)
+            {
+                return SelectAnnots.Count;
+            }
+            return 0;
+        }
+        public bool AddItem(AnnotData item)
+        {
+            if (item == null)
+            {
+                return false;
+            }
+            List<int> pageIndexList = SelectAnnots.Select(x => x.PageIndex).Distinct().ToList();
+            if(pageIndexList.Count > 1 )
+            {
+                SelectAnnots.Clear();
+            }
+
+            if( pageIndexList.Count==1 && pageIndexList[0]!=item.PageIndex)
+            {
+                SelectAnnots.Clear();
+            }
+
+            if (RemoveItem(item))
+            {
+                SelectAnnots.Add(item);
+                return true;
+            }
+            return false;
+        }
+        public bool HasItem(AnnotData item)
+        {
+            if (item == null)
+            {
+                return false;
+            }
+
+            if(SelectAnnots!=null && SelectAnnots.Count > 0)
+            {
+                return SelectAnnots.Where(x => x.AnnotIndex == item.AnnotIndex && x.PageIndex == item.PageIndex).Count() > 0;
+            }
+
+            return false;
+        }
+
+        public bool RemoveItem(AnnotData item)
+        {
+            if (item == null || item.PageIndex < 0 || item.AnnotIndex < 0)
+            {
+                return false;
+            }
+
+            List<AnnotData> checkList = SelectAnnots.Where(x => x.AnnotIndex == item.AnnotIndex && x.PageIndex == item.PageIndex).ToList();
+            if (checkList != null && checkList.Count > 0)
+            {
+                foreach (AnnotData removeItem in checkList)
+                {
+                    SelectAnnots.Remove(removeItem);
+                }
+            }
+            return true;
+        }
+
+        public void ClearItem()
+        { 
+            SelectAnnots?.Clear(); 
+        }
+        public Rect GetOutBoundRect()
+        {
+            if (SelectAnnots.Count > 0)
+            {
+                double left = 0;
+                double top = 0;
+                double right = 0;
+                double bottom = 0;
+
+                for (int i=0;i< SelectAnnots.Count;i++)
+                {
+                   AnnotData checkItem= SelectAnnots[i];
+                    if (i == 0) 
+                    {
+                        left=checkItem.PaintRect.Left;
+                        top=checkItem.PaintRect.Top;
+                        right=checkItem.PaintRect.Right;
+                        bottom=checkItem.PaintRect.Bottom;
+                        continue;
+                    }
+
+                    left = Math.Min(left, checkItem.PaintRect.Left);
+                    top = Math.Min(top, checkItem.PaintRect.Top);
+                    right = Math.Max(right, checkItem.PaintRect.Right);
+                    bottom = Math.Max(bottom, checkItem.PaintRect.Bottom);
+                }
+
+                if(right<left ||  bottom<top)
+                {
+                    return Rect.Empty;
+                }
+
+                return new Rect(left, top, right-left, bottom-top);
+            }
+           
+            return Rect.Empty;
+        }
+
+        public void DrawOutBound(DrawingContext drawDC) 
+        {
+            Rect boudRect = GetOutBoundRect();
+            if (boudRect.IsEmpty || boudRect.Width == 0 || boudRect.Height == 0)
+            { 
+                return;
+            }
+
+            drawDC.DrawRectangle(Brushes.Transparent, DrawPen, boudRect);
+        }
+
+        public void DrawIndividual(DrawingContext drawDC)
+        {
+            if(SelectAnnots==null || SelectAnnots.Count==0)
+            {
+                return;
+            }
+
+            foreach(AnnotData checkItem in SelectAnnots)
+            {
+                drawDC.DrawRectangle(null, DrawPen, checkItem.PaintRect);
+            }
+        }
+
+        public void DrawControlPoint(DrawingContext drawDC)
+        {
+            Rect boudRect = GetOutBoundRect();
+            ControlPoints.Clear();
+            double centerX = (boudRect.Left + boudRect.Right) / 2;
+            double centerY = (boudRect.Top + boudRect.Bottom) / 2;
+
+            ControlPoints.Add(new Point(boudRect.Left, boudRect.Top));
+            ControlPoints.Add(new Point(boudRect.Left, centerY));
+            ControlPoints.Add(new Point(boudRect.Left, boudRect.Bottom));
+            ControlPoints.Add(new Point(centerX, boudRect.Bottom));
+            ControlPoints.Add(new Point(boudRect.Right, boudRect.Bottom));
+            ControlPoints.Add(new Point(boudRect.Right, centerY));
+            ControlPoints.Add(new Point(boudRect.Right, boudRect.Top));
+            ControlPoints.Add(new Point(centerX, boudRect.Top));
+
+            foreach (Point point in ControlPoints)
+            {
+                drawDC.DrawRectangle(Brushes.White, DrawPen, new Rect(point.X- RectPadding,point.Y- RectPadding, RectPadding*2, RectPadding*2));
+            }
+        }
+
+        public PointControlType GetHitControlIndex(Point point)
+        {
+            for (int i = 0; i < ControlPoints.Count; i++)
+            {
+                Point checkPoint = ControlPoints[i];
+                Rect checkBound = new Rect(checkPoint.X - RectPadding, checkPoint.Y - RectPadding, RectPadding * 2, RectPadding * 2);
+                if (checkBound.Contains(point))
+                {
+                    return (PointControlType)i;
+                }
+            }
+
+            Rect outBound = GetOutBoundRect();
+            if (outBound.Contains(point))
+            {
+                return PointControlType.Body;
+            }
+
+            return PointControlType.None;
+        }
+    }
+}

+ 61 - 18
Demo/Examples/ComPDFKit.Tool/DrawTool/CreateAnnotTool.cs

@@ -28,6 +28,7 @@ using System.Windows.Input;
 using System.Windows.Media;
 using System.Windows.Media;
 using System.Windows.Media.Animation;
 using System.Windows.Media.Animation;
 using System.Windows.Media.Media3D;
 using System.Windows.Media.Media3D;
+using System.Windows.Shapes;
 using static ComPDFKit.PDFAnnotation.CTextAttribute.CFontNameHelper;
 using static ComPDFKit.PDFAnnotation.CTextAttribute.CFontNameHelper;
 using static ComPDFKit.Tool.Help.ImportWin32;
 using static ComPDFKit.Tool.Help.ImportWin32;
 
 
@@ -87,6 +88,7 @@ namespace ComPDFKit.Tool.DrawTool
         /// The rectangle representing the original page range (calculated offset in continuous mode)
         /// The rectangle representing the original page range (calculated offset in continuous mode)
         /// </summary>
         /// </summary>
         protected Rect pageBound { get; set; }
         protected Rect pageBound { get; set; }
+        protected int pageIndex { get; set; } = -1;
 
 
         /// <summary>
         /// <summary>
         /// The rectangle at standard DPI (without subtracting half of the pen thickness)
         /// The rectangle at standard DPI (without subtracting half of the pen thickness)
@@ -245,6 +247,7 @@ namespace ComPDFKit.Tool.DrawTool
         {
         {
             RemoveTextBox();
             RemoveTextBox();
             mouseStartPoint = downPoint;
             mouseStartPoint = downPoint;
+            mouseEndPoint = downPoint;
             isDrawAnnot = true;
             isDrawAnnot = true;
             this.maxRect = maxRect;
             this.maxRect = maxRect;
             zoomFactor = zoom;
             zoomFactor = zoom;
@@ -261,6 +264,7 @@ namespace ComPDFKit.Tool.DrawTool
                 drawPoints.Add(downPoint);
                 drawPoints.Add(downPoint);
                 this.cropPoint = cropPoint;
                 this.cropPoint = cropPoint;
                 this.pageBound = pageBound;
                 this.pageBound = pageBound;
+                this.pageIndex = cPDFPage.PageIndex;
                 DPIRect = new Rect();
                 DPIRect = new Rect();
                 if (annotType != C_ANNOTATION_TYPE.C_ANNOTATION_POLYGON)
                 if (annotType != C_ANNOTATION_TYPE.C_ANNOTATION_POLYGON)
                 {
                 {
@@ -308,6 +312,7 @@ namespace ComPDFKit.Tool.DrawTool
                 mouseEndPoint = new Point();
                 mouseEndPoint = new Point();
                 moveOffset = new Point();
                 moveOffset = new Point();
                 pageBound = new Rect();
                 pageBound = new Rect();
+                pageIndex = -1;
                 DPIRect = new Rect();
                 DPIRect = new Rect();
                 cPDFAnnotation = null;
                 cPDFAnnotation = null;
                 inkDrawPoints.Clear();
                 inkDrawPoints.Clear();
@@ -338,7 +343,7 @@ namespace ComPDFKit.Tool.DrawTool
                         DrawText();
                         DrawText();
                         break;
                         break;
                     case C_ANNOTATION_TYPE.C_ANNOTATION_LINE:
                     case C_ANNOTATION_TYPE.C_ANNOTATION_LINE:
-                        if ((cPDFAnnotation as CPDFLineAnnotation).IsMersured())
+                        if ((cPDFAnnotation as CPDFLineAnnotation).IsMeasured())
                         {
                         {
                             DrawLineMeasure(drawDC);
                             DrawLineMeasure(drawDC);
                         }
                         }
@@ -680,6 +685,16 @@ namespace ComPDFKit.Tool.DrawTool
                 lineSegment.IsSmoothJoin = true;
                 lineSegment.IsSmoothJoin = true;
                 pathFigure.Segments.Add(lineSegment);
                 pathFigure.Segments.Add(lineSegment);
             }
             }
+            if(annotLine.Dash!=null && annotLine.Dash.Length>0)
+            {
+                DashStyle dash = new DashStyle();
+                foreach (var offset in annotLine.Dash)
+                {
+                    dash.Dashes.Add(offset);
+                }
+                DrawPen.DashStyle = dash;
+                DrawPen.DashCap = PenLineCap.Flat;
+            }
             Rect checkRect = pageBound;
             Rect checkRect = pageBound;
             RectangleGeometry rectGeometry = new RectangleGeometry();
             RectangleGeometry rectGeometry = new RectangleGeometry();
             drawRect = rectGeometry.Rect = checkRect;
             drawRect = rectGeometry.Rect = checkRect;
@@ -859,7 +874,7 @@ namespace ComPDFKit.Tool.DrawTool
             Pen DrawPen = new Pen(new SolidColorBrush(color), polyLine.GetBorderWidth());
             Pen DrawPen = new Pen(new SolidColorBrush(color), polyLine.GetBorderWidth());
             SolidColorBrush TextBrush = Brushes.Red;
             SolidColorBrush TextBrush = Brushes.Red;
 
 
-            if (polyLine.IsMersured())
+            if (polyLine.IsMeasured())
             {
             {
                 CPDFPerimeterMeasure measureInfo = polyLine.GetPerimeterMeasure();
                 CPDFPerimeterMeasure measureInfo = polyLine.GetPerimeterMeasure();
                 if (measureInfo != null && measureInfo.TextAttribute != null && measureInfo.TextAttribute.FontColor != null && measureInfo.TextAttribute.FontColor.Length >= 3)
                 if (measureInfo != null && measureInfo.TextAttribute != null && measureInfo.TextAttribute.FontColor != null && measureInfo.TextAttribute.FontColor.Length >= 3)
@@ -1042,7 +1057,7 @@ namespace ComPDFKit.Tool.DrawTool
             Pen EndDrawPen = new Pen(Brushes.Black, polyLine.GetBorderWidth());
             Pen EndDrawPen = new Pen(Brushes.Black, polyLine.GetBorderWidth());
             SolidColorBrush TextBrush = Brushes.Red;
             SolidColorBrush TextBrush = Brushes.Red;
 
 
-            if (polyLine.IsMersured())
+            if (polyLine.IsMeasured())
             {
             {
                 CPDFAreaMeasure measureInfo = polyLine.GetAreaMeasure();
                 CPDFAreaMeasure measureInfo = polyLine.GetAreaMeasure();
                 if (measureInfo != null && measureInfo.TextAttribute != null && measureInfo.TextAttribute.FontColor != null && measureInfo.TextAttribute.FontColor.Length >= 3)
                 if (measureInfo != null && measureInfo.TextAttribute != null && measureInfo.TextAttribute.FontColor != null && measureInfo.TextAttribute.FontColor.Length >= 3)
@@ -1307,7 +1322,7 @@ namespace ComPDFKit.Tool.DrawTool
             Pen DrawPen = new Pen(new SolidColorBrush(color), polyLine.GetBorderWidth());
             Pen DrawPen = new Pen(new SolidColorBrush(color), polyLine.GetBorderWidth());
             SolidColorBrush TextBrush = Brushes.Red;
             SolidColorBrush TextBrush = Brushes.Red;
 
 
-            if (polyLine.IsMersured())
+            if (polyLine.IsMeasured())
             {
             {
                 CPDFDistanceMeasure measureInfo = polyLine.GetDistanceMeasure();
                 CPDFDistanceMeasure measureInfo = polyLine.GetDistanceMeasure();
                 if (measureInfo != null && measureInfo.TextAttribute != null && measureInfo.TextAttribute.FontColor != null && measureInfo.TextAttribute.FontColor.Length >= 3)
                 if (measureInfo != null && measureInfo.TextAttribute != null && measureInfo.TextAttribute.FontColor != null && measureInfo.TextAttribute.FontColor.Length >= 3)
@@ -1432,9 +1447,12 @@ namespace ComPDFKit.Tool.DrawTool
         }
         }
 
 
         #endregion
         #endregion
-        public void MultipleClick(Point downPoint)
+        public void MultipleClick(Point downPoint,int pageIndex)
         {
         {
-            drawPoints.Add(downPoint);
+            if(pageIndex==this.pageIndex)
+            {
+                drawPoints.Add(downPoint);
+            }
         }
         }
 
 
         public Rect GetMaxRect()
         public Rect GetMaxRect()
@@ -1451,8 +1469,7 @@ namespace ComPDFKit.Tool.DrawTool
                     CPDFFreeTextAnnotation annotFreeText = (cPDFAnnotation as CPDFFreeTextAnnotation);
                     CPDFFreeTextAnnotation annotFreeText = (cPDFAnnotation as CPDFFreeTextAnnotation);
 
 
                     TextBox textui = new TextBox();
                     TextBox textui = new TextBox();
-
-                    Border textBorder = new Border();
+                    DashedBorder textBorder = new DashedBorder();
                     textBorder.Child = textui;
                     textBorder.Child = textui;
                    
                    
                     CTextAttribute textAttribute = annotFreeText.FreeTextDa;
                     CTextAttribute textAttribute = annotFreeText.FreeTextDa;
@@ -1517,14 +1534,27 @@ namespace ComPDFKit.Tool.DrawTool
 
 
                     textBorder.Padding = new Thickness(0);
                     textBorder.Padding = new Thickness(0);
                     textBorder.BorderBrush = new SolidColorBrush(borderColor);
                     textBorder.BorderBrush = new SolidColorBrush(borderColor);
-                    textBorder.BorderThickness = new Thickness(DpiHelper.PDFNumToStandardNum(annotFreeText.GetBorderWidth() * zoomFactor));
+                    double rawWidth = annotFreeText.GetBorderWidth();
+                    double drawWidth = DpiHelper.PDFNumToStandardNum(rawWidth * zoomFactor);
+                    textBorder.BorderThickness = new Thickness(drawWidth);
+                    if (annotFreeText.BorderStyle != C_BORDER_STYLE.BS_SOLID && annotFreeText.Dash != null && annotFreeText.Dash.Length > 0)
+                    {
+                        //补充保存虚线样式
+                        DoubleCollection dashCollection = new DoubleCollection();
+                        foreach (float num in annotFreeText.Dash)
+                        {
+                            dashCollection.Add(num);
+                        }
+                        textBorder?.DrawDashBorder(true, drawWidth,rawWidth, dashCollection);
+                    }
+
                     textui.BorderThickness = new Thickness(0);
                     textui.BorderThickness = new Thickness(0);
                     textui.Text = annotFreeText.Content;
                     textui.Text = annotFreeText.Content;
 
 
-                    string fontName = string.Empty;
-                    string fontFamily = string.Empty;
-                    CPDFFont.GetFamilyStyleName(annotFreeText.FreeTextDa.FontName, ref fontFamily, ref fontName);
-                    textui.FontFamily = new FontFamily(fontFamily);
+                    //string fontName = string.Empty;
+                    //string fontFamily = string.Empty;
+                    //CPDFFont.GetFamilyStyleName(annotFreeText.FreeTextDa.FontName, ref fontFamily, ref fontName);
+                    textui.FontFamily = new FontFamily(annotFreeText.FreeTextDa.FontName + ",Microsoft YaHei");
 
 
                     textui.AcceptsReturn = true;
                     textui.AcceptsReturn = true;
                     textui.TextWrapping = TextWrapping.Wrap;
                     textui.TextWrapping = TextWrapping.Wrap;
@@ -1746,15 +1776,28 @@ namespace ComPDFKit.Tool.DrawTool
                     lastTextui.Background = new SolidColorBrush(backgroundColor);
                     lastTextui.Background = new SolidColorBrush(backgroundColor);
                     lastTextBorder.Padding = new Thickness(0);
                     lastTextBorder.Padding = new Thickness(0);
                     lastTextBorder.BorderBrush = new SolidColorBrush(borderColor);
                     lastTextBorder.BorderBrush = new SolidColorBrush(borderColor);
-                    lastTextBorder.BorderThickness = new Thickness(DpiHelper.PDFNumToStandardNum(annotFreeText.GetBorderWidth() * zoomFactor));
+                    double rawWidth = annotFreeText.GetBorderWidth();
+                    double drawWidth = DpiHelper.PDFNumToStandardNum(rawWidth * zoomFactor);
+                    lastTextBorder.BorderThickness = new Thickness(drawWidth);
                     lastTextui.BorderThickness = new Thickness(0);
                     lastTextui.BorderThickness = new Thickness(0);
                     lastTextui.Text = annotFreeText.Content;
                     lastTextui.Text = annotFreeText.Content;
                     lastTextui.Opacity = annotFreeText.Transparency;
                     lastTextui.Opacity = annotFreeText.Transparency;
+                    if (annotFreeText.BorderStyle != C_BORDER_STYLE.BS_SOLID && annotFreeText.Dash != null && annotFreeText.Dash.Length > 0)
+                    {
+                        //补充保存虚线样式
+                        DashedBorder dashBorder = (DashedBorder)lastTextBorder;
+                        DoubleCollection dashCollection = new DoubleCollection();
+                        foreach (float num in annotFreeText.Dash)
+                        {
+                            dashCollection.Add(num);
+                        }
+                        dashBorder.DrawDashBorder(true, drawWidth,rawWidth, dashCollection);
+                    }
 
 
-                    string fontName = string.Empty;
-                    string fontFamily = string.Empty;
-                    CPDFFont.GetFamilyStyleName(annotFreeText.FreeTextDa.FontName, ref fontFamily, ref fontName);
-                    lastTextui.FontFamily = new FontFamily(fontFamily);
+                    //string fontName = string.Empty;
+                    //string fontFamily = string.Empty;
+                    //CPDFFont.GetFamilyStyleName(annotFreeText.FreeTextDa.FontName, ref fontFamily, ref fontName);
+                    lastTextui.FontFamily = new FontFamily(annotFreeText.FreeTextDa.FontName + ",Microsoft YaHei");
 
 
                     lastTextui.FontWeight = IsBold(textAttribute.FontName) ? FontWeights.Bold : FontWeights.Normal;
                     lastTextui.FontWeight = IsBold(textAttribute.FontName) ? FontWeights.Bold : FontWeights.Normal;
                     lastTextui.FontStyle = IsItalic(textAttribute.FontName) ? FontStyles.Italic : FontStyles.Normal;
                     lastTextui.FontStyle = IsItalic(textAttribute.FontName) ? FontStyles.Italic : FontStyles.Normal;

+ 16 - 1
Demo/Examples/ComPDFKit.Tool/DrawTool/CreateCustomizeTool.cs

@@ -67,6 +67,7 @@ namespace ComPDFKit.Tool.DrawTool
         /// Standard DPI rectangle (without removing half of the pen thickness)
         /// Standard DPI rectangle (without removing half of the pen thickness)
         /// </summary>
         /// </summary>
         protected Rect DPIRect { get; set; }
         protected Rect DPIRect { get; set; }
+        internal int ErasePageIndex {  get; set; }
         public SolidColorBrush FillBrush;
         public SolidColorBrush FillBrush;
         public Pen DrawPen;
         public Pen DrawPen;
         public event EventHandler<List<AnnotParam>> DeleteChanged;
         public event EventHandler<List<AnnotParam>> DeleteChanged;
@@ -272,8 +273,18 @@ namespace ComPDFKit.Tool.DrawTool
             GroupHistory historyGroup=new GroupHistory();
             GroupHistory historyGroup=new GroupHistory();
             CPDFDocument pdfDoc = PDFViewer?.GetDocument();
             CPDFDocument pdfDoc = PDFViewer?.GetDocument();
             List<AnnotParam> paramList = new List<AnnotParam>();
             List<AnnotParam> paramList = new List<AnnotParam>();
+            List<AnnotParam> paramNewList = new List<AnnotParam>();
+
+            PDFViewer.GetPointPageInfo(mouseEndPoint, out int index, out Rect checkpaintRect, out Rect checkpageBound);
+         
             foreach (var item in annotControlList)
             foreach (var item in annotControlList)
             {
             {
+                AnnotData coreAnnotData = item.GetAnnotData();
+
+                if (coreAnnotData == null || coreAnnotData.PageIndex != ErasePageIndex)
+                {
+                    continue;
+                }
                 InkAnnot ink = item as InkAnnot;
                 InkAnnot ink = item as InkAnnot;
                 int Tag = ErasePoint(ink, eraseRect);
                 int Tag = ErasePoint(ink, eraseRect);
                 if (Tag == 1)
                 if (Tag == 1)
@@ -281,9 +292,11 @@ namespace ComPDFKit.Tool.DrawTool
                     CPDFAnnotation delAnnot = item.GetAnnotData().Annot;
                     CPDFAnnotation delAnnot = item.GetAnnotData().Annot;
                     AnnotHistory annotHistory = ParamConverter.CreateHistory(delAnnot);
                     AnnotHistory annotHistory = ParamConverter.CreateHistory(delAnnot);
                     AnnotParam annotParam = null;
                     AnnotParam annotParam = null;
+                    AnnotParam annotNewParam = null; 
                     if (pdfDoc != null)
                     if (pdfDoc != null)
                     {
                     {
                         annotParam = ParamConverter.CPDFDataConverterToAnnotParam(pdfDoc, delAnnot.Page.PageIndex, delAnnot);
                         annotParam = ParamConverter.CPDFDataConverterToAnnotParam(pdfDoc, delAnnot.Page.PageIndex, delAnnot);
+                        annotNewParam= ParamConverter.CPDFDataConverterToAnnotParam(pdfDoc, delAnnot.Page.PageIndex, delAnnot);
                         annotHistory.CurrentParam = annotParam;
                         annotHistory.CurrentParam = annotParam;
                         annotHistory.Action=HistoryAction.Remove;
                         annotHistory.Action=HistoryAction.Remove;
                         annotHistory.PDFDoc=pdfDoc;
                         annotHistory.PDFDoc=pdfDoc;
@@ -295,6 +308,8 @@ namespace ComPDFKit.Tool.DrawTool
                         if(annotParam != null)
                         if(annotParam != null)
                         {
                         {
                             paramList.Add(annotParam);
                             paramList.Add(annotParam);
+                            
+                            paramNewList.Add(annotNewParam);
                         }
                         }
                         historyGroup.Histories.Add(annotHistory);
                         historyGroup.Histories.Add(annotHistory);
                     }
                     }
@@ -307,7 +322,7 @@ namespace ComPDFKit.Tool.DrawTool
             }
             }
             if(paramList.Count > 0)
             if(paramList.Count > 0)
             {
             {
-                DeleteChanged?.Invoke(this, paramList);
+                DeleteChanged?.Invoke(this, paramNewList);
             }
             }
         }
         }
     }
     }

+ 47 - 0
Demo/Examples/ComPDFKit.Tool/DrawTool/DashBorder.cs

@@ -0,0 +1,47 @@
+using ComPDFKitViewer.Annot;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Media;
+using System.Windows.Shapes;
+
+namespace ComPDFKit.Tool.DrawTool
+{
+    internal class DashedBorder : Border
+    {
+        private bool DrawDash {  get; set; }
+        private double DashThickness {  get; set; }
+        private double DashWidth { get; set; }
+        private DoubleCollection DashArray { get; set; }
+        protected override void OnRender(DrawingContext dc)
+        {
+            if (DrawDash)
+            {
+                Pen dashPen = new Pen(BorderBrush, DashThickness);
+                dashPen.DashCap = PenLineCap.Flat;
+                DashStyle dash = new DashStyle();
+                foreach (double offset in DashArray)
+                {
+                    dash.Dashes.Add(offset / DashWidth);
+                }
+                dashPen.DashStyle = dash;
+                dc.DrawRectangle(null, dashPen, new Rect(0, 0, ActualWidth, ActualHeight));
+                return;
+            }
+            base.OnRender(dc);
+        }
+        public void DrawDashBorder(bool isDash,double dashWidth,double rawWidth, DoubleCollection dashArray)
+        {
+            DrawDash = isDash;
+            DashArray = dashArray;
+            DashThickness=dashWidth;
+            DashWidth=rawWidth;
+            InvalidateVisual();
+        }
+    }
+}

+ 450 - 0
Demo/Examples/ComPDFKit.Tool/DrawTool/FrameSelectTool.cs

@@ -0,0 +1,450 @@
+using ComPDFKit.Import;
+using ComPDFKit.Measure;
+using ComPDFKit.PDFAnnotation;
+using ComPDFKit.PDFDocument;
+using ComPDFKit.PDFPage;
+using ComPDFKit.Tool.Help;
+using ComPDFKit.Tool.SettingParam;
+using ComPDFKit.Tool.UndoManger;
+using ComPDFKit.Viewer.Helper;
+using ComPDFKit.Viewer.Layer;
+using ComPDFKitViewer;
+using ComPDFKitViewer.Annot;
+using ComPDFKitViewer.BaseObject;
+using ComPDFKitViewer.Helper;
+using ComPDFKitViewer.Layer;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Annotations;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Media.Media3D;
+using static ComPDFKit.PDFAnnotation.CTextAttribute.CFontNameHelper;
+using static ComPDFKit.Tool.Help.ImportWin32;
+
+namespace ComPDFKit.Tool.DrawTool
+{
+    internal class FrameSelectTool : CustomizeLayer
+    {
+
+        #region Attributes
+
+        /// <summary>
+        /// Indicates whether proportional scaling is required
+        /// </summary>
+        protected bool isProportionalScaling { get; set; } = false;
+
+        /// <summary>
+        /// Mouse start point
+        /// </summary>
+        protected Point mouseStartPoint { get; set; }
+
+        /// <summary>
+        /// Mouse end point
+        /// </summary>
+        protected Point mouseEndPoint { get; set; }
+
+        /// <summary>
+        /// Crop point
+        /// </summary>
+        protected Point cropPoint { get; set; }
+
+        /// <summary>
+        ///Is drawing annotation
+        /// </summary>
+        protected bool isFrameSelect { get; set; }
+
+        /// <summary>   
+        /// Current zoom factor
+        /// </summary>
+        private double zoomFactor { get; set; } = 1;
+
+        /// <summary>
+        /// Draw rectangle
+        /// </summary>
+        protected Rect drawRect { get; set; } = new Rect();
+
+        /// <summary> 
+        /// The rectangle representing the maximum drawing area
+        /// </summary>
+        protected Rect maxRect { get; set; }
+
+        /// <summary> 
+        /// The rectangle representing the original page range (calculated offset in continuous mode)
+        /// </summary>
+        protected Rect pageBound { get; set; }
+
+        /// <summary>
+        /// The rectangle at standard DPI (without subtracting half of the pen thickness)
+        /// </summary>
+        protected Rect DPIRect { get; set; }
+
+        /// <summary>
+        /// The offset value during movement
+        /// </summary>
+        protected Point moveOffset { get; set; } = new Point(0, 0);
+
+        /// <summary>
+        /// The offset value during movement
+        /// </summary>
+        protected int pageIndex { get; set; } = -1;
+
+        protected DrawingContext drawDC { get; set; }
+
+        /// <summary>
+        /// The collection of points measured for annotation drawing
+        /// </summary>
+        protected PointCollection drawPoints { get; set; } = new PointCollection();
+
+        protected double textPadding { get; set; } = 10;
+
+        protected Border lastTextBorder;
+
+        #endregion
+
+        public FrameSelectTool()
+        {
+        }
+
+        public Point GetStartPoint()
+        {
+            return DpiHelper.StandardPointToPDFPoint(new Point((mouseStartPoint.X - pageBound.X + (cropPoint.X * zoomFactor)) / zoomFactor, (mouseStartPoint.Y - pageBound.Y + (cropPoint.Y * zoomFactor)) / zoomFactor));
+        }
+
+        public Point GetEndPoint()
+        {
+            if (moveOffset == new Point())
+            {
+                return new Point(-1, -1);
+            }
+            else
+            {
+                return DpiHelper.StandardPointToPDFPoint(new Point((mouseEndPoint.X - pageBound.X + (cropPoint.X * zoomFactor)) / zoomFactor, (mouseEndPoint.Y - pageBound.Y + (cropPoint.Y * zoomFactor)) / zoomFactor));
+            }
+        }
+
+        public double GetMoveLength()
+        {
+            if (mouseEndPoint == new Point())
+            {
+                return 0;
+            }
+            Point checkPoint = mouseEndPoint;
+            checkPoint.X = Math.Max(pageBound.Left, checkPoint.X);
+            checkPoint.X = Math.Min(pageBound.Right, checkPoint.X);
+            checkPoint.Y = Math.Max(pageBound.Top, checkPoint.Y);
+            checkPoint.Y = Math.Min(pageBound.Bottom, checkPoint.Y);
+
+            Vector moveOffset = checkPoint - mouseStartPoint;
+            return moveOffset.Length;
+        }
+
+        public void SetIsProportionalScaling(bool isOpen)
+        {
+            isProportionalScaling = isOpen;
+        }
+
+        #region Draw
+        public void StartDraw(Point downPoint, Rect maxRect, Rect pageBound, double zoom, int pageindex)
+        {
+            this.pageBound = pageBound;
+            pageIndex = pageindex;
+            isFrameSelect = true;
+            drawRect = new Rect();
+            DPIRect = new Rect();
+            mouseStartPoint = downPoint;
+            isFrameSelect = true;
+            this.maxRect = maxRect;
+            zoomFactor = zoom;
+            moveOffset = new Point();
+            DPIRect = new Rect();
+        }
+        bool noDraw=false;
+        public void MoveDraw(Point downPoint, double zoom)
+        {
+            if (isFrameSelect)
+            {
+                noDraw = true;
+                moveOffset = new Point(
+                    mouseEndPoint.X - downPoint.X,
+                    mouseEndPoint.Y - downPoint.Y
+                    );
+                mouseEndPoint = downPoint;
+                zoomFactor = zoom;
+                Draw();
+            }
+            noDraw = false;
+        }
+
+        public Rect EndDraw(ref int index)
+        {
+            if (noDraw && isFrameSelect)
+            {
+                new Rect();
+            }
+            if (!DPIRect.Equals(new Rect()))
+            {
+                Rect StandardRect = new Rect(
+                    (DPIRect.Left - pageBound.X + (cropPoint.X * zoomFactor)) / zoomFactor, (DPIRect.Top - pageBound.Y + (cropPoint.Y * zoomFactor)) / zoomFactor,
+                    DPIRect.Width / zoomFactor, DPIRect.Height / zoomFactor);
+                isFrameSelect = false;
+                noDraw = false;
+                mouseStartPoint = new Point();
+                mouseEndPoint = new Point();
+                moveOffset = new Point();
+                pageBound = new Rect();
+                DPIRect = new Rect();
+                drawPoints.Clear();
+                ClearDraw();
+                index = pageIndex;
+                return DpiHelper.StandardRectToPDFRect(StandardRect);
+            }
+            isFrameSelect = false;
+            noDraw = false;
+            return new Rect();
+        }
+
+        public override void Draw()
+        {
+            if (noDraw&& isFrameSelect)
+            {
+                Dispatcher.Invoke(() =>
+            {
+
+                drawDC = Open();
+                DrawSquare(drawDC);
+                Present();
+            });
+            }
+        }
+
+        public virtual void ClearDraw()
+        {
+            Open();
+            Present();
+        }
+
+        private void DrawSquare(DrawingContext drawingContext)
+        {
+            try
+            {
+                Pen DrawPen = new Pen(new SolidColorBrush(Color.FromRgb(71, 126, 222)), 2);
+
+                SolidColorBrush FillBrush = new SolidColorBrush(Colors.Transparent);
+                FillBrush = new SolidColorBrush(Color.FromArgb(0, 255, 255, 255));
+
+                if (isProportionalScaling)
+                {
+                    Point mouseOffset = (Point)(mouseStartPoint - mouseEndPoint);
+                    if (mouseOffset.X < 0)
+                    {
+                        if (mouseOffset.Y > 0)
+                        {
+                            mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseStartPoint.X - mouseEndPoint.X);
+                        }
+                        else
+                        {
+                            mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseEndPoint.X - mouseStartPoint.X);
+                        }
+                    }
+                    else
+                    {
+                        if (mouseOffset.Y > 0)
+                        {
+                            mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseEndPoint.X - mouseStartPoint.X);
+                        }
+                        else
+                        {
+                            mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseStartPoint.X - mouseEndPoint.X);
+                        }
+                    }
+                }
+
+                Rect rect = new Rect(mouseStartPoint, mouseEndPoint);
+
+                double mLeft = rect.Left;
+                double mRight = rect.Right;
+                double mUp = rect.Top;
+                double mDown = rect.Bottom;
+                if (rect.Left < maxRect.Left)
+                {
+                    mLeft = maxRect.Left;
+                }
+                if (rect.Right > maxRect.Right)
+                {
+                    mRight = maxRect.Right;
+                }
+                if (rect.Top < maxRect.Top)
+                {
+                    mUp = maxRect.Top;
+                }
+                if (rect.Bottom > maxRect.Bottom)
+                {
+                    mDown = maxRect.Bottom;
+                }
+                DPIRect = new Rect(mLeft, mUp, mRight - mLeft, mDown - mUp);
+                int halfPenWidth = (int)Math.Ceiling(DrawPen.Thickness / 2);
+                double drawWidth = DPIRect.Width - halfPenWidth * 2;
+                double drawHeight = DPIRect.Height - halfPenWidth * 2;
+                if (drawWidth > 0 && drawHeight > 0)
+                {
+                    drawRect = new Rect(
+                        (int)DPIRect.Left + halfPenWidth,
+                        (int)DPIRect.Top + halfPenWidth,
+                        (int)DPIRect.Width - halfPenWidth * 2,
+                        (int)DPIRect.Height - halfPenWidth * 2);
+                    drawingContext?.DrawRectangle(null, DrawPen, drawRect);
+                    halfPenWidth = (int)Math.Floor(DrawPen.Thickness / 2);
+                    if (drawRect.Width - halfPenWidth * 2 > 0 && drawRect.Height - halfPenWidth * 2 > 0)
+                    {
+                        Rect innerRect = new Rect(drawRect.Left + halfPenWidth, drawRect.Top + halfPenWidth, drawRect.Width - 2 * halfPenWidth, drawRect.Height - 2 * halfPenWidth);
+
+                        drawingContext?.DrawRectangle(FillBrush, null, innerRect);
+                    }
+                }
+                else
+                {
+                    drawRect = new Rect();
+                }
+            }
+            catch { }
+        }
+
+        public Rect GetMaxRect()
+        {
+            return maxRect;
+        }
+
+        /// <summary>
+        /// Use to calculate the point drawn at a fixed angle
+        /// </summary>
+        /// <param name="currentPoint">
+        /// Current point
+        /// </param>
+        /// <param name="startPoint">
+        /// Start point
+        /// </param>
+        /// <param name="pageBound">
+        /// Maximum drawing area
+        /// </param>
+        /// <returns>
+        /// Return the calculated point
+        /// </returns>
+        internal Point CalcAnglePoint(Point currentPoint, Point startPoint, Rect pageBound)
+        {
+            Vector angleVector = currentPoint - startPoint;
+            Point originPoint = new Point(startPoint.X, startPoint.Y - angleVector.Length);
+            Vector orignVector = originPoint - startPoint;
+            Rect checkRect = pageBound;
+            int angle = (int)Vector.AngleBetween(orignVector, angleVector);
+            if (angle < 0)
+            {
+                angle += 360;
+            }
+            int mod = angle % 45;
+            int quot = angle / 45;
+            Point anglePoint = currentPoint;
+
+            int rotateAngle = 0;
+            if (mod < 22)
+            {
+                Matrix rotateMatrix = new Matrix();
+                rotateAngle = quot * 45;
+                rotateMatrix.RotateAt(rotateAngle, startPoint.X, startPoint.Y);
+                anglePoint = rotateMatrix.Transform(originPoint);
+                anglePoint = new Point((int)anglePoint.X, (int)anglePoint.Y);
+            }
+            else
+            {
+                Matrix rotateMatrix = new Matrix();
+                rotateAngle = (quot + 1) * 45;
+                rotateMatrix.RotateAt(rotateAngle, startPoint.X, startPoint.Y);
+                anglePoint = rotateMatrix.Transform(originPoint);
+                anglePoint = new Point((int)anglePoint.X, (int)anglePoint.Y);
+            }
+
+
+            if (checkRect.Contains(anglePoint) == false)
+            {
+                switch (rotateAngle)
+                {
+                    case 0:
+                        {
+                            anglePoint.X = startPoint.X;
+                            anglePoint.Y = Math.Max(checkRect.Top, Math.Min(anglePoint.Y, startPoint.Y));
+                        }
+                        break;
+                    case 45:
+                        {
+                            double addValue = Math.Min(anglePoint.X - startPoint.X, checkRect.Right - startPoint.X);
+                            addValue = Math.Min(addValue, startPoint.Y - checkRect.Top);
+                            anglePoint.X = startPoint.X + addValue;
+                            anglePoint.Y = startPoint.Y - addValue;
+                        }
+                        break;
+                    case 90:
+                        {
+                            anglePoint.X = startPoint.X + Math.Min(anglePoint.X - startPoint.X, checkRect.Right - startPoint.X);
+                            anglePoint.Y = startPoint.Y;
+                        }
+                        break;
+                    case 135:
+                        {
+                            double addValue = Math.Min(anglePoint.X - startPoint.X, checkRect.Right - startPoint.X);
+                            addValue = Math.Min(addValue, checkRect.Bottom - startPoint.Y);
+                            anglePoint.X = startPoint.X + addValue;
+                            anglePoint.Y = startPoint.Y + addValue;
+                        }
+                        break;
+                    case 180:
+                        {
+                            anglePoint.X = startPoint.X;
+                            anglePoint.Y = Math.Min(anglePoint.Y, checkRect.Bottom);
+                        }
+                        break;
+                    case 225:
+                        {
+                            double addValue = Math.Min(startPoint.X - anglePoint.X, startPoint.X - checkRect.Left);
+                            addValue = Math.Min(addValue, checkRect.Bottom - startPoint.Y);
+                            anglePoint.X = startPoint.X - addValue;
+                            anglePoint.Y = startPoint.Y + addValue;
+                        }
+                        break;
+                    case 270:
+                        {
+                            anglePoint.X = startPoint.X - Math.Min(startPoint.X - anglePoint.X, startPoint.X - checkRect.Left);
+                            anglePoint.Y = startPoint.Y;
+                        }
+                        break;
+                    case 315:
+                        {
+                            double addValue = Math.Min(startPoint.X - anglePoint.X, startPoint.X - checkRect.Left);
+                            addValue = Math.Min(addValue, startPoint.Y - checkRect.Top);
+                            anglePoint.X = startPoint.X - addValue;
+                            anglePoint.Y = startPoint.Y - addValue;
+                        }
+                        break;
+                    case 360:
+                        {
+                            anglePoint.X = startPoint.X;
+                            anglePoint.Y = Math.Max(checkRect.Top, Math.Min(anglePoint.Y, startPoint.Y));
+                        }
+                        break;
+                    default:
+                        break;
+                }
+            }
+            return anglePoint;
+        }
+    }
+    #endregion
+}

+ 193 - 17
Demo/Examples/ComPDFKit.Tool/DrawTool/MultiSelectedRect.cs

@@ -179,6 +179,7 @@ namespace ComPDFKit.Tool.DrawTool
         /// Array passed from outside for multiple selection
         /// Array passed from outside for multiple selection
         /// </summary>
         /// </summary>
         protected List<SelectedRect> selectedRects = new List<SelectedRect>();
         protected List<SelectedRect> selectedRects = new List<SelectedRect>();
+        protected Dictionary<SelectedRect,KeyValuePair<int,int>> RelationDict=new Dictionary<SelectedRect, KeyValuePair<int, int>>();
 
 
         protected bool isHover = false;
         protected bool isHover = false;
 
 
@@ -207,13 +208,53 @@ namespace ComPDFKit.Tool.DrawTool
         public MultiSelectedRect(DefaultDrawParam defaultDrawParam, SelectedType type) : base()
         public MultiSelectedRect(DefaultDrawParam defaultDrawParam, SelectedType type) : base()
         {
         {
             drawParam = defaultDrawParam;
             drawParam = defaultDrawParam;
-            currentDrawPointType = DrawPointType.Square;
+            currentDrawPointType = DrawPointType.Circle;
             selectedType = type;
             selectedType = type;
         }
         }
 
 
-        public void SetMulitSelectedRect(SelectedRect selectedobject)
+        public void SetMulitSelectedRect(SelectedRect selectedobject,int pageIndex,int editIndex)
         {
         {
             selectedRects.Add(selectedobject);
             selectedRects.Add(selectedobject);
+            RelationDict[selectedobject] = new KeyValuePair<int, int>(pageIndex, editIndex);
+        }
+
+        public bool GetRelationKey(SelectedRect selectedobject,out int pageIndex,out int editIndex)
+        {
+            pageIndex = -1;
+            editIndex = -1;
+            if(RelationDict!=null && RelationDict.ContainsKey(selectedobject))
+            {
+                KeyValuePair<int, int> relateData = RelationDict[selectedobject];
+                pageIndex = relateData.Key;
+                editIndex = relateData.Value;
+                return true;
+            }
+
+            return false;
+        }
+        /// <summary>
+        /// delete
+        /// </summary>
+        /// <param name="selectedobject"></param>
+        public void DelMulitSelectedRect(SelectedRect selectedobject)
+        {
+            selectedRects.Remove(selectedobject);
+            RelationDict.Remove(selectedobject);
+        }
+
+        /// <summary>
+        /// get selectedRects Index
+        /// </summary>
+        /// <param name="selectedobject"></param>
+        /// <returns></returns>
+        public int GetMulitSelectedRectIndex(SelectedRect selectedobject)
+        {
+          return selectedRects.IndexOf(selectedobject);
+        }
+
+        public List<SelectedRect> GetMulitSelectList()
+        {
+            return selectedRects==null ? new List<SelectedRect>() : selectedRects;
         }
         }
 
 
         public SelectedType GetSelectedType()
         public SelectedType GetSelectedType()
@@ -226,6 +267,7 @@ namespace ComPDFKit.Tool.DrawTool
             if (selectedType != type)
             if (selectedType != type)
             {
             {
                 selectedRects.Clear();
                 selectedRects.Clear();
+                RelationDict.Clear();
             }
             }
             selectedType = type;
             selectedType = type;
         }
         }
@@ -233,6 +275,7 @@ namespace ComPDFKit.Tool.DrawTool
         public void CleanMulitSelectedRect()
         public void CleanMulitSelectedRect()
         {
         {
             selectedRects.Clear();
             selectedRects.Clear();
+            RelationDict.Clear();
         }
         }
 
 
         public virtual void OnMouseLeftButtonDown(Point downPoint)
         public virtual void OnMouseLeftButtonDown(Point downPoint)
@@ -296,6 +339,25 @@ namespace ComPDFKit.Tool.DrawTool
             return (float)(drawRect.Height / drawDefaultRect.Height);
             return (float)(drawRect.Height / drawDefaultRect.Height);
         }
         }
 
 
+        /// <summary>
+        /// Multiple selection of movement distance
+        /// </summary>
+        /// <returns></returns>
+        public float GetChangeX()
+        {
+            return (float)(drawRect.Width - drawDefaultRect.Width);
+        }
+
+        /// <summary>
+        /// Multiple selection of movement distance
+        /// </summary>
+        /// <returns></returns>
+        public float GetChangeY()
+        {
+            return (float)(drawRect.Height - drawDefaultRect.Height);
+        }
+
+
         public void Draw()
         public void Draw()
         {
         {
             switch (currentDrawType)
             switch (currentDrawType)
@@ -311,7 +373,7 @@ namespace ComPDFKit.Tool.DrawTool
                             SolidColorBrush solidColorBrush = drawParam.SPDFEditMultiRectFillBrush;
                             SolidColorBrush solidColorBrush = drawParam.SPDFEditMultiRectFillBrush;
                             Pen pen = drawParam.SPDFEditMultiRectLinePen;
                             Pen pen = drawParam.SPDFEditMultiRectLinePen;
                             GetBrushAndPen(ref solidColorBrush, ref pen);
                             GetBrushAndPen(ref solidColorBrush, ref pen);
-                            if (selectedRects.Count > 1)
+                            if (selectedRects.Count >= 1)
                             {
                             {
                                 foreach (SelectedRect item in selectedRects)
                                 foreach (SelectedRect item in selectedRects)
                                 {
                                 {
@@ -338,7 +400,14 @@ namespace ComPDFKit.Tool.DrawTool
                                         SolidColorBrush moveBrush = drawParam.PDFEditMultiMoveBrush;
                                         SolidColorBrush moveBrush = drawParam.PDFEditMultiMoveBrush;
                                         Pen movepen = drawParam.PDFEditMultiMovePen;
                                         Pen movepen = drawParam.PDFEditMultiMovePen;
                                         GetMoveBrushAndPen(ref moveBrush, ref movepen);
                                         GetMoveBrushAndPen(ref moveBrush, ref movepen);
-                                        DrawMoveBounds(drawDC, hitControlType, movepen, moveBrush, drawRect);
+                                        if (selectedType == SelectedType.PDFEdit)
+                                        {
+                                            DrawMoveBounds(drawDC, hitControlType, movepen, moveBrush, drawRect, drawParam.PDFEditMultiMoveRectPen);
+                                        }
+                                        else
+                                        {
+                                            DrawMoveBounds(drawDC, hitControlType, movepen, moveBrush, drawRect);
+                                        }
                                     }
                                     }
                                     drawDC?.DrawRectangle(solidColorBrush, pen, drawDefaultRect);
                                     drawDC?.DrawRectangle(solidColorBrush, pen, drawDefaultRect);
                                     break;
                                     break;
@@ -349,7 +418,15 @@ namespace ComPDFKit.Tool.DrawTool
                             switch (currentDrawPointType)
                             switch (currentDrawPointType)
                             {
                             {
                                 case DrawPointType.Circle:
                                 case DrawPointType.Circle:
-                                    DrawCirclePoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);
+                                    if (selectedType == SelectedType.PDFEdit)
+                                    {
+                                        //Edit Settings Frame
+                                        DrawCirclePoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);
+                                    }
+                                    else
+                                    {
+                                        DrawCirclePoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);
+                                    }
                                     break;
                                     break;
                                 case DrawPointType.Square:
                                 case DrawPointType.Square:
                                     DrawSquarePoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);
                                     DrawSquarePoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);
@@ -579,7 +656,7 @@ namespace ComPDFKit.Tool.DrawTool
         /// <param name="moveRect">
         /// <param name="moveRect">
         /// Move rectangle
         /// Move rectangle
         /// </param>
         /// </param>
-        protected void DrawMoveBounds(DrawingContext drawDc, PointControlType controltype, Pen activePen, Brush moveBrush, Rect moveRect)
+        protected void DrawMoveBounds(DrawingContext drawDc, PointControlType controltype, Pen activePen, Brush moveBrush, Rect moveRect, Pen RectPen = null)
         {
         {
             switch (controltype)
             switch (controltype)
             {
             {
@@ -615,15 +692,20 @@ namespace ComPDFKit.Tool.DrawTool
                     break;
                     break;
                 case PointControlType.Body:
                 case PointControlType.Body:
                 case PointControlType.Line:
                 case PointControlType.Line:
-                    drawDc?.DrawLine(activePen, new Point(0, moveRect.Top), new Point(PDFViewerActualWidth, moveRect.Top));
-                    drawDc?.DrawLine(activePen, new Point(0, moveRect.Bottom), new Point(PDFViewerActualWidth, moveRect.Bottom));
-                    drawDc?.DrawLine(activePen, new Point(moveRect.Left, 0), new Point(moveRect.Left, PDFViewerActualHeight));
-                    drawDc?.DrawLine(activePen, new Point(moveRect.Right, 0), new Point(moveRect.Right, PDFViewerActualHeight));
+                    drawDc?.DrawLine(activePen, new Point(0, moveRect.Top), new Point(moveRect.Left, moveRect.Top));
+                    drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Top), new Point(PDFViewerActualWidth, moveRect.Top));
+                    drawDc?.DrawLine(activePen, new Point(moveRect.Left, moveRect.Top), new Point(moveRect.Left, 0));
+                    drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Top), new Point(moveRect.Right, 0));
+
+                    drawDc?.DrawLine(activePen, new Point(0, moveRect.Bottom), new Point(moveRect.Left, moveRect.Bottom));
+                    drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Bottom), new Point(PDFViewerActualWidth, moveRect.Bottom));
+                    drawDc?.DrawLine(activePen, new Point(moveRect.Left, moveRect.Bottom), new Point(moveRect.Left, PDFViewerActualHeight));
+                    drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Bottom), new Point(moveRect.Right, PDFViewerActualHeight));
                     break;
                     break;
                 default:
                 default:
                     break;
                     break;
             }
             }
-            drawDc?.DrawRectangle(moveBrush, null, moveRect);
+            drawDc?.DrawRectangle(moveBrush, RectPen, moveRect);
         }
         }
 
 
         public virtual void ClearDraw()
         public virtual void ClearDraw()
@@ -1177,7 +1259,60 @@ namespace ComPDFKit.Tool.DrawTool
                     switch (currentDrawPointType)
                     switch (currentDrawPointType)
                     {
                     {
                         case DrawPointType.Circle:
                         case DrawPointType.Circle:
+                            if (IgnorePointsList.Contains(checkPoint))
+                            {
+                                continue;
+                            }
                             Vector checkVector = checkPoint - point;
                             Vector checkVector = checkPoint - point;
+                            double wlen = drawRect.Width;
+                            if (wlen > 50)
+                            {
+                                wlen = 20;
+                            }
+                            else
+                            {
+                                wlen = wlen / 3;
+                            }
+                            double hlen = drawRect.Height;
+                            if (hlen > 50)
+                            {
+                                hlen = 20;
+                            }
+                            else
+                            {
+                                hlen = wlen / 3;
+                            }
+                            if ((PointControlType)i == PointControlType.RightMiddle)
+                            {
+
+                                if (Math.Abs(point.X - checkPoint.X) < wlen && checkVector.Length < drawRect.Height / 3)
+                                {
+                                    return (PointControlType)i;
+                                }
+                            }
+                            if ((PointControlType)i == PointControlType.LeftMiddle)
+                            {
+                                if (Math.Abs(point.X - checkPoint.X) < wlen && checkVector.Length < drawRect.Height / 3)
+                                {
+                                    return (PointControlType)i;
+                                }
+                            }
+
+                            if ((PointControlType)i == PointControlType.MiddleTop)
+                            {
+                                if (Math.Abs(point.Y - checkPoint.Y) < hlen && checkVector.Length < drawRect.Width / 3)
+                                {
+                                    return (PointControlType)i;
+                                }
+                            }
+
+                            if ((PointControlType)i == PointControlType.MiddlBottom)
+                            {
+                                if (Math.Abs(point.Y - checkPoint.Y) < hlen && checkVector.Length < drawRect.Width / 3)
+                                {
+                                    return (PointControlType)i;
+                                }
+                            }
                             if (checkVector.Length < pointSize)
                             if (checkVector.Length < pointSize)
                             {
                             {
                                 return (PointControlType)i;
                                 return (PointControlType)i;
@@ -1196,19 +1331,19 @@ namespace ComPDFKit.Tool.DrawTool
                     }
                     }
                 }
                 }
 
 
-                Rect defrect = drawDefaultRect;
+                Rect defrect = drawRect;
 
 
                 defrect.X -= rectPadding;
                 defrect.X -= rectPadding;
                 defrect.Y -= rectPadding;
                 defrect.Y -= rectPadding;
                 defrect.Width += rectPadding;
                 defrect.Width += rectPadding;
                 defrect.Height += rectPadding;
                 defrect.Height += rectPadding;
-                if (drawDefaultRect.Contains(point))
+                if (drawRect.Contains(point))
                 {
                 {
                     Rect rect = new Rect(
                     Rect rect = new Rect(
-                        Math.Max(drawDefaultRect.X + rectPadding, 0),
-                        Math.Max(drawDefaultRect.Y + rectPadding, 0),
-                        drawDefaultRect.Width - 2 * rectPadding,
-                        drawDefaultRect.Height - 2 * rectPadding);
+                        Math.Max(drawRect.X + rectPadding, 0),
+                        Math.Max(drawRect.Y + rectPadding, 0),
+                        drawRect.Width - 2 * rectPadding,
+                        drawRect.Height - 2 * rectPadding);
                     if (rect.Contains(point))
                     if (rect.Contains(point))
                     {
                     {
                         if (!ignoreList.Contains(PointControlType.Body))
                         if (!ignoreList.Contains(PointControlType.Body))
@@ -1224,5 +1359,46 @@ namespace ComPDFKit.Tool.DrawTool
             }
             }
             return PointControlType.None;
             return PointControlType.None;
         }
         }
+
+        /// <summary>
+        /// Get the rectangle where the current point is located
+        /// </summary>
+        /// <param name="clickPoint">
+        /// Coordinate point
+        /// </param>
+        /// <returns>
+        /// Control point type
+        /// </returns>
+        public SelectedRect GetHitControlRect(Point point)
+        {
+            HitTestResult hitResult = VisualTreeHelper.HitTest(this, point);
+            if (hitResult != null && hitResult.VisualHit is DrawingVisual)
+            {
+                foreach (SelectedRect selectedRect in selectedRects) {
+                    Rect defrect = selectedRect.GetRect();
+                    defrect.X -= rectPadding;
+                    defrect.Y -= rectPadding;
+                    defrect.Width += rectPadding;
+                    defrect.Height += rectPadding;
+
+                    if (defrect.Contains(point))
+                    {
+                        Rect rect = new Rect(
+                            Math.Max(defrect.X + rectPadding, 0),
+                            Math.Max(defrect.Y + rectPadding, 0),
+                            defrect.Width - 2 * rectPadding,
+                            defrect.Height - 2 * rectPadding);
+                        if (rect.Contains(point))
+                        {
+                            return selectedRect;
+                        }
+                    }
+
+                }
+
+                
+            }
+            return null;
+        }
     }
     }
 }
 }

+ 301 - 19
Demo/Examples/ComPDFKit.Tool/DrawTool/SelectedRect.cs

@@ -17,6 +17,7 @@ using System.Windows.Input;
 using System.Windows.Media;
 using System.Windows.Media;
 using System.Windows.Media.Media3D;
 using System.Windows.Media.Media3D;
 using System.Xml.Linq;
 using System.Xml.Linq;
+using static ComPDFKit.Tool.Help.ImportWin32;
 using static System.Net.Mime.MediaTypeNames;
 using static System.Net.Mime.MediaTypeNames;
 
 
 namespace ComPDFKit.Tool.DrawTool
 namespace ComPDFKit.Tool.DrawTool
@@ -75,11 +76,42 @@ namespace ComPDFKit.Tool.DrawTool
 
 
         public AnnotData annotData { get; set; }
         public AnnotData annotData { get; set; }
 
 
-        public double Angle {  get; set; }
+        public double Angle { get; set; }
     }
     }
 
 
     public partial class SelectedRect : DrawingVisual
     public partial class SelectedRect : DrawingVisual
     {
     {
+        /// <summary>
+        /// Re-layout child elements
+        /// </summary>
+        public void Arrange()
+        {
+            foreach (Visual child in Children)
+            {
+                if (!(child is UIElement))
+                {
+                    continue;
+                }
+                UIElement checkChild = child as UIElement;
+                try
+                {
+                    double left = Canvas.GetLeft(checkChild);
+                    double top = Canvas.GetTop(checkChild);
+                    double width = (double)checkChild.GetValue(FrameworkElement.WidthProperty);
+                    double height = (double)checkChild.GetValue(FrameworkElement.HeightProperty);
+                    checkChild.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
+                    checkChild.Arrange(new Rect(
+                        double.IsNaN(left) ? 0 : left,
+                        double.IsNaN(top) ? 0 : top,
+                        double.IsNaN(width) ? checkChild.DesiredSize.Width : width,
+                        double.IsNaN(height) ? checkChild.DesiredSize.Height : height));
+                }
+                catch (Exception ex)
+                {
+
+                }
+            }
+        }
         protected DefaultDrawParam DrawParam = new DefaultDrawParam();
         protected DefaultDrawParam DrawParam = new DefaultDrawParam();
 
 
         protected DrawingContext drawDC { get; set; }
         protected DrawingContext drawDC { get; set; }
@@ -99,9 +131,9 @@ namespace ComPDFKit.Tool.DrawTool
         protected bool isSelected = false;
         protected bool isSelected = false;
 
 
         protected SelectedType selectedType = SelectedType.None;
         protected SelectedType selectedType = SelectedType.None;
-        public bool CanRotate {  get; set; }
+        public bool CanRotate { get; set; }
         private double angle = 0;
         private double angle = 0;
-        private Point rotateCenter= new Point(0,0);
+        private Point rotateCenter = new Point(0, 0);
         private int rotateline = 25;
         private int rotateline = 25;
         public SelectedType GetSelectedType()
         public SelectedType GetSelectedType()
         {
         {
@@ -115,7 +147,7 @@ namespace ComPDFKit.Tool.DrawTool
 
 
         public bool GetIsHover()
         public bool GetIsHover()
         {
         {
-           return isHover;
+            return isHover;
         }
         }
 
 
         public void SetIsSelected(bool selected)
         public void SetIsSelected(bool selected)
@@ -125,7 +157,7 @@ namespace ComPDFKit.Tool.DrawTool
 
 
         public bool GetIsSelected()
         public bool GetIsSelected()
         {
         {
-           return isSelected;
+            return isSelected;
         }
         }
 
 
         public void SetCurrentDrawPointType(DrawPointType type)
         public void SetCurrentDrawPointType(DrawPointType type)
@@ -147,7 +179,15 @@ namespace ComPDFKit.Tool.DrawTool
             HitTestResult hitResult = VisualTreeHelper.HitTest(this, downPoint);
             HitTestResult hitResult = VisualTreeHelper.HitTest(this, downPoint);
             if (hitResult != null && hitResult.VisualHit is DrawingVisual)
             if (hitResult != null && hitResult.VisualHit is DrawingVisual)
             {
             {
-                hitControlType = GetHitControlIndex(downPoint);
+                //Crop judgment point
+                if (currentDrawPointType == DrawPointType.Crop)
+                {
+                    hitControlType = GetHitCropControlIndex(downPoint);
+                }
+                else
+                {
+                    hitControlType = GetHitControlIndex(downPoint);
+                }
                 if (hitControlType != PointControlType.None)
                 if (hitControlType != PointControlType.None)
                 {
                 {
                     cacheRect = drawRect;
                     cacheRect = drawRect;
@@ -235,7 +275,7 @@ namespace ComPDFKit.Tool.DrawTool
         private void DrawNormal(DrawingContext drawDC)
         private void DrawNormal(DrawingContext drawDC)
         {
         {
             Rect currentRect = SetDrawRect;
             Rect currentRect = SetDrawRect;
-           
+
             switch (currentDrawMoveType)
             switch (currentDrawMoveType)
             {
             {
                 case DrawMoveType.kDefault:
                 case DrawMoveType.kDefault:
@@ -285,12 +325,12 @@ namespace ComPDFKit.Tool.DrawTool
             {
             {
                 RotateTransform transform = new RotateTransform();
                 RotateTransform transform = new RotateTransform();
                 transform.Angle = angle;
                 transform.Angle = angle;
-               // if(hitControlType==PointControlType.Body || hitControlType==PointControlType.Line)
+                // if(hitControlType==PointControlType.Body || hitControlType==PointControlType.Line)
                 {
                 {
-                    rotateCenter.X  = drawRect.Left + drawRect.Width / 2;
+                    rotateCenter.X = drawRect.Left + drawRect.Width / 2;
                     rotateCenter.Y = drawRect.Top + drawRect.Height / 2;
                     rotateCenter.Y = drawRect.Top + drawRect.Height / 2;
                 }
                 }
-              
+
                 transform.CenterX = rotateCenter.X;
                 transform.CenterX = rotateCenter.X;
                 transform.CenterY = rotateCenter.Y;
                 transform.CenterY = rotateCenter.Y;
 
 
@@ -302,7 +342,7 @@ namespace ComPDFKit.Tool.DrawTool
         {
         {
             if (CanRotate)
             if (CanRotate)
             {
             {
-               
+
                 drawDC.Pop();
                 drawDC.Pop();
             }
             }
         }
         }
@@ -417,7 +457,7 @@ namespace ComPDFKit.Tool.DrawTool
                     if (isHover)
                     if (isHover)
                     {
                     {
                         colorBrush = DrawParam.PDFEditRectFillHoverBrush;
                         colorBrush = DrawParam.PDFEditRectFillHoverBrush;
-                        pen = DrawParam.PDFEditRectLineHoverPen;
+                        pen = editHoverPen;//DrawParam.PDFEditRectLineHoverPen;
                     }
                     }
                     else
                     else
                     {
                     {
@@ -429,7 +469,16 @@ namespace ComPDFKit.Tool.DrawTool
                         else
                         else
                         {
                         {
                             colorBrush = DrawParam.PDFEditRectFillBrush;
                             colorBrush = DrawParam.PDFEditRectFillBrush;
-                            pen = DrawParam.PDFEditRectLinePen;
+                            //init Color
+                            if (showCreatTextRect)
+                            {
+                                pen = DrawParam.PDFEditRectLinePen;
+                            }
+                            else
+                            {
+                                pen = editPen;
+                            }
+                            // editPen; //editPen;//// DrawParam.PDFEditRectLinePen; 
                         }
                         }
                     }
                     }
                     break;
                     break;
@@ -437,6 +486,31 @@ namespace ComPDFKit.Tool.DrawTool
                     break;
                     break;
             }
             }
         }
         }
+        public void SetShowCreatTextRect(bool ShowCreatTextRect)
+        {
+            showCreatTextRect = ShowCreatTextRect;
+        }
+
+        public void SetEditPen(Pen editPen = null, Pen editHoverPen = null)
+        {
+            if (editPen == null)
+            {
+                this.editPen = DrawParam.PDFEditRectLinePen;
+            }
+            else
+            {
+                this.editPen = new Pen(editPen.Brush, editPen.Thickness);
+            }
+            if (editHoverPen == null)
+            {
+                this.editHoverPen = DrawParam.PDFEditRectLineHoverPen;
+            }
+            else
+            {
+                this.editHoverPen = editHoverPen;
+            }
+        }
+
         public virtual void ClearDraw()
         public virtual void ClearDraw()
         {
         {
             SetDrawRect = drawRect = new Rect();
             SetDrawRect = drawRect = new Rect();
@@ -454,13 +528,13 @@ namespace ComPDFKit.Tool.DrawTool
             drawDC?.Close();
             drawDC?.Close();
         }
         }
 
 
-        public void SetRect(Rect newRect,double zoom)
+        public void SetRect(Rect newRect, double zoom)
         {
         {
-            if(newRect == Rect.Empty || newRect == null)
+            if (newRect == Rect.Empty || newRect == null)
             {
             {
                 return;
                 return;
             }
             }
-            newRect = new Rect((int)(newRect.X - rectPadding* zoom), (int)(newRect.Y - rectPadding* zoom),(int)( newRect.Width + 2 * rectPadding* zoom), (int)(newRect.Height + 2 * rectPadding* zoom));
+            newRect = new Rect((int)(newRect.X - rectPadding * zoom), (int)(newRect.Y - rectPadding * zoom), (int)(newRect.Width + 2 * rectPadding * zoom), (int)(newRect.Height + 2 * rectPadding * zoom));
             currentZoom = zoom;
             currentZoom = zoom;
             SetDrawRect = drawRect = newRect;
             SetDrawRect = drawRect = newRect;
             drawCenterPoint = new Point(drawRect.Left + drawRect.Width / 2, drawRect.Top + drawRect.Height / 2);
             drawCenterPoint = new Point(drawRect.Left + drawRect.Width / 2, drawRect.Top + drawRect.Height / 2);
@@ -493,6 +567,48 @@ namespace ComPDFKit.Tool.DrawTool
             return drawRect;
             return drawRect;
         }
         }
 
 
+        /// <summary>
+        /// Obtain cropped and actual region margin
+        /// </summary>
+        /// <returns></returns>
+        public Thickness GetClipThickness()
+        {
+            return clipThickness;
+        }
+
+        /// <summary>
+        /// Get ClipRect
+        /// </summary>
+        /// <returns></returns>
+        public Rect GetClipRect()
+        {
+            Rect drawrect = new Rect(0, 0, 0, 0);
+            drawrect.X = SetDrawRect.X - clipThickness.Left * currentZoom;
+            drawrect.Y = SetDrawRect.Y - clipThickness.Top * currentZoom;
+            drawrect.Width = SetDrawRect.Width - clipThickness.Right * currentZoom + clipThickness.Left * currentZoom;
+            drawrect.Height = SetDrawRect.Height - clipThickness.Bottom * currentZoom + clipThickness.Top * currentZoom;
+            return drawrect;
+        }
+
+        /// <summary>
+        /// Set cropping and actual area margins
+        /// </summary>
+        /// <returns></returns>
+        public void SetClipThickness(Thickness rect)
+        {
+            try
+            {
+                Rect drawrect = new Rect(0, 0, 0, 0);
+                drawrect.X = SetDrawRect.X - rect.Left * currentZoom;
+                drawrect.Y = SetDrawRect.Y - rect.Top * currentZoom;
+                drawrect.Width = SetDrawRect.Width - rect.Right * currentZoom + rect.Left * currentZoom;
+                drawrect.Height = SetDrawRect.Height - rect.Bottom * currentZoom + rect.Top * currentZoom;
+                drawRect = drawrect;
+                clipThickness = rect;
+            }
+            catch { }
+        }
+
         public void SetMaxRect(Rect rect)
         public void SetMaxRect(Rect rect)
         {
         {
             maxRect = rect;
             maxRect = rect;
@@ -502,6 +618,13 @@ namespace ComPDFKit.Tool.DrawTool
             return maxRect;
             return maxRect;
         }
         }
 
 
+        public void UpdateAnnotData(AnnotData annotData)
+        {
+            if (selectedRectData != null)
+            {
+                selectedRectData.annotData = annotData;
+            }
+        }
         public void SetAnnotData(AnnotData annotData)
         public void SetAnnotData(AnnotData annotData)
         {
         {
             SetIgnorePoints(new List<PointControlType>());
             SetIgnorePoints(new List<PointControlType>());
@@ -580,6 +703,33 @@ namespace ComPDFKit.Tool.DrawTool
             }
             }
         }
         }
 
 
+        /// <summary>
+        /// Set Edit that need to be ignored
+        /// </summary>
+        /// <param name="types">
+        /// The collection of point types that need to be ignored
+        /// </param>
+        public void SetEditIgnorePoints(List<PointControlType> ignoreTextPoints, List<PointControlType> ignoreImagePoints, DrawPointType drawEditPointType, bool IsText = true)
+        {
+            SetCurrentDrawPointType(drawEditPointType);
+            if (IsText)
+            {
+                ignorePoints.Clear();
+                foreach (PointControlType type in ignoreTextPoints)
+                {
+                    ignorePoints.Add(type);
+                }
+            }
+            else
+            {
+                ignorePoints.Clear();
+                foreach (PointControlType type in ignoreImagePoints)
+                {
+                    ignorePoints.Add(type);
+                }
+            }
+        }
+
         /// <summary>
         /// <summary>
         /// Ignore all points
         /// Ignore all points
         /// </summary>
         /// </summary>
@@ -685,7 +835,7 @@ namespace ComPDFKit.Tool.DrawTool
         {
         {
             if (CanRotate)
             if (CanRotate)
             {
             {
-                return GetRotateHitIndex(point,isIgnore);
+                return GetRotateHitIndex(point, isIgnore);
             }
             }
 
 
             return GetNormalHitIndex(point, isIgnore);
             return GetNormalHitIndex(point, isIgnore);
@@ -717,7 +867,60 @@ namespace ComPDFKit.Tool.DrawTool
                     switch (currentDrawPointType)
                     switch (currentDrawPointType)
                     {
                     {
                         case DrawPointType.Circle:
                         case DrawPointType.Circle:
+                            if (IgnorePointsList.Contains(checkPoint))
+                            {
+                                continue;
+                            }
                             Vector checkVector = checkPoint - point;
                             Vector checkVector = checkPoint - point;
+                            double wlen = drawRect.Width;
+                            if (wlen > 50)
+                            {
+                                wlen = 20;
+                            }
+                            else
+                            {
+                                wlen = wlen / 3;
+                            }
+                            double hlen = drawRect.Height;
+                            if (hlen > 50)
+                            {
+                                hlen = 20;
+                            }
+                            else
+                            {
+                                hlen = wlen / 3;
+                            }
+                            if ((PointControlType)i == PointControlType.RightMiddle)
+                            {
+
+                                if (Math.Abs(point.X - checkPoint.X) < wlen && checkVector.Length < drawRect.Height / 3)
+                                {
+                                    return (PointControlType)i;
+                                }
+                            }
+                            if ((PointControlType)i == PointControlType.LeftMiddle)
+                            {
+                                if (Math.Abs(point.X - checkPoint.X) < wlen && checkVector.Length < drawRect.Height / 3)
+                                {
+                                    return (PointControlType)i;
+                                }
+                            }
+
+                            if ((PointControlType)i == PointControlType.MiddleTop)
+                            {
+                                if (Math.Abs(point.Y - checkPoint.Y) < hlen && checkVector.Length < drawRect.Width / 3)
+                                {
+                                    return (PointControlType)i;
+                                }
+                            }
+
+                            if ((PointControlType)i == PointControlType.MiddlBottom)
+                            {
+                                if (Math.Abs(point.Y - checkPoint.Y) < hlen && checkVector.Length < drawRect.Width / 3)
+                                {
+                                    return (PointControlType)i;
+                                }
+                            }
                             if (checkVector.Length < pointSize)
                             if (checkVector.Length < pointSize)
                             {
                             {
                                 return (PointControlType)i;
                                 return (PointControlType)i;
@@ -743,7 +946,6 @@ namespace ComPDFKit.Tool.DrawTool
                             break;
                             break;
                     }
                     }
                 }
                 }
-
                 if (drawRect.Contains(point))
                 if (drawRect.Contains(point))
                 {
                 {
                     double rectWidth = (drawRect.Width - 2 * rectPadding > 0) ? drawRect.Width - 2 * rectPadding : 0;
                     double rectWidth = (drawRect.Width - 2 * rectPadding > 0) ? drawRect.Width - 2 * rectPadding : 0;
@@ -763,6 +965,7 @@ namespace ComPDFKit.Tool.DrawTool
                 }
                 }
             }
             }
             return PointControlType.None;
             return PointControlType.None;
+
         }
         }
 
 
         private PointControlType GetRotateHitIndex(Point point, bool isIgnore = true)
         private PointControlType GetRotateHitIndex(Point point, bool isIgnore = true)
@@ -779,7 +982,7 @@ namespace ComPDFKit.Tool.DrawTool
                 Vector transVector = matrix.Transform(currentVector);
                 Vector transVector = matrix.Transform(currentVector);
                 Point checkPos = new Point(centerPoint.X + transVector.X, centerPoint.Y + transVector.Y);
                 Point checkPos = new Point(centerPoint.X + transVector.X, centerPoint.Y + transVector.Y);
 
 
-                point= checkPos;
+                point = checkPos;
                 List<PointControlType> ignoreList = GetIgnorePoints();
                 List<PointControlType> ignoreList = GetIgnorePoints();
 
 
                 List<Point> IgnorePointsList = new List<Point>();
                 List<Point> IgnorePointsList = new List<Point>();
@@ -867,5 +1070,84 @@ namespace ComPDFKit.Tool.DrawTool
                 Draw();
                 Draw();
             }
             }
         }
         }
+        /// <summary>
+        /// The position of the points in the cropping box
+        /// </summary>
+        /// <param name="point"></param>
+        /// <param name="isIgnore"></param>
+        /// <returns></returns>
+        public PointControlType GetHitCropControlIndex(Point point, bool isIgnore = true)
+        {
+            List<Point> controlCurrentPoints = GetControlPoint(drawRect);
+            HitTestResult hitResult = VisualTreeHelper.HitTest(this, point);
+            if (hitResult != null && hitResult.VisualHit is DrawingVisual)
+            {
+                List<PointControlType> ignoreList = GetIgnorePoints();
+
+                List<Point> IgnorePointsList = new List<Point>();
+                foreach (PointControlType type in ignoreList)
+                {
+                    if ((int)type < controlCurrentPoints.Count)
+                    {
+                        IgnorePointsList.Add(controlCurrentPoints[(int)type]);
+                    }
+                }
+                for (int i = 0; i < controlCurrentPoints.Count; i++)
+                {
+                    Point checkPoint = controlCurrentPoints[i];
+
+                    if (isIgnore && IgnorePointsList.Contains(checkPoint))
+                    {
+                        continue;
+                    }
+                    switch (currentDrawPointType)
+                    {
+                        case DrawPointType.Circle:
+                            Vector checkVector = checkPoint - point;
+                            if (checkVector.Length < pointSize)
+                            {
+                                return (PointControlType)i;
+                            }
+                            break;
+                        case DrawPointType.Square:
+
+                            Rect checkRect = new Rect(Math.Max(checkPoint.X - pointSize, 0), Math.Max(checkPoint.Y - pointSize, 0), pointSize * 2, pointSize * 2);
+                            if (checkRect.Contains(point))
+                            {
+                                return (PointControlType)i;
+                            }
+                            break;
+
+                        case DrawPointType.Crop:
+                            Rect cropRect = new Rect(Math.Max(checkPoint.X - pointSize, 0), Math.Max(checkPoint.Y - pointSize, 0), pointSize * 2, pointSize * 2);
+                            if (cropRect.Contains(point))
+                            {
+                                return (PointControlType)i;
+                            }
+                            break;
+                        default:
+                            break;
+                    }
+                }
+                if (drawRect.Contains(point))
+                {
+                    double rectWidth = (drawRect.Width - 2 * rectPadding > 0) ? drawRect.Width - 2 * rectPadding : 0;
+                    double rectHeight = (drawRect.Height - 2 * rectPadding > 0) ? drawRect.Height - 2 * rectPadding : 0;
+                    Rect rect = new Rect(Math.Max(drawRect.X + rectPadding, 0), Math.Max(drawRect.Y + rectPadding, 0), rectWidth, rectHeight);
+                    if (rect.Contains(point))
+                    {
+                        if (!ignoreList.Contains(PointControlType.Body))
+                        {
+                            return PointControlType.Body;
+                        }
+                    }
+                    if (!ignoreList.Contains(PointControlType.Body))
+                    {
+                        return PointControlType.Line;
+                    }
+                }
+            }
+            return PointControlType.None;
+        }
     }
     }
 }
 }

+ 404 - 23
Demo/Examples/ComPDFKit.Tool/DrawTool/SelectedRect.protected.cs

@@ -15,7 +15,12 @@ namespace ComPDFKit.Tool.DrawTool
         /// <summary>
         /// <summary>
         /// Current control point drawing style.
         /// Current control point drawing style.
         /// </summary>
         /// </summary>
-        protected DrawPointType currentDrawPointType { get; set; }
+        protected DrawPointType currentDrawPointType
+        {
+            get;
+            set;
+        }
+
 
 
         /// <summary>
         /// <summary>
         /// Current drag drawing style.
         /// Current drag drawing style.
@@ -97,6 +102,19 @@ namespace ComPDFKit.Tool.DrawTool
         /// </summary>
         /// </summary>
         protected Point moveOffset { get; set; } = new Point(0, 0);
         protected Point moveOffset { get; set; } = new Point(0, 0);
 
 
+        /// <summary>
+        /// Current drawing rectangle (calculated during operation).
+        /// </summary>
+        protected Thickness clipThickness = new Thickness(0, 0, 0, 0);
+
+        private Pen editPen { get; set; } = new Pen(new SolidColorBrush(Color.FromRgb(71, 126, 222)), 2) { DashStyle = DashStyles.Dash };
+
+        private Pen editHoverPen { get; set; } = new Pen(new SolidColorBrush(Color.FromRgb(71, 126, 222)), 2) { DashStyle = DashStyles.Dash };
+
+        private bool showCreatTextRect = false;
+
+        protected bool isOutSideScaling = false;
+
         /// <summary>
         /// <summary>
         /// Current actual display width and height of PDFVIewer.
         /// Current actual display width and height of PDFVIewer.
         /// </summary>
         /// </summary>
@@ -140,6 +158,24 @@ namespace ComPDFKit.Tool.DrawTool
             controlPoints.Add(new Point(centerX, currentRect.Top));
             controlPoints.Add(new Point(centerX, currentRect.Top));
         }
         }
 
 
+        protected List<Point> GetControlPoint(Rect currentRect)
+        {
+            List<Point> controlCurrentPoints = new List<Point>();
+            controlCurrentPoints.Clear();
+            int centerX = (int)(currentRect.Left + currentRect.Right) / 2;
+            int centerY = (int)(currentRect.Top + currentRect.Bottom) / 2;
+
+            controlCurrentPoints.Add(new Point(currentRect.Left, currentRect.Top));
+            controlCurrentPoints.Add(new Point(currentRect.Left, centerY));
+            controlCurrentPoints.Add(new Point(currentRect.Left, currentRect.Bottom));
+            controlCurrentPoints.Add(new Point(centerX, currentRect.Bottom));
+            controlCurrentPoints.Add(new Point(currentRect.Right, currentRect.Bottom));
+            controlCurrentPoints.Add(new Point(currentRect.Right, centerY));
+            controlCurrentPoints.Add(new Point(currentRect.Right, currentRect.Top));
+            controlCurrentPoints.Add(new Point(centerX, currentRect.Top));
+            return controlCurrentPoints;
+        }
+
         /// <summary>
         /// <summary>
         /// Calcuate the offset of the current rectangle in the maximum rectangle range
         /// Calcuate the offset of the current rectangle in the maximum rectangle range
         /// </summary>
         /// </summary>
@@ -203,9 +239,22 @@ namespace ComPDFKit.Tool.DrawTool
             {
             {
                 return false;
                 return false;
             }
             }
-            return NormalScaling(mousePoint);
+            if (!isOutSideScaling)
+            {
+                return NormalScaling(mousePoint);
+            }
+            else
+            {
+                return OutSideScaling(mousePoint);
+            }
         }
         }
 
 
+        public void SetOutSideScaling(bool IsOutSideScaling)
+        {
+            isOutSideScaling = IsOutSideScaling;
+        }
+
+
         private Size GetProportionalScalingSize(double width, double height)
         private Size GetProportionalScalingSize(double width, double height)
         {
         {
             double minHeight = RectMinHeight + 2 * rectPadding * currentZoom;
             double minHeight = RectMinHeight + 2 * rectPadding * currentZoom;
@@ -852,6 +901,316 @@ namespace ComPDFKit.Tool.DrawTool
             }
             }
             return false;
             return false;
         }
         }
+        /// <summary>
+        /// Provisional logic, to be further improved, not yet used: Draw the algorithm in the form of normal scaling (drag a point, only scale in one direction).
+        /// </summary>
+        /// <param name="mousePoint">Current mouse position.</param>
+        /// <returns></returns>
+        protected bool OutSideScaling(Point mousePoint)
+        {
+            try
+            {
+                double left = 0, right = 0, top = 0, bottom = 0;
+                double minHeight = RectMinHeight + 2 * rectPadding * currentZoom;
+                double minWidth = rectMinWidth + 2 * rectPadding * currentZoom;
+
+                Point centerPoint = new Point((cacheRect.Right + cacheRect.Left) / 2, (cacheRect.Bottom + cacheRect.Top) / 2);
+                Point moveVector = (Point)(mousePoint - centerPoint);
+                moveVector = ProportionalScalingOffsetPos(moveVector);
+
+                switch (hitControlType)
+                {
+                    case PointControlType.LeftTop:
+                        {
+                            left = centerPoint.X + moveVector.X;
+                            right = cacheRect.Right;
+                            top = centerPoint.Y + moveVector.Y;
+                            bottom = cacheRect.Bottom;
+                            if (isProportionalScaling)
+                            {
+                                Size size = GetProportionalScalingSize(right - left, bottom - top);
+                                left = right - size.Width;
+                                top = bottom - size.Height;
+                                if (left < maxRect.Left)
+                                {
+                                    double tmpWidth = right - left;
+                                    left = maxRect.Left;
+                                    double width = right - left;
+                                    double height = (bottom - top) * width / tmpWidth;
+                                    top = bottom - height;
+                                }
+
+                                if (top < maxRect.Top)
+                                {
+                                    double tmpHeight = bottom - top;
+                                    top = maxRect.Top;
+                                    double height = bottom - top;
+                                    double width = (right - left) * height / tmpHeight;
+                                    left = right - width;
+                                }
+                            }
+                            else
+                            {
+                                if (left + minWidth > right)
+                                {
+                                    left = right - minWidth;
+                                }
+
+                                if (top + minHeight > bottom)
+                                {
+                                    top = bottom - minHeight;
+                                }
+                            }
+                        }
+                        break;
+
+                    case PointControlType.LeftMiddle:
+                        {
+                            left = centerPoint.X + moveVector.X;
+                            right = cacheRect.Right;
+                            top = cacheRect.Top;
+                            bottom = cacheRect.Bottom;
+                            if (left + minWidth > right)
+                            {
+                                left = right - minWidth;
+                            }
+                        }
+                        break;
+
+                    case PointControlType.LeftBottom:
+                        {
+                            left = centerPoint.X + moveVector.X;
+                            right = cacheRect.Right;
+                            top = cacheRect.Top;
+                            bottom = centerPoint.Y + moveVector.Y;
+                            if (isProportionalScaling)
+                            {
+                                Size size = GetProportionalScalingSize(right - left, bottom - top);
+                                left = right - size.Width;
+                                bottom = top + size.Height;
+                                if (left < maxRect.Left)
+                                {
+                                    double tmpWidth = right - left;
+                                    left = maxRect.Left;
+                                    double width = right - left;
+                                    double height = (bottom - top) * width / tmpWidth;
+                                    bottom = top + height;
+                                }
+
+                                if (bottom > maxRect.Bottom)
+                                {
+                                    double tmpHeight = bottom - top;
+                                    bottom = maxRect.Bottom;
+                                    double height = bottom - top;
+                                    double width = (right - left) * height / tmpHeight;
+                                    left = right - width;
+                                }
+                            }
+                            else
+                            {
+                                if (left + minWidth > right)
+                                {
+                                    left = right - minWidth;
+                                }
+
+                                if (top + minHeight > bottom)
+                                {
+                                    bottom = top + minHeight;
+                                }
+                            }
+                        }
+                        break;
+
+                    case PointControlType.MiddlBottom:
+                        {
+                            left = cacheRect.Left;
+                            right = cacheRect.Right;
+                            top = cacheRect.Top;
+                            bottom = centerPoint.Y + moveVector.Y;
+                            if (top + minHeight > bottom)
+                            {
+                                bottom = top + minHeight;
+                            }
+                        }
+                        break;
+
+                    case PointControlType.RightBottom:
+                        {
+                            left = cacheRect.Left;
+                            right = centerPoint.X + moveVector.X;
+                            top = cacheRect.Top;
+                            bottom = centerPoint.Y + moveVector.Y;
+                            if (isProportionalScaling)
+                            {
+                                Size size = GetProportionalScalingSize(right - left, bottom - top);
+                                right = left + size.Width;
+                                bottom = top + size.Height;
+                                if (right > maxRect.Right)
+                                {
+                                    double tmpWidth = right - left;
+                                    right = maxRect.Right;
+                                    double width = right - left;
+                                    double height = (bottom - top) * width / tmpWidth;
+                                    bottom = top + height;
+                                }
+
+                                if (bottom > maxRect.Bottom)
+                                {
+                                    double tmpHeight = bottom - top;
+                                    bottom = maxRect.Bottom;
+                                    double height = bottom - top;
+                                    double width = (right - left) * height / tmpHeight;
+                                    right = left + width;
+                                }
+                            }
+                            else
+                            {
+                                if (left + minWidth > right)
+                                {
+                                    right = left + minWidth;
+                                }
+
+                                if (top + minHeight > bottom)
+                                {
+                                    bottom = top + minHeight;
+                                }
+                            }
+                        }
+                        break;
+
+                    case PointControlType.RightMiddle:
+                        {
+                            left = cacheRect.Left;
+                            right = centerPoint.X + moveVector.X;
+                            top = cacheRect.Top;
+                            bottom = cacheRect.Bottom;
+                            if (left + minWidth > right)
+                            {
+                                right = left + minWidth;
+                            }
+                        }
+                        break;
+
+                    case PointControlType.RightTop:
+                        {
+                            left = cacheRect.Left;
+                            right = centerPoint.X + moveVector.X;
+                            top = centerPoint.Y + moveVector.Y;
+                            bottom = cacheRect.Bottom;
+                            if (isProportionalScaling)
+                            {
+                                Size size = GetProportionalScalingSize(right - left, bottom - top);
+                                right = left + size.Width;
+                                top = bottom - size.Height;
+                                if (right > maxRect.Right)
+                                {
+                                    double tmpWidth = right - left;
+                                    right = maxRect.Right;
+                                    double width = right - left;
+                                    double height = (bottom - top) * width / tmpWidth;
+                                    top = bottom - height;
+                                }
+
+                                if (top < maxRect.Top)
+                                {
+                                    double tmpHeight = bottom - top;
+                                    top = maxRect.Top;
+                                    double height = bottom - top;
+                                    double width = (right - left) * height / tmpHeight;
+                                    right = left + width;
+                                }
+                            }
+                            else
+                            {
+                                if (left + minWidth > right)
+                                {
+                                    right = left + minWidth;
+                                }
+
+                                if (top + minHeight > bottom)
+                                {
+                                    top = bottom - minHeight;
+                                }
+                            }
+                        }
+                        break;
+
+                    case PointControlType.MiddleTop:
+                        {
+                            left = cacheRect.Left;
+                            right = cacheRect.Right;
+                            top = centerPoint.Y + moveVector.Y;
+                            bottom = cacheRect.Bottom;
+                            if (top + minHeight > bottom)
+                            {
+                                top = bottom - minHeight;
+                            }
+                        }
+                        break;
+
+                    case PointControlType.Body:
+                    case PointControlType.Line:
+                        {
+                            double newleft = maxRect.Left - SetDrawRect.Width + 10;
+                            double newright = maxRect.Right + SetDrawRect.Width - 10;
+                            double newtop = maxRect.Top - SetDrawRect.Height + 10;
+                            double newbottom = maxRect.Bottom + SetDrawRect.Height - 10;
+                            if (newleft < 0)
+                            {
+                                newleft = 0;
+                            }
+                            Rect newMaxRect = new Rect(newleft, newtop, newright - newleft, newbottom - newtop);
+
+                            Point OffsetPos = CalcMoveBound(cacheRect, ((Point)(mousePoint - mouseDownPoint)), newMaxRect);
+                            left = cacheRect.Left + OffsetPos.X;
+                            right = cacheRect.Right + OffsetPos.X;
+                            top = cacheRect.Top + OffsetPos.Y;
+                            bottom = cacheRect.Bottom + OffsetPos.Y;
+                        }
+                        break;
+
+                    default:
+                        break;
+                }
+
+                //if (left < maxRect.Left)
+                //{
+                //    left = maxRect.Left;
+                //}
+
+                //if (top < maxRect.Top)
+                //{
+                //    top = maxRect.Top;
+                //}
+
+                if (right > maxRect.Right + SetDrawRect.Width - 10)
+                {
+                    if (left > maxRect.Right - 10)
+                    {
+                        left = maxRect.Right - 10;
+                    }
+                    right = maxRect.Right + SetDrawRect.Width - 10;
+                }
+
+                if (bottom > maxRect.Bottom + SetDrawRect.Height - 10)
+                {
+                    if (top > maxRect.Bottom - 10)
+                    {
+                        top = maxRect.Bottom - 10;
+                    }
+                    bottom = maxRect.Bottom + SetDrawRect.Height - 10;
+                }
+
+                drawRect = new Rect(left, top, right - left, bottom - top);
+                moveOffset = new Point(drawRect.X - cacheRect.X, drawRect.Y - cacheRect.Y);
+                return true;
+            }
+            catch (Exception ex)
+            {
+            }
+            return false;
+        }
+
         /// <summary>
         /// <summary>
         /// Proportional scaling offset calibration
         /// Proportional scaling offset calibration
         /// </summary>
         /// </summary>
@@ -994,60 +1353,77 @@ namespace ComPDFKit.Tool.DrawTool
 
 
         protected void DrawCropPoint(DrawingContext drawingContext, List<PointControlType> ignoreList, int PointSize, Pen PointPen, SolidColorBrush BorderBrush)
         protected void DrawCropPoint(DrawingContext drawingContext, List<PointControlType> ignoreList, int PointSize, Pen PointPen, SolidColorBrush BorderBrush)
         {
         {
-            GeometryGroup controlGroup = new GeometryGroup();
-            controlGroup.FillRule = FillRule.Nonzero;
-
+            //GeometryGroup controlGroup = new GeometryGroup();
+            //controlGroup.FillRule = FillRule.Nonzero;
+            clipThickness.Left = (SetDrawRect.Left - drawRect.Left)/currentZoom;
+            clipThickness.Top = (SetDrawRect.Top - drawRect.Top) / currentZoom;
+            clipThickness.Right = (SetDrawRect.Right - drawRect.Right) / currentZoom;
+            clipThickness.Bottom = (SetDrawRect.Bottom - drawRect.Bottom) / currentZoom;
+            List<Point> controlCurrentPoints = GetControlPoint(drawRect);
+            CombinedGeometry controlGroup = new CombinedGeometry();
+            RectangleGeometry paintGeometry = new RectangleGeometry();
+            paintGeometry.Rect = SetDrawRect;
+            controlGroup.Geometry1 = paintGeometry;
+            RectangleGeometry moveGeometry = new RectangleGeometry();
+            Rect clippedBorder = drawRect;
+            if (clippedBorder.IsEmpty == false)
+            {
+                moveGeometry.Rect = drawRect;
+            }
+            controlGroup.Geometry2 = moveGeometry;
+            controlGroup.GeometryCombineMode = GeometryCombineMode.Exclude;
             //Left Top Corner
             //Left Top Corner
             if (!ignoreList.Contains(PointControlType.LeftTop))
             if (!ignoreList.Contains(PointControlType.LeftTop))
             {
             {
-                drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlPoints[0].X - PointSize, controlPoints[0].Y - PointSize, PointSize, PointSize * 4));
-                drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlPoints[0].X - PointSize, controlPoints[0].Y - PointSize, PointSize * 4, PointSize));
+                drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[0].X - PointSize, controlCurrentPoints[0].Y - PointSize, PointSize, PointSize * 4));
+                drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[0].X - PointSize, controlCurrentPoints[0].Y - PointSize, PointSize * 4, PointSize));
             }
             }
 
 
             //Left Center
             //Left Center
             if (!ignoreList.Contains(PointControlType.LeftMiddle))
             if (!ignoreList.Contains(PointControlType.LeftMiddle))
             {
             {
-                drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlPoints[1].X - PointSize, (controlPoints[1].Y + controlPoints[1].Y - PointSize * 5) / 2, PointSize, PointSize * 5));
+                drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[1].X - PointSize, (controlCurrentPoints[1].Y + controlCurrentPoints[1].Y - PointSize * 5) / 2, PointSize, PointSize * 5));
             }
             }
 
 
             //Left Bottom Corner
             //Left Bottom Corner
             if (!ignoreList.Contains(PointControlType.LeftBottom))
             if (!ignoreList.Contains(PointControlType.LeftBottom))
             {
             {
-                drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlPoints[2].X - PointSize, controlPoints[2].Y - PointSize * 3, PointSize, PointSize * 4));
-                drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlPoints[2].X - PointSize, controlPoints[2].Y, PointSize * 4, PointSize));
+                drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[2].X - PointSize, controlCurrentPoints[2].Y - PointSize * 3, PointSize, PointSize * 4));
+                drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[2].X - PointSize, controlCurrentPoints[2].Y, PointSize * 4, PointSize));
             }
             }
 
 
             //Bottom Center
             //Bottom Center
             if (!ignoreList.Contains(PointControlType.MiddlBottom))
             if (!ignoreList.Contains(PointControlType.MiddlBottom))
             {
             {
-                drawingContext?.DrawRectangle(BorderBrush, null, new Rect((controlPoints[3].X + controlPoints[3].X - PointSize * 5) / 2, controlPoints[3].Y, PointSize * 5, PointSize));
+                drawingContext?.DrawRectangle(BorderBrush, null, new Rect((controlCurrentPoints[3].X + controlCurrentPoints[3].X - PointSize * 5) / 2, controlCurrentPoints[3].Y, PointSize * 5, PointSize));
             }
             }
 
 
             //Bottom Right Corner
             //Bottom Right Corner
             if (!ignoreList.Contains(PointControlType.RightBottom))
             if (!ignoreList.Contains(PointControlType.RightBottom))
             {
             {
-                drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlPoints[4].X, controlPoints[4].Y - PointSize * 3, PointSize, PointSize * 4));
-                drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlPoints[4].X - PointSize * 3, controlPoints[4].Y, PointSize * 4, PointSize));
+                drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[4].X, controlCurrentPoints[4].Y - PointSize * 3, PointSize, PointSize * 4));
+                drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[4].X - PointSize * 3, controlCurrentPoints[4].Y, PointSize * 4, PointSize));
             }
             }
 
 
             //Right Center
             //Right Center
             if (!ignoreList.Contains(PointControlType.RightMiddle))
             if (!ignoreList.Contains(PointControlType.RightMiddle))
             {
             {
-                drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlPoints[5].X, (controlPoints[5].Y + controlPoints[5].Y - PointSize * 5) / 2, PointSize, PointSize * 5));
+                drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[5].X, (controlCurrentPoints[5].Y + controlCurrentPoints[5].Y - PointSize * 5) / 2, PointSize, PointSize * 5));
             }
             }
 
 
             //Right Top Corner
             //Right Top Corner
             if (!ignoreList.Contains(PointControlType.RightTop))
             if (!ignoreList.Contains(PointControlType.RightTop))
             {
             {
-                drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlPoints[6].X, controlPoints[6].Y - PointSize, PointSize, PointSize * 4));
-                drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlPoints[6].X - PointSize * 4, controlPoints[6].Y - PointSize, PointSize * 4, PointSize));
+                drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[6].X, controlCurrentPoints[6].Y - PointSize, PointSize, PointSize * 4));
+                drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[6].X - PointSize * 4, controlCurrentPoints[6].Y - PointSize, PointSize * 4, PointSize));
             }
             }
 
 
             //Top Center
             //Top Center
             if (!ignoreList.Contains(PointControlType.MiddleTop))
             if (!ignoreList.Contains(PointControlType.MiddleTop))
             {
             {
-                drawingContext?.DrawRectangle(BorderBrush, null, new Rect((controlPoints[7].X + controlPoints[7].X - PointSize * 5) / 2, controlPoints[7].Y - PointSize, PointSize * 5, PointSize));
+                drawingContext?.DrawRectangle(BorderBrush, null, new Rect((controlCurrentPoints[7].X + controlCurrentPoints[7].X - PointSize * 5) / 2, controlCurrentPoints[7].Y - PointSize, PointSize * 5, PointSize));
             }
             }
+            BorderBrush = new SolidColorBrush(Color.FromArgb(0x3F, 0x00, 0x00, 0x00));
             drawingContext?.DrawGeometry(BorderBrush, PointPen, controlGroup);
             drawingContext?.DrawGeometry(BorderBrush, PointPen, controlGroup);
         }
         }
 
 
@@ -1069,7 +1445,7 @@ namespace ComPDFKit.Tool.DrawTool
         /// <param name="moveRect">
         /// <param name="moveRect">
         /// Current rectangle to draw
         /// Current rectangle to draw
         /// </param>
         /// </param>
-        protected void DrawMoveBounds(DrawingContext drawDc, PointControlType controltype, Pen activePen, Brush moveBrush, Rect moveRect)
+        protected void DrawMoveBounds(DrawingContext drawDc, PointControlType controltype, Pen activePen, Brush moveBrush, Rect moveRect, Pen RectPen = null)
         {
         {
             switch (controltype)
             switch (controltype)
             {
             {
@@ -1105,15 +1481,20 @@ namespace ComPDFKit.Tool.DrawTool
                     break;
                     break;
                 case PointControlType.Body:
                 case PointControlType.Body:
                 case PointControlType.Line:
                 case PointControlType.Line:
-                    drawDc?.DrawLine(activePen, new Point(0, moveRect.Top), new Point(PDFViewerActualWidth, moveRect.Top));
-                    drawDc?.DrawLine(activePen, new Point(0, moveRect.Bottom), new Point(PDFViewerActualWidth, moveRect.Bottom));
-                    drawDc?.DrawLine(activePen, new Point(moveRect.Left, 0), new Point(moveRect.Left, PDFViewerActualHeight));
-                    drawDc?.DrawLine(activePen, new Point(moveRect.Right, 0), new Point(moveRect.Right, PDFViewerActualHeight));
+                    drawDc?.DrawLine(activePen, new Point(0, moveRect.Top), new Point(moveRect.Left, moveRect.Top));
+                    drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Top), new Point(PDFViewerActualWidth, moveRect.Top));
+                    drawDc?.DrawLine(activePen, new Point(moveRect.Left, moveRect.Top), new Point(moveRect.Left, 0));
+                    drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Top), new Point(moveRect.Right, 0));
+
+                    drawDc?.DrawLine(activePen, new Point(0, moveRect.Bottom), new Point(moveRect.Left, moveRect.Bottom));
+                    drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Bottom), new Point(PDFViewerActualWidth, moveRect.Bottom));
+                    drawDc?.DrawLine(activePen, new Point(moveRect.Left, moveRect.Bottom), new Point(moveRect.Left, PDFViewerActualHeight));
+                    drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Bottom), new Point(moveRect.Right, PDFViewerActualHeight));
                     break;
                     break;
                 default:
                 default:
                     break;
                     break;
             }
             }
-            drawDc?.DrawRectangle(moveBrush, null, moveRect);
+            drawDc?.DrawRectangle(moveBrush, RectPen, moveRect);
         }
         }
 
 
         /// <summary>
         /// <summary>

+ 83 - 0
Demo/Examples/ComPDFKit.Tool/Help/CommonHelper.cs

@@ -5,6 +5,12 @@ using System.Text;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using System.Windows.Media;
 using System.Windows.Media;
 using System.Windows;
 using System.Windows;
+using ComPDFKitViewer;
+using System.IO;
+using System.Runtime.Remoting.Messaging;
+using System.Windows.Media.Imaging;
+using System.ComponentModel;
+using ComPDFKit.PDFAnnotation;
 
 
 namespace ComPDFKit.Tool.Help
 namespace ComPDFKit.Tool.Help
 {
 {
@@ -103,6 +109,83 @@ namespace ComPDFKit.Tool.Help
             catch { return children; }
             catch { return children; }
         }
         }
 
 
+        public static PathGeometry GetPathIcon(string iconKey)
+        {
+            string pathIcon = "M18 3H2V15H5V18L10 15H18V3ZM5 6H11V7.5H5V6ZM5 9.5H15V11H5V9.5Z";
+            try
+            {
+                TypeConverter typeCovert = TypeDescriptor.GetConverter(typeof(Geometry));
+                if (CPDFViewer.StickyIconDict != null && CPDFViewer.StickyIconDict.ContainsKey(iconKey))
+                {
+                    pathIcon = CPDFViewer.StickyIconDict[iconKey];
+                }
+
+                return PathGeometry.CreateFromGeometry((Geometry)typeCovert.ConvertFrom(pathIcon));
+            }
+            catch (Exception ex)
+            {
+
+            }
+
+            return new PathGeometry();
+        }
+
+        private static bool GetIconData(string iconName, Brush fillBrush, out string tempImagePath)
+        {
+            tempImagePath = string.Empty;
+
+            try
+            {
+                if (CPDFViewer.StickyIconDict != null && CPDFViewer.StickyIconDict.ContainsKey(iconName))
+                {
+                    PathGeometry iconGeometry = GetPathIcon(iconName);
+                    DrawingVisual iconVisual = new DrawingVisual();
+                    DrawingContext iconContext = iconVisual.RenderOpen();
+                    iconContext.DrawGeometry(fillBrush, null, iconGeometry);
+                    iconContext.Close();
+                    RenderTargetBitmap renderBitmap = new RenderTargetBitmap(32, 32, 96, 96, PixelFormats.Pbgra32);
+                    renderBitmap.Render(iconVisual);
+                    string tempPath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), Guid.NewGuid().ToString());
+
+                    PngBitmapEncoder pngEncoder = new PngBitmapEncoder();
+                    using (FileStream fs = File.Create(tempPath))
+                    {
+                        pngEncoder.Frames.Add(BitmapFrame.Create(renderBitmap));
+                        pngEncoder.Save(fs);
+                    }
+                    tempImagePath = tempPath;
+                    return true;
+                }
+            }
+            catch (Exception ex)
+            {
+
+            }
+
+            return false;
+        }
+
+        public static void UpdateStickyAP(CPDFTextAnnotation textAnnotation)
+        {
+            if(textAnnotation==null || textAnnotation.IsValid()==false)
+            {
+                return;
+            }
+            try
+            {
+                string iconName = textAnnotation.GetIconName();
+                byte opacity = textAnnotation.GetTransparency();
+                SolidColorBrush fillBrush = new SolidColorBrush(Color.FromArgb(opacity, textAnnotation.Color[0], textAnnotation.Color[1], textAnnotation.Color[2]));
 
 
+                if (GetIconData(iconName, fillBrush, out string apPath) && File.Exists(apPath))
+                {
+                    textAnnotation.UpdateApWithImage(apPath, string.Empty, textAnnotation.GetRotation());
+                    File.Delete(apPath);
+                }
+            }
+            catch (Exception ex)
+            {
+            }
+        }
     }
     }
 }
 }

+ 20 - 1
Demo/Examples/ComPDFKit.Tool/Help/PDFHelp.cs

@@ -173,7 +173,26 @@ namespace ComPDFKit.Tool.Help
                     frame.CopyPixels(imageData, frame.PixelWidth * 4, 0);
                     frame.CopyPixels(imageData, frame.PixelWidth * 4, 0);
                 }
                 }
 
 
-                imageWidth = frame.PixelWidth;
+                int stride = ((int)frame.PixelWidth) * 4;
+                for (int i = 0; i < (int)(frame.PixelHeight); i++)
+                {
+                    for (int j = 0; j < (int)(frame.PixelWidth); j++)
+                    {
+                        byte b = imageData[i * stride + j * 4];
+                        byte g = imageData[i * stride + j * 4 + 1];
+                        byte r = imageData[i * stride + j * 4 + 2];
+                        byte a = imageData[i * stride + j * 4 + 3];
+
+                        if (a == 0 && b == 0 && g == 0 && r == 0)
+                        {
+                            imageData[i * stride + j * 4] = 255;
+                            imageData[i * stride + j * 4 + 1] = 255;
+                            imageData[i * stride + j * 4 + 2] = 255;
+                            continue;
+                        }
+                    }
+                }
+                        imageWidth = frame.PixelWidth;
                 imageHeight = frame.PixelHeight;
                 imageHeight = frame.PixelHeight;
             }
             }
         }
         }

+ 87 - 9
Demo/Examples/ComPDFKit.Tool/Help/ParamConverter.cs

@@ -9,6 +9,7 @@ using ComPDFKit.PDFPage.Edit;
 using ComPDFKit.Tool.SettingParam;
 using ComPDFKit.Tool.SettingParam;
 using ComPDFKit.Tool.UndoManger;
 using ComPDFKit.Tool.UndoManger;
 using ComPDFKit.Viewer.Helper;
 using ComPDFKit.Viewer.Helper;
+using ComPDFKitViewer.Annot;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;
@@ -64,7 +65,7 @@ namespace ComPDFKit.Tool.Help
                     annotHistory = new FreeTextAnnotHistory();
                     annotHistory = new FreeTextAnnotHistory();
                     break;
                     break;
                 case C_ANNOTATION_TYPE.C_ANNOTATION_LINE:
                 case C_ANNOTATION_TYPE.C_ANNOTATION_LINE:
-                    if ((cPDFAnnotation as CPDFLineAnnotation).IsMersured())
+                    if ((cPDFAnnotation as CPDFLineAnnotation).IsMeasured())
                     {
                     {
                         annotHistory = new LineMeasureAnnotHistory();
                         annotHistory = new LineMeasureAnnotHistory();
                     }
                     }
@@ -169,6 +170,68 @@ namespace ComPDFKit.Tool.Help
             return annotHistory;
             return annotHistory;
         }
         }
 
 
+        public static AnnotHistory CreateHistory(AnnotParam annotParam)
+        {
+            if (annotParam != null)
+            {
+                switch (annotParam.CurrentType)
+                {
+                    case C_ANNOTATION_TYPE.C_ANNOTATION_HIGHLIGHT:
+                        return new HighlightAnnotHistory();
+                    case C_ANNOTATION_TYPE.C_ANNOTATION_UNDERLINE:
+                        return new UnderlineAnnotHistory();
+                    case C_ANNOTATION_TYPE.C_ANNOTATION_STRIKEOUT:
+                        return new StrikeoutAnnotHistory();
+                    case C_ANNOTATION_TYPE.C_ANNOTATION_SQUIGGLY:
+                        return new SquigglyAnnotHistory();
+                    case C_ANNOTATION_TYPE.C_ANNOTATION_INK:
+                        return new InkAnnotHistory();
+                    case C_ANNOTATION_TYPE.C_ANNOTATION_FREETEXT:
+                        return new FreeTextAnnotHistory();
+                    case C_ANNOTATION_TYPE.C_ANNOTATION_TEXT:
+                        return new StickyNoteAnnotHistory();
+                    case C_ANNOTATION_TYPE.C_ANNOTATION_SQUARE:
+                        return new SquareAnnotHistory();
+                    case C_ANNOTATION_TYPE.C_ANNOTATION_CIRCLE:
+                        return new CircleAnnotHistory();
+                    case C_ANNOTATION_TYPE.C_ANNOTATION_LINE:
+                        return new LineAnnotHistory();
+                    case C_ANNOTATION_TYPE.C_ANNOTATION_LINK:
+                        return new LinkAnnotHistory();
+                    case C_ANNOTATION_TYPE.C_ANNOTATION_STAMP:
+                        return new StampAnnotHistory();
+                    case C_ANNOTATION_TYPE.C_ANNOTATION_WIDGET:
+                        {
+                            WidgetParm widgetParam = annotParam as WidgetParm;
+                            if (widgetParam != null)
+                            {
+                                switch (widgetParam.WidgetType)
+                                {
+                                    case C_WIDGET_TYPE.WIDGET_RADIOBUTTON:
+                                        return new RadioButtonHistory();
+                                    case C_WIDGET_TYPE.WIDGET_CHECKBOX:
+                                        return new CheckBoxHistory();
+                                    case C_WIDGET_TYPE.WIDGET_TEXTFIELD:
+                                        return new TextBoxHistory();
+                                    case C_WIDGET_TYPE.WIDGET_LISTBOX:
+                                        return new ListBoxHistory();
+                                    case C_WIDGET_TYPE.WIDGET_COMBOBOX:
+                                        return new ComboBoxHistory();
+                                    case C_WIDGET_TYPE.WIDGET_PUSHBUTTON:
+                                        return new PushButtonHistory();
+                                    default:
+                                        break;
+                                }
+                            }
+                        }
+                        break;
+                    default:
+                        break;
+                }
+            }
+            return new AnnotHistory();
+        }
+
         public static bool RemovePageAnnot(Dictionary<int, List<int>> removeAnnots, CPDFDocument cPDFDocument)
         public static bool RemovePageAnnot(Dictionary<int, List<int>> removeAnnots, CPDFDocument cPDFDocument)
         {
         {
             if (cPDFDocument == null || removeAnnots.Count <= 0)
             if (cPDFDocument == null || removeAnnots.Count <= 0)
@@ -347,7 +410,7 @@ namespace ComPDFKit.Tool.Help
             bool isBold = false;
             bool isBold = false;
             bool isItalic = false;
             bool isItalic = false;
 
 
-            cPDFEditArea.GetTextStyle(ref fontName, ref fontSize, ref fontColor, ref transparency, ref isBold, ref isItalic);
+            cPDFEditArea.GetTextStyle(ref fontName,ref fontSize, ref fontColor, ref transparency, ref isBold, ref isItalic);
             textEditParam.FontName = fontName;
             textEditParam.FontName = fontName;
             textEditParam.FontSize = fontSize;
             textEditParam.FontSize = fontSize;
             textEditParam.FontColor = fontColor;
             textEditParam.FontColor = fontColor;
@@ -821,7 +884,7 @@ namespace ComPDFKit.Tool.Help
                         CPDFLineAnnotation lineAnnot = pdfAnnot as CPDFLineAnnotation;
                         CPDFLineAnnotation lineAnnot = pdfAnnot as CPDFLineAnnotation;
                         if (lineAnnot != null)
                         if (lineAnnot != null)
                         {
                         {
-                            if(lineAnnot.IsMersured())
+                            if(lineAnnot.IsMeasured())
                             {
                             {
                                 return GetLineMeasureParam(lineAnnot);
                                 return GetLineMeasureParam(lineAnnot);
                             }
                             }
@@ -932,7 +995,7 @@ namespace ComPDFKit.Tool.Help
                 case C_ANNOTATION_TYPE.C_ANNOTATION_POLYLINE:
                 case C_ANNOTATION_TYPE.C_ANNOTATION_POLYLINE:
                     {
                     {
                         CPDFPolylineAnnotation polylineAnnot= pdfAnnot as CPDFPolylineAnnotation;
                         CPDFPolylineAnnotation polylineAnnot= pdfAnnot as CPDFPolylineAnnotation;
-                        if (polylineAnnot!=null && polylineAnnot.IsMersured())
+                        if (polylineAnnot!=null && polylineAnnot.IsMeasured())
                         {
                         {
                             return GetPolyLineMeasureParam(polylineAnnot);
                             return GetPolyLineMeasureParam(polylineAnnot);
                         }
                         }
@@ -941,7 +1004,7 @@ namespace ComPDFKit.Tool.Help
                 case C_ANNOTATION_TYPE.C_ANNOTATION_POLYGON:
                 case C_ANNOTATION_TYPE.C_ANNOTATION_POLYGON:
                     {
                     {
                         CPDFPolygonAnnotation polygonAnnot= pdfAnnot as CPDFPolygonAnnotation;
                         CPDFPolygonAnnotation polygonAnnot= pdfAnnot as CPDFPolygonAnnotation;
-                        if(polygonAnnot!=null && polygonAnnot.IsMersured())
+                        if(polygonAnnot!=null && polygonAnnot.IsMeasured())
                         {
                         {
                             return GetPolygonMeasureParam(polygonAnnot);
                             return GetPolygonMeasureParam(polygonAnnot);
                         }
                         }
@@ -1231,7 +1294,7 @@ namespace ComPDFKit.Tool.Help
 
 
         internal static LineMeasureParam GetLineMeasureParam(CPDFLineAnnotation lineAnnot)
         internal static LineMeasureParam GetLineMeasureParam(CPDFLineAnnotation lineAnnot)
         {
         {
-            if (lineAnnot == null || lineAnnot.IsValid() == false || lineAnnot.IsMersured()==false)
+            if (lineAnnot == null || lineAnnot.IsValid() == false || lineAnnot.IsMeasured()==false)
             {
             {
                 return null;
                 return null;
             }
             }
@@ -1245,7 +1308,9 @@ namespace ComPDFKit.Tool.Help
             {
             {
                 measureParam.LineColor = new byte[3] { lineAnnot.LineColor[0], lineAnnot.LineColor[1], lineAnnot.LineColor[2] };
                 measureParam.LineColor = new byte[3] { lineAnnot.LineColor[0], lineAnnot.LineColor[1], lineAnnot.LineColor[2] };
             }
             }
-
+            measureParam.LeadLength=distanceMeasure.GetLeadLength();
+            measureParam.LeadExtension=distanceMeasure.GetLeadExtension();
+            measureParam.LeadOffset=distanceMeasure.GetLeadOffset();
             measureParam.BorderStyle = lineAnnot.BorderStyle;
             measureParam.BorderStyle = lineAnnot.BorderStyle;
             measureParam.LineWidth = lineAnnot.LineWidth;
             measureParam.LineWidth = lineAnnot.LineWidth;
             measureParam.Transparency = lineAnnot.Transparency;
             measureParam.Transparency = lineAnnot.Transparency;
@@ -1316,6 +1381,12 @@ namespace ComPDFKit.Tool.Help
                 }
                 }
             }
             }
 
 
+            if(inkAnnot.Dash!=null && inkAnnot.Dash.Length>0)
+            {
+                inkParam.Dash =new float[inkAnnot.Dash.Length];
+                inkAnnot.Dash.CopyTo(inkParam.Dash, 0);
+            }
+
             GetAnnotCommonParam(inkAnnot, inkParam);
             GetAnnotCommonParam(inkAnnot, inkParam);
             return inkParam;
             return inkParam;
         }
         }
@@ -1380,6 +1451,12 @@ namespace ComPDFKit.Tool.Help
                 freetextParam.Alignment = freetextAnnot.Alignment;
                 freetextParam.Alignment = freetextAnnot.Alignment;
             }
             }
 
 
+            if (freetextAnnot.Dash != null && freetextAnnot.Dash.Length > 0)
+            {
+                freetextParam.Dash = new float[freetextAnnot.Dash.Length];
+                freetextAnnot.Dash.CopyTo(freetextParam.Dash, 0);
+            }
+
             GetAnnotCommonParam(freetextAnnot, freetextParam);
             GetAnnotCommonParam(freetextAnnot, freetextParam);
             return freetextParam;
             return freetextParam;
         }
         }
@@ -1539,6 +1616,7 @@ namespace ComPDFKit.Tool.Help
                 };
                 };
             }
             }
 
 
+            stickyParam.IconName=stickyAnnot.GetIconName();
             GetAnnotCommonParam(stickyAnnot, stickyParam);
             GetAnnotCommonParam(stickyAnnot, stickyParam);
 
 
             return stickyParam;
             return stickyParam;
@@ -1732,7 +1810,7 @@ namespace ComPDFKit.Tool.Help
 
 
         internal static PolyLineMeasureParam GetPolyLineMeasureParam(CPDFPolylineAnnotation polylineAnnot)
         internal static PolyLineMeasureParam GetPolyLineMeasureParam(CPDFPolylineAnnotation polylineAnnot)
         {
         {
-            if (polylineAnnot == null || polylineAnnot.IsValid() == false || polylineAnnot.IsMersured()==false)
+            if (polylineAnnot == null || polylineAnnot.IsValid() == false || polylineAnnot.IsMeasured()==false)
             {
             {
                 return null;
                 return null;
             }
             }
@@ -1766,7 +1844,7 @@ namespace ComPDFKit.Tool.Help
 
 
         internal static PolygonMeasureParam GetPolygonMeasureParam(CPDFPolygonAnnotation polygonAnnot)
         internal static PolygonMeasureParam GetPolygonMeasureParam(CPDFPolygonAnnotation polygonAnnot)
         {
         {
-            if (polygonAnnot == null || polygonAnnot.IsValid() == false || polygonAnnot.IsMersured() == false)
+            if (polygonAnnot == null || polygonAnnot.IsValid() == false || polygonAnnot.IsMeasured() == false)
             {
             {
                 return null;
                 return null;
             }
             }

+ 70 - 81
Demo/Examples/ComPDFKit.Tool/PDFTextSearch.cs

@@ -5,11 +5,8 @@ using ComPDFKit.PDFPage;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Diagnostics;
-using System.Linq;
-using System.Text;
 using System.Text.RegularExpressions;
 using System.Text.RegularExpressions;
 using System.Threading;
 using System.Threading;
-using System.Threading.Tasks;
 using System.Windows.Media;
 using System.Windows.Media;
 using System.Windows;
 using System.Windows;
 
 
@@ -150,104 +147,96 @@ namespace ComPDFKit.Tool
             searchResult.StartPage = startPage;
             searchResult.StartPage = startPage;
             searchResult.EndPage = endPage;
             searchResult.EndPage = endPage;
             double searchPercent = 100;
             double searchPercent = 100;
-            try
-            {
 
 
-                mSearchDocument = CPDFDocument.InitWithFilePath(TextSearchDocument.FilePath);
-                if (password != null && password != string.Empty)
-                {
-                    mSearchDocument.UnlockWithPassword(password);
-                }
-                password = string.Empty;
-            }
-            catch (Exception ex)
+            mSearchDocument = CPDFDocument.InitWithFilePath(TextSearchDocument.FilePath);
+            if (mSearchDocument.IsLocked && !string.IsNullOrEmpty(password))
             {
             {
-
+                mSearchDocument.UnlockWithPassword(password);
             }
             }
-            if (mSearchDocument != null)
+
+            if (mSearchDocument != null && !mSearchDocument.IsLocked)
             {
             {
-                try
+                int pageMaxCount = 0;
+                int recordCount = 0;
+                searchPercent = 0;
+                for (int i = startPage; i <= endPage; i++)
                 {
                 {
-                    int pageMaxCount = 0;
-                    int recordCount = 0;
-                    searchPercent = 0;
-                    for (int i = startPage; i <= endPage; i++)
+                    CPDFTextSearcher mPDFTextSearcher = new CPDFTextSearcher();
+                    CPDFPage pageCore = mSearchDocument.PageAtIndex(i);
+                    if(pageCore == null)
                     {
                     {
-                        CPDFTextSearcher mPDFTextSearcher = new CPDFTextSearcher();
-                        CPDFPage pageCore = mSearchDocument.PageAtIndex(i);
-                        CPDFTextPage textPage = pageCore.GetTextPage();
-                        int startIndex = 0;
+                        continue;
+                    }   
 
 
-                        List<TextSearchItem> textSearchItems = new List<TextSearchItem>();
-                        if (mPDFTextSearcher.FindStart(textPage, searchKeywords, searchOption, startIndex))
+                    CPDFTextPage textPage = pageCore.GetTextPage();
+                    int startIndex = 0;
+                    List<TextSearchItem> textSearchItems = new List<TextSearchItem>();
+                    if (mPDFTextSearcher.FindStart(textPage, searchKeywords, searchOption, startIndex))
+                    {
+                        CRect textRect = new CRect();
+                        string textContent = "";
+                        while (mPDFTextSearcher.FindNext(pageCore, textPage, ref textRect, ref textContent, ref startIndex))
                         {
                         {
-                            CRect textRect = new CRect();
-                            string textContent = "";
-                            while (mPDFTextSearcher.FindNext(pageCore, textPage, ref textRect, ref textContent, ref startIndex))
+                            if (textContent == "")
                             {
                             {
-                                if (textContent == "")
-                                {
-                                    textContent = searchKeywords;
-                                }
-                                textSearchItems.Add(new TextSearchItem()
-                                {
-                                    PageIndex = i,
-                                    TextRect = new Rect(textRect.left, textRect.top, textRect.width(), textRect.height()),
-                                    TextContent = textContent,
-                                    PageRotate = pageCore.Rotation
-                                });
-                                var matchResult = Regex.Matches(textContent, searchKeywords, RegexOptions.IgnoreCase);
-                                if (matchResult != null)
-                                {
-                                    recordCount += matchResult.Count;
-                                }
+                                textContent = searchKeywords;
+                            }
+
+                            textSearchItems.Add(new TextSearchItem()
+                            {
+                                PageIndex = i,
+                                TextRect = new Rect(textRect.left, textRect.top, textRect.width(), textRect.height()),
+                                TextContent = textContent,
+                                PageRotate = pageCore.Rotation
+                            });
+
+                            var matchResult = Regex.Matches(textContent, searchKeywords, RegexOptions.IgnoreCase);
+                            if (matchResult != null)
+                            {
+                                recordCount += matchResult.Count;
                             }
                             }
-                        }
-                        mPDFTextSearcher.FindClose();
-                        if (textSearchItems.Count > 0)
-                        {
-                            searchResult.Items.Add(i, textSearchItems);
-                        }
-                        pageMaxCount = Math.Max(pageMaxCount, textSearchItems.Count);
-                        searchResult.TotalCount = recordCount;
-                        searchResult.PageMaxCount = pageMaxCount;
-                        if (SearchPercentHandler != null)
-                        {
-                            searchPercent = (int)((i + 1 - startPage) * 100 / (endPage + 1 - startPage));
-                            searchResult.Percent = searchPercent;
-                            searchResult.CurrentPage = i;
-                            SearchPercentHandler.Invoke(this, searchResult);
-                        }
-                        mSearchDocument.ReleasePages(i);
-                        if (isCancel)
-                        {
-                            break;
                         }
                         }
                     }
                     }
-                    searchPercent = 100;
-                }
-                catch (Exception ex)
-                {
 
 
+                    mPDFTextSearcher.FindClose();
+                    if (textSearchItems.Count > 0)
+                    {
+                        searchResult.Items.Add(i, textSearchItems);
+                    }
+
+                    pageMaxCount = Math.Max(pageMaxCount, textSearchItems.Count);
+                    searchResult.TotalCount = recordCount;
+                    searchResult.PageMaxCount = pageMaxCount;
+                    if (SearchPercentHandler != null)
+                    {
+                        searchPercent = (int)((i + 1 - startPage) * 100 / (endPage + 1 - startPage));
+                        searchResult.Percent = searchPercent;
+                        searchResult.CurrentPage = i;
+                        SearchPercentHandler.Invoke(this, searchResult);
+                    }
+
+                    mSearchDocument.ReleasePages(i);
+                    if (isCancel)
+                    {
+                        break;
+                    }
                 }
                 }
+
+                searchPercent = 100;
                 mSearchDocument.Release();
                 mSearchDocument.Release();
             }
             }
-            try
+
+            if (SearchCompletedHandler != null && !isCancel)
             {
             {
-                if (SearchCompletedHandler != null && !isCancel)
-                {
-                    searchResult.Percent = searchPercent;
-                    SearchCompletedHandler.Invoke(this, searchResult);
-                }
-                if (SearchCancelHandler != null && isCancel)
-                {
-                    SearchCancelHandler.Invoke(this, searchResult);
-                }
+                searchResult.Percent = searchPercent;
+                SearchCompletedHandler.Invoke(this, searchResult);
             }
             }
-            catch (Exception ex)
-            {
 
 
+            if (SearchCancelHandler != null && isCancel)
+            {
+                SearchCancelHandler.Invoke(this, searchResult);
             }
             }
+
             CanDoSearch = true;
             CanDoSearch = true;
             isCancel = false;
             isCancel = false;
         }
         }

+ 9 - 1
Demo/Examples/ComPDFKit.Tool/SettingParam/AnnotParam/FreeTextParam.cs

@@ -21,11 +21,11 @@ namespace ComPDFKit.Tool
         public string FontName { get; set; } = string.Empty;
         public string FontName { get; set; } = string.Empty;
         public double FontSize { get; set; }
         public double FontSize { get; set; }
         public C_TEXT_ALIGNMENT Alignment {  get; set; }
         public C_TEXT_ALIGNMENT Alignment {  get; set; }
+        public float[] Dash { get; set; }
 
 
         public bool IsReadOnly { get; set; }
         public bool IsReadOnly { get; set; }
         public override bool CopyTo(AnnotParam transfer)
         public override bool CopyTo(AnnotParam transfer)
         {
         {
-            
             FreeTextParam freetextTransfer = transfer as FreeTextParam;
             FreeTextParam freetextTransfer = transfer as FreeTextParam;
             if (freetextTransfer == null)
             if (freetextTransfer == null)
             {
             {
@@ -52,6 +52,14 @@ namespace ComPDFKit.Tool
                 freetextTransfer.FontColor = (byte[])FontColor.Clone();
                 freetextTransfer.FontColor = (byte[])FontColor.Clone();
             }
             }
 
 
+            freetextTransfer.Dash = null;
+            if (Dash != null)
+            {
+                float[] DashCopy = new float[Dash.Length];
+                Dash.CopyTo(DashCopy, 0);
+                freetextTransfer.Dash = DashCopy;
+            }
+
             freetextTransfer.HasBgColor = HasBgColor;
             freetextTransfer.HasBgColor = HasBgColor;
             freetextTransfer.LineWidth = LineWidth;
             freetextTransfer.LineWidth = LineWidth;
             freetextTransfer.IsBold = IsBold;
             freetextTransfer.IsBold = IsBold;

+ 9 - 2
Demo/Examples/ComPDFKit.Tool/SettingParam/AnnotParam/InkParam.cs

@@ -15,7 +15,7 @@ namespace ComPDFKit.Tool
         public byte[] InkColor { get; set; }
         public byte[] InkColor { get; set; }
         public double Thickness { get; set; }
         public double Thickness { get; set; }
         public List<List<CPoint>> InkPath { get; set; }
         public List<List<CPoint>> InkPath { get; set; }
-
+        public float[] Dash { get; set; }
         public override bool CopyTo(AnnotParam transfer)
         public override bool CopyTo(AnnotParam transfer)
         {
         {
             InkParam inkTransfer = transfer as InkParam;
             InkParam inkTransfer = transfer as InkParam;
@@ -51,7 +51,14 @@ namespace ComPDFKit.Tool
 
 
                 inkTransfer.InkPath = inkPoints;
                 inkTransfer.InkPath = inkPoints;
             }
             }
-
+            inkTransfer.Dash = null;
+            if (Dash != null)
+            {
+                float[] DashCopy=new float[Dash.Length];
+                Dash.CopyTo(DashCopy,0);
+                inkTransfer.Dash = DashCopy;
+            }
+            
             return true;
             return true;
         }
         }
     }
     }

+ 23 - 18
Demo/Examples/ComPDFKit.Tool/SettingParam/AnnotParam/LineMeasureParam.cs

@@ -30,33 +30,35 @@ namespace ComPDFKit.Tool
         public bool IsItalic { get; set; }
         public bool IsItalic { get; set; }
         public C_BORDER_STYLE BorderStyle { get; set; }
         public C_BORDER_STYLE BorderStyle { get; set; }
         public CPDFMeasureInfo measureInfo { get; set; }
         public CPDFMeasureInfo measureInfo { get; set; }
-
+        public double LeadLength {  get; set; }
+        public double LeadExtension {  get; set; }
+        public double LeadOffset {  get; set; }
         public override bool CopyTo(AnnotParam transfer)
         public override bool CopyTo(AnnotParam transfer)
         {
         {
-            LineMeasureParam polygonTransfer = transfer as LineMeasureParam;
-            if (polygonTransfer == null)
+            LineMeasureParam lineTransfer = transfer as LineMeasureParam;
+            if (lineTransfer == null)
             {
             {
                 return false;
                 return false;
             }
             }
 
 
-            if (!base.CopyTo(polygonTransfer))
+            if (!base.CopyTo(lineTransfer))
             {
             {
                 return false;
                 return false;
             }
             }
 
 
             if (LineColor != null)
             if (LineColor != null)
             {
             {
-                polygonTransfer.LineColor = (byte[])LineColor.Clone();
+                lineTransfer.LineColor = (byte[])LineColor.Clone();
             }
             }
 
 
             if (LineDash != null)
             if (LineDash != null)
             {
             {
-                polygonTransfer.LineDash = (float[])LineDash.Clone();
+                lineTransfer.LineDash = (float[])LineDash.Clone();
             }
             }
 
 
             if (FontColor != null)
             if (FontColor != null)
             {
             {
-                polygonTransfer.FontColor = (byte[])FontColor.Clone();
+                lineTransfer.FontColor = (byte[])FontColor.Clone();
             }
             }
 
 
             if (measureInfo != null)
             if (measureInfo != null)
@@ -78,19 +80,22 @@ namespace ComPDFKit.Tool
                     RulerTranslate= measureInfo.RulerTranslate,
                     RulerTranslate= measureInfo.RulerTranslate,
                     CaptionType = measureInfo.CaptionType,
                     CaptionType = measureInfo.CaptionType,
                 };
                 };
-                polygonTransfer.measureInfo = cPDFMeasureInfo;
+                lineTransfer.measureInfo = cPDFMeasureInfo;
             }
             }
 
 
-            polygonTransfer.LineWidth = LineWidth;
-            polygonTransfer.HeadLineType = HeadLineType;
-            polygonTransfer.TailLineType = TailLineType;
-            polygonTransfer.FontName = FontName;
-            polygonTransfer.FontSize = FontSize;
-            polygonTransfer.IsBold = IsBold;
-            polygonTransfer.IsItalic = IsItalic;
-            polygonTransfer.HeadPoint = HeadPoint;
-            polygonTransfer.TailPoint = TailPoint;
-            polygonTransfer.BorderStyle = BorderStyle;
+            lineTransfer.LineWidth = LineWidth;
+            lineTransfer.HeadLineType = HeadLineType;
+            lineTransfer.TailLineType = TailLineType;
+            lineTransfer.FontName = FontName;
+            lineTransfer.FontSize = FontSize;
+            lineTransfer.IsBold = IsBold;
+            lineTransfer.IsItalic = IsItalic;
+            lineTransfer.HeadPoint = HeadPoint;
+            lineTransfer.TailPoint = TailPoint;
+            lineTransfer.BorderStyle = BorderStyle;
+            lineTransfer.LeadExtension=LeadExtension;
+            lineTransfer.LeadLength = LeadLength;
+            lineTransfer.LeadOffset = LeadOffset;
 
 
             return true;
             return true;
         }
         }

+ 5 - 1
Demo/Examples/ComPDFKit.Tool/SettingParam/AnnotParam/StampParam.cs

@@ -18,7 +18,10 @@ namespace ComPDFKit.Tool
 		public C_TEXTSTAMP_COLOR TextStampColor {  get; set; }
 		public C_TEXTSTAMP_COLOR TextStampColor {  get; set; }
 		public MemoryStream ImageStream { get; set; }
 		public MemoryStream ImageStream { get; set; }
 		public int Rotation { get; set; }	
 		public int Rotation { get; set; }	
-
+		//暂时做旋转用
+		//后续底层更新旋转角度支持后废除
+		//-1 逆时针 0 未动  1顺时针
+		public int Clockwise {  get; set; }
 
 
         public override bool CopyTo(AnnotParam transfer)
         public override bool CopyTo(AnnotParam transfer)
 		{
 		{
@@ -40,6 +43,7 @@ namespace ComPDFKit.Tool
 			stampTransfer.TextStampShape = TextStampShape;
 			stampTransfer.TextStampShape = TextStampShape;
 			stampTransfer.ImageStream = ImageStream;
 			stampTransfer.ImageStream = ImageStream;
 			stampTransfer.Rotation = Rotation;
 			stampTransfer.Rotation = Rotation;
+			stampTransfer.Clockwise = Clockwise;
 
 
 			return true;
 			return true;
 		}
 		}

+ 3 - 0
Demo/Examples/ComPDFKit.Tool/SettingParam/AnnotParam/StickyNoteParam.cs

@@ -11,6 +11,7 @@ namespace ComPDFKit.Tool
         }
         }
 
 
         public byte[] StickyNoteColor { get; set; }
         public byte[] StickyNoteColor { get; set; }
+        public string IconName { get; set; } = string.Empty;
 
 
         public override bool CopyTo(AnnotParam transfer)
         public override bool CopyTo(AnnotParam transfer)
         {
         {
@@ -30,6 +31,8 @@ namespace ComPDFKit.Tool
                 stickynoteTransfer.StickyNoteColor = (byte[])StickyNoteColor.Clone();
                 stickynoteTransfer.StickyNoteColor = (byte[])StickyNoteColor.Clone();
             }
             }
 
 
+            stickynoteTransfer.IconName = IconName;
+
             return true;
             return true;
         }
         }
     }
     }

+ 18 - 0
Demo/Examples/ComPDFKit.Tool/SettingParam/DefaultSettingParam.cs

@@ -1112,6 +1112,14 @@ namespace ComPDFKit.Tool.SettingParam
             get { return pDFEditMovePen.Clone(); }
             get { return pDFEditMovePen.Clone(); }
             set { pDFEditMovePen = value; }
             set { pDFEditMovePen = value; }
         }
         }
+        private Pen pDFEditMoveRectPen;
+
+        public Pen PDFEditMoveRectPen
+        {
+            get { return pDFEditMoveRectPen.Clone(); }
+            set { pDFEditMoveRectPen = value; }
+        }
+
 
 
         #region Not selected state
         #region Not selected state
 
 
@@ -1331,6 +1339,14 @@ namespace ComPDFKit.Tool.SettingParam
             set { pDFEditMultiMovePen = value; }
             set { pDFEditMultiMovePen = value; }
         }
         }
 
 
+        private Pen pDFEditMultiMoveRectPen;
+
+        public Pen PDFEditMultiMoveRectPen
+        {
+            get { return pDFEditMultiMoveRectPen.Clone(); }
+            set { pDFEditMultiMoveRectPen = value; }
+        }
+
         #region Not selected state
         #region Not selected state
 
 
         private SolidColorBrush pDFEditMultiRectFillBrush;
         private SolidColorBrush pDFEditMultiRectFillBrush;
@@ -1620,6 +1636,7 @@ namespace ComPDFKit.Tool.SettingParam
             CaretBrush = new SolidColorBrush(Color.FromArgb(0x46, 0x46, 0x82, 0xB4));
             CaretBrush = new SolidColorBrush(Color.FromArgb(0x46, 0x46, 0x82, 0xB4));
             CaretPen = new Pen(Brushes.Black, 1);
             CaretPen = new Pen(Brushes.Black, 1);
             PDFEditMovePen = new Pen(new SolidColorBrush(Color.FromRgb(0x00, 0xFF, 0x00)), 2);
             PDFEditMovePen = new Pen(new SolidColorBrush(Color.FromRgb(0x00, 0xFF, 0x00)), 2);
+            PDFEditMoveRectPen = new Pen(new SolidColorBrush(Color.FromRgb(0x00, 0xFF, 0x00)), 2);
             PDFEditMoveBrush = new SolidColorBrush(Color.FromArgb(0x46, 0x46, 0x82, 0xB4));
             PDFEditMoveBrush = new SolidColorBrush(Color.FromArgb(0x46, 0x46, 0x82, 0xB4));
 
 
 
 
@@ -1657,6 +1674,7 @@ namespace ComPDFKit.Tool.SettingParam
             ViewerImageBackgroundBrush = new SolidColorBrush(Color.FromArgb(0x46, 0x46, 0x82, 0xB4));
             ViewerImageBackgroundBrush = new SolidColorBrush(Color.FromArgb(0x46, 0x46, 0x82, 0xB4));
 
 
             //PDFEditMultiSelected
             //PDFEditMultiSelected
+            PDFEditMultiMoveRectPen = new Pen(new SolidColorBrush(Color.FromRgb(0x00, 0xFF, 0x00)), 2);
             PDFEditMultiMovePen = new Pen(new SolidColorBrush(Color.FromRgb(0x00, 0xFF, 0x00)), 2);
             PDFEditMultiMovePen = new Pen(new SolidColorBrush(Color.FromRgb(0x00, 0xFF, 0x00)), 2);
             PDFEditMultiMoveBrush = new SolidColorBrush(Color.FromArgb(0x46, 0x46, 0x82, 0xB4));
             PDFEditMultiMoveBrush = new SolidColorBrush(Color.FromArgb(0x46, 0x46, 0x82, 0xB4));
 
 

+ 2 - 2
Demo/Examples/ComPDFKit.Tool/UndoManger/AnnotHistory.cs

@@ -114,7 +114,7 @@ namespace ComPDFKit.Tool.UndoManger
             {
             {
                 checkAnnotList.Add((AnnotHistory)checkItem);
                 checkAnnotList.Add((AnnotHistory)checkItem);
             }
             }
-            //而且 checkAnnotList 要从大到小排序
+
             List<AnnotHistory> loopList = new List<AnnotHistory>();
             List<AnnotHistory> loopList = new List<AnnotHistory>();
             if (checkAnnotList != null && checkAnnotList.Count > 0)
             if (checkAnnotList != null && checkAnnotList.Count > 0)
             {
             {
@@ -169,7 +169,7 @@ namespace ComPDFKit.Tool.UndoManger
             if (GetPageIndex() == pageIndex)
             if (GetPageIndex() == pageIndex)
             {
             {
                 int oldIndex = GetAnnotIndex();
                 int oldIndex = GetAnnotIndex();
-                if (oldIndex == annotIndex && oldIndex>=0)
+                if (oldIndex == annotIndex && oldIndex >= 0)
                 {
                 {
                     SetAnnotIndex(-1);
                     SetAnnotIndex(-1);
                     HistoryIndex = -1;
                     HistoryIndex = -1;

+ 18 - 26
Demo/Examples/ComPDFKit.Tool/UndoManger/AnnotHistory/FreeTextAnnotHistory.cs

@@ -1,6 +1,7 @@
 using ComPDFKit.PDFAnnotation;
 using ComPDFKit.PDFAnnotation;
 using ComPDFKit.PDFPage;
 using ComPDFKit.PDFPage;
 using ComPDFKit.Tool.Help;
 using ComPDFKit.Tool.Help;
+using ComPDFKitViewer.Annot;
 using static ComPDFKit.PDFAnnotation.CTextAttribute.CFontNameHelper;
 using static ComPDFKit.PDFAnnotation.CTextAttribute.CFontNameHelper;
 
 
 namespace ComPDFKit.Tool.UndoManger
 namespace ComPDFKit.Tool.UndoManger
@@ -80,10 +81,7 @@ namespace ComPDFKit.Tool.UndoManger
                 }
                 }
                 textAttr.FontColor = fontColor;
                 textAttr.FontColor = fontColor;
                 textAttr.FontSize = (float)currentParam.FontSize;
                 textAttr.FontSize = (float)currentParam.FontSize;
-                textAttr.FontName = ObtainFontName(
-					GetFontType(currentParam.FontName),
-                    currentParam.IsBold,
-                    currentParam.IsItalic);
+                textAttr.FontName = currentParam.FontName;
 
 
                 textAnnot.SetFreetextDa(textAttr);
                 textAnnot.SetFreetextDa(textAttr);
 
 
@@ -98,6 +96,12 @@ namespace ComPDFKit.Tool.UndoManger
                 {
                 {
                     textAnnot.SetContent(currentParam.Content);
                     textAnnot.SetContent(currentParam.Content);
                 }
                 }
+
+                if (currentParam.Dash != null && currentParam.Dash.Length > 0)
+                {
+                    textAnnot.SetBorderStyle(C_BORDER_STYLE.BS_DASHDED, currentParam.Dash);
+                }
+
                 textAnnot.SetIsLocked(currentParam.Locked);
                 textAnnot.SetIsLocked(currentParam.Locked);
                 textAnnot.SetCreationDate(PDFHelp.GetCurrentPdfTime());
                 textAnnot.SetCreationDate(PDFHelp.GetCurrentPdfTime());
                 textAnnot.UpdateAp();
                 textAnnot.UpdateAp();
@@ -176,10 +180,7 @@ namespace ComPDFKit.Tool.UndoManger
                 if(updateParam.FontName != checkParam.FontName)
                 if(updateParam.FontName != checkParam.FontName)
                 {
                 {
                     CTextAttribute textAttr = textAnnot.FreeTextDa;
                     CTextAttribute textAttr = textAnnot.FreeTextDa;
-                    bool isBold = IsBold(textAttr.FontName);
-                    bool isItalic = IsItalic(textAttr.FontName);
-                    FontType fontType = GetFontType(updateParam.FontName);
-                    textAttr.FontName = ObtainFontName(fontType, isBold, isItalic);
+                    textAttr.FontName = updateParam.FontName;
                     textAnnot.SetFreetextDa(textAttr);
                     textAnnot.SetFreetextDa(textAttr);
                 }
                 }
 
 
@@ -199,24 +200,6 @@ namespace ComPDFKit.Tool.UndoManger
                         textAnnot.SetFreetextDa(textAttr);
                         textAnnot.SetFreetextDa(textAttr);
                     }
                     }
                 }
                 }
-               
-                if(updateParam.IsBold != checkParam.IsBold)
-                {
-                    CTextAttribute textAttr = textAnnot.FreeTextDa;
-                    bool isItalic = IsItalic(textAttr.FontName);
-                    FontType fontType = GetFontType(textAttr.FontName);
-                    textAttr.FontName = ObtainFontName(fontType, updateParam.IsBold, isItalic);
-                    textAnnot.SetFreetextDa(textAttr);
-                }
-
-                if(updateParam.IsItalic != checkParam.IsItalic)
-                {
-                    CTextAttribute textAttr = textAnnot.FreeTextDa;
-                    bool isBold = IsBold(textAttr.FontName);
-                    FontType fontType = GetFontType(textAttr.FontName);
-                    textAttr.FontName = ObtainFontName(fontType, isBold, updateParam.IsItalic);
-                    textAnnot.SetFreetextDa(textAttr);
-                }
 
 
                 if (!updateParam.ClientRect.Equals(checkParam.ClientRect))
                 if (!updateParam.ClientRect.Equals(checkParam.ClientRect))
                 {
                 {
@@ -238,6 +221,15 @@ namespace ComPDFKit.Tool.UndoManger
                     textAnnot.SetIsLocked(updateParam.Locked);
                     textAnnot.SetIsLocked(updateParam.Locked);
                 }
                 }
 
 
+                if (updateParam.Dash != null && updateParam.Dash.Length > 0)
+                {
+                    textAnnot.SetBorderStyle(C_BORDER_STYLE.BS_DASHDED, updateParam.Dash);
+                }
+                else
+                {
+                    textAnnot.SetBorderStyle(C_BORDER_STYLE.BS_SOLID, new float[0]);
+                }
+
                 textAnnot.SetModifyDate(PDFHelp.GetCurrentPdfTime());
                 textAnnot.SetModifyDate(PDFHelp.GetCurrentPdfTime());
                 textAnnot.UpdateAp();
                 textAnnot.UpdateAp();
 
 

+ 15 - 0
Demo/Examples/ComPDFKit.Tool/UndoManger/AnnotHistory/InkAnnotHistory.cs

@@ -69,6 +69,12 @@ namespace ComPDFKit.Tool.UndoManger
                 {
                 {
                     inkAnnot.SetContent(currentParam.Content);
                     inkAnnot.SetContent(currentParam.Content);
                 }
                 }
+
+                if (currentParam.Dash != null && currentParam.Dash.Length > 0)
+                {
+                    inkAnnot.SetBorderStyle(C_BORDER_STYLE.BS_DASHDED,currentParam.Dash);
+                }
+
                 inkAnnot.SetIsLocked(currentParam.Locked);
                 inkAnnot.SetIsLocked(currentParam.Locked);
                 inkAnnot.SetCreationDate(PDFHelp.GetCurrentPdfTime());
                 inkAnnot.SetCreationDate(PDFHelp.GetCurrentPdfTime());
                 inkAnnot.UpdateAp();
                 inkAnnot.UpdateAp();
@@ -124,6 +130,15 @@ namespace ComPDFKit.Tool.UndoManger
                     inkAnnot.SetInkPath(updateParam.InkPath);
                     inkAnnot.SetInkPath(updateParam.InkPath);
                 }
                 }
 
 
+                if (updateParam.Dash!=null && updateParam.Dash.Length>0)
+                {
+                    inkAnnot.SetBorderStyle(C_BORDER_STYLE.BS_DASHDED,updateParam.Dash);
+                }
+                else
+                {
+                    inkAnnot.SetBorderStyle(C_BORDER_STYLE.BS_SOLID,new float[0]);
+                }
+
                 if (updateParam.Transparency != checkParam.Transparency)
                 if (updateParam.Transparency != checkParam.Transparency)
                 {
                 {
                     inkAnnot.SetTransparency((byte)updateParam.Transparency);
                     inkAnnot.SetTransparency((byte)updateParam.Transparency);

+ 14 - 10
Demo/Examples/ComPDFKit.Tool/UndoManger/AnnotHistory/LineMeasureAnnotHistory.cs

@@ -102,6 +102,9 @@ namespace ComPDFKit.Tool.UndoManger
                     CPDFDistanceMeasure polygonMeasure = polygonAnnot.GetDistanceMeasure();
                     CPDFDistanceMeasure polygonMeasure = polygonAnnot.GetDistanceMeasure();
                     if (polygonMeasure != null)
                     if (polygonMeasure != null)
                     {
                     {
+                        polygonMeasure.SetLeadLength((float)currentParam.LeadLength);
+                        polygonMeasure.SetLeadExtension((float)currentParam.LeadExtension);
+                        polygonMeasure.SetLeadOffset((float)currentParam.LeadOffset);
                         polygonMeasure.SetMeasureInfo(currentParam.measureInfo);
                         polygonMeasure.SetMeasureInfo(currentParam.measureInfo);
                         polygonMeasure.SetMeasureScale(currentParam.measureInfo.RulerBase, currentParam.measureInfo.RulerBaseUnit,
                         polygonMeasure.SetMeasureScale(currentParam.measureInfo.RulerBase, currentParam.measureInfo.RulerBaseUnit,
                                                        currentParam.measureInfo.RulerTranslate, currentParam.measureInfo.RulerTranslateUnit);
                                                        currentParam.measureInfo.RulerTranslate, currentParam.measureInfo.RulerTranslateUnit);
@@ -143,7 +146,7 @@ namespace ComPDFKit.Tool.UndoManger
             if (MakeAnnotValid(CurrentParam))
             if (MakeAnnotValid(CurrentParam))
             {
             {
                 CPDFLineAnnotation polygonAnnot = Annot as CPDFLineAnnotation;
                 CPDFLineAnnotation polygonAnnot = Annot as CPDFLineAnnotation;
-                if (polygonAnnot == null || !polygonAnnot.IsValid() || !polygonAnnot.IsMersured())
+                if (polygonAnnot == null || !polygonAnnot.IsValid() || !polygonAnnot.IsMeasured())
                 {
                 {
                     return false;
                     return false;
                 }
                 }
@@ -209,16 +212,17 @@ namespace ComPDFKit.Tool.UndoManger
                 {
                 {
                     polygonAnnot.SetIsLocked(updateParam.Locked);
                     polygonAnnot.SetIsLocked(updateParam.Locked);
                 }
                 }
-                if (updateParam.measureInfo != checkParam.measureInfo)
+
+                CPDFDistanceMeasure polygonMeasure = polygonAnnot.GetDistanceMeasure();
+                if (polygonMeasure != null)
                 {
                 {
-                    CPDFDistanceMeasure polygonMeasure = polygonAnnot.GetDistanceMeasure();
-                    if (polygonMeasure != null)
-                    {
-                        polygonMeasure.SetMeasureInfo(updateParam.measureInfo);
-                        polygonMeasure.SetMeasureScale(updateParam.measureInfo.RulerBase, updateParam.measureInfo.RulerBaseUnit,
-                                                       updateParam.measureInfo.RulerTranslate, updateParam.measureInfo.RulerTranslateUnit);
-                        polygonMeasure.UpdateAnnotMeasure();
-                    }
+                    polygonMeasure.SetLeadLength((float)updateParam.LeadLength);
+                    polygonMeasure.SetLeadExtension((float)updateParam.LeadExtension);
+                    polygonMeasure.SetLeadOffset((float)updateParam.LeadOffset);
+                    polygonMeasure.SetMeasureInfo(updateParam.measureInfo);
+                    polygonMeasure.SetMeasureScale(updateParam.measureInfo.RulerBase, updateParam.measureInfo.RulerBaseUnit,
+                                                   updateParam.measureInfo.RulerTranslate, updateParam.measureInfo.RulerTranslateUnit);
+                    polygonMeasure.UpdateAnnotMeasure();
                 }
                 }
                 polygonAnnot.SetModifyDate(PDFHelp.GetCurrentPdfTime());
                 polygonAnnot.SetModifyDate(PDFHelp.GetCurrentPdfTime());
 
 

+ 1 - 1
Demo/Examples/ComPDFKit.Tool/UndoManger/AnnotHistory/PolyLineMeasureAnnotHistory.cs

@@ -137,7 +137,7 @@ namespace ComPDFKit.Tool.UndoManger
             if (MakeAnnotValid(CurrentParam))
             if (MakeAnnotValid(CurrentParam))
             {
             {
                 CPDFPolylineAnnotation polygonAnnot = Annot as CPDFPolylineAnnotation;
                 CPDFPolylineAnnotation polygonAnnot = Annot as CPDFPolylineAnnotation;
-                if (polygonAnnot == null || !polygonAnnot.IsValid() || !polygonAnnot.IsMersured())
+                if (polygonAnnot == null || !polygonAnnot.IsValid() || !polygonAnnot.IsMeasured())
                 {
                 {
                     return false;
                     return false;
                 }
                 }

+ 1 - 1
Demo/Examples/ComPDFKit.Tool/UndoManger/AnnotHistory/PolygonMeasureAnnotHistory.cs

@@ -146,7 +146,7 @@ namespace ComPDFKit.Tool.UndoManger
             if (MakeAnnotValid(CurrentParam))
             if (MakeAnnotValid(CurrentParam))
             {
             {
                 CPDFPolygonAnnotation polygonAnnot = Annot as CPDFPolygonAnnotation;
                 CPDFPolygonAnnotation polygonAnnot = Annot as CPDFPolygonAnnotation;
-                if (polygonAnnot == null || !polygonAnnot.IsValid() || !polygonAnnot.IsMersured())
+                if (polygonAnnot == null || !polygonAnnot.IsValid() || !polygonAnnot.IsMeasured())
                 {
                 {
                     return false;
                     return false;
                 }
                 }

+ 242 - 9
Demo/Examples/ComPDFKit.Tool/UndoManger/AnnotHistory/StampAnnotHistory.cs

@@ -1,7 +1,11 @@
-using ComPDFKit.PDFAnnotation;
+using ComPDFKit.Import;
+using ComPDFKit.PDFAnnotation;
 using ComPDFKit.PDFPage;
 using ComPDFKit.PDFPage;
 using ComPDFKit.Tool.Help;
 using ComPDFKit.Tool.Help;
+using System;
 using System.IO;
 using System.IO;
+using System.IO.Ports;
+using System.Windows;
 using System.Windows.Media;
 using System.Windows.Media;
 using System.Windows.Media.Imaging;
 using System.Windows.Media.Imaging;
 
 
@@ -120,11 +124,16 @@ namespace ComPDFKit.Tool.UndoManger
 					default:
 					default:
 						break;
 						break;
 				}
 				}
+                //stampAnnot.UpdateAp();
+                stampAnnot.SetTransparency((byte)currentParam.Transparency);
+                //string imagePath = string.Empty;
+                //if (GetAnnotOpacityImage(stampAnnot, currentParam.Transparency / 255.0, 5, out imagePath) && File.Exists(imagePath))
+                //{
+                //    stampAnnot.SetImageStamp(imagePath, string.Empty);
+                //    File.Delete(imagePath);
+                //}
 
 
-				stampAnnot.SetTransparency((byte)currentParam.Transparency);
-				
-
-				if (!string.IsNullOrEmpty(currentParam.Author))
+                if (!string.IsNullOrEmpty(currentParam.Author))
 				{
 				{
 					stampAnnot.SetAuthor(currentParam.Author);
 					stampAnnot.SetAuthor(currentParam.Author);
 				}
 				}
@@ -171,10 +180,38 @@ namespace ComPDFKit.Tool.UndoManger
 				StampParam updateParam = (isUndo ? PreviousParam : CurrentParam) as StampParam;
 				StampParam updateParam = (isUndo ? PreviousParam : CurrentParam) as StampParam;
 				StampParam checkParam = (isUndo ? CurrentParam : PreviousParam) as StampParam;
 				StampParam checkParam = (isUndo ? CurrentParam : PreviousParam) as StampParam;
 
 
-				if (updateParam.Transparency != checkParam.Transparency)
+                if (updateParam.Clockwise!=0)
+                {
+                    string imagePath = string.Empty;
+
+                    bool clockwise = updateParam.Clockwise== 1 ? true : false;
+                    if(isUndo)
+                    {
+                        clockwise=!clockwise;
+                    }
+
+                    if (GetAnnotRotateImage(stampAnnot, clockwise, 5, out imagePath) && File.Exists(imagePath))
+                    {
+                        CRect rawRect = stampAnnot.GetRect();
+                        Point centerPos = new Point(rawRect.left + rawRect.width() / 2, rawRect.top + rawRect.height() / 2);
+                        Rect saveRect = new Rect(centerPos.X - rawRect.height() / 2, centerPos.Y - rawRect.width() / 2, rawRect.height(), rawRect.width());
+
+                        stampAnnot.SetRect(new CRect((float)saveRect.Left, (float)saveRect.Bottom, (float)saveRect.Right, (float)saveRect.Top));
+                        stampAnnot.SetImageStamp(imagePath, string.Empty);
+                        File.Delete(imagePath);
+                    }
+                }
+
+                if (updateParam.Transparency != checkParam.Transparency)
 				{
 				{
-					stampAnnot.SetTransparency((byte)updateParam.Transparency);
-				}
+                    string imagePath = string.Empty;
+                    if (GetAnnotOpacityImage(stampAnnot, updateParam.Transparency/255.0, 5, out imagePath) && File.Exists(imagePath))
+                    {
+                        stampAnnot.SetImageStamp(imagePath, string.Empty);
+                        File.Delete(imagePath);
+                    }
+                    stampAnnot.SetTransparency((byte)updateParam.Transparency);
+                }
 
 
 				if (!updateParam.ClientRect.Equals(checkParam.ClientRect))
 				if (!updateParam.ClientRect.Equals(checkParam.ClientRect))
                 {
                 {
@@ -213,5 +250,201 @@ namespace ComPDFKit.Tool.UndoManger
 			}
 			}
 			return false;
 			return false;
 		}
 		}
-	}
+
+        private bool GetAnnotRotateImage(CPDFStampAnnotation annot, bool clockwise, double zoom, out string imagePath)
+        {
+            imagePath = string.Empty;
+
+            if (annot == null || annot.IsValid() == false)
+            {
+                return false;
+            }
+
+            try
+            {
+                double opacity = annot.GetTransparency() / 255.0;
+                CRect rawRect = annot.GetRect();
+                Rect drawRect = new Rect(0, 0, (int)(rawRect.width() * 96.0 / 72.0 * zoom), (int)(rawRect.height() * 96.0 / 72.0 * zoom));
+
+                byte[] imageData = new byte[(int)drawRect.Width * (int)drawRect.Height * 4];
+                annot.RenderAnnot((int)drawRect.Width, (int)drawRect.Height, imageData);
+
+                int stride = ((int)drawRect.Width) * 4;
+                for (int i = 0; i < (int)(drawRect.Height); i++)
+                {
+                    for (int j = 0; j < (int)(drawRect.Width); j++)
+                    {
+                        byte b = imageData[i * stride + j * 4];
+                        byte g = imageData[i * stride + j * 4 + 1];
+                        byte r = imageData[i * stride + j * 4 + 2];
+                        byte a = imageData[i * stride + j * 4 + 3];
+
+                        if (a == 0 && b == 255 && g == 255 && r == 255)
+                        {
+                            continue;
+                        }
+
+                        if (a == 0 && opacity > 0)
+                        {
+                            imageData[i * stride + j * 4] = 255;
+                            imageData[i * stride + j * 4 + 1] = 255;
+                            imageData[i * stride + j * 4 + 2] = 255;
+                            continue;
+                        }
+
+                        if (opacity == 0)
+                        {
+                            imageData[i * stride + j * 4 + 3] = 255;
+                            continue;
+                        }
+                        imageData[i * stride + j * 4 + 3] = (byte)(opacity * 255);
+                    }
+                }
+
+                WriteableBitmap writeImage = new WriteableBitmap((int)drawRect.Width, (int)drawRect.Height, 96, 96, PixelFormats.Bgra32, null);
+                writeImage.WritePixels(new Int32Rect(0, 0, (int)drawRect.Width, (int)drawRect.Height), imageData, ((int)drawRect.Width) * 4, 0);
+
+                RotateTransform rotateTransform = new RotateTransform();
+                rotateTransform.Angle = clockwise ? 90 : -90;
+                rotateTransform.CenterX = drawRect.Width / 2;
+                rotateTransform.CenterY = drawRect.Height / 2;
+                TranslateTransform translateTransform = new TranslateTransform();
+                if (clockwise == false)
+                {
+                    translateTransform.X = -(drawRect.Width - drawRect.Height) / 2;
+                    translateTransform.Y = -(drawRect.Width - drawRect.Height) / 2;
+                }
+                else
+                {
+                    translateTransform.X = (drawRect.Width - drawRect.Height) / 2;
+                    translateTransform.Y = (drawRect.Width - drawRect.Height) / 2;
+                }
+
+                DrawingVisual drawVisual = new DrawingVisual();
+
+                DrawingContext drawDC = drawVisual.RenderOpen();
+                drawDC.PushTransform(rotateTransform);
+                drawDC.PushTransform(translateTransform);
+                drawDC.DrawImage(writeImage, new Rect(0, 0, writeImage.Width, writeImage.Height));
+                drawDC.Pop();
+                drawDC.Pop();
+                drawDC.Close();
+
+                RenderTargetBitmap renderBitmap = new RenderTargetBitmap((int)drawRect.Height, (int)drawRect.Width, 96, 96, PixelFormats.Pbgra32);
+                renderBitmap.Render(drawVisual);
+                string tempPath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), Guid.NewGuid().ToString());
+                BitmapSource saveImageData = renderBitmap;
+                if (opacity == 0)
+                {
+                    stride = saveImageData.PixelWidth * 4;
+                    imageData = new byte[stride * saveImageData.PixelHeight];
+                    saveImageData.CopyPixels(imageData, stride, 0);
+                    for (int i = 0; i < saveImageData.PixelHeight; i++)
+                    {
+                        for (int j = 0; j < saveImageData.PixelWidth; j++)
+                        {
+                            byte b = imageData[i * stride + j * 4];
+                            byte g = imageData[i * stride + j * 4 + 1];
+                            byte r = imageData[i * stride + j * 4 + 2];
+                            byte a = imageData[i * stride + j * 4 + 3];
+
+                            if (a == 0 && b == 255 && g == 255 && r == 255)
+                            {
+                                continue;
+                            }
+
+                            if (a == 0 && b == 0 && g == 0 && r == 0)
+                            {
+                                imageData[i * stride + j * 4] = 255;
+                                imageData[i * stride + j * 4 + 1] = 255;
+                                imageData[i * stride + j * 4 + 2] = 255;
+                                continue;
+                            }
+
+                            imageData[i * stride + j * 4 + 3] = (byte)(opacity * 255);
+                        }
+                    }
+                    writeImage = new WriteableBitmap(saveImageData.PixelWidth, saveImageData.PixelHeight, 96, 96, PixelFormats.Bgra32, null);
+                    writeImage.WritePixels(new Int32Rect(0, 0, saveImageData.PixelWidth, saveImageData.PixelHeight), imageData, stride, 0);
+                    saveImageData = writeImage;
+                }
+                PngBitmapEncoder pngEncoder = new PngBitmapEncoder();
+                using (FileStream fs = File.Create(tempPath))
+                {
+                    pngEncoder.Frames.Add(BitmapFrame.Create(saveImageData));
+                    pngEncoder.Save(fs);
+                }
+                imagePath = tempPath;
+                return true;
+            }
+            catch (Exception ex)
+            {
+
+            }
+
+            return false;
+        }
+
+        private bool GetAnnotOpacityImage(CPDFStampAnnotation annot, double opacity, double zoom, out string imagePath)
+        {
+            imagePath = string.Empty;
+            if (annot == null || annot.IsValid() == false)
+            {
+                return false;
+            }
+
+            try
+            {
+                CRect rawRect = annot.GetRect();
+                Rect drawRect = new Rect(0, 0, (int)(rawRect.width() * 96.0 / 72.0 * zoom), (int)(rawRect.height() * 96.0 / 72.0 * zoom));
+
+                byte[] imageData = new byte[(int)drawRect.Width * (int)drawRect.Height * 4];
+                annot.RenderAnnot((int)drawRect.Width, (int)drawRect.Height, imageData);
+                byte annotOpacity = annot.GetTransparency();
+
+                int stride = ((int)drawRect.Width) * 4;
+                for (int i = 0; i < (int)(drawRect.Height); i++)
+                {
+                    for (int j = 0; j < (int)(drawRect.Width); j++)
+                    {
+                        byte b = imageData[i * stride + j * 4];
+                        byte g = imageData[i * stride + j * 4 + 1];
+                        byte r = imageData[i * stride + j * 4 + 2];
+                        byte a = imageData[i * stride + j * 4 + 3];
+
+                        if (a == 0 && b == 255 && g == 255 && r == 255)
+                        {
+                            continue;
+                        }
+                    
+                        if (a == 0 && annotOpacity > 0)
+                        {
+                            imageData[i * stride + j * 4] = 255;
+                            imageData[i * stride + j * 4 + 1] = 255;
+                            imageData[i * stride + j * 4 + 2] = 255;
+                            continue;
+                        }
+                        imageData[i * stride + j * 4 + 3] = (byte)(opacity * 255);
+                    }
+                }
+
+                WriteableBitmap writeImage = new WriteableBitmap((int)drawRect.Width, (int)drawRect.Height, 96, 96, PixelFormats.Bgra32, null);
+                writeImage.WritePixels(new Int32Rect(0, 0, (int)drawRect.Width, (int)drawRect.Height), imageData, stride, 0);
+                string tempPath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), Guid.NewGuid().ToString());
+                PngBitmapEncoder pngEncoder = new PngBitmapEncoder();
+                using (FileStream fs = File.Create(tempPath))
+                {
+                    pngEncoder.Frames.Add(BitmapFrame.Create(writeImage));
+                    pngEncoder.Save(fs);
+                }
+                imagePath = tempPath;
+                return true;
+            }
+            catch (Exception ex)
+            {
+
+            }
+            return false;
+        }
+    }
 }
 }

+ 13 - 2
Demo/Examples/ComPDFKit.Tool/UndoManger/AnnotHistory/StickyNoteAnnotHistory.cs

@@ -68,9 +68,15 @@ namespace ComPDFKit.Tool.UndoManger
                 {
                 {
                     stickynoteAnnot.SetContent(currentParam.Content);
                     stickynoteAnnot.SetContent(currentParam.Content);
                 }
                 }
+
+                if (string.IsNullOrEmpty(currentParam.IconName) == false)
+                {
+                    stickynoteAnnot.SetIconName(currentParam.IconName);
+                }
+
                 stickynoteAnnot.SetIsLocked(currentParam.Locked);
                 stickynoteAnnot.SetIsLocked(currentParam.Locked);
                 stickynoteAnnot.SetCreationDate(PDFHelp.GetCurrentPdfTime());
                 stickynoteAnnot.SetCreationDate(PDFHelp.GetCurrentPdfTime());
-                stickynoteAnnot.UpdateAp();
+                CommonHelper.UpdateStickyAP(stickynoteAnnot);
                 stickynoteAnnot.ReleaseAnnot();
                 stickynoteAnnot.ReleaseAnnot();
 
 
                 if (currentParam != null)
                 if (currentParam != null)
@@ -134,13 +140,18 @@ namespace ComPDFKit.Tool.UndoManger
                     stickynoteAnnot.SetContent(updateParam.Content);
                     stickynoteAnnot.SetContent(updateParam.Content);
                 }
                 }
 
 
+                if(updateParam.IconName!=checkParam.IconName && !string.IsNullOrEmpty(updateParam.IconName))
+                {
+                    stickynoteAnnot.SetIconName(updateParam.IconName);
+                }
+
                 if (updateParam.Locked != checkParam.Locked)
                 if (updateParam.Locked != checkParam.Locked)
                 {
                 {
                     stickynoteAnnot.SetIsLocked(updateParam.Locked);
                     stickynoteAnnot.SetIsLocked(updateParam.Locked);
                 }
                 }
 
 
                 stickynoteAnnot.SetModifyDate(PDFHelp.GetCurrentPdfTime());
                 stickynoteAnnot.SetModifyDate(PDFHelp.GetCurrentPdfTime());
-                stickynoteAnnot.UpdateAp();
+                CommonHelper.UpdateStickyAP(stickynoteAnnot);
 
 
                 return true;
                 return true;
             }
             }

+ 4 - 28
Demo/Examples/ComPDFKit.Tool/UndoManger/FormHistory/ComboBoxHistory.cs

@@ -84,12 +84,9 @@ namespace ComPDFKit.Tool.UndoManger
                 }
                 }
                 textAttr.FontColor = fontColor;
                 textAttr.FontColor = fontColor;
 				textAttr.FontSize = (float)currentParam.FontSize;
 				textAttr.FontSize = (float)currentParam.FontSize;
-				textAttr.FontName = ObtainFontName(
-					GetFontType(currentParam.FontName),
-					currentParam.IsBold,
-					currentParam.IsItalic);
+				textAttr.FontName = currentParam.FontName;
 
 
-				comboboxWidget.SetTextAttribute(textAttr);
+                comboboxWidget.SetTextAttribute(textAttr);
 
 
 				if(currentParam.OptionItems!=null && currentParam.OptionItems.Count > 0)
 				if(currentParam.OptionItems!=null && currentParam.OptionItems.Count > 0)
 				{
 				{
@@ -198,11 +195,8 @@ namespace ComPDFKit.Tool.UndoManger
 				if (updateParam.FontName != checkParam.FontName)
 				if (updateParam.FontName != checkParam.FontName)
 				{
 				{
 					CTextAttribute textAttr = comboboxWidget.GetTextAttribute();
 					CTextAttribute textAttr = comboboxWidget.GetTextAttribute();
-					bool isBold = IsBold(textAttr.FontName);
-					bool isItalic = IsItalic(textAttr.FontName);
-					FontType fontType = GetFontType(updateParam.FontName);
-					textAttr.FontName = ObtainFontName(fontType, isBold, isItalic);
-					comboboxWidget.SetTextAttribute(textAttr);
+					textAttr.FontName = updateParam.FontName;
+                    comboboxWidget.SetTextAttribute(textAttr);
 				}
 				}
 
 
 				if (updateParam.FontSize != checkParam.FontSize)
 				if (updateParam.FontSize != checkParam.FontSize)
@@ -222,24 +216,6 @@ namespace ComPDFKit.Tool.UndoManger
                     }
                     }
 				}
 				}
 
 
-				if (updateParam.IsBold != checkParam.IsBold)
-				{
-					CTextAttribute textAttr = comboboxWidget.GetTextAttribute();
-					bool isItalic = IsItalic(textAttr.FontName);
-					FontType fontType = GetFontType(textAttr.FontName);
-					textAttr.FontName = ObtainFontName(fontType, updateParam.IsBold, isItalic);
-					comboboxWidget.SetTextAttribute(textAttr);
-				}
-
-				if (updateParam.IsItalic != checkParam.IsItalic)
-				{
-					CTextAttribute textAttr = comboboxWidget.GetTextAttribute();
-					bool isBold = IsBold(textAttr.FontName);
-					FontType fontType = GetFontType(textAttr.FontName);
-					textAttr.FontName = ObtainFontName(fontType, isBold, updateParam.IsItalic);
-					comboboxWidget.SetTextAttribute(textAttr);
-				}
-
 				if (updateParam.OptionItems != null)
 				if (updateParam.OptionItems != null)
 				{
 				{
 					int optionsCount = comboboxWidget.GetItemsCount();
 					int optionsCount = comboboxWidget.GetItemsCount();

+ 4 - 29
Demo/Examples/ComPDFKit.Tool/UndoManger/FormHistory/ListBoxHistory.cs

@@ -84,12 +84,9 @@ namespace ComPDFKit.Tool.UndoManger
                 }
                 }
                 textAttr.FontColor = fontColor;
                 textAttr.FontColor = fontColor;
 				textAttr.FontSize = (float)currentParam.FontSize;
 				textAttr.FontSize = (float)currentParam.FontSize;
-				textAttr.FontName = ObtainFontName(
-					GetFontType(currentParam.FontName),
-					currentParam.IsBold,
-					currentParam.IsItalic);
+				textAttr.FontName = currentParam.FontName;
 
 
-				listboxWidget.SetTextAttribute(textAttr);
+                listboxWidget.SetTextAttribute(textAttr);
 
 
 				if (currentParam.OptionItems != null && currentParam.OptionItems.Count > 0)
 				if (currentParam.OptionItems != null && currentParam.OptionItems.Count > 0)
 				{
 				{
@@ -198,11 +195,8 @@ namespace ComPDFKit.Tool.UndoManger
 				if (updateParam.FontName != checkParam.FontName)
 				if (updateParam.FontName != checkParam.FontName)
 				{
 				{
 					CTextAttribute textAttr = listboxWidget.GetTextAttribute();
 					CTextAttribute textAttr = listboxWidget.GetTextAttribute();
-					bool isBold = IsBold(textAttr.FontName);
-					bool isItalic = IsItalic(textAttr.FontName);
-					FontType fontType = GetFontType(updateParam.FontName);
-					textAttr.FontName = ObtainFontName(fontType, isBold, isItalic);
-					listboxWidget.SetTextAttribute(textAttr);
+					textAttr.FontName = updateParam.FontName;
+                    listboxWidget.SetTextAttribute(textAttr);
 				}
 				}
 
 
 				if (updateParam.FontSize != checkParam.FontSize)
 				if (updateParam.FontSize != checkParam.FontSize)
@@ -222,25 +216,6 @@ namespace ComPDFKit.Tool.UndoManger
                     }
                     }
                 }
                 }
 
 
-
-                if (updateParam.IsBold != checkParam.IsBold)
-				{
-					CTextAttribute textAttr = listboxWidget.GetTextAttribute();
-					bool isItalic = IsItalic(textAttr.FontName);
-					FontType fontType = GetFontType(textAttr.FontName);
-					textAttr.FontName = ObtainFontName(fontType, updateParam.IsBold, isItalic);
-					listboxWidget.SetTextAttribute(textAttr);
-				}
-
-				if (updateParam.IsItalic != checkParam.IsItalic)
-				{
-					CTextAttribute textAttr = listboxWidget.GetTextAttribute();
-					bool isBold = IsBold(textAttr.FontName);
-					FontType fontType = GetFontType(textAttr.FontName);
-					textAttr.FontName = ObtainFontName(fontType, isBold, updateParam.IsItalic);
-					listboxWidget.SetTextAttribute(textAttr);
-				}
-
 				if (updateParam.OptionItems != null)
 				if (updateParam.OptionItems != null)
 				{
 				{
 					int optionsCount = listboxWidget.GetItemsCount();
 					int optionsCount = listboxWidget.GetItemsCount();

+ 4 - 28
Demo/Examples/ComPDFKit.Tool/UndoManger/FormHistory/PushButtonHistory.cs

@@ -92,12 +92,9 @@ namespace ComPDFKit.Tool.UndoManger
                 }
                 }
 				textAttr.FontColor = fontColor;
 				textAttr.FontColor = fontColor;
 				textAttr.FontSize = (float)currentParam.FontSize;
 				textAttr.FontSize = (float)currentParam.FontSize;
-				textAttr.FontName = ObtainFontName(
-					GetFontType(currentParam.FontName),
-					currentParam.IsBold,
-					currentParam.IsItalic);
+				textAttr.FontName = currentParam.FontName;
 
 
-				pushbuttonWidget.SetTextAttribute(textAttr);
+                pushbuttonWidget.SetTextAttribute(textAttr);
 
 
 				switch (currentParam.Action)
 				switch (currentParam.Action)
 				{
 				{
@@ -215,11 +212,8 @@ namespace ComPDFKit.Tool.UndoManger
 				if (updateParam.FontName != checkParam.FontName)
 				if (updateParam.FontName != checkParam.FontName)
 				{
 				{
 					CTextAttribute textAttr = pushbutton.GetTextAttribute();
 					CTextAttribute textAttr = pushbutton.GetTextAttribute();
-					bool isBold = IsBold(textAttr.FontName);
-					bool isItalic = IsItalic(textAttr.FontName);
-					FontType fontType = GetFontType(updateParam.FontName);
-					textAttr.FontName = ObtainFontName(fontType, isBold, isItalic);
-					pushbutton.SetTextAttribute(textAttr);
+					textAttr.FontName = updateParam.FontName;
+                    pushbutton.SetTextAttribute(textAttr);
 				}
 				}
 
 
 				if (updateParam.FontSize != checkParam.FontSize)
 				if (updateParam.FontSize != checkParam.FontSize)
@@ -239,24 +233,6 @@ namespace ComPDFKit.Tool.UndoManger
                     }
                     }
                 }
                 }
 
 
-                if (updateParam.IsBold != checkParam.IsBold)
-				{
-					CTextAttribute textAttr = pushbutton.GetTextAttribute();
-					bool isItalic = IsItalic(textAttr.FontName);
-					FontType fontType = GetFontType(textAttr.FontName);
-					textAttr.FontName = ObtainFontName(fontType, updateParam.IsBold, isItalic);
-					pushbutton.SetTextAttribute(textAttr);
-				}
-
-				if (updateParam.IsItalic != checkParam.IsItalic)
-				{
-					CTextAttribute textAttr = pushbutton.GetTextAttribute();
-					bool isBold = IsBold(textAttr.FontName);
-					FontType fontType = GetFontType(textAttr.FontName);
-					textAttr.FontName = ObtainFontName(fontType, isBold, updateParam.IsItalic);
-					pushbutton.SetTextAttribute(textAttr);
-				}
-
 				switch (updateParam.Action)
 				switch (updateParam.Action)
 				{
 				{
 					case C_ACTION_TYPE.ACTION_TYPE_GOTO:
 					case C_ACTION_TYPE.ACTION_TYPE_GOTO:

+ 4 - 28
Demo/Examples/ComPDFKit.Tool/UndoManger/FormHistory/TextBoxHistory.cs

@@ -86,12 +86,9 @@ namespace ComPDFKit.Tool.UndoManger
                 }
                 }
 				textAttr.FontColor = fontColor;
 				textAttr.FontColor = fontColor;
 				textAttr.FontSize = (float)currentParam.FontSize;
 				textAttr.FontSize = (float)currentParam.FontSize;
-				textAttr.FontName = ObtainFontName(
-					GetFontType(currentParam.FontName),
-					currentParam.IsBold,
-					currentParam.IsItalic);
+				textAttr.FontName = currentParam.FontName;
 
 
-				textWidget.SetTextAttribute(textAttr);
+                textWidget.SetTextAttribute(textAttr);
                 textWidget.SetJustification(currentParam.Alignment);
                 textWidget.SetJustification(currentParam.Alignment);
 
 
 				textWidget.SetBorderWidth((float)currentParam.LineWidth);
 				textWidget.SetBorderWidth((float)currentParam.LineWidth);
@@ -185,11 +182,8 @@ namespace ComPDFKit.Tool.UndoManger
 				if (updateParam.FontName != checkParam.FontName)
 				if (updateParam.FontName != checkParam.FontName)
 				{
 				{
 					CTextAttribute textAttr = textWidget.GetTextAttribute();
 					CTextAttribute textAttr = textWidget.GetTextAttribute();
-					bool isBold = IsBold(textAttr.FontName);
-					bool isItalic = IsItalic(textAttr.FontName);
-					FontType fontType = GetFontType(updateParam.FontName);
-					textAttr.FontName = ObtainFontName(fontType, isBold, isItalic);
-					textWidget.SetTextAttribute(textAttr);
+					textAttr.FontName = updateParam.FontName;
+                    textWidget.SetTextAttribute(textAttr);
 				}
 				}
 
 
 				if (updateParam.FontSize != checkParam.FontSize)
 				if (updateParam.FontSize != checkParam.FontSize)
@@ -209,24 +203,6 @@ namespace ComPDFKit.Tool.UndoManger
                     }
                     }
 				}
 				}
 
 
-				if (updateParam.IsBold != checkParam.IsBold)
-				{
-					CTextAttribute textAttr = textWidget.GetTextAttribute();
-					bool isItalic = IsItalic(textAttr.FontName);
-					FontType fontType = GetFontType(textAttr.FontName);
-					textAttr.FontName = ObtainFontName(fontType, updateParam.IsBold, isItalic);
-					textWidget.SetTextAttribute(textAttr);
-				}
-
-				if (updateParam.IsItalic != checkParam.IsItalic)
-				{
-					CTextAttribute textAttr = textWidget.GetTextAttribute();
-					bool isBold = IsBold(textAttr.FontName);
-					FontType fontType = GetFontType(textAttr.FontName);
-					textAttr.FontName = ObtainFontName(fontType, isBold, updateParam.IsItalic);
-					textWidget.SetTextAttribute(textAttr);
-				}
-
 				if (updateParam.Alignment != checkParam.Alignment)
 				if (updateParam.Alignment != checkParam.Alignment)
 				{
 				{
                     textWidget.SetJustification(updateParam.Alignment);
                     textWidget.SetJustification(updateParam.Alignment);

+ 8 - 7
Demo/Examples/ComPDFKit.Tool/UndoManger/GroupHistory.cs

@@ -15,7 +15,6 @@ namespace ComPDFKit.Tool.UndoManger
             if (Histories != null && Histories.Count > 0)
             if (Histories != null && Histories.Count > 0)
             {
             {
                 bool success = true;
                 bool success = true;
-                //需要排序
 
 
                 List<AnnotHistory> checkAnnotList = new List<AnnotHistory>();
                 List<AnnotHistory> checkAnnotList = new List<AnnotHistory>();
                 List<IHistory> OtherList = new List<IHistory>();
                 List<IHistory> OtherList = new List<IHistory>();
@@ -31,7 +30,6 @@ namespace ComPDFKit.Tool.UndoManger
                     OtherList.Add(history);
                     OtherList.Add(history);
                 }
                 }
 
 
-                //而且 checkAnnotList 要从大到小排序
                 List<AnnotHistory> loopList = new List<AnnotHistory>();
                 List<AnnotHistory> loopList = new List<AnnotHistory>();
                 if (checkAnnotList != null && checkAnnotList.Count > 0)
                 if (checkAnnotList != null && checkAnnotList.Count > 0)
                 {
                 {
@@ -66,7 +64,6 @@ namespace ComPDFKit.Tool.UndoManger
             if (Histories != null && Histories.Count > 0)
             if (Histories != null && Histories.Count > 0)
             {
             {
                 bool success = true;
                 bool success = true;
-                //需要排序
 
 
                 List<AnnotHistory> checkAnnotList = new List<AnnotHistory>();
                 List<AnnotHistory> checkAnnotList = new List<AnnotHistory>();
                 List<IHistory> OtherList = new List<IHistory>();
                 List<IHistory> OtherList = new List<IHistory>();
@@ -82,7 +79,6 @@ namespace ComPDFKit.Tool.UndoManger
                     OtherList.Add(history);
                     OtherList.Add(history);
                 }
                 }
 
 
-                //而且 checkAnnotList 要从大到小排序
                 List<AnnotHistory> loopList = new List<AnnotHistory>();
                 List<AnnotHistory> loopList = new List<AnnotHistory>();
                 if (checkAnnotList != null && checkAnnotList.Count > 0)
                 if (checkAnnotList != null && checkAnnotList.Count > 0)
                 {
                 {
@@ -103,6 +99,11 @@ namespace ComPDFKit.Tool.UndoManger
                     success &= history.Undo();
                     success &= history.Undo();
                 }
                 }
 
 
+                foreach (IHistory history in OtherList)
+                {
+                    success &= history.Undo();
+                }
+
                 foreach (IHistory history in OtherList)
                 foreach (IHistory history in OtherList)
                 {
                 {
                     success &= history.Undo();
                     success &= history.Undo();
@@ -131,7 +132,7 @@ namespace ComPDFKit.Tool.UndoManger
             if (checkItem is GroupHistory)
             if (checkItem is GroupHistory)
             {
             {
                 GroupHistory groupHistory = (GroupHistory)checkItem;
                 GroupHistory groupHistory = (GroupHistory)checkItem;
-                foreach (IHistory checkHistory in groupHistory.Histories)
+                foreach(IHistory checkHistory in groupHistory.Histories)
                 {
                 {
                     AnnotHistory checkAnnot = checkHistory as AnnotHistory;
                     AnnotHistory checkAnnot = checkHistory as AnnotHistory;
                     if (checkAnnot == null || checkAnnotList.Contains(checkAnnot))
                     if (checkAnnot == null || checkAnnotList.Contains(checkAnnot))
@@ -146,7 +147,7 @@ namespace ComPDFKit.Tool.UndoManger
             {
             {
                 checkAnnotList.Add((AnnotHistory)checkItem);
                 checkAnnotList.Add((AnnotHistory)checkItem);
             }
             }
-            //而且 checkAnnotList 要从大到小排序
+
             List<AnnotHistory> loopList = new List<AnnotHistory>();
             List<AnnotHistory> loopList = new List<AnnotHistory>();
             if (checkAnnotList != null && checkAnnotList.Count > 0)
             if (checkAnnotList != null && checkAnnotList.Count > 0)
             {
             {
@@ -227,7 +228,7 @@ namespace ComPDFKit.Tool.UndoManger
                 if (annotHistory.GetPageIndex() == pageIndex && annotHistory.HistoryIndex == prevIndex)
                 if (annotHistory.GetPageIndex() == pageIndex && annotHistory.HistoryIndex == prevIndex)
                 {
                 {
                     annotHistory.SetAnnotIndex(annotIndex);
                     annotHistory.SetAnnotIndex(annotIndex);
-                    annotHistory.HistoryIndex =annotIndex;
+                    annotHistory.HistoryIndex = annotIndex;
                 }
                 }
             }
             }
         }
         }

+ 1 - 1
Demo/Examples/ComPDFKit.Tool/UndoManger/MultiAnnotHistory.cs

@@ -69,7 +69,7 @@ namespace ComPDFKit.Tool.UndoManger
             {
             {
                 checkAnnotList.Add((AnnotHistory)checkItem);
                 checkAnnotList.Add((AnnotHistory)checkItem);
             }
             }
-            //而且 checkAnnotList 要从大到小排序
+
             List<AnnotHistory> loopList = new List<AnnotHistory>();
             List<AnnotHistory> loopList = new List<AnnotHistory>();
             if (checkAnnotList != null && checkAnnotList.Count > 0)
             if (checkAnnotList != null && checkAnnotList.Count > 0)
             {
             {

+ 28 - 21
Demo/Examples/ComPDFKit.Tool/UndoManger/PDFEditHistory/PDFEditHistory.cs

@@ -3,36 +3,43 @@ using ComPDFKitViewer.Helper;
 
 
 namespace ComPDFKit.Tool.UndoManger
 namespace ComPDFKit.Tool.UndoManger
 {
 {
-	public class PDFEditHistory : IHistory
-	{
-		public CPDFEditPage EditPage { get; set; }
-		public int PageIndex {  get; set; }
-		public bool Redo()
-		{
+    public class PDFEditHistory : IHistory
+    {
+        public CPDFEditPage EditPage { get; set; }
+        public int PageIndex { get; set; }
+        public bool Redo()
+        {
             if (EditPage != null && EditPage.IsValid())
             if (EditPage != null && EditPage.IsValid())
             {
             {
                 bool result = EditPage.Redo();
                 bool result = EditPage.Redo();
-                EditPage.EndEdit();
+                if (result)
+                {
+                    EditPage.EndEdit();
+                }
                 return result;
                 return result;
+
             }
             }
 
 
             return false;
             return false;
-		}
+        }
 
 
-		public bool Undo()
-		{
-			if(EditPage!=null && EditPage.IsValid())
-			{
-				bool result= EditPage.Undo();
-				EditPage.EndEdit();
-				return result;
-			}
-			return false;
-		}
+        public bool Undo()
+        {
+            if (EditPage != null && EditPage.IsValid())
+            {
+                bool result = EditPage.Undo();
+                if (result)
+                {
+                    EditPage.EndEdit();
+                }
+                return result;
+            }
+            return false;
+        }
 
 
-		public void Check(IHistory changeItem, bool undo, bool redo, bool add)
+        public void Check(IHistory changeItem, bool undo, bool redo, bool add)
         {
         {
 
 
-		}
-	}
+        }
+    }
 }
 }

+ 1 - 1
Demo/Examples/Compdfkit.Controls/Annotation/CPDFAnnotationPreviewerControl.xaml.cs

@@ -175,7 +175,7 @@ namespace ComPDFKit.Controls.PDFControl
             string fontFamily = string.Empty;
             string fontFamily = string.Empty;
             string fontStyle = string.Empty;
             string fontStyle = string.Empty;
 
 
-            CPDFFont.GetFamlyStyleName(freeTextData.FontFamily, ref fontFamily, ref fontStyle);
+            CPDFFont.GetFamilyStyleName(freeTextData.FontFamily, ref fontFamily, ref fontStyle);
             FreeText.FontFamily = new FontFamily(fontFamily); 
             FreeText.FontFamily = new FontFamily(fontFamily); 
             FreeText.FontSize = freeTextData.FontSize / 1.2;
             FreeText.FontSize = freeTextData.FontSize / 1.2;
             FreeText.Foreground = new SolidColorBrush(freeTextData.BorderColor);
             FreeText.Foreground = new SolidColorBrush(freeTextData.BorderColor);

+ 6 - 1
Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationData/CPDFAnnotationData.cs

@@ -25,7 +25,12 @@ namespace ComPDFKit.Controls.Data
         Signature,
         Signature,
         Link,
         Link,
         Audio,
         Audio,
-        Image
+        Image,
+        PolyLine,
+        Polygon,
+        LineMeasure,
+        PolyLineMeasure,
+        PolygonMeasure
     }
     }
 
 
     public enum SignatureType
     public enum SignatureType

File diff suppressed because it is too large
+ 65 - 1
Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationList/PDFAnnotationListControl/CPDFAnnotationListControl.xaml


+ 203 - 18
Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationList/PDFAnnotationListControl/CPDFAnnotationListControl.xaml.cs

@@ -6,19 +6,19 @@ using ComPDFKit.Tool.Help;
 using ComPDFKitViewer;
 using ComPDFKitViewer;
 using ComPDFKitViewer.BaseObject;
 using ComPDFKitViewer.BaseObject;
 using System.Collections.Generic;
 using System.Collections.Generic;
-using System.Linq;
 using System.IO;
 using System.IO;
 using System.Windows;
 using System.Windows;
-using System.Windows.Annotations;
 using System.Windows.Controls;
 using System.Windows.Controls;
-using ComPDFKit.Controls.Helper;
-using static ComPDFKit.Controls.PDFControlUI.CPDFAnnoationListUI;
+using static ComPDFKit.Controls.PDFControlUI.CPDFAnnotationListUI;
+using ComPDFKit.Controls.PDFControlUI;
+using System.Windows.Input;
+using System;
 
 
 namespace ComPDFKit.Controls.PDFControl
 namespace ComPDFKit.Controls.PDFControl
 {
 {
     public partial class CPDFAnnotationListControl : UserControl
     public partial class CPDFAnnotationListControl : UserControl
     {
     {
-        private List<C_ANNOTATION_TYPE> OmitList = new List<C_ANNOTATION_TYPE> 
+        private List<C_ANNOTATION_TYPE> OmitList = new List<C_ANNOTATION_TYPE>
         {
         {
             C_ANNOTATION_TYPE.C_ANNOTATION_UNKOWN,
             C_ANNOTATION_TYPE.C_ANNOTATION_UNKOWN,
             C_ANNOTATION_TYPE.C_ANNOTATION_LINK,
             C_ANNOTATION_TYPE.C_ANNOTATION_LINK,
@@ -43,6 +43,52 @@ namespace ComPDFKit.Controls.PDFControl
         {
         {
             AnnotationList.DeleteItemHandler -= AnnotationList_DeleteItemHandler;
             AnnotationList.DeleteItemHandler -= AnnotationList_DeleteItemHandler;
             AnnotationList.DeleteItemHandler += AnnotationList_DeleteItemHandler;
             AnnotationList.DeleteItemHandler += AnnotationList_DeleteItemHandler;
+            AnnotationList.ReplyStatusChanged -= AnnotationList_ReplyStatusChanged;
+            AnnotationList.ReplyStatusChanged += AnnotationList_ReplyStatusChanged;
+            AnnotationReplyListControl.ReplyListChanged -= AnnotationReplyListControl_ReplyListChanged;
+            AnnotationReplyListControl.ReplyListChanged += AnnotationReplyListControl_ReplyListChanged;
+        }
+
+        private void AnnotationList_ReplyStatusChanged(object sender, CPDFAnnotationState e)
+        {
+            if (sender is ReplyStatusControl replyStatusControl)
+            {
+                if (replyStatusControl.DataContext is AnnotationBindData data)
+                {
+                    if (pdfViewer != null)
+                    {
+                        CPDFAnnotation annot = data.BindProperty.Annotation;
+                        if (annot != null)
+                        {
+                            annot.SetState(e);
+                            pdfViewer.PDFViewTool.GetCPDFViewer().UpdateAnnotFrame();
+                            pdfViewer.PDFViewTool.IsDocumentModified = true;
+                        }
+                    }
+                }
+            }
+            else if (sender is CheckBox checkBox)
+            {
+                if (checkBox.DataContext is AnnotationBindData data)
+                {
+                    if (pdfViewer != null)
+                    {
+                        CPDFAnnotation annot = data.BindProperty.Annotation;
+                        if (annot != null)
+                        {
+                            annot.SetMarkedAnnotState(checkBox.IsChecked == true ? CPDFAnnotationState.C_ANNOTATION_MARKED : CPDFAnnotationState.C_ANNOTATION_UNMARKED, "");
+                            pdfViewer.PDFViewTool.GetCPDFViewer().UpdateAnnotFrame();
+                            pdfViewer.PDFViewTool.IsDocumentModified = true;
+                        }
+                    }
+                }
+            }
+        }
+
+        private void AnnotationReplyListControl_ReplyListChanged(object sender, System.EventArgs e)
+        {
+            pdfViewer.PDFViewTool.IsDocumentModified = true;
+            pdfViewer.PDFViewTool.GetCPDFViewer().UpdateAnnotFrame();
         }
         }
 
 
         private void AnnotationList_DeleteItemHandler(object sender, Dictionary<int, List<int>> e)
         private void AnnotationList_DeleteItemHandler(object sender, Dictionary<int, List<int>> e)
@@ -71,9 +117,9 @@ namespace ComPDFKit.Controls.PDFControl
             }
             }
             else
             else
             {
             {
-                BaseAnnot baseAnnot= pdfViewer.PDFToolManager.GetCacheHitTestAnnot();
+                BaseAnnot baseAnnot = pdfViewer.PDFToolManager.GetCacheHitTestAnnot();
                 AnnotData annotData = baseAnnot?.GetAnnotData();
                 AnnotData annotData = baseAnnot?.GetAnnotData();
-                if(annotData != null)
+                if (annotData != null)
                 {
                 {
                     AnnotationList.SelectAnnotationChanged(annotData.PageIndex, annotData.AnnotIndex);
                     AnnotationList.SelectAnnotationChanged(annotData.PageIndex, annotData.AnnotIndex);
                 }
                 }
@@ -95,21 +141,49 @@ namespace ComPDFKit.Controls.PDFControl
 
 
             List<BindAnnotationResult> bindAnnotationResults = new List<BindAnnotationResult>();
             List<BindAnnotationResult> bindAnnotationResults = new List<BindAnnotationResult>();
 
 
+            pdfViewer.UpdateAnnotFrame();
             for (int i = 0; i < pageCount; i++)
             for (int i = 0; i < pageCount; i++)
             {
             {
-
                 List<AnnotParam> annotList = GetAnnotCommentList(i, pdfViewer.PDFViewTool.GetCPDFViewer().GetDocument());
                 List<AnnotParam> annotList = GetAnnotCommentList(i, pdfViewer.PDFViewTool.GetCPDFViewer().GetDocument());
-                if (annotList != null&& annotList.Count>0)
+                List<CPDFAnnotation> annotCoreList = pdfViewer?.GetCPDFViewer()?.GetDocument()?.PageAtIndex(i, false)?.GetAnnotations();
+                if (annotList != null && annotList.Count > 0)
                 {
                 {
                     Dispatcher.Invoke(() =>
                     Dispatcher.Invoke(() =>
                     {
                     {
                         foreach (AnnotParam annot in annotList)
                         foreach (AnnotParam annot in annotList)
                         {
                         {
-                            bindAnnotationResults.Add(new BindAnnotationResult
+                            CPDFAnnotation annotCore = annotCoreList[annot.AnnotIndex];
+                            if (annotCore == null || annotCore.IsReplyAnnot() || annotCore.Type == C_ANNOTATION_TYPE.C_ANNOTATION_LINK)
+                            {
+                                continue;
+                            }
+
+                            var bindResult = new BindAnnotationResult
                             {
                             {
                                 PageIndex = i,
                                 PageIndex = i,
-                                annotationData = annot
-                            });
+                                annotationData = annot,
+                                pdfViewer = pdfViewer,
+                                ReplyState = annotCore.GetState(),
+                                IsMarkState = annotCore.IsMarkedStateAnnot()
+                            };
+
+                            List<CPDFTextAnnotation> replyAnnotations = annotCore?.GetReplies();
+                            if (replyAnnotations != null && replyAnnotations.Count > 0)
+                            {
+                                foreach (CPDFTextAnnotation replyAnnot in replyAnnotations)
+                                {
+                                    if (replyAnnot == null)
+                                    {
+                                        continue;
+                                    }
+
+                                    bindResult.ReplyList.Add(new ReplyData
+                                    {
+                                        ReplyAnnotation = replyAnnot,
+                                    });
+                                }
+                            }
+                            bindAnnotationResults.Add(bindResult);
                         }
                         }
                     });
                     });
                 }
                 }
@@ -135,12 +209,12 @@ namespace ComPDFKit.Controls.PDFControl
             {
             {
                 foreach (CPDFAnnotation annotation in docAnnots)
                 foreach (CPDFAnnotation annotation in docAnnots)
                 {
                 {
-                    if (annotation==null|| OmitList.Contains(annotation.Type))
+                    if (annotation == null || OmitList.Contains(annotation.Type))
                     {
                     {
                         continue;
                         continue;
                     }
                     }
-                    AnnotParam annotParam= ParamConverter.CPDFDataConverterToAnnotParam(currentDoc,pageIndex,annotation);
-                    if (annotParam!=null)
+                    AnnotParam annotParam = ParamConverter.CPDFDataConverterToAnnotParam(currentDoc, pageIndex, annotation);
+                    if (annotParam != null)
                     {
                     {
                         annotList.Add(annotParam);
                         annotList.Add(annotParam);
                     }
                     }
@@ -177,8 +251,8 @@ namespace ComPDFKit.Controls.PDFControl
             {
             {
                 Directory.CreateDirectory(tempPath);
                 Directory.CreateDirectory(tempPath);
             }
             }
-            pdfViewer.PDFToolManager.GetDocument().ImportAnnotationFromXFDFPath(selectedPath,tempPath);
-                
+            pdfViewer.PDFToolManager.GetDocument().ImportAnnotationFromXFDFPath(selectedPath, tempPath);
+
             LoadAnnotationList();
             LoadAnnotationList();
             pdfViewer.PDFViewTool.GetCPDFViewer().UpdateVirtualNodes();
             pdfViewer.PDFViewTool.GetCPDFViewer().UpdateVirtualNodes();
             pdfViewer.PDFViewTool.GetCPDFViewer().UpdateRenderFrame();
             pdfViewer.PDFViewTool.GetCPDFViewer().UpdateRenderFrame();
@@ -194,11 +268,122 @@ namespace ComPDFKit.Controls.PDFControl
             {
             {
                 Directory.CreateDirectory(tempPath);
                 Directory.CreateDirectory(tempPath);
             }
             }
-
             if (pdfViewer.PDFToolManager.GetDocument().ExportAnnotationToXFDFPath(selectedPath, tempPath))
             if (pdfViewer.PDFToolManager.GetDocument().ExportAnnotationToXFDFPath(selectedPath, tempPath))
             {
             {
                 System.Diagnostics.Process.Start("explorer.exe", "/select," + selectedPath);
                 System.Diagnostics.Process.Start("explorer.exe", "/select," + selectedPath);
             }
             }
         }
         }
     }
     }
+
+    public class ExpandAllReplyCommand : ICommand
+    {
+        public event EventHandler CanExecuteChanged;
+
+        public bool CanExecute(object parameter)
+        {
+            return true;
+        }
+
+        public void Execute(object parameter)
+        {
+            if (parameter is CPDFAnnotationListControl annotationListControl)
+            {
+                annotationListControl.AnnotationList.ExpandAllReply(true);
+            }
+        }
+    }
+
+    public class FoldAllReplyCommand : ICommand
+    {
+        public event EventHandler CanExecuteChanged;
+
+        public bool CanExecute(object parameter)
+        {
+            return true;
+        }
+
+        public void Execute(object parameter)
+        {
+            if (parameter is CPDFAnnotationListControl annotationListControl)
+            {
+                annotationListControl.AnnotationList.ExpandAllReply(false);
+            }
+        }
+    }
+
+    public class DeleteAllAnnotCommand : ICommand
+    {
+        public event EventHandler CanExecuteChanged;
+
+        public bool CanExecute(object parameter)
+        {
+            return true;
+        }
+
+        public void Execute(object parameter)
+        {
+            if (parameter is CPDFAnnotationListControl annotationListControl)
+            {
+                annotationListControl.AnnotationList.DeleteAllReply();
+                annotationListControl.LoadAnnotationList();
+                annotationListControl.AnnotationList.DeleteAllAnnot();
+            }
+        }
+    }
+
+    public class DeleteAllReplyCommand : ICommand
+    {
+        public event EventHandler CanExecuteChanged;
+
+        public bool CanExecute(object parameter)
+        {
+            return true;
+        }
+
+        public void Execute(object parameter)
+        {
+            if (parameter is CPDFAnnotationListControl annotationListControl)
+            {
+                annotationListControl.AnnotationList.DeleteAllReply();
+                annotationListControl.LoadAnnotationList();
+            }
+        }
+    }
+
+    public class ExpandAnnotListCommand : ICommand
+    {
+        public event EventHandler CanExecuteChanged;
+
+        public bool CanExecute(object parameter)
+        {
+            return true;
+        }
+
+        public void Execute(object parameter)
+        {
+            if (parameter is CPDFAnnotationListControl annotationListControl)
+            {
+                annotationListControl.AnnotationList.ExpandAnnotList(true);
+            }
+        }
+    }
+
+    public class FoldAnnotListCommand : ICommand
+    {
+        public event EventHandler CanExecuteChanged;
+
+        public bool CanExecute(object parameter)
+        {
+            return true;
+        }
+
+        public void Execute(object parameter)
+        {
+            if (parameter is CPDFAnnotationListControl annotationListControl)
+            {
+                annotationListControl.AnnotationList.ExpandAnnotList(false);
+            }
+        }
+    }
+
 }
 }

+ 134 - 0
Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationList/PDFAnnotationListUI/AnnotationReplyListControl.xaml

@@ -0,0 +1,134 @@
+<UserControl x:Class="ComPDFKit.Controls.PDFControlUI.AnnotationReplyListControl"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
+             xmlns:common="clr-namespace:ComPDFKit.Controls.Common"
+             xmlns:local="clr-namespace:ComPDFKit.Controls.PDFControlUI"
+             mc:Ignorable="d" 
+             Loaded= "UserControl_Loaded"
+             d:DesignHeight="450" d:DesignWidth="800">
+    <UserControl.Resources>
+        <ResourceDictionary>
+            <ResourceDictionary.MergedDictionaries>
+                <ResourceDictionary Source="../../../Asset/Styles/MenuItemStyle.xaml"></ResourceDictionary>
+            </ResourceDictionary.MergedDictionaries>
+            <common:TextLengthToVisibilityConverter x:Key="TextLengthToVisibilityConverter"></common:TextLengthToVisibilityConverter>
+            <common:SubtractionConverter x:Key="SubtractionConverter"></common:SubtractionConverter>
+            <common:AntiVisibilityConverter x:Key="AntiVisibilityConverter"></common:AntiVisibilityConverter>
+            <common:BoolToVisibleConverter x:Key="BoolToVisibleConverter"></common:BoolToVisibleConverter>
+            <common:BotaResourceConverter x:Key="BotaResourceConverter"></common:BotaResourceConverter>
+        </ResourceDictionary>
+    </UserControl.Resources>
+    <Grid x:Name="ReplyGrid" Margin="0">
+        <Grid.RowDefinitions>
+            <RowDefinition Height="0"></RowDefinition>
+            <RowDefinition Height="0"></RowDefinition>
+            <RowDefinition Height="0"></RowDefinition>
+        </Grid.RowDefinitions>
+
+        <Grid Grid.Row="0">
+            <TextBox x:Name="InputTxb" Height="30" VerticalContentAlignment="Center"></TextBox>
+            <TextBlock Text="{Binding Converter={StaticResource BotaResourceConverter},ConverterParameter=Holder_Reply}" VerticalAlignment="Center" Margin="10,0,0,0" Foreground="#A0A0A0" IsHitTestVisible="False"
+                      Visibility="{Binding ElementName=InputTxb, Path=Text, Converter={StaticResource TextLengthToVisibilityConverter}}"></TextBlock>
+        </Grid>
+
+        <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
+            <Button Content="{Binding Converter={StaticResource BotaResourceConverter},ConverterParameter=Button_Cancel}" Background="Transparent" BorderThickness="0" Margin="0,0,5,0" Width="56" Height="30" Click="ButtonCancel_Click"></Button>
+            <Button Content="{Binding Converter={StaticResource BotaResourceConverter},ConverterParameter=Button_Reply}" Width="56" Height="30" Foreground="White" Background="#1460F3" BorderThickness="0" Click="ReplyButton_Click"></Button>
+        </StackPanel>
+
+        <ListView Grid.Row="2" x:Name="ReplyList" Margin="0,0,0,0" VirtualizingPanel.IsVirtualizingWhenGrouping="True" 
+                 ScrollViewer.HorizontalScrollBarVisibility="Hidden" BorderThickness="0" SelectionMode="Single" 
+                   Visibility="{Binding ElementName=ReplyList, Path=HasItems, Converter={StaticResource BoolToVisibleConverter}}">
+            <ListView.ItemsPanel>
+                <ItemsPanelTemplate>
+                    <VirtualizingStackPanel Background="#FAFCFF" HorizontalAlignment="Stretch" MaxHeight="200"
+                                           Width="{Binding ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}, Converter={StaticResource SubtractionConverter}, ConverterParameter=5}"></VirtualizingStackPanel>
+                </ItemsPanelTemplate>
+            </ListView.ItemsPanel>
+            <ListView.ItemContainerStyle>
+                <Style TargetType="ListViewItem">
+                    <Setter Property="Template">
+                        <Setter.Value>
+                            <ControlTemplate TargetType="ListViewItem">
+                                <ContentPresenter />
+                            </ControlTemplate>
+                        </Setter.Value>
+                    </Setter>
+                    <Setter Property="MinHeight" Value="0" />
+                    <Setter Property="Height" Value="Auto" /> 
+                </Style>
+            </ListView.ItemContainerStyle>
+            <ListView.ItemTemplate>
+                <ItemContainerTemplate> 
+                    <Grid>
+                        <Grid.Style>
+                            <Style TargetType="Grid"> 
+                                <Style.Triggers>
+                                    <Trigger Property="IsMouseOver" Value="True">
+                                        <Setter Property="Background" Value="#D0D9E1"/> 
+                                    </Trigger>
+                                    <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListViewItem}}" Value="True">
+                                        <Setter Property="Background" Value="#D0D9E1"/> 
+                                    </DataTrigger>
+                                </Style.Triggers>
+                            </Style>
+                        </Grid.Style>
+                        <Grid.RowDefinitions>
+                            <RowDefinition Height="Auto"/>
+                            <RowDefinition Height="Auto"/>
+                        </Grid.RowDefinitions>
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="*"/>
+                            <ColumnDefinition Width="Auto"/>
+                        </Grid.ColumnDefinitions>
+
+                        <DockPanel Grid.Column="0">
+                            <StackPanel VerticalAlignment="Center">
+                                <TextBlock Text="{Binding Author}" FontSize="14" Foreground="#43474D" VerticalAlignment="Center"/>
+                                <TextBlock Text="{Binding Date}" FontSize="11" Foreground="#999999" VerticalAlignment="Center"/>
+                            </StackPanel>
+                        </DockPanel>
+
+                        <Menu Background="Transparent" BorderThickness="0" Grid.Column="1">
+                            <MenuItem  BorderThickness="0" Width="30" Height="30" Padding="4,3,0,0">
+                                <MenuItem.Header>
+                                    <Canvas Width="30" Height="30"  VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
+                                        <Path Data="M10 5.5C10.8284 5.5 11.5 4.82843 11.5 4C11.5 3.17157 10.8284 2.5 10 2.5C9.17157 2.5 8.5 3.17157 8.5 4C8.5 4.82843 9.17157 5.5 10 5.5ZM11.5 10C11.5 10.8284 10.8284 11.5 10 11.5C9.17157 11.5 8.5 10.8284 8.5 10C8.5 9.17157 9.17157 8.5 10 8.5C10.8284 8.5 11.5 9.17157 11.5 10ZM11.5 16C11.5 16.8284 10.8284 17.5 10 17.5C9.17157 17.5 8.5 16.8284 8.5 16C8.5 15.1716 9.17157 14.5 10 14.5C10.8284 14.5 11.5 15.1716 11.5 16Z" 
+                                             Fill="#43474D"/>
+                                    </Canvas>
+                                </MenuItem.Header>
+                                <MenuItem Header="{Binding Converter={StaticResource BotaResourceConverter},ConverterParameter=Menu_Edit}" Style="{StaticResource Sub_MenuItem}">
+                                    <MenuItem.Command>
+                                        <local:ShowContentBoxCommand/>
+                                    </MenuItem.Command>
+                                    <MenuItem.CommandParameter>
+                                        <Binding ElementName="ContentBox"/>
+                                    </MenuItem.CommandParameter>
+                                </MenuItem>
+
+                                <MenuItem Header="{Binding Converter={StaticResource BotaResourceConverter},ConverterParameter=Menu_Delete}" Style="{StaticResource Sub_MenuItem}">
+                                    <MenuItem.Command>
+                                        <local:DeleteReplyCommand/>
+                                    </MenuItem.Command>
+                                    <MenuItem.CommandParameter>
+                                        <Binding Path="."></Binding>
+                                    </MenuItem.CommandParameter>
+                                </MenuItem>
+                            </MenuItem>
+                        </Menu>
+                        <Grid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
+                            <TextBox x:Name="ContentBox" Text="{Binding Content}" FontSize="14" Foreground="#666666" Margin="5,5,0,0"
+                                    Visibility="Collapsed" VerticalAlignment="Center" LostFocus="ContentBox_LostFocus"></TextBox>
+
+                            <TextBlock Text="{Binding Content}" x:Name="ContentTxb" FontSize="14" Foreground="#666666" Margin="5,5,0,0" VerticalAlignment="Center"
+                                      Visibility="{Binding ElementName=ContentBox,Path=Visibility,Converter={StaticResource AntiVisibilityConverter}}"></TextBlock>
+                        </Grid>
+
+                    </Grid>
+                </ItemContainerTemplate>
+            </ListView.ItemTemplate>
+        </ListView>
+    </Grid>
+</UserControl>

+ 215 - 0
Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationList/PDFAnnotationListUI/AnnotationReplyListControl.xaml.cs

@@ -0,0 +1,215 @@
+using System;
+using System.Collections.ObjectModel;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+
+namespace ComPDFKit.Controls.PDFControlUI
+{
+    /// <summary>
+    /// Interaction logic for AnnotationReplyListControl.xaml
+    /// </summary>
+    public partial class AnnotationReplyListControl : UserControl
+    {
+        public ObservableCollection<CPDFAnnotationListUI.ReplyData> ReplyListSource
+        {
+            get => (ObservableCollection<CPDFAnnotationListUI.ReplyData>)GetValue(ReplyListProperty);
+            set => SetValue(ReplyListProperty, value);
+        }
+
+        /// <summary>
+        /// The source of the reply list.
+        /// </summary>
+        public static readonly DependencyProperty ReplyListProperty = DependencyProperty.Register(
+            nameof(ReplyListSource),
+            typeof(ObservableCollection<CPDFAnnotationListUI.ReplyData>),
+            typeof(AnnotationReplyListControl),
+            new PropertyMetadata(null, OnReplyListSourceChanged));
+
+        private static void OnReplyListSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            var newReplyListSource = e.NewValue as ObservableCollection<CPDFAnnotationListUI.ReplyData>;
+            if (d is AnnotationReplyListControl control)
+            {
+                control.ReplyList.ItemsSource = newReplyListSource;
+            }
+        }
+
+        public bool IsShowInput
+        {
+            get => (bool)GetValue(IsShowInputProperty);
+            set => SetValue(IsShowInputProperty, value);
+        }
+
+        /// <summary>
+        /// The visibility of the reply input.
+        /// </summary>
+        public static readonly DependencyProperty IsShowInputProperty = DependencyProperty.Register(
+            nameof(IsShowInput),
+            typeof(bool),
+            typeof(AnnotationReplyListControl),
+            new PropertyMetadata(false, OnIsShowInputChanged));
+
+        public static event EventHandler ReplyListChanged;
+        public static event EventHandler<CPDFAnnotationListUI.ReplyData> ReplyDeleted;
+
+
+        private static void OnIsShowInputChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            if (d is AnnotationReplyListControl control)
+            {
+                control.SetReplyInputVisibility((bool)e.NewValue);
+            }
+        }
+
+        public bool IsShowList
+        {
+            get => (bool)GetValue(IsShowListProperty);
+            set => SetValue(IsShowListProperty, value);
+        }
+
+        /// <summary>
+        /// The visibility of the reply list.
+        /// </summary>
+        public static readonly DependencyProperty IsShowListProperty = DependencyProperty.Register(
+            nameof(IsShowList),
+            typeof(bool),
+            typeof(AnnotationReplyListControl),
+            new PropertyMetadata(false, OnIsShowListChanged));
+
+        public void SetReplyInputVisibility(bool isVisible)
+        {
+            if (isVisible)
+            {
+                ReplyGrid.RowDefinitions[0].Height = new GridLength(1, GridUnitType.Auto);
+                ReplyGrid.RowDefinitions[1].Height = new GridLength(1, GridUnitType.Auto);
+            }
+            else
+            {
+                ReplyGrid.RowDefinitions[0].Height = new GridLength(0);
+                ReplyGrid.RowDefinitions[1].Height = new GridLength(0);
+            }
+        }
+
+        private static void OnIsShowListChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            if (d is AnnotationReplyListControl control)
+            {
+                control.SetReplyListVisibility((bool)e.NewValue);
+            }
+        }
+
+        public void SetReplyListVisibility(bool isVisible)
+        {
+            ReplyGrid.RowDefinitions[2].Height = isVisible ? new GridLength(1, GridUnitType.Auto) : new GridLength(0);
+        }
+
+        public static void InvokeReplyListChanged()
+        {
+            ReplyListChanged?.Invoke(null, EventArgs.Empty);
+        }
+
+        public static void InvokeReplyDeleted(CPDFAnnotationListUI.ReplyData replyData)
+        {
+            ReplyDeleted?.Invoke(null, replyData);
+        }
+
+        public AnnotationReplyListControl()
+        {
+            InitializeComponent();
+        }
+
+
+        private void ReplyButton_Click(object sender, RoutedEventArgs e)
+        {
+            if (sender is Button button)
+            {
+                if (button.DataContext is AnnotationBindData annotBindData)
+                {
+                    if (!string.IsNullOrEmpty(InputTxb.Text))
+                    {
+                        var replyAnnot = annotBindData.BindProperty.Annotation.CreateReplyAnnotation();
+                        replyAnnot.SetContent(InputTxb.Text);
+                        replyAnnot.SetAuthor(Data.CPDFAnnotationData.Author);
+                        annotBindData.BindProperty.ReplyList.Add(new CPDFAnnotationListUI.ReplyData
+                        {
+                            ReplyAnnotation = replyAnnot
+                        });
+                        InputTxb.Text = string.Empty;
+                        InvokeReplyListChanged();
+                    }
+                }
+            }
+        }
+
+        private void ButtonCancel_Click(object sender, RoutedEventArgs e)
+        {
+            IsShowInput = false;
+        }
+
+        private void ContentBox_LostFocus(object sender, RoutedEventArgs e)
+        {
+            if (sender is TextBox textBox)
+            {
+                textBox.Visibility = Visibility.Collapsed;
+                if (textBox.DataContext is CPDFAnnotationListUI.ReplyData replyData)
+                {
+                    replyData.ReplyAnnotation.SetContent(textBox.Text);
+                    InvokeReplyListChanged();
+                }
+            }
+        }
+
+        private void UserControl_Loaded(object sender, RoutedEventArgs e)
+        {
+            ReplyDeleted -= AnnotationReplyListControl_ReplyDeleted;
+            ReplyDeleted += AnnotationReplyListControl_ReplyDeleted;
+        }
+
+        private void AnnotationReplyListControl_ReplyDeleted(object sender, CPDFAnnotationListUI.ReplyData e)
+        {
+            ReplyListSource.Remove(e);
+        }
+    }
+
+    public class ShowContentBoxCommand : ICommand
+    {
+        public event EventHandler CanExecuteChanged;
+
+        public bool CanExecute(object parameter)
+        {
+            return true;
+        }
+
+        public void Execute(object parameter)
+        {
+            if (parameter is TextBox textBox)
+            {
+                textBox.Visibility = Visibility.Visible;
+                textBox.Focus();
+                textBox.SelectAll();
+            }
+        }
+    }
+
+    public class DeleteReplyCommand : ICommand
+    {
+        public event EventHandler CanExecuteChanged;
+
+        public bool CanExecute(object parameter)
+        {
+            return true;
+        }
+
+        public void Execute(object parameter)
+        {
+            if (parameter is CPDFAnnotationListUI.ReplyData replyData)
+            {
+                replyData.ReplyAnnotation.RemoveAnnot();
+                AnnotationReplyListControl.InvokeReplyDeleted(replyData);
+                AnnotationReplyListControl.InvokeReplyListChanged();
+            }
+        }
+    }
+
+}

+ 0 - 239
Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationList/PDFAnnotationListUI/CPDFAnnoationListUI.xaml.cs

@@ -1,239 +0,0 @@
-using ComPDFKit.PDFAnnotation;
-using ComPDFKit.Tool;
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.Text.RegularExpressions;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Input;
-using ComPDFKit.Controls.Helper;
-
-namespace ComPDFKit.Controls.PDFControlUI
-{
-    public partial class CPDFAnnoationListUI : UserControl
-    {
-        public class BindAnnotationResult : INotifyPropertyChanged
-        {
-            public int PageIndex { get; set; }
-
-            public int AnnotIndex { get => annotationData.AnnotIndex; }
-
-            public string CreateDate
-            {
-                get
-                {
-                    if (Regex.IsMatch(annotationData.CreateTime, "(?<=D\\:)[0-9]+(?=[\\+\\-])"))
-                    {
-                        string dateStr = Regex.Match(annotationData.CreateTime, "(?<=D\\:)[0-9]+(?=[\\+\\-])").Value;
-                        return (dateStr.Substring(0, 4) + "-" + dateStr.Substring(4, 2) + "-" + dateStr.Substring(6, 2) + ", " + dateStr.Substring(8, 2) + ":" +
-                            dateStr.Substring(10, 2));
-                    }
-                    else
-                    {
-                        return String.Empty;
-                    }
-                }
-            }
-
-            public string Note
-            {
-                get => annotationData.Content;
-            }
-
-            public C_ANNOTATION_TYPE CurrentAnnotationType
-            {
-                get => annotationData.CurrentType;
-            }
-
-            public AnnotParam annotationData { get; set; }
-
-            public event PropertyChangedEventHandler PropertyChanged;
-            protected void OnPropertyChanged(string propertyName)
-            {
-                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
-            }
-        }
-
-        internal class AnnotationBindData
-        {
-            public BindAnnotationResult BindProperty { get; set; }
-            public AnnotationBindData()
-            {
-                BindProperty = new BindAnnotationResult();
-            }
-            public int ShowPageIndex { get { return BindProperty.PageIndex + 1; } set { BindProperty.PageIndex = value; } }
-        }
-
-        private ObservableCollection<AnnotationBindData> annotationList = new ObservableCollection<AnnotationBindData>();
-
-        public event EventHandler<object> AnnotationSelectionChanged;
-
-        public event EventHandler<Dictionary<int, List<int>>> DeleteItemHandler;
-
-        private ContextMenu popContextMenu;
-        private bool enableSelectEvent = true;
-
-        public CPDFAnnoationListUI()
-        {
-            InitializeComponent();
-            ICollectionView groupView = CollectionViewSource.GetDefaultView(annotationList);
-            groupView.GroupDescriptions.Add(new PropertyGroupDescription(nameof(AnnotationBindData.ShowPageIndex)));
-            popContextMenu = new ContextMenu();
-            MenuItem deleteMenu = new MenuItem();
-            deleteMenu.Header = LanguageHelper.BotaManager.GetString("Menu_Delete");
-            deleteMenu.Click -= DeleteMenu_Click;
-            deleteMenu.Click += DeleteMenu_Click;
-            popContextMenu.Items.Add(deleteMenu);
-            MenuItem deleteAllMenu = new MenuItem();
-            deleteAllMenu.Header = LanguageHelper.BotaManager.GetString("Menu_DeleteAll");
-            deleteAllMenu.Click -= DeleteAllMenu_Click;
-            deleteAllMenu.Click += DeleteAllMenu_Click;
-            popContextMenu.Items.Add(deleteAllMenu);
-        }
-
-        private void DeleteAllMenu_Click(object sender, RoutedEventArgs e)
-        {
-            try
-            {
-                Dictionary<int, List<int>> delDict = new Dictionary<int, List<int>>();
-
-                foreach (AnnotationBindData bindData in annotationList)
-                {
-                    if (delDict.ContainsKey(bindData.BindProperty.PageIndex) == false)
-                    {
-                        delDict[bindData.BindProperty.PageIndex] = new List<int>();
-                    }
-                    delDict[bindData.BindProperty.PageIndex].Add(bindData.BindProperty.AnnotIndex);
-                }
-
-                if (delDict.Count > 0)
-                {
-                    DeleteItemHandler?.Invoke(this, delDict);
-                }
-            }
-            catch (Exception ex)
-            {
-
-            }
-        }
-
-        private void DeleteMenu_Click(object sender, RoutedEventArgs e)
-        {
-            try
-            {
-                if (AnnotationList != null && AnnotationList.SelectedIndex >= 0)
-                {
-                    AnnotationBindData bindData = annotationList[AnnotationList.SelectedIndex];
-
-                    Dictionary<int, List<int>> delDict = new Dictionary<int, List<int>>();
-                    delDict[bindData.BindProperty.PageIndex] = new List<int>()
-                    {
-                        bindData.BindProperty.AnnotIndex
-                    };
-                    DeleteItemHandler?.Invoke(this, delDict);
-                }
-            }
-            catch (Exception ex)
-            {
-
-            }
-        }
-
-        public void SetAnnotationList(List<BindAnnotationResult> results)
-        {
-            annotationList.Clear();
-            AnnotationList.ContextMenu = null;
-            if (results == null || results.Count == 0)
-            {
-                AnnotationList.ItemsSource = null;
-                NoContentText.Visibility = Visibility.Visible;
-                return;
-            }
-
-            foreach (BindAnnotationResult item in results)
-            {
-                annotationList.Add(new AnnotationBindData()
-                {
-                    BindProperty = item
-                });
-            }
-            AnnotationList.ItemsSource = annotationList;
-            if (annotationList.Count > 0)
-            {
-                AnnotationList.ContextMenu = popContextMenu;
-            }
-            AnnotationList.Visibility = Visibility.Visible;
-            NoContentText.Visibility = Visibility.Collapsed;
-        }
-
-        private void AnnotationListControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
-        {
-            if (enableSelectEvent)
-            {
-                try
-                {
-                    AnnotationSelectionChanged?.Invoke(this, (e.AddedItems[0] as AnnotationBindData).BindProperty);
-                }
-                catch { }
-            }
-        }
-         
-        public void CancelSelected()
-        {
-            AnnotationList.SelectedIndex = -1;
-        }
-
-        public void SelectAnnotationChanged(int annotationIndex = -1)
-        {
-
-            AnnotationList.SelectedIndex = annotationIndex;
-        }
-
-        public void SelectAnnotationChanged(int pageIIndex, int annotIndex)
-        {
-            if (annotationList != null && annotationList.Count > 0)
-            {
-                for (int i = 0; i < annotationList.Count; i++)
-                {
-                    AnnotationBindData data = annotationList[i];
-                    if (data.BindProperty.PageIndex == pageIIndex && data.BindProperty.AnnotIndex == annotIndex)
-                    {
-                        enableSelectEvent = false;
-                        AnnotationList.SelectedIndex = i;
-                        enableSelectEvent = true;
-                        break;
-                    }
-                }
-            }
-        }
-
-        private void AnnotationList_ContextMenuOpening(object sender, ContextMenuEventArgs e)
-        {
-            try
-            {
-                MenuItem checkMenu = popContextMenu.Items[0] as MenuItem;
-                if (checkMenu != null)
-                {
-                    checkMenu.IsEnabled = true;
-                }
-                if (AnnotationList != null && AnnotationList.SelectedIndex == -1)
-                {
-                    checkMenu.IsEnabled = false;
-                }
-
-            }
-            catch (Exception ex)
-            {
-
-            }
-        }
-
-        private void AnnotationList_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
-        {
-            CancelSelected();
-        }
-    }
-}

File diff suppressed because it is too large
+ 121 - 24
Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationList/PDFAnnotationListUI/CPDFAnnoationListUI.xaml


+ 690 - 0
Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationList/PDFAnnotationListUI/CPDFAnnotationListUI.xaml.cs

@@ -0,0 +1,690 @@
+using ComPDFKit.PDFAnnotation;
+using ComPDFKit.Tool;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Text.RegularExpressions;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Input;
+using ComPDFKit.Controls.Helper;
+using System.Collections.Specialized;
+using ComPDFKit.Controls.PDFControl;
+using static ComPDFKit.Controls.PDFControlUI.CPDFAnnotationListUI;
+using ComPDFKit.Controls.Data;
+
+namespace ComPDFKit.Controls.PDFControlUI
+{
+    public class ShowReplyListCommand : ICommand
+    {
+        public event EventHandler CanExecuteChanged;
+
+        public bool CanExecute(object parameter)
+        {
+            return true;
+        }
+
+        public void Execute(object parameter)
+        {
+            if (parameter is AnnotationBindData data)
+            {
+                data.IsReplyListVisible = !data.IsReplyListVisible;
+            }
+        }
+    }
+
+    public class ShowReplyInputCommand : ICommand
+    {
+        public event EventHandler CanExecuteChanged;
+
+        public bool CanExecute(object parameter)
+        {
+            return true;
+        }
+
+        public void Execute(object parameter)
+        {
+            if (parameter is AnnotationBindData data)
+            {
+                data.IsReplyInputVisible = !data.IsReplyInputVisible;
+                if(data.IsReplyInputVisible)
+                {
+                    data.IsReplyListVisible = true;
+                }
+            }
+        }
+    }
+
+    internal class AnnotationBindData : INotifyPropertyChanged
+    {
+        public PDFViewControl pdfViewer { get; set; }
+
+        public AnnotParam annotationData { get; set; }
+
+        public string ReplyCount
+        {
+            get => ReplyList.Count.ToString();
+        }
+
+        private bool _isReplyListVisible = true;
+        public bool IsReplyListVisible
+        {
+            get { return _isReplyListVisible; }
+            set
+            {
+                _isReplyListVisible = value;
+                OnPropertyChanged(nameof(IsReplyListVisible));
+            }
+        }
+
+        private bool _isReplyInputVisible;
+        public bool IsReplyInputVisible
+        {
+            get { return _isReplyInputVisible; }
+            set
+            {
+                _isReplyInputVisible = value;
+                OnPropertyChanged(nameof(IsReplyInputVisible));
+            }
+        }
+
+        public int PageIndex { get; set; }
+
+        public int AnnotIndex { get => annotationData.AnnotIndex; }
+
+        public string Author
+        {
+            get => annotationData.Author;
+        }
+
+        public string Note
+        {
+            get => annotationData.Content;
+        }
+
+
+        private CPDFAnnotation _annotation;
+        public CPDFAnnotation Annotation
+        {
+            get
+            {
+                List<CPDFAnnotation> annotCoreList = pdfViewer?.GetCPDFViewer()?.GetDocument()?.PageAtIndex(annotationData.PageIndex, false)?.GetAnnotations();
+                return annotCoreList[annotationData.AnnotIndex];
+            }
+        }
+
+        private ObservableCollection<ReplyData> _replyList = new ObservableCollection<ReplyData>();
+
+        public ObservableCollection<ReplyData> ReplyList
+        {
+            get => _replyList;
+            set
+            {
+                if (_replyList != value)
+                {
+                    if (_replyList != null)
+                    {
+                        // Unsubscribe from the previous collection
+                        _replyList.CollectionChanged -= ReplyList_CollectionChanged;
+                    }
+
+                    _replyList = value;
+
+                    if (_replyList != null)
+                    {
+                        // Subscribe to the new collection
+                        _replyList.CollectionChanged += ReplyList_CollectionChanged;
+                    }
+
+                    OnPropertyChanged(nameof(ReplyList));
+                }
+            }
+        }
+
+        private ObservableCollection<AnnotationBindData> annotationList = new ObservableCollection<AnnotationBindData>();
+
+        private void ReplyList_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+        {
+            // Notify that the ReplyCount has changed when the collection changes
+            OnPropertyChanged(nameof(ReplyCount));
+        }
+
+        public BindAnnotationResult BindProperty { get; set; }
+        public AnnotationBindData()
+        {
+            BindProperty = new BindAnnotationResult();
+        }
+        public int ShowPageIndex { get { return BindProperty.PageIndex + 1; } set { BindProperty.PageIndex = value; } }
+
+        public event PropertyChangedEventHandler PropertyChanged;
+        protected void OnPropertyChanged(string propertyName)
+        {
+            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+        }
+    }
+
+    public partial class CPDFAnnotationListUI : UserControl
+    {
+        public event EventHandler<CPDFAnnotationState> ReplyStatusChanged;
+
+        public class ReplyData
+        {
+            public CPDFAnnotation ReplyAnnotation { get; set; }
+
+            public string Author
+            {
+                get => ReplyAnnotation.GetAuthor();
+                set => ReplyAnnotation.SetAuthor(value);
+            }
+
+            public string Date
+            {
+                get
+                {
+                    try
+                    {
+                        if (Regex.IsMatch(ReplyAnnotation.GetCreationDate(), "(?<=D\\:)[0-9]+(?=[\\+\\-])"))
+                        {
+                            string dateStr = Regex.Match(ReplyAnnotation.GetCreationDate(), "(?<=D\\:)[0-9]+(?=[\\+\\-])").Value;
+                            return (dateStr.Substring(0, 4) + "-" + dateStr.Substring(4, 2) + "-" + dateStr.Substring(6, 2) + ", " + dateStr.Substring(8, 2) + ":" +
+                                    dateStr.Substring(10, 2));
+                        }
+                        else
+                        {
+                            return string.Empty;
+                        }
+                    }
+                    catch (Exception)
+                    {
+                        return string.Empty;
+                    }
+
+                }
+                set => ReplyAnnotation.SetCreationDate(value);
+            }
+
+            public string Content
+            {
+                get => ReplyAnnotation.GetContent();
+                set => ReplyAnnotation.SetContent(value);
+            }
+        }
+         
+        public class BindAnnotationResult : INotifyPropertyChanged
+        {
+            private ObservableCollection<ReplyData> _replyList = new ObservableCollection<ReplyData>();
+
+            public ObservableCollection<ReplyData> ReplyList
+            {
+                get => _replyList;
+                set
+                {
+                    if (_replyList != value)
+                    {
+                        if (_replyList != null)
+                        {
+                            // Unsubscribe from the previous collection
+                            _replyList.CollectionChanged -= ReplyList_CollectionChanged;
+                        }
+
+                        _replyList = value;
+
+                        if (_replyList != null)
+                        {
+                            // Subscribe to the new collection
+                            _replyList.CollectionChanged += ReplyList_CollectionChanged; ;
+                        }
+
+                        OnPropertyChanged(nameof(ReplyList));
+                    }
+                }
+            }
+
+            private void ReplyList_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+            {         
+                OnPropertyChanged(nameof(ReplyCount));
+            }
+
+            private Visibility _isAnnotListVisible = Visibility.Visible;
+            public Visibility IsAnnotListVisible
+            {
+                get { return _isAnnotListVisible; }
+                set
+                {
+                    _isAnnotListVisible = value;
+                    OnPropertyChanged(nameof(IsAnnotListVisible));
+                }
+            }
+
+            public int PageIndex { get; set; }
+
+            public int AnnotIndex { get => annotationData.AnnotIndex; }
+
+            public string Author
+            {
+                get => annotationData.Author;
+            }
+
+            public string ReplyCount
+            {
+                get => ReplyList.Count.ToString();
+            }
+
+            public string CreateDate
+            {
+                get
+                {
+                    if (Regex.IsMatch(annotationData.CreateTime, "(?<=D\\:)[0-9]+(?=[\\+\\-])"))
+                    {
+                        string dateStr = Regex.Match(annotationData.CreateTime, "(?<=D\\:)[0-9]+(?=[\\+\\-])").Value;
+                        return (dateStr.Substring(0, 4) + "-" + dateStr.Substring(4, 2) + "-" + dateStr.Substring(6, 2) + ", " + dateStr.Substring(8, 2) + ":" +
+                            dateStr.Substring(10, 2));
+                    }
+                    else
+                    {
+                        return string.Empty;
+                    }
+                }
+            }
+
+            public string Note
+            {
+                get => annotationData.Content;
+            }
+
+            public CPDFAnnotationType CurrentAnnotationType
+            {
+                get
+                {
+                    switch(Annotation.Type)
+                    {
+                        case C_ANNOTATION_TYPE.C_ANNOTATION_CIRCLE:
+                            return CPDFAnnotationType.Circle;
+
+                        case C_ANNOTATION_TYPE.C_ANNOTATION_SQUARE:
+                            return CPDFAnnotationType.Square;
+
+                        case C_ANNOTATION_TYPE.C_ANNOTATION_LINE:
+                            {
+                                if(Annotation.IsMeasured())
+                                    return CPDFAnnotationType.LineMeasure;
+                                else
+                                    return CPDFAnnotationType.Line;
+                            }
+
+                        case C_ANNOTATION_TYPE.C_ANNOTATION_FREETEXT:
+                             return CPDFAnnotationType.FreeText;
+
+                        case C_ANNOTATION_TYPE.C_ANNOTATION_HIGHLIGHT:
+                             return CPDFAnnotationType.Highlight;
+
+                        case C_ANNOTATION_TYPE.C_ANNOTATION_SQUIGGLY:
+                            return CPDFAnnotationType.Squiggly;
+
+                        case C_ANNOTATION_TYPE.C_ANNOTATION_STRIKEOUT:
+                            return CPDFAnnotationType.Strikeout;
+
+                        case C_ANNOTATION_TYPE.C_ANNOTATION_UNDERLINE:
+                            return CPDFAnnotationType.Underline;
+
+                        case C_ANNOTATION_TYPE.C_ANNOTATION_INK:
+                            return CPDFAnnotationType.Freehand;
+
+                        case C_ANNOTATION_TYPE.C_ANNOTATION_TEXT:
+                            return CPDFAnnotationType.Note;
+
+                        case C_ANNOTATION_TYPE.C_ANNOTATION_STAMP:
+                            return CPDFAnnotationType.Stamp;
+
+                        case C_ANNOTATION_TYPE.C_ANNOTATION_POLYLINE:
+                            {
+                                if (Annotation.IsMeasured())
+                                    return CPDFAnnotationType.PolyLineMeasure;
+                                else
+                                    return CPDFAnnotationType.PolyLine;
+                            }
+
+                        case C_ANNOTATION_TYPE.C_ANNOTATION_POLYGON:
+                            {
+                                if (Annotation.IsMeasured())
+                                    return CPDFAnnotationType.PolygonMeasure;
+                                else
+                                    return CPDFAnnotationType.Polygon;
+                            }
+
+                        default:
+                            return CPDFAnnotationType.Note;
+
+                    }
+
+                }
+
+            }
+
+            public AnnotParam annotationData { get; set; }
+
+            private CPDFAnnotation _annotation;
+            public CPDFAnnotation Annotation
+            {
+                get
+                {
+                    List<CPDFAnnotation> annotCoreList = pdfViewer?.GetCPDFViewer()?.GetDocument()?.PageAtIndex(annotationData.PageIndex, false)?.GetAnnotations();
+                    return annotCoreList[annotationData.AnnotIndex];
+                }
+            }
+
+            public PDFViewControl pdfViewer { get; set; }
+
+            public CPDFAnnotationState ReplyState { get; set; }
+
+            public bool IsMarkState { get; set; }
+            public BindAnnotationResult()
+            {
+                ReplyList.CollectionChanged += ReplyList_CollectionChanged;
+            }
+             
+            public event PropertyChangedEventHandler PropertyChanged;
+            protected void OnPropertyChanged(string propertyName)
+            {
+                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+            } 
+        }
+
+        private ObservableCollection<AnnotationBindData> annotationList = new ObservableCollection<AnnotationBindData>();
+
+        public event EventHandler<object> AnnotationSelectionChanged;
+
+        public event EventHandler<Dictionary<int, List<int>>> DeleteItemHandler;
+
+        private ContextMenu popContextMenu;
+        private bool enableSelectEvent = true;
+
+        public CPDFAnnotationListUI()
+        {
+            InitializeComponent();
+            ICollectionView groupView = CollectionViewSource.GetDefaultView(annotationList);
+            groupView.GroupDescriptions.Add(new PropertyGroupDescription(nameof(AnnotationBindData.ShowPageIndex)));
+            AnnotationList.PreviewMouseRightButtonUp += ((sender, args) => { SetContextMenu(); });
+        }
+
+        private void SetContextMenu()
+        {
+            if (AnnotationList.SelectedIndex == -1)
+            {
+                return;
+            }
+            popContextMenu = new ContextMenu();
+            AnnotationBindData data = annotationList[AnnotationList.SelectedIndex];
+
+            MenuItem deleteMenu = new MenuItem();
+            deleteMenu.Header = LanguageHelper.BotaManager.GetString("Menu_Delete");
+            deleteMenu.Click -= DeleteMenu_Click;
+            deleteMenu.Click += DeleteMenu_Click;
+            popContextMenu.Items.Add(deleteMenu);
+
+            MenuItem deleteAllMenu = new MenuItem();
+            deleteAllMenu.Header = LanguageHelper.BotaManager.GetString("Menu_DeleteAll");
+            deleteAllMenu.Click -= DeleteAllMenu_Click;
+            deleteAllMenu.Click += DeleteAllMenu_Click;
+            popContextMenu.Items.Add(deleteAllMenu);
+
+            MenuItem replyMenu = new MenuItem();
+            replyMenu.Header = LanguageHelper.BotaManager.GetString("Menu_AddReply");
+            replyMenu.Click += (sender, e) =>
+            {
+                if (AnnotationList != null && AnnotationList.SelectedIndex >= 0)
+                {
+                    data.IsReplyInputVisible = true;
+                }
+            };
+            popContextMenu.Items.Add(replyMenu);
+
+            MenuItem showReplyMenu = new MenuItem();
+
+            if (data.IsReplyListVisible)
+            {
+                showReplyMenu.Header = LanguageHelper.BotaManager.GetString("Menu_FoldReply");
+            }
+            else
+            {
+                showReplyMenu.Header = LanguageHelper.BotaManager.GetString("Menu_ExpandReply");
+            }
+            showReplyMenu.Click += (sender, e) =>
+            {
+                if (AnnotationList != null && AnnotationList.SelectedIndex >= 0)
+                {
+                    data.IsReplyListVisible = !data.IsReplyListVisible;
+                }
+            };
+            popContextMenu.Items.Add(showReplyMenu);
+
+            AnnotationList.ContextMenu = popContextMenu;
+        }
+
+        public void DeleteAllAnnot()
+        {
+            try
+            {
+                Dictionary<int, List<int>> delDict = new Dictionary<int, List<int>>();
+
+                foreach (AnnotationBindData bindData in annotationList)
+                {
+                    if (delDict.ContainsKey(bindData.BindProperty.PageIndex) == false)
+                    {
+                        delDict[bindData.BindProperty.PageIndex] = new List<int>();
+                    }
+                    delDict[bindData.BindProperty.PageIndex].Add(bindData.BindProperty.AnnotIndex);
+                }
+
+                if (delDict.Count > 0)
+                {
+                    DeleteItemHandler?.Invoke(this, delDict);
+                }
+            }
+            catch (Exception ex)
+            {
+                return;
+            }
+        }
+
+        public void DeleteAllReply()
+        {
+            try
+            {
+                foreach (var data in annotationList)
+                {
+                    foreach (var replyData in data.BindProperty.ReplyList)
+                    {
+                        replyData.ReplyAnnotation.RemoveAnnot();
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                return;
+            }
+        }
+
+        public void ExpandAllReply(bool isExpand)
+        {
+            foreach (AnnotationBindData data in annotationList)
+            {
+                data.IsReplyListVisible = isExpand;
+            }
+        }
+
+        public void ExpandAnnotList(bool isExpand)
+        {
+            foreach (AnnotationBindData data in annotationList)
+            {
+                if (isExpand)
+                    data.BindProperty.IsAnnotListVisible = Visibility.Visible;
+                else
+                    data.BindProperty.IsAnnotListVisible = Visibility.Collapsed;
+            }
+        }
+
+        private void DeleteAllMenu_Click(object sender, RoutedEventArgs e)
+        {
+            try
+            {
+                Dictionary<int, List<int>> delDict = new Dictionary<int, List<int>>();
+
+                foreach (AnnotationBindData bindData in annotationList)
+                {
+                    if (delDict.ContainsKey(bindData.BindProperty.PageIndex) == false)
+                    {
+                        delDict[bindData.BindProperty.PageIndex] = new List<int>();
+                    }
+                    delDict[bindData.BindProperty.PageIndex].Add(bindData.BindProperty.AnnotIndex);
+                }
+
+                if (delDict.Count > 0)
+                {
+                    DeleteItemHandler?.Invoke(this, delDict);
+                }
+            }
+            catch (Exception ex)
+            {
+
+            }
+        }
+
+        private void DeleteMenu_Click(object sender, RoutedEventArgs e)
+        {
+            try
+            {
+                if (AnnotationList != null && AnnotationList.SelectedIndex >= 0)
+                {
+                    AnnotationBindData bindData = annotationList[AnnotationList.SelectedIndex];
+
+                    Dictionary<int, List<int>> delDict = new Dictionary<int, List<int>>();
+                    delDict[bindData.BindProperty.PageIndex] = new List<int>()
+                    {
+                        bindData.BindProperty.AnnotIndex
+                    };
+                    DeleteItemHandler?.Invoke(this, delDict);
+                }
+            }
+            catch (Exception ex)
+            {
+
+            }
+        }
+
+        public void SetAnnotationList(List<BindAnnotationResult> results)
+        {
+            annotationList.Clear();
+            AnnotationList.ContextMenu = null;
+            if (results == null || results.Count == 0)
+            {
+                AnnotationList.ItemsSource = null;
+                NoContentText.Visibility = Visibility.Visible;
+                return;
+            }
+
+            foreach (BindAnnotationResult item in results)
+            {
+                annotationList.Add(new AnnotationBindData()
+                {
+                    BindProperty = item
+                });
+            }
+            AnnotationList.ItemsSource = annotationList;
+            if (annotationList.Count > 0)
+            {
+                AnnotationList.ContextMenu = popContextMenu;
+            }
+            AnnotationList.Visibility = Visibility.Visible;
+            NoContentText.Visibility = Visibility.Collapsed;
+        }
+
+        private void AnnotationListControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+            if (enableSelectEvent)
+            {
+                try
+                {
+                    if (e.AddedItems[0] is AnnotationBindData annotationBindData)
+                    {
+                        AnnotationSelectionChanged?.Invoke(this, (annotationBindData).BindProperty);
+                    }
+                }
+                catch { }
+            }
+        }
+
+        public void CancelSelected()
+        {
+            AnnotationList.SelectedIndex = -1;
+        }
+
+        public void SelectAnnotationChanged(int annotationIndex = -1)
+        {
+
+            AnnotationList.SelectedIndex = annotationIndex;
+        }
+
+        public void SelectAnnotationChanged(int pageIIndex, int annotIndex)
+        {
+            if (annotationList != null && annotationList.Count > 0)
+            {
+                for (int i = 0; i < annotationList.Count; i++)
+                {
+                    AnnotationBindData data = annotationList[i];
+                    if (data.BindProperty.PageIndex == pageIIndex && data.BindProperty.AnnotIndex == annotIndex)
+                    {
+                        enableSelectEvent = false;
+                        AnnotationList.SelectedIndex = i;
+                        enableSelectEvent = true;
+                        break;
+                    }
+                }
+            }
+        }
+
+        private void AnnotationList_ContextMenuOpening(object sender, ContextMenuEventArgs e)
+        {
+            try
+            {
+                if (popContextMenu.Items[0] is MenuItem checkMenu)
+                {
+                    if (checkMenu != null)
+                    {
+                        checkMenu.IsEnabled = true;
+                    }
+                    if (AnnotationList != null && AnnotationList.SelectedIndex == -1)
+                    {
+                        checkMenu.IsEnabled = false;
+                    }
+                }  
+            }
+            catch (Exception ex)
+            {
+
+            }
+        }
+
+        private void AnnotationList_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            CancelSelected();
+        }
+
+        private void ToggleButton_Checked(object sender, RoutedEventArgs e)
+        {
+            ReplyStatusChanged?.Invoke(sender, CPDFAnnotationState.C_ANNOTATION_MARKED);
+        }
+
+        private void ToggleButton_Unchecked(object sender, RoutedEventArgs e)
+        {
+            ReplyStatusChanged?.Invoke(sender, CPDFAnnotationState.C_ANNOTATION_UNMARKED);
+        }
+
+        private void StatusControl_ReplyStatusChanged(object sender, CPDFAnnotationState e)
+        {
+            ReplyStatusChanged?.Invoke(sender, e);
+        }
+    }
+}

+ 71 - 0
Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationList/PDFAnnotationListUI/ReplyStatusControl.xaml

@@ -0,0 +1,71 @@
+<UserControl x:Class="ComPDFKit.Controls.PDFControlUI.ReplyStatusControl"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:local="clr-namespace:ComPDFKit.Controls.PDFControlUI"
+             mc:Ignorable="d"  
+             d:DesignHeight="450" d:DesignWidth="800">
+    <UserControl.Resources>
+        <Style x:Key="MenuItemStyle" TargetType="local:PathMenuItem">
+            <Setter Property="Template">
+                <Setter.Value>
+                    <ControlTemplate TargetType="{x:Type local:PathMenuItem}">
+                        <Border x:Name="border"
+                            Background="#FFFFFF"
+                            BorderThickness="0"
+                            Height="40">
+                            <Grid Margin="20,0,20,0">
+                                <Grid.ColumnDefinitions>
+                                    <ColumnDefinition Width="Auto"></ColumnDefinition>
+                                    <ColumnDefinition Width="Auto"></ColumnDefinition>
+                                </Grid.ColumnDefinitions>
+                                <ContentPresenter x:Name="IconPresenter"
+                                              ContentSource="IconPath"
+                                              Grid.Column="0">
+                                </ContentPresenter>
+                                <ContentPresenter x:Name="contentPresenter"
+                                              Grid.Column="1"
+                                              ContentSource="Header"
+                                              TextBlock.Foreground="#000000"
+                                              TextBlock.FontFamily="SegoeUI"
+                                              TextBlock.FontSize="15"
+                                              Margin="10,0,0,0"
+                                              HorizontalAlignment="Left"
+                                              VerticalAlignment="Center">
+                                </ContentPresenter>
+                            </Grid>
+                        </Border>
+                        <ControlTemplate.Triggers>
+                            <Trigger Property="IsEnabled" Value="False">
+                                <Setter Property="TextBlock.Foreground" TargetName="contentPresenter" Value="#6A6A6A"></Setter>
+                                <Setter TargetName="border" Property="Background" Value="#EFEFEF"></Setter>
+                            </Trigger>
+                            <Trigger Property="IsHighlighted" Value="True">
+                                <Setter Property="Background" TargetName="border" Value="#2894FF"></Setter>
+                                <Setter Property="BorderBrush" TargetName="border" Value="#2894FF"></Setter>
+                                <Setter Property="TextBlock.Foreground" TargetName="contentPresenter" Value="#FFFFFF"></Setter>
+                            </Trigger>
+                        </ControlTemplate.Triggers>
+                    </ControlTemplate>
+                </Setter.Value>
+            </Setter>
+        </Style>
+    </UserControl.Resources>
+    <Grid Height="auto">
+        <Grid Height="30" Width="30">
+            <Menu Background="Transparent">
+                <local:PathMenuItem x:Name="IconMenu" Height="30" Width="30" Margin="0" Padding="0">
+                    <local:PathMenuItem.Header>
+                        <Grid x:Name="ButtonIcon" Height="30" Width="30">
+                            <Canvas Height="20" Width="20"> 
+                                <Rectangle Stroke="#5A000000" StrokeThickness="2" Width="16" Height="16"/>
+                                <Line X1="1" Y1="1" X2="15" Y2="15" Stroke="#5A000000" StrokeThickness="2"/>
+                            </Canvas>
+                        </Grid>
+                    </local:PathMenuItem.Header>
+                </local:PathMenuItem>
+            </Menu>
+        </Grid>
+    </Grid>
+</UserControl>

File diff suppressed because it is too large
+ 175 - 0
Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationList/PDFAnnotationListUI/ReplyStatusControl.xaml.cs


+ 8 - 4
Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationPanel/PDFAnnotationControl/CPDFAnnotationControl.xaml.cs

@@ -12,7 +12,6 @@ using ComPDFKit.Controls.Annotation.PDFAnnotationUI;
 using Microsoft.Win32;
 using Microsoft.Win32;
 using System.Windows.Media;
 using System.Windows.Media;
 using ComPDFKit.Controls.Properties;
 using ComPDFKit.Controls.Properties;
-using static ComPDFKit.Tool.CPDFToolManager;
 using ComPDFKit.PDFAnnotation;
 using ComPDFKit.PDFAnnotation;
 using ComPDFKit.Tool;
 using ComPDFKit.Tool;
 using ComPDFKit.Tool.Help;
 using ComPDFKit.Tool.Help;
@@ -101,7 +100,6 @@ namespace ComPDFKit.Controls.PDFControl
         {
         {
             if (e.IsCreate)
             if (e.IsCreate)
             {
             {
-                pdfViewerControl.UpdateAnnotFrame();
                 if (currentAnnotationType == CPDFAnnotationType.Image || currentAnnotationType == CPDFAnnotationType.Stamp || currentAnnotationType == CPDFAnnotationType.Signature)
                 if (currentAnnotationType == CPDFAnnotationType.Image || currentAnnotationType == CPDFAnnotationType.Stamp || currentAnnotationType == CPDFAnnotationType.Signature)
                 {
                 {
                     pdfViewerControl.SetToolType(ToolType.Pan);
                     pdfViewerControl.SetToolType(ToolType.Pan);
@@ -409,6 +407,7 @@ namespace ComPDFKit.Controls.PDFControl
                         PDFHelp.ImageStreamToByte(stampParam.ImageStream, ref imageData, ref imageWidth, ref imageHeight);
                         PDFHelp.ImageStreamToByte(stampParam.ImageStream, ref imageData, ref imageWidth, ref imageHeight);
                         if (imageData != null && imageWidth > 0 && imageHeight > 0)
                         if (imageData != null && imageWidth > 0 && imageHeight > 0)
                         {
                         {
+                            pdfViewerControl.PDFViewTool.GetCPDFViewer().SetMouseImageMaxSize(200, 300);
                             pdfViewerControl.SetStampMouseImage(imageData, imageWidth, imageHeight);
                             pdfViewerControl.SetStampMouseImage(imageData, imageWidth, imageHeight);
                         }
                         }
 
 
@@ -434,6 +433,7 @@ namespace ComPDFKit.Controls.PDFControl
                                     PDFHelp.ImageStreamToByte(stampParam.ImageStream, ref imageData, ref imageWidth, ref imageHeight);
                                     PDFHelp.ImageStreamToByte(stampParam.ImageStream, ref imageData, ref imageWidth, ref imageHeight);
                                     if (imageData != null && imageWidth > 0 && imageHeight > 0)
                                     if (imageData != null && imageWidth > 0 && imageHeight > 0)
                                     {
                                     {
+                                        pdfViewerControl.PDFViewTool.GetCPDFViewer().SetMouseImageMaxSize(200, 300);
                                         pdfViewerControl.SetStampMouseImage(imageData, imageWidth, imageHeight);
                                         pdfViewerControl.SetStampMouseImage(imageData, imageWidth, imageHeight);
                                         pdfViewerControl.SetIsVisibleCustomMouse(true);
                                         pdfViewerControl.SetIsVisibleCustomMouse(true);
                                         pdfViewerControl.SetIsShowStampMouse(true);
                                         pdfViewerControl.SetIsShowStampMouse(true);
@@ -446,6 +446,7 @@ namespace ComPDFKit.Controls.PDFControl
                                     WriteableBitmap writeableBitmap = CreateInkImage(signatureParam as InkParam);
                                     WriteableBitmap writeableBitmap = CreateInkImage(signatureParam as InkParam);
                                     byte[] imageArray = new byte[writeableBitmap.PixelWidth * writeableBitmap.PixelHeight * 4];
                                     byte[] imageArray = new byte[writeableBitmap.PixelWidth * writeableBitmap.PixelHeight * 4];
                                     writeableBitmap.CopyPixels(imageArray, writeableBitmap.PixelWidth * 4, 0);
                                     writeableBitmap.CopyPixels(imageArray, writeableBitmap.PixelWidth * 4, 0);
+                                    pdfViewerControl.PDFViewTool.GetCPDFViewer().SetMouseImageMaxSize(writeableBitmap.PixelWidth, writeableBitmap.PixelHeight);
                                     pdfViewerControl.SetStampMouseImage(imageArray, writeableBitmap.PixelWidth, writeableBitmap.PixelHeight);
                                     pdfViewerControl.SetStampMouseImage(imageArray, writeableBitmap.PixelWidth, writeableBitmap.PixelHeight);
                                     pdfViewerControl.SetIsVisibleCustomMouse(true);
                                     pdfViewerControl.SetIsVisibleCustomMouse(true);
                                     pdfViewerControl.SetIsShowStampMouse(true);
                                     pdfViewerControl.SetIsShowStampMouse(true);
@@ -484,6 +485,7 @@ namespace ComPDFKit.Controls.PDFControl
             {
             {
                 return null;
                 return null;
             }
             }
+
             if (inkParam.InkPath != null && inkParam.InkPath.Count > 0)
             if (inkParam.InkPath != null && inkParam.InkPath.Count > 0)
             {
             {
                 GeometryGroup PaintGeomtry = new GeometryGroup();
                 GeometryGroup PaintGeomtry = new GeometryGroup();
@@ -514,10 +516,10 @@ namespace ComPDFKit.Controls.PDFControl
                         }
                         }
                     }
                     }
                 }
                 }
+
                 if (minLeft >= 0 && maxLeft > minLeft && minTop >= 0 && maxTop > minTop)
                 if (minLeft >= 0 && maxLeft > minLeft && minTop >= 0 && maxTop > minTop)
                 {
                 {
                     List<List<CPoint>> points = new List<List<CPoint>>();
                     List<List<CPoint>> points = new List<List<CPoint>>();
-
                     foreach (List<CPoint> Item in inkParam.InkPath)
                     foreach (List<CPoint> Item in inkParam.InkPath)
                     {
                     {
                         PathGeometry PaintPath = new PathGeometry();
                         PathGeometry PaintPath = new PathGeometry();
@@ -548,13 +550,13 @@ namespace ComPDFKit.Controls.PDFControl
                             points.Add(changeList);
                             points.Add(changeList);
                         }
                         }
                     }
                     }
+
                     int drawWidth = (int)DpiHelper.PDFNumToStandardNum(maxLeft - minLeft);
                     int drawWidth = (int)DpiHelper.PDFNumToStandardNum(maxLeft - minLeft);
                     int drawHeight = (int)DpiHelper.PDFNumToStandardNum(maxTop - minTop);
                     int drawHeight = (int)DpiHelper.PDFNumToStandardNum(maxTop - minTop);
 
 
                     inkParam.InkPath = points;
                     inkParam.InkPath = points;
                     DefaultSettingParam defaultSettingParam = pdfViewerControl.PDFViewTool.GetDefaultSettingParam();
                     DefaultSettingParam defaultSettingParam = pdfViewerControl.PDFViewTool.GetDefaultSettingParam();
                     defaultSettingParam.SetAnnotParam(inkParam);
                     defaultSettingParam.SetAnnotParam(inkParam);
-
                     DrawingVisual copyVisual = new DrawingVisual();
                     DrawingVisual copyVisual = new DrawingVisual();
                     DrawingContext copyContext = copyVisual.RenderOpen();
                     DrawingContext copyContext = copyVisual.RenderOpen();
 
 
@@ -895,6 +897,8 @@ namespace ComPDFKit.Controls.PDFControl
                                     {
                                     {
                                         frame.CopyPixels(imageArray, frame.PixelWidth * 4, 0);
                                         frame.CopyPixels(imageArray, frame.PixelWidth * 4, 0);
                                     }
                                     }
+
+                                    pdfViewerControl.PDFViewTool.GetCPDFViewer().SetMouseImageMaxSize(200, 300);
                                     pdfViewerControl.SetStampMouseImage(imageArray, frame.PixelWidth, frame.PixelHeight);
                                     pdfViewerControl.SetStampMouseImage(imageArray, frame.PixelWidth, frame.PixelHeight);
                                 }
                                 }
 
 

+ 1 - 0
Demo/Examples/Compdfkit.Controls/Annotation/PDFAnnotationPanel/PDFAnnotationUI/CPDFSignatureUI.xaml.cs

@@ -75,6 +75,7 @@ namespace ComPDFKit.Controls.Annotation.PDFAnnotationPanel.PDFAnnotationUI
             else
             else
             {
             {
                 FillForm(((sender as ListBoxItem).DataContext as CPDFSignatureData).SourcePath);
                 FillForm(((sender as ListBoxItem).DataContext as CPDFSignatureData).SourcePath);
+                viewControl.PDFViewTool.IsDocumentModified = true;
             }
             }
         }
         }
 
 

+ 1 - 1
Demo/Examples/Compdfkit.Controls/Asset/Styles/ComboBoxStyle.xaml

@@ -394,7 +394,7 @@
                                     <Border.Effect>
                                     <Border.Effect>
                                         <DropShadowEffect Color="Black" BlurRadius="4" ShadowDepth="0" Opacity="0.5"/>
                                         <DropShadowEffect Color="Black" BlurRadius="4" ShadowDepth="0" Opacity="0.5"/>
                                     </Border.Effect>
                                     </Border.Effect>
-                                    <ScrollViewer Margin="4,6,4,6" Style="{DynamicResource ScrollViewerStyle}" MaxHeight="{TemplateBinding MaxDropDownHeight}" SnapsToDevicePixels="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" CanContentScroll="True">
+                                    <ScrollViewer Margin="0,3,0,6" Style="{DynamicResource ScrollViewerStyle}" MaxHeight="{TemplateBinding MaxDropDownHeight}" SnapsToDevicePixels="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" CanContentScroll="True">
                                         <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" Background="White"/>
                                         <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" Background="White"/>
                                     </ScrollViewer>
                                     </ScrollViewer>
                                 </Border>
                                 </Border>

+ 0 - 2
Demo/Examples/Compdfkit.Controls/Asset/Styles/ListBoxItemStyle.xaml

@@ -20,8 +20,6 @@
     <Style x:Key="ThumbnailListBoxItemStyle" TargetType="{x:Type ListBoxItem}">
     <Style x:Key="ThumbnailListBoxItemStyle" TargetType="{x:Type ListBoxItem}">
         <Setter Property="SnapsToDevicePixels" Value="True"/>
         <Setter Property="SnapsToDevicePixels" Value="True"/>
         <Setter Property="Padding" Value="4,1"/>
         <Setter Property="Padding" Value="4,1"/>
-        <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
-        <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
         <Setter Property="Background" Value="Transparent"/>
         <Setter Property="Background" Value="Transparent"/>
         <Setter Property="BorderBrush" Value="Transparent"/>
         <Setter Property="BorderBrush" Value="Transparent"/>
         <Setter Property="BorderThickness" Value="1"/>
         <Setter Property="BorderThickness" Value="1"/>

+ 4 - 0
Demo/Examples/Compdfkit.Controls/Common/BarControl/CPDFTitleBarControl.xaml

@@ -38,6 +38,8 @@
                         <MenuItem Header="{Binding Converter={StaticResource CommonResourceConverter},ConverterParameter=HelpMenu_Service}" Style="{StaticResource Sub_MenuItem}" Click="ServiceTerms_Click"></MenuItem>
                         <MenuItem Header="{Binding Converter={StaticResource CommonResourceConverter},ConverterParameter=HelpMenu_Service}" Style="{StaticResource Sub_MenuItem}" Click="ServiceTerms_Click"></MenuItem>
                         <MenuItem Header="{Binding Converter={StaticResource CommonResourceConverter},ConverterParameter=HelpMenu_DeviceID}" Style="{StaticResource Sub_MenuItem}" Click="DeviceSerial_Click"></MenuItem>
                         <MenuItem Header="{Binding Converter={StaticResource CommonResourceConverter},ConverterParameter=HelpMenu_DeviceID}" Style="{StaticResource Sub_MenuItem}" Click="DeviceSerial_Click"></MenuItem>
                     </MenuItem>
                     </MenuItem>
+
+                    <MenuItem Header="{Binding Converter={StaticResource CommonResourceConverter},ConverterParameter=Printer_Print}" Style="{StaticResource Dropdown_MenuItem}" Click="PrintItem_Click"></MenuItem>
                 </Menu>
                 </Menu>
 
 
                 <Menu 
                 <Menu 
@@ -68,6 +70,8 @@
                         <MenuItem Header="Contact us" Style="{StaticResource Sub_MenuItem }"></MenuItem>
                         <MenuItem Header="Contact us" Style="{StaticResource Sub_MenuItem }"></MenuItem>
                     </MenuItem>
                     </MenuItem>
                 </Menu>
                 </Menu>
+                
+                
             </StackPanel>
             </StackPanel>
         </Grid>
         </Grid>
     </Grid>
     </Grid>

+ 7 - 1
Demo/Examples/Compdfkit.Controls/Common/BarControl/CPDFTitleBarControl.xaml.cs

@@ -19,7 +19,8 @@ namespace ComPDFKit.Controls.PDFControl
         public event EventHandler SaveFileEvent;
         public event EventHandler SaveFileEvent;
         public event EventHandler SaveAsFileEvent;
         public event EventHandler SaveAsFileEvent;
         public event EventHandler FlattenEvent; 
         public event EventHandler FlattenEvent; 
-
+        public event EventHandler PrintEvent;
+           
         public CPDFTitleBarControl()
         public CPDFTitleBarControl()
         {
         {
             InitializeComponent();
             InitializeComponent();
@@ -79,5 +80,10 @@ namespace ComPDFKit.Controls.PDFControl
         {
         {
             FlattenEvent?.Invoke(sender, RoutedEventArgs.Empty);
             FlattenEvent?.Invoke(sender, RoutedEventArgs.Empty);
         }
         }
+
+        private void PrintItem_Click(object sender, RoutedEventArgs e)
+        {
+            PrintEvent?.Invoke(sender, RoutedEventArgs.Empty);
+        }
     }
     }
 }
 }

+ 2 - 4
Demo/Examples/Compdfkit.Controls/Common/BaseControl/PageNumberControl.xaml

@@ -14,7 +14,6 @@
                 <ColumnDefinition Width="auto"></ColumnDefinition>
                 <ColumnDefinition Width="auto"></ColumnDefinition>
             </Grid.ColumnDefinitions>
             </Grid.ColumnDefinitions>
 
 
-            <!--上一页-->
             <Border Background="Transparent" Width="20" Height="20" Margin="11,0,0,0" MouseLeftButtonDown="PrevPageBorder_MouseLeftButtonDown">
             <Border Background="Transparent" Width="20" Height="20" Margin="11,0,0,0" MouseLeftButtonDown="PrevPageBorder_MouseLeftButtonDown">
                 <Path Fill="White" VerticalAlignment="Center" HorizontalAlignment="Center">
                 <Path Fill="White" VerticalAlignment="Center" HorizontalAlignment="Center">
                     <Path.Data>
                     <Path.Data>
@@ -26,16 +25,15 @@
                 </Path>
                 </Path>
             </Border>
             </Border>
 
 
-            <!--页码范围-->
             <TextBlock Name="PageRangeText" Grid.Column="1" Foreground="White" FontSize="12" VerticalAlignment="Center" HorizontalAlignment="Center" 
             <TextBlock Name="PageRangeText" Grid.Column="1" Foreground="White" FontSize="12" VerticalAlignment="Center" HorizontalAlignment="Center" 
-                       MouseLeftButtonUp="PageRangeText_MouseLeftButtonUp">19999/99999</TextBlock>
+                       MouseLeftButtonUp="PageRangeText_MouseLeftButtonUp">1/1</TextBlock>
 
 
             <TextBox Name="PageInputText" Grid.Column="1" VerticalAlignment="Center" Background="Transparent" Foreground="White" FontSize="12"
             <TextBox Name="PageInputText" Grid.Column="1" VerticalAlignment="Center" Background="Transparent" Foreground="White" FontSize="12"
                      LostFocus="PageInputText_LostFocus" KeyDown="PageInputText_KeyDown" Visibility="Collapsed" InputMethod.IsInputMethodEnabled="False"
                      LostFocus="PageInputText_LostFocus" KeyDown="PageInputText_KeyDown" Visibility="Collapsed" InputMethod.IsInputMethodEnabled="False"
                      PreviewKeyDown="PageInputText_PreviewKeyDown" CaretBrush="White" CommandManager.PreviewCanExecute="PageInputText_CanExecute"
                      PreviewKeyDown="PageInputText_PreviewKeyDown" CaretBrush="White" CommandManager.PreviewCanExecute="PageInputText_CanExecute"
                      HorizontalContentAlignment="Center"
                      HorizontalContentAlignment="Center"
                       ></TextBox>
                       ></TextBox>
-            <!--下一页-->
+            
             <Border Width="20" Height="20" Background="Transparent" Grid.Column="2" Margin="0,0,11,0" MouseLeftButtonDown="NextPageBorder_MouseLeftButtonDown">
             <Border Width="20" Height="20" Background="Transparent" Grid.Column="2" Margin="0,0,11,0" MouseLeftButtonDown="NextPageBorder_MouseLeftButtonDown">
                 <Path Fill="White" VerticalAlignment="Center" HorizontalAlignment="Center">
                 <Path Fill="White" VerticalAlignment="Center" HorizontalAlignment="Center">
                     <Path.Data>
                     <Path.Data>

+ 3 - 3
Demo/Examples/Compdfkit.Controls/Common/Convert/AnnotArgsTypeToVisibilityConverter.cs

@@ -1,4 +1,4 @@
-using ComPDFKit.PDFAnnotation;
+using ComPDFKit.Controls.Data;
 using System;
 using System;
 using System.Globalization;
 using System.Globalization;
 using System.Windows;
 using System.Windows;
@@ -6,12 +6,12 @@ using System.Windows.Data;
 
 
 namespace ComPDFKit.Controls.Common
 namespace ComPDFKit.Controls.Common
 {
 {
-    [ValueConversion(typeof(C_ANNOTATION_TYPE), typeof(Visibility))]
+    [ValueConversion(typeof(CPDFAnnotationType), typeof(Visibility))]
     public class AnnotArgsTypeToVisibilityConverter : IValueConverter
     public class AnnotArgsTypeToVisibilityConverter : IValueConverter
     {
     {
         public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
         public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
         {
         {
-            C_ANNOTATION_TYPE annotArgsType = (C_ANNOTATION_TYPE)value;
+            CPDFAnnotationType annotArgsType = (CPDFAnnotationType)value;
             if (annotArgsType.ToString() == parameter as string)
             if (annotArgsType.ToString() == parameter as string)
             {
             {
                 return Visibility.Visible;
                 return Visibility.Visible;

+ 25 - 0
Demo/Examples/Compdfkit.Controls/Common/Convert/AntiVisibilityConverter.cs

@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Data;
+
+namespace ComPDFKit.Controls.Common
+{
+    [ValueConversion(typeof(Visibility), typeof(Visibility))]
+    internal class AntiVisibilityConverter: IValueConverter
+    {
+        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            return (Visibility)value == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
+        }
+
+        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            return (Visibility)value == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
+        }
+    }
+}

+ 8 - 10
Demo/Examples/Compdfkit.Controls/Common/Convert/LanguageResourceConverter.cs

@@ -6,8 +6,6 @@ using ComPDFKit.Controls.Helper;
 
 
 namespace ComPDFKit.Controls.Common
 namespace ComPDFKit.Controls.Common
 {
 {
-
-
     public class BotaResourceConverter : IValueConverter
     public class BotaResourceConverter : IValueConverter
     {
     {
         public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
         public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
@@ -22,7 +20,7 @@ namespace ComPDFKit.Controls.Common
 
 
         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
         {
         {
-            throw new NotSupportedException();
+            return null;
         }
         }
     }
     }
 
 
@@ -40,7 +38,7 @@ namespace ComPDFKit.Controls.Common
 
 
         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
         {
         {
-            throw new NotSupportedException();
+            return null;
         }
         }
     }
     }
 
 
@@ -58,7 +56,7 @@ namespace ComPDFKit.Controls.Common
 
 
         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
         {
         {
-            throw new NotSupportedException();
+            return null;
         }
         }
     }
     }
 
 
@@ -76,7 +74,7 @@ namespace ComPDFKit.Controls.Common
 
 
         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
         {
         {
-            throw new NotSupportedException();
+            return null;
         }
         }
     }
     }
 
 
@@ -94,7 +92,7 @@ namespace ComPDFKit.Controls.Common
 
 
         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
         {
         {
-            throw new NotSupportedException();
+            return null;
         }
         }
     }
     }
     
     
@@ -112,7 +110,7 @@ namespace ComPDFKit.Controls.Common
 
 
         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
         {
         {
-            throw new NotSupportedException();
+            return null;
         }
         }
     }
     }
     
     
@@ -130,7 +128,7 @@ namespace ComPDFKit.Controls.Common
 
 
         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
         {
         {
-            throw new NotSupportedException();
+            return null;
         }
         }
     }
     }
     
     
@@ -148,7 +146,7 @@ namespace ComPDFKit.Controls.Common
 
 
         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
         {
         {
-            throw new NotSupportedException();
+            return null;
         }
         }
     }
     }
 }
 }

+ 28 - 0
Demo/Examples/Compdfkit.Controls/Common/Convert/SubtractionConverter.cs

@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace ComPDFKit.Controls.Common 
+{
+    [ValueConversion(typeof(double), typeof(double))]
+    public class SubtractionConverter : IValueConverter
+    {
+        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            if (value is double actualWidth && parameter is string parameterValue && double.TryParse(parameterValue, out double subtractValue))
+            {
+                return actualWidth - subtractValue;
+            }
+            return value;
+        }
+
+        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            return null;
+        }
+    }
+}

+ 1 - 1
Demo/Examples/Compdfkit.Controls/Common/PropertyControl/PDFFont/CPDFFontControl.xaml.cs

@@ -31,7 +31,7 @@ namespace ComPDFKit.Controls.Common
                 var _fontFamilyName = string.Empty;
                 var _fontFamilyName = string.Empty;
                 var _fontStyleName = string.Empty;
                 var _fontStyleName = string.Empty;
                 _postScriptName = value;
                 _postScriptName = value;
-                CPDFFont.GetFamlyStyleName(_postScriptName, ref _fontFamilyName, ref _fontStyleName);
+                CPDFFont.GetFamilyStyleName(_postScriptName, ref _fontFamilyName, ref _fontStyleName);
                 FontFamilyValue = _fontFamilyName;
                 FontFamilyValue = _fontFamilyName;
                 FontStyleValue = _fontStyleName;
                 FontStyleValue = _fontStyleName;
             }
             }

+ 48 - 7
Demo/Examples/Compdfkit.Controls/Compdfkit.Controls.csproj

@@ -28,6 +28,7 @@
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
   </PropertyGroup>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -37,6 +38,7 @@
     <DefineConstants>TRACE</DefineConstants>
     <DefineConstants>TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
   </PropertyGroup>
   </PropertyGroup>
   <PropertyGroup>
   <PropertyGroup>
     <StartupObject />
     <StartupObject />
@@ -52,6 +54,7 @@
     <PlatformTarget>x64</PlatformTarget>
     <PlatformTarget>x64</PlatformTarget>
     <LangVersion>7</LangVersion>
     <LangVersion>7</LangVersion>
     <ErrorReport>prompt</ErrorReport>
     <ErrorReport>prompt</ErrorReport>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
   </PropertyGroup>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
     <OutputPath>bin\x64\Release\</OutputPath>
     <OutputPath>bin\x64\Release\</OutputPath>
@@ -61,6 +64,7 @@
     <PlatformTarget>x64</PlatformTarget>
     <PlatformTarget>x64</PlatformTarget>
     <LangVersion>7</LangVersion>
     <LangVersion>7</LangVersion>
     <ErrorReport>prompt</ErrorReport>
     <ErrorReport>prompt</ErrorReport>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
   </PropertyGroup>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
     <DebugSymbols>true</DebugSymbols>
     <DebugSymbols>true</DebugSymbols>
@@ -70,6 +74,7 @@
     <PlatformTarget>x86</PlatformTarget>
     <PlatformTarget>x86</PlatformTarget>
     <LangVersion>7</LangVersion>
     <LangVersion>7</LangVersion>
     <ErrorReport>prompt</ErrorReport>
     <ErrorReport>prompt</ErrorReport>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
   </PropertyGroup>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
     <OutputPath>bin\x86\Release\</OutputPath>
     <OutputPath>bin\x86\Release\</OutputPath>
@@ -79,6 +84,7 @@
     <PlatformTarget>x86</PlatformTarget>
     <PlatformTarget>x86</PlatformTarget>
     <LangVersion>7</LangVersion>
     <LangVersion>7</LangVersion>
     <ErrorReport>prompt</ErrorReport>
     <ErrorReport>prompt</ErrorReport>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
   </PropertyGroup>
   </PropertyGroup>
   <ItemGroup>
   <ItemGroup>
     <Reference Include="Nager.Country, Version=4.0.0.0, Culture=neutral, processorArchitecture=MSIL">
     <Reference Include="Nager.Country, Version=4.0.0.0, Culture=neutral, processorArchitecture=MSIL">
@@ -87,10 +93,12 @@
     <Reference Include="PresentationFramework.Aero2, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
     <Reference Include="PresentationFramework.Aero2, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
       <HintPath>..\packages\PresentationFramework.Aero2.1.0.1\lib\PresentationFramework.Aero2.dll</HintPath>
       <HintPath>..\packages\PresentationFramework.Aero2.1.0.1\lib\PresentationFramework.Aero2.dll</HintPath>
     </Reference>
     </Reference>
+    <Reference Include="ReachFramework" />
     <Reference Include="System" />
     <Reference Include="System" />
     <Reference Include="System.Data" />
     <Reference Include="System.Data" />
     <Reference Include="System.Drawing" />
     <Reference Include="System.Drawing" />
     <Reference Include="System.Management" />
     <Reference Include="System.Management" />
+    <Reference Include="System.Printing" />
     <Reference Include="System.Windows.Forms" />
     <Reference Include="System.Windows.Forms" />
     <Reference Include="System.Xml" />
     <Reference Include="System.Xml" />
     <Reference Include="Microsoft.CSharp" />
     <Reference Include="Microsoft.CSharp" />
@@ -118,8 +126,14 @@
     <Compile Include="Annotation\PDFAnnotationList\PDFAnnotationListControl\CPDFAnnotationListControl.xaml.cs">
     <Compile Include="Annotation\PDFAnnotationList\PDFAnnotationListControl\CPDFAnnotationListControl.xaml.cs">
       <DependentUpon>CPDFAnnotationListControl.xaml</DependentUpon>
       <DependentUpon>CPDFAnnotationListControl.xaml</DependentUpon>
     </Compile>
     </Compile>
-    <Compile Include="Annotation\PDFAnnotationList\PDFAnnotationListUI\CPDFAnnoationListUI.xaml.cs">
-      <DependentUpon>CPDFAnnoationListUI.xaml</DependentUpon>
+    <Compile Include="Annotation\PDFAnnotationList\PDFAnnotationListUI\AnnotationReplyListControl.xaml.cs">
+      <DependentUpon>AnnotationReplyListControl.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Annotation\PDFAnnotationList\PDFAnnotationListUI\CPDFAnnotationListUI.xaml.cs">
+      <DependentUpon>CPDFAnnotationListUI.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Annotation\PDFAnnotationList\PDFAnnotationListUI\ReplyStatusControl.xaml.cs">
+      <DependentUpon>ReplyStatusControl.xaml</DependentUpon>
     </Compile>
     </Compile>
     <Compile Include="Annotation\PDFAnnotationPanel\PDFAnnotationUI\CPDFFreehandUI.xaml.cs">
     <Compile Include="Annotation\PDFAnnotationPanel\PDFAnnotationUI\CPDFFreehandUI.xaml.cs">
       <DependentUpon>CPDFFreehandUI.xaml</DependentUpon>
       <DependentUpon>CPDFFreehandUI.xaml</DependentUpon>
@@ -162,6 +176,7 @@
     <Compile Include="Common\BaseControl\PageNumberControl.xaml.cs">
     <Compile Include="Common\BaseControl\PageNumberControl.xaml.cs">
       <DependentUpon>PageNumberControl.xaml</DependentUpon>
       <DependentUpon>PageNumberControl.xaml</DependentUpon>
     </Compile>
     </Compile>
+    <Compile Include="Common\Convert\AntiVisibilityConverter.cs" />
     <Compile Include="Common\Convert\BoolToColorConverter.cs" />
     <Compile Include="Common\Convert\BoolToColorConverter.cs" />
     <Compile Include="Common\Convert\HeightToTopMarginConverter.cs" />
     <Compile Include="Common\Convert\HeightToTopMarginConverter.cs" />
     <Compile Include="Common\Convert\HomePageFileListHeightConverter.cs" />
     <Compile Include="Common\Convert\HomePageFileListHeightConverter.cs" />
@@ -178,6 +193,7 @@
     <Compile Include="Common\Convert\StringToVisibilityConverter.cs" />
     <Compile Include="Common\Convert\StringToVisibilityConverter.cs" />
     <Compile Include="Common\Convert\ShowDefaultCloseButtonConverter.cs" />
     <Compile Include="Common\Convert\ShowDefaultCloseButtonConverter.cs" />
     <Compile Include="Common\Convert\ShowIconConverter.cs" />
     <Compile Include="Common\Convert\ShowIconConverter.cs" />
+    <Compile Include="Common\Convert\SubtractionConverter.cs" />
     <Compile Include="Common\Convert\TagToBoolConverter.cs" />
     <Compile Include="Common\Convert\TagToBoolConverter.cs" />
     <Compile Include="Common\Convert\WindowStateToPathConverter.cs" />
     <Compile Include="Common\Convert\WindowStateToPathConverter.cs" />
     <Compile Include="Common\Convert\WindowStateToThicknessConverter.cs" />
     <Compile Include="Common\Convert\WindowStateToThicknessConverter.cs" />
@@ -380,6 +396,14 @@
     <Compile Include="Common\BarControl\FormBarControl.xaml.cs">
     <Compile Include="Common\BarControl\FormBarControl.xaml.cs">
       <DependentUpon>FormBarControl.xaml</DependentUpon>
       <DependentUpon>FormBarControl.xaml</DependentUpon>
     </Compile>
     </Compile>
+    <Compile Include="Printer\PrinterDialog.xaml.cs">
+      <DependentUpon>PrinterDialog.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Printer\PrinterModel.cs" />
+    <Compile Include="Printer\PrintHelper.cs" />
+    <Compile Include="Printer\PrintPreviewControl.xaml.cs">
+      <DependentUpon>PrintPreviewControl.xaml</DependentUpon>
+    </Compile>
     <Compile Include="Security\Encryption\DecryptionDialog.xaml.cs">
     <Compile Include="Security\Encryption\DecryptionDialog.xaml.cs">
       <DependentUpon>DecryptionDialog.xaml</DependentUpon>
       <DependentUpon>DecryptionDialog.xaml</DependentUpon>
     </Compile>
     </Compile>
@@ -745,7 +769,15 @@
       <SubType>Designer</SubType>
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
       <Generator>MSBuild:Compile</Generator>
     </Page>
     </Page>
-    <Page Include="Annotation\PDFAnnotationList\PDFAnnotationListUI\CPDFAnnoationListUI.xaml">
+    <Page Include="Annotation\PDFAnnotationList\PDFAnnotationListUI\AnnotationReplyListControl.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="Annotation\PDFAnnotationList\PDFAnnotationListUI\CPDFAnnotationListUI.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="Annotation\PDFAnnotationList\PDFAnnotationListUI\ReplyStatusControl.xaml">
       <SubType>Designer</SubType>
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
       <Generator>MSBuild:Compile</Generator>
     </Page>
     </Page>
@@ -1081,6 +1113,14 @@
       <SubType>Designer</SubType>
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
       <Generator>MSBuild:Compile</Generator>
     </Page>
     </Page>
+    <Page Include="Printer\PrinterDialog.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="Printer\PrintPreviewControl.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
     <Page Include="Security\Encryption\DecryptionDialog.xaml" />
     <Page Include="Security\Encryption\DecryptionDialog.xaml" />
     <Page Include="Security\Encryption\EncryptionDialog.xaml" />
     <Page Include="Security\Encryption\EncryptionDialog.xaml" />
     <Page Include="Security\Encryption\FileGridListControl.xaml" />
     <Page Include="Security\Encryption\FileGridListControl.xaml" />
@@ -1296,18 +1336,19 @@
     </Page>
     </Page>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="..\..\..\..\compdfkit_windows\ComPDFKit\ComPDFKitCSharp\ComPDFKit.NET.csproj">
-      <Project>{56e518ad-c126-4b48-9a09-0a64c87020e4}</Project>
+    <ProjectReference Include="..\..\..\..\ComPDFKit-ForRebuild\ComPDFKit\ComPDFKitCSharp\ComPDFKit.NET.csproj">
+      <Project>{122caf49-dcf7-49b1-8872-80b363e187e4}</Project>
       <Name>ComPDFKit.NET</Name>
       <Name>ComPDFKit.NET</Name>
     </ProjectReference>
     </ProjectReference>
-    <ProjectReference Include="..\..\..\..\compdfkit_windows_rebuild\ComPDFKit.Tool\ComPDFKit.Tool.csproj">
+    <ProjectReference Include="..\..\..\..\ComPDFKit-Rebuild\ComPDFKit.Tool\ComPDFKit.Tool.csproj">
       <Project>{a061ee7a-6704-4bd9-86ee-48ed5df75e2f}</Project>
       <Project>{a061ee7a-6704-4bd9-86ee-48ed5df75e2f}</Project>
       <Name>ComPDFKit.Tool</Name>
       <Name>ComPDFKit.Tool</Name>
     </ProjectReference>
     </ProjectReference>
-    <ProjectReference Include="..\..\..\..\compdfkit_windows_rebuild\ComPDFKit.Viewer\ComPDFKit.Viewer.csproj">
+    <ProjectReference Include="..\..\..\..\ComPDFKit-Rebuild\ComPDFKit.Viewer\ComPDFKit.Viewer.csproj">
       <Project>{783263cf-0da3-4095-9df8-2c4a6b3ff908}</Project>
       <Project>{783263cf-0da3-4095-9df8-2c4a6b3ff908}</Project>
       <Name>ComPDFKit.Viewer</Name>
       <Name>ComPDFKit.Viewer</Name>
     </ProjectReference>
     </ProjectReference>
   </ItemGroup>
   </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 </Project>
 </Project>

+ 3 - 1
Demo/Examples/Compdfkit.Controls/DigitalSignature/DigitalSignatureControl/DigitalSignatureControl.xaml.cs

@@ -214,7 +214,9 @@ namespace ComPDFKit.Controls.PDFControl
 
 
         private void PDFViewControl_MouseLeftButtonDownHandler(object sender, MouseEventObject e)
         private void PDFViewControl_MouseLeftButtonDownHandler(object sender, MouseEventObject e)
         {
         {
-            if (PDFViewControl.PDFViewTool.GetToolType() == ToolType.WidgetEdit && e.annotType== C_ANNOTATION_TYPE.C_ANNOTATION_WIDGET)
+            if (PDFViewControl.PDFViewTool.GetToolType() == ToolType.Viewer
+                || PDFViewControl.PDFViewTool.GetToolType() == ToolType.Pan 
+                && e.annotType== C_ANNOTATION_TYPE.C_ANNOTATION_WIDGET)
             {
             {
                 BaseWidget baseWidget = PDFViewControl.GetCacheHitTestWidget();
                 BaseWidget baseWidget = PDFViewControl.GetCacheHitTestWidget();
                 if(baseWidget == null)
                 if(baseWidget == null)

+ 102 - 36
Demo/Examples/Compdfkit.Controls/Edit/ContentEditCOntrol/ContentEditControl.xaml.cs

@@ -17,7 +17,6 @@ using System.Windows.Controls.Primitives;
 using System.Windows.Forms;
 using System.Windows.Forms;
 using System.Windows.Input;
 using System.Windows.Input;
 using System.Windows.Media;
 using System.Windows.Media;
-using static ComPDFKit.Tool.CPDFToolManager;
 using System.Windows.Media.Imaging;
 using System.Windows.Media.Imaging;
 using ComPDFKit.Import;
 using ComPDFKit.Import;
 using ComPDFKit.Tool.Help;
 using ComPDFKit.Tool.Help;
@@ -28,6 +27,7 @@ using KeyEventHandler = System.Windows.Input.KeyEventHandler;
 using MenuItem = System.Windows.Controls.MenuItem;
 using MenuItem = System.Windows.Controls.MenuItem;
 using OpenFileDialog = Microsoft.Win32.OpenFileDialog;
 using OpenFileDialog = Microsoft.Win32.OpenFileDialog;
 using UserControl = System.Windows.Controls.UserControl;
 using UserControl = System.Windows.Controls.UserControl;
+using System.Linq;
 
 
 namespace ComPDFKit.Controls.PDFControl
 namespace ComPDFKit.Controls.PDFControl
 {
 {
@@ -54,7 +54,7 @@ namespace ComPDFKit.Controls.PDFControl
         private bool textAreaCreating = false;
         private bool textAreaCreating = false;
 
 
         public event PropertyChangedEventHandler PropertyChanged;
         public event PropertyChangedEventHandler PropertyChanged;
-         
+
         public bool CanUndo
         public bool CanUndo
         {
         {
             get
             get
@@ -70,8 +70,9 @@ namespace ComPDFKit.Controls.PDFControl
                 }
                 }
                 catch (Exception ex)
                 catch (Exception ex)
                 {
                 {
+                    return false;
+                }
 
 
-                } 
                 return false;
                 return false;
             }
             }
         }
         }
@@ -91,7 +92,7 @@ namespace ComPDFKit.Controls.PDFControl
                 }
                 }
                 catch (Exception ex)
                 catch (Exception ex)
                 {
                 {
-
+                    return false;
                 }
                 }
 
 
                 return false;
                 return false;
@@ -113,7 +114,7 @@ namespace ComPDFKit.Controls.PDFControl
                 }
                 }
                 catch (Exception ex)
                 catch (Exception ex)
                 {
                 {
-
+                    return false;
                 }
                 }
 
 
                 return false;
                 return false;
@@ -156,7 +157,7 @@ namespace ComPDFKit.Controls.PDFControl
             PdfViewControl.PDFViewTool.GetCPDFViewer().SetIsShowStampMouse(false);
             PdfViewControl.PDFViewTool.GetCPDFViewer().SetIsShowStampMouse(false);
             PdfViewControl.PDFViewTool.SelectedEditAreaForIndex(-1, -1);
             PdfViewControl.PDFViewTool.SelectedEditAreaForIndex(-1, -1);
         }
         }
-         
+
         public void SetViewSettings(Visibility visibility, CPDFDisplaySettingsControl displaySettingsControl = null)
         public void SetViewSettings(Visibility visibility, CPDFDisplaySettingsControl displaySettingsControl = null)
         {
         {
             this.PropertyContainer.Child = displaySettingsControl;
             this.PropertyContainer.Child = displaySettingsControl;
@@ -173,7 +174,7 @@ namespace ComPDFKit.Controls.PDFControl
         {
         {
             this.displaySettingsControl = displaySettingsControl;
             this.displaySettingsControl = displaySettingsControl;
         }
         }
-         
+
         public void InitWithPDFViewer(PDFViewControl view)
         public void InitWithPDFViewer(PDFViewControl view)
         {
         {
             PdfViewControl.PDFViewTool.GetCPDFViewer().UndoManager.PropertyChanged -= UndoManager_PropertyChanged;
             PdfViewControl.PDFViewTool.GetCPDFViewer().UndoManager.PropertyChanged -= UndoManager_PropertyChanged;
@@ -197,6 +198,7 @@ namespace ComPDFKit.Controls.PDFControl
                 {
                 {
                     PdfViewControl.PDFViewTool.RemoveHandler(KeyDownEvent, KeyDownHandler);
                     PdfViewControl.PDFViewTool.RemoveHandler(KeyDownEvent, KeyDownHandler);
                 }
                 }
+
                 KeyDownHandler = new KeyEventHandler(PDFView_KeyDown);
                 KeyDownHandler = new KeyEventHandler(PDFView_KeyDown);
                 PdfViewControl.PDFViewTool.AddHandler(KeyDownEvent, KeyDownHandler, false);
                 PdfViewControl.PDFViewTool.AddHandler(KeyDownEvent, KeyDownHandler, false);
             }
             }
@@ -204,7 +206,7 @@ namespace ComPDFKit.Controls.PDFControl
 
 
         private void PdfViewControl_DrawChanged(object sender, EventArgs e)
         private void PdfViewControl_DrawChanged(object sender, EventArgs e)
         {
         {
-            if(textAreaCreating && PdfViewControl.PDFToolManager.GetCreateContentEditType() == CPDFEditType.EditText)
+            if (textAreaCreating && PdfViewControl.PDFToolManager.GetCreateContentEditType() == CPDFEditType.EditText)
             {
             {
                 textAreaCreating = false;
                 textAreaCreating = false;
                 int pageIndex = -1;
                 int pageIndex = -1;
@@ -218,7 +220,7 @@ namespace ComPDFKit.Controls.PDFControl
                     if (editAreaArea.Type == CPDFEditType.EditText)
                     if (editAreaArea.Type == CPDFEditType.EditText)
                     {
                     {
                         PDFEditParam pDFEditParam = ParamConverter.CPDFDataConverterToPDFEitParam(PdfViewControl.PDFToolManager.GetDocument(), editAreaArea, pageIndex);
                         PDFEditParam pDFEditParam = ParamConverter.CPDFDataConverterToPDFEitParam(PdfViewControl.PDFToolManager.GetDocument(), editAreaArea, pageIndex);
-                        pdfContentEditControl.SetPDFTextEditData((TextEditParam)pDFEditParam, true);
+                        pdfContentEditControl.SetPDFTextEditData(new List<TextEditParam> { (TextEditParam)pDFEditParam }, true);
                         PropertyContainer.Child = pdfContentEditControl;
                         PropertyContainer.Child = pdfContentEditControl;
                     }
                     }
                 }
                 }
@@ -234,6 +236,16 @@ namespace ComPDFKit.Controls.PDFControl
             {
             {
                 return;
                 return;
             }
             }
+
+            if (e.Key == Key.LeftShift || e.Key == Key.RightShift)
+            {
+                PdfViewControl.PDFViewTool.SetMultiSelectKey(e.Key);
+            }
+            else if (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl)
+            {
+                PdfViewControl.PDFViewTool.SetMultiSelectKey(e.Key);
+            }
+
             int pageIndex = -1;
             int pageIndex = -1;
             CPDFEditTextArea textArea = PdfViewControl.PDFToolManager.GetSelectedEditAreaObject(ref pageIndex) as CPDFEditTextArea;
             CPDFEditTextArea textArea = PdfViewControl.PDFToolManager.GetSelectedEditAreaObject(ref pageIndex) as CPDFEditTextArea;
             if (textArea == null)
             if (textArea == null)
@@ -335,31 +347,34 @@ namespace ComPDFKit.Controls.PDFControl
 
 
             if (Keyboard.Modifiers == ModifierKeys.None)
             if (Keyboard.Modifiers == ModifierKeys.None)
             {
             {
-                var oldFrame = textArea.GetFrame();
+                CRect textFrame = textArea.GetFrame();
                 if (e.Key == Key.Left)
                 if (e.Key == Key.Left)
                 {
                 {
-                    oldFrame.left -= 5;
+                    textFrame.left -= 5;
+                    textArea.SetFrame(textFrame);
                     e.Handled = true;
                     e.Handled = true;
                 }
                 }
 
 
                 if (e.Key == Key.Right)
                 if (e.Key == Key.Right)
                 {
                 {
-                    oldFrame.left += 5;
+                    textFrame.left += 5;
+                    textArea.SetFrame(textFrame);
                     e.Handled = true;
                     e.Handled = true;
                 }
                 }
 
 
                 if (e.Key == Key.Up)
                 if (e.Key == Key.Up)
                 {
                 {
-                    oldFrame.top -= 5;
+                    textFrame.top -= 5;
+                    textArea.SetFrame(textFrame);
                     e.Handled = true;
                     e.Handled = true;
                 }
                 }
 
 
                 if (e.Key == Key.Down)
                 if (e.Key == Key.Down)
                 {
                 {
-                    oldFrame.top += 5;
+                    textFrame.top += 5;
+                    textArea.SetFrame(textFrame);
                     e.Handled = true;
                     e.Handled = true;
                 }
                 }
-                textArea.SetFrame(oldFrame);
             }
             }
 
 
             if (Keyboard.Modifiers == (ModifierKeys.Control | ModifierKeys.Shift))
             if (Keyboard.Modifiers == (ModifierKeys.Control | ModifierKeys.Shift))
@@ -369,6 +384,7 @@ namespace ComPDFKit.Controls.PDFControl
                     startPoint = GetPoint(textArea);
                     startPoint = GetPoint(textArea);
                     isUpdateStartPoint = false;
                     isUpdateStartPoint = false;
                 }
                 }
+
                 if (e.Key == Key.Left)
                 if (e.Key == Key.Left)
                 {
                 {
                     textArea.GetPreWordCharPlace();
                     textArea.GetPreWordCharPlace();
@@ -431,7 +447,7 @@ namespace ComPDFKit.Controls.PDFControl
             PropertyContainer.Child = propertytPanel;
             PropertyContainer.Child = propertytPanel;
             PropertyContainer.Visibility = visible;
             PropertyContainer.Visibility = visible;
         }
         }
-         
+
         private void PanelState_PropertyChanged(object sender, PropertyChangedEventArgs e)
         private void PanelState_PropertyChanged(object sender, PropertyChangedEventArgs e)
         {
         {
             if (e.PropertyName == nameof(PanelState.IsLeftPanelExpand))
             if (e.PropertyName == nameof(PanelState.IsLeftPanelExpand))
@@ -475,15 +491,13 @@ namespace ComPDFKit.Controls.PDFControl
                     textEditParam.EditIndex = -1;
                     textEditParam.EditIndex = -1;
                     textEditParam.TextAlign = TextAlignType.AlignLeft;
                     textEditParam.TextAlign = TextAlignType.AlignLeft;
                     textEditParam.Transparency = 255;
                     textEditParam.Transparency = 255;
-                    pdfContentEditControl.SetPDFTextEditData(textEditParam);
+                    pdfContentEditControl.SetPDFTextEditData(new List<TextEditParam> { textEditParam });
                     DefaultSettingParam defaultSettingParam = PdfViewControl.PDFViewTool.GetDefaultSettingParam();
                     DefaultSettingParam defaultSettingParam = PdfViewControl.PDFViewTool.GetDefaultSettingParam();
                     defaultSettingParam.SetPDFEditParamm(textEditParam);
                     defaultSettingParam.SetPDFEditParamm(textEditParam);
                     panelState.RightPanel = PanelState.RightPanelState.PropertyPanel;
                     panelState.RightPanel = PanelState.RightPanelState.PropertyPanel;
                     PdfViewControl.PDFToolManager.SetCreateContentEditType(CPDFEditType.EditText);
                     PdfViewControl.PDFToolManager.SetCreateContentEditType(CPDFEditType.EditText);
                     PdfViewControl.PDFViewTool.SetCurrentEditType(CPDFEditType.EditText);
                     PdfViewControl.PDFViewTool.SetCurrentEditType(CPDFEditType.EditText);
                 }
                 }
-
-                PdfViewControl.PDFViewTool.GetCPDFViewer().UpdateRenderFrame();
             }
             }
 
 
         }
         }
@@ -494,7 +508,6 @@ namespace ComPDFKit.Controls.PDFControl
             if (senderBtn != null && PdfViewControl != null)
             if (senderBtn != null && PdfViewControl != null)
             {
             {
                 ClearPDFEditState(senderBtn);
                 ClearPDFEditState(senderBtn);
-                PdfViewControl.PDFViewTool.GetCPDFViewer().UpdateRenderFrame();
                 panelState.RightPanel = PanelState.RightPanelState.None;
                 panelState.RightPanel = PanelState.RightPanelState.None;
                 senderBtn.IsChecked = false;
                 senderBtn.IsChecked = false;
                 OpenFileDialog openFileDialog = new OpenFileDialog();
                 OpenFileDialog openFileDialog = new OpenFileDialog();
@@ -556,7 +569,7 @@ namespace ComPDFKit.Controls.PDFControl
             {
             {
                 if (PdfViewControl.PDFToolManager.GetCreateContentEditType() == CPDFEditType.EditText)
                 if (PdfViewControl.PDFToolManager.GetCreateContentEditType() == CPDFEditType.EditText)
                 {
                 {
-                    pdfContentEditControl.SetPDFTextEditData(pdfTextCreateParam);
+                    pdfContentEditControl.SetPDFTextEditData(new List<TextEditParam> { pdfTextCreateParam });
                 }
                 }
                 else if (PdfViewControl.PDFToolManager.GetCreateContentEditType() == CPDFEditType.None)
                 else if (PdfViewControl.PDFToolManager.GetCreateContentEditType() == CPDFEditType.None)
                 {
                 {
@@ -613,6 +626,19 @@ namespace ComPDFKit.Controls.PDFControl
                 case MouseHitTestType.ImageEdit:
                 case MouseHitTestType.ImageEdit:
                     CreateImageEditMenu(sender, ref ContextMenu);
                     CreateImageEditMenu(sender, ref ContextMenu);
                     break;
                     break;
+                case MouseHitTestType.Unknown:
+                    List<int> pageInts = new List<int>();
+                    List<CPDFEditArea> editAreas = PdfViewControl.PDFToolManager.GetSelectedEditAreaListObject(ref pageInts);
+                    if (editAreas.Count > 0)
+                    {
+                        CreateMultiTextEditMenu(sender, ref ContextMenu);
+                    }
+                    else
+                    {
+                        ContextMenu.Items.Add(new MenuItem() { Header = LanguageHelper.CommonManager.GetString("Menu_Paste"), Command = ApplicationCommands.Paste, CommandTarget = (UIElement)sender });
+                        ContextMenu.Items.Add(new MenuItem() { Header = LanguageHelper.CommonManager.GetString("Menu_MatchPaste"), Command = CustomCommands.PasteWithoutStyle, CommandTarget = (UIElement)sender });
+                    }
+                    break;
                 default:
                 default:
                     ContextMenu.Items.Add(new MenuItem() { Header = LanguageHelper.CommonManager.GetString("Menu_Paste"), Command = ApplicationCommands.Paste, CommandTarget = (UIElement)sender });
                     ContextMenu.Items.Add(new MenuItem() { Header = LanguageHelper.CommonManager.GetString("Menu_Paste"), Command = ApplicationCommands.Paste, CommandTarget = (UIElement)sender });
                     ContextMenu.Items.Add(new MenuItem() { Header = LanguageHelper.CommonManager.GetString("Menu_MatchPaste"), Command = CustomCommands.PasteWithoutStyle, CommandTarget = (UIElement)sender });
                     ContextMenu.Items.Add(new MenuItem() { Header = LanguageHelper.CommonManager.GetString("Menu_MatchPaste"), Command = CustomCommands.PasteWithoutStyle, CommandTarget = (UIElement)sender });
@@ -621,7 +647,7 @@ namespace ComPDFKit.Controls.PDFControl
             PdfViewControl.SetRightMenu(ContextMenu);
             PdfViewControl.SetRightMenu(ContextMenu);
         }
         }
         #endregion
         #endregion
-        
+
         #region Property changed
         #region Property changed
         protected void OnPropertyChanged([CallerMemberName] string name = null)
         protected void OnPropertyChanged([CallerMemberName] string name = null)
         {
         {
@@ -683,27 +709,54 @@ namespace ComPDFKit.Controls.PDFControl
                     PdfViewControl.PDFToolManager.SetCreateContentEditType(CPDFEditType.None);
                     PdfViewControl.PDFToolManager.SetCreateContentEditType(CPDFEditType.None);
                 }
                 }
 
 
-                if(PdfViewControl.PDFToolManager.GetCreateContentEditType() == CPDFEditType.EditText)
+                if (PdfViewControl.PDFToolManager.GetCreateContentEditType() == CPDFEditType.EditText)
                 {
                 {
                     textAreaCreating = true;
                     textAreaCreating = true;
                 }
                 }
             }
             }
 
 
             int pageIndex = -1;
             int pageIndex = -1;
-            CPDFEditArea editAreaArea = PdfViewControl.PDFToolManager.GetSelectedEditAreaObject(ref pageIndex);
-            if (editAreaArea == null)
+            CPDFEditArea editArea = PdfViewControl.PDFToolManager.GetSelectedEditAreaObject(ref pageIndex);
+            List<int> pageInts = new List<int>();
+            List<CPDFEditArea> editAreas = PdfViewControl.PDFToolManager.GetSelectedEditAreaListObject(ref pageInts);
+
+            if (editArea != null)
             {
             {
-                return;
+                if (editArea.Type == CPDFEditType.EditText)
+                {
+                    PDFEditParam editParam = ParamConverter.CPDFDataConverterToPDFEitParam(PdfViewControl.PDFToolManager.GetDocument(), editArea, pageIndex);
+                    pdfContentEditControl.SetPDFTextEditData(new List<TextEditParam> { (TextEditParam)editParam }, true);
+                    PropertyContainer.Child = pdfContentEditControl;
+                }
             }
             }
-            else
+            else if (editAreas != null && editAreas.Count != 0)
             {
             {
-                if (editAreaArea.Type == CPDFEditType.EditText)
+                List<CPDFEditTextArea> editTextAreas = editAreas.OfType<CPDFEditTextArea>().ToList();
+                editTextAreas.ForEach(textArea => textArea.SelectAllChars());
+                if (editAreas.Count == editTextAreas.Count)
                 {
                 {
-                    PDFEditParam pDFEditParam = ParamConverter.CPDFDataConverterToPDFEitParam(PdfViewControl.PDFToolManager.GetDocument(), editAreaArea, pageIndex);
-                    pdfContentEditControl.SetPDFTextEditData((TextEditParam)pDFEditParam, true);
+                    List<TextEditParam> editParams = editTextAreas.
+                        Select(area => ParamConverter.CPDFDataConverterToPDFEitParam(PdfViewControl.PDFToolManager.GetDocument(), area, pageInts.FirstOrDefault())).
+                        Cast<TextEditParam>().ToList();
+                    pdfContentEditControl.SetPDFTextEditData(editParams, true);
+                    PropertyContainer.Child = pdfContentEditControl;
+                }
+                else if (editTextAreas.Count == 0)
+                {
+                    List<ImageEditParam> editParams = editAreas.
+                        Select(area => ParamConverter.CPDFDataConverterToPDFEitParam(PdfViewControl.PDFToolManager.GetDocument(), area, pageInts.FirstOrDefault())).
+                        Cast<ImageEditParam>().ToList();
+                    pdfContentEditControl.SetPDFImageEditData(editParams);
                     PropertyContainer.Child = pdfContentEditControl;
                     PropertyContainer.Child = pdfContentEditControl;
                 }
                 }
-                //panelState.RightPanel = PanelState.RightPanelState.PropertyPanel;
+                else
+                {
+                    pdfContentEditControl.ClearContentControl();
+                }
+            }
+            else
+            {
+                return;
             }
             }
         }
         }
 
 
@@ -722,7 +775,7 @@ namespace ComPDFKit.Controls.PDFControl
             {
             {
                 if (PdfViewControl.PDFToolManager.GetCreateContentEditType() != CPDFEditType.EditText)
                 if (PdfViewControl.PDFToolManager.GetCreateContentEditType() != CPDFEditType.EditText)
                 {
                 {
-                    pdfContentEditControl.ClearContentControl(); 
+                    pdfContentEditControl.ClearContentControl();
                 }
                 }
                 return;
                 return;
             }
             }
@@ -731,7 +784,7 @@ namespace ComPDFKit.Controls.PDFControl
                 if (editAreaArea.Type == CPDFEditType.EditText)
                 if (editAreaArea.Type == CPDFEditType.EditText)
                 {
                 {
                     PDFEditParam pDFEditParam = ParamConverter.CPDFDataConverterToPDFEitParam(PdfViewControl.PDFToolManager.GetDocument(), editAreaArea, pageIndex);
                     PDFEditParam pDFEditParam = ParamConverter.CPDFDataConverterToPDFEitParam(PdfViewControl.PDFToolManager.GetDocument(), editAreaArea, pageIndex);
-                    pdfContentEditControl.SetPDFTextEditData((TextEditParam)pDFEditParam, true);
+                    pdfContentEditControl.SetPDFTextEditData(new List<TextEditParam> { (TextEditParam)pDFEditParam }, true);
                     PropertyContainer.Child = pdfContentEditControl;
                     PropertyContainer.Child = pdfContentEditControl;
                 }
                 }
 
 
@@ -744,9 +797,14 @@ namespace ComPDFKit.Controls.PDFControl
                         pageView.MouseLeftButtonUp += PageView_MouseLeftButtonUp;
                         pageView.MouseLeftButtonUp += PageView_MouseLeftButtonUp;
                     }
                     }
                     PDFEditParam pDFEditParam = ParamConverter.CPDFDataConverterToPDFEitParam(PdfViewControl.PDFToolManager.GetDocument(), editAreaArea, pageIndex);
                     PDFEditParam pDFEditParam = ParamConverter.CPDFDataConverterToPDFEitParam(PdfViewControl.PDFToolManager.GetDocument(), editAreaArea, pageIndex);
-                    pdfContentEditControl.SetPDFImageEditData((ImageEditParam)pDFEditParam);
+                    pdfContentEditControl.SetPDFImageEditData(new List<ImageEditParam> { (ImageEditParam)pDFEditParam });
                     PropertyContainer.Child = pdfContentEditControl;
                     PropertyContainer.Child = pdfContentEditControl;
-                } 
+                }
+
+                else
+                {
+
+                }
             }
             }
         }
         }
 
 
@@ -765,7 +823,7 @@ namespace ComPDFKit.Controls.PDFControl
             }
             }
             if (imageAreaParam != null)
             if (imageAreaParam != null)
             {
             {
-                pdfContentEditControl.SetPDFImageEditData((ImageEditParam)imageAreaParam);
+                pdfContentEditControl.SetPDFImageEditData(new List<ImageEditParam> { (ImageEditParam)imageAreaParam });
             }
             }
         }
         }
 
 
@@ -966,6 +1024,14 @@ namespace ComPDFKit.Controls.PDFControl
             menu.Items.Add(new MenuItem() { Header = LanguageHelper.CommonManager.GetString("Menu_Delete"), Command = ApplicationCommands.Delete, CommandTarget = (UIElement)sender });
             menu.Items.Add(new MenuItem() { Header = LanguageHelper.CommonManager.GetString("Menu_Delete"), Command = ApplicationCommands.Delete, CommandTarget = (UIElement)sender });
             menu.Items.Add(new MenuItem() { Header = LanguageHelper.CommonManager.GetString("Menu_Paste"), Command = ApplicationCommands.Paste, CommandTarget = (UIElement)sender });
             menu.Items.Add(new MenuItem() { Header = LanguageHelper.CommonManager.GetString("Menu_Paste"), Command = ApplicationCommands.Paste, CommandTarget = (UIElement)sender });
         }
         }
+
+        private void CreateMultiTextEditMenu(object sender, ref ContextMenu menu)
+        {
+            menu.Items.Add(new MenuItem() { Header = LanguageHelper.CommonManager.GetString("Menu_Copy"), Command = ApplicationCommands.Copy, CommandTarget = (UIElement)sender });
+            menu.Items.Add(new MenuItem() { Header = LanguageHelper.CommonManager.GetString("Menu_Cut"), Command = ApplicationCommands.Cut, CommandTarget = (UIElement)sender });
+            menu.Items.Add(new MenuItem() { Header = LanguageHelper.CommonManager.GetString("Menu_Delete"), Command = ApplicationCommands.Delete, CommandTarget = (UIElement)sender });
+            menu.Items.Add(new MenuItem() { Header = LanguageHelper.CommonManager.GetString("Menu_Paste"), Command = ApplicationCommands.Paste, CommandTarget = (UIElement)sender });
+        }
     }
     }
 }
 }
 #endregion
 #endregion

+ 4 - 2
Demo/Examples/Compdfkit.Controls/Edit/PDFContentEditControl.xaml.cs

@@ -1,6 +1,7 @@
 using ComPDFKit.Tool;
 using ComPDFKit.Tool;
 using ComPDFKit.Controls.PDFControl;
 using ComPDFKit.Controls.PDFControl;
 using System.Windows.Controls;
 using System.Windows.Controls;
+using System.Collections.Generic;
 
 
 namespace ComPDFKit.Controls.Edit
 namespace ComPDFKit.Controls.Edit
 {
 {
@@ -32,7 +33,7 @@ namespace ComPDFKit.Controls.Edit
             PDFImageEditControl.SetRotationText(rotation);
             PDFImageEditControl.SetRotationText(rotation);
         }
         }
 
 
-        public void SetPDFTextEditData(TextEditParam editEvent, bool isTemp = false)
+        public void SetPDFTextEditData(List<TextEditParam> editEvent, bool isTemp = false)
         {
         {
             if (!isTemp)
             if (!isTemp)
             {
             {
@@ -59,12 +60,13 @@ namespace ComPDFKit.Controls.Edit
             ContentEditContainer.Child = null;
             ContentEditContainer.Child = null;
         }
         }
 
 
-        public void SetPDFImageEditData(ImageEditParam editEvent)
+        public void SetPDFImageEditData(List<ImageEditParam> editEvent)
         {
         {
             PDFImageEditControl.SetPDFImageEditData(editEvent);
             PDFImageEditControl.SetPDFImageEditData(editEvent);
             ContentEditContainer.Child = PDFImageEditControl;
             ContentEditContainer.Child = PDFImageEditControl;
         }
         }
 
 
+
         //public void SetPDFImageMultiEditData(List<PDFEditEvent> editEventList)
         //public void SetPDFImageMultiEditData(List<PDFEditEvent> editEventList)
         //{
         //{
         //    PDFImageEditControl.SetPDFImageMultiEditData(editEventList);
         //    PDFImageEditControl.SetPDFImageMultiEditData(editEventList);

+ 90 - 96
Demo/Examples/Compdfkit.Controls/Edit/PDFImageEdit/PDFImageEditControl/PDFImageEditControl.xaml

@@ -6,7 +6,7 @@
              xmlns:local="clr-namespace:ComPDFKit.Controls.Edit"
              xmlns:local="clr-namespace:ComPDFKit.Controls.Edit"
              xmlns:common="clr-namespace:ComPDFKit.Controls.Common"
              xmlns:common="clr-namespace:ComPDFKit.Controls.Common"
              mc:Ignorable="d" 
              mc:Ignorable="d" 
-             d:DesignHeight="480" d:DesignWidth="800" MinWidth="260" Padding="10"
+             d:DesignHeight="720" d:DesignWidth="280" MinWidth="260" Padding="10"
              Background="#FAFCFF">
              Background="#FAFCFF">
     <UserControl.Resources>
     <UserControl.Resources>
         <ResourceDictionary>
         <ResourceDictionary>
@@ -18,48 +18,41 @@
             <common:CommonResourceConverter x:Key="CommonResourceConverter" />
             <common:CommonResourceConverter x:Key="CommonResourceConverter" />
         </ResourceDictionary>
         </ResourceDictionary>
     </UserControl.Resources>
     </UserControl.Resources>
-    
-    <Grid>
-        <Grid.RowDefinitions>
-            <RowDefinition Height="auto"></RowDefinition>
-            <RowDefinition Height="auto"></RowDefinition>
-            <RowDefinition Height="auto"></RowDefinition>
-            <RowDefinition Height="auto"></RowDefinition>
-            <RowDefinition Height="auto"></RowDefinition>
-            <RowDefinition Height="auto"></RowDefinition>
-        </Grid.RowDefinitions>
+    <ScrollViewer VerticalScrollBarVisibility="Auto">
 
 
-        <Border Background="White" Height="36">
-            <TextBlock FontSize="14" FontWeight="Bold" HorizontalAlignment="Center" Foreground="#42464D" VerticalAlignment="Center" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_ImageProperty}"></TextBlock>
-        </Border>
+        <StackPanel>
 
 
-        <Border Name="ImageThumbBorder" Background="White" Grid.Row="1" MinHeight="100" CornerRadius="5" Margin="0,16,0,0" BorderThickness="1" BorderBrush="#E2E3E6">
-            <Image Name="ImageThumbUI" MaxHeight="80" MaxWidth="230" Stretch="Uniform"></Image>
-        </Border>
-         
-        <StackPanel Grid.Row="2"  Margin="0,33,0,0" >
-            <local:CPDFImageRotateUI x:Name="RotateUI" FontSize="16"></local:CPDFImageRotateUI>
-            <Grid Margin="0,10,0,0">
-                <TextBlock Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Rotation}" FontFamily="Microsoft YaHei" FontSize="14" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock>
-                <TextBox Padding="5,0,5,0" x:Name="RotationTxb" HorizontalAlignment="Right" VerticalContentAlignment="Center" Width="110" Height="32" LostFocus="RotationTxb_LostFocus" PreviewKeyDown="RotationTxb_PreviewKeyDown"></TextBox>
-            </Grid>
-        </StackPanel>
-        
-        <local:CPDFImageFlipUI x:Name="FlipUI" Grid.Row="3" FontSize="16" Margin="0,10,0,0"></local:CPDFImageFlipUI>
-         
-        <Grid Grid.Row="4" Margin="0,20,0,0">
-            <Grid.ColumnDefinitions>
-                <ColumnDefinition Width="*"></ColumnDefinition>
-                <ColumnDefinition Width="auto"></ColumnDefinition>
-            </Grid.ColumnDefinitions>
-            <Grid.RowDefinitions>
-                <RowDefinition Height="auto"></RowDefinition>
-                <RowDefinition Height="auto"></RowDefinition>
-            </Grid.RowDefinitions>
+            <Border Background="White" Height="36">
+                <TextBlock FontSize="14" FontWeight="Bold" HorizontalAlignment="Center" Foreground="#42464D" VerticalAlignment="Center" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_ImageProperty}"></TextBlock>
+            </Border>
+
+            <Border Name="ImageThumbBorder" Background="White" Grid.Row="1" MinHeight="100" CornerRadius="5" Margin="0,16,0,0" BorderThickness="1" BorderBrush="#E2E3E6" Visibility="{Binding OnlySingleVisible}">
+                <Image Name="ImageThumbUI" MaxHeight="80" MaxWidth="230" Stretch="Uniform"></Image>
+            </Border>
+
+            <StackPanel Grid.Row="2"  >
+                <local:CPDFImageRotateUI x:Name="RotateUI" FontSize="16"></local:CPDFImageRotateUI>
+                <Grid Margin="0,10,0,0">
+                    <TextBlock Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Rotation}" FontFamily="Microsoft YaHei" FontSize="14" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock>
+                    <TextBox Padding="5,0,5,0" x:Name="RotationTxb" HorizontalAlignment="Right" VerticalContentAlignment="Center" Width="110" Height="32" LostFocus="RotationTxb_LostFocus" PreviewKeyDown="RotationTxb_PreviewKeyDown"></TextBox>
+                </Grid>
+            </StackPanel>
+
+            <local:CPDFImageFlipUI x:Name="FlipUI" Grid.Row="3" FontSize="16" Margin="0,10,0,0"></local:CPDFImageFlipUI>
+
+            <Grid Grid.Row="4" Margin="0,20,0,0">
+                <Grid.ColumnDefinitions>
+                    <ColumnDefinition Width="*"></ColumnDefinition>
+                    <ColumnDefinition Width="auto"></ColumnDefinition>
+                </Grid.ColumnDefinitions>
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="auto"></RowDefinition>
+                    <RowDefinition Height="auto"></RowDefinition>
+                </Grid.RowDefinitions>
 
 
-            <TextBlock FontSize="14" Foreground="#43474D" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Opacity}"></TextBlock>
+                <TextBlock FontSize="14" Foreground="#43474D" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Opacity}"></TextBlock>
 
 
-            <Slider Style="{StaticResource SliderStyle}" Grid.Row="1" Width="148" Height="28"
+                <Slider Style="{StaticResource SliderStyle}" Grid.Row="1" Width="148" Height="28"
                     Name="ImasgeOpacitySlider" 
                     Name="ImasgeOpacitySlider" 
                     Value="14"  
                     Value="14"  
                     IsSelectionRangeEnabled="True" 
                     IsSelectionRangeEnabled="True" 
@@ -75,81 +68,82 @@
                     Tag="true"
                     Tag="true"
                     />
                     />
 
 
-            <Grid Grid.Row="1" Grid.Column="1" Margin="0,10,0,0">
-                <ComboBox Name="OpacityComboBox" VerticalContentAlignment="Center" Width="72" Height="28" Foreground="#43474D" FontSize="14"
+                <Grid Grid.Row="1" Grid.Column="1" Margin="0,10,0,0">
+                    <ComboBox Name="OpacityComboBox" VerticalContentAlignment="Center" Width="72" Height="28" Foreground="#43474D" FontSize="14"
                               SelectionChanged="OpacityComboBox_SelectionChanged" BorderBrush="#1E000000">
                               SelectionChanged="OpacityComboBox_SelectionChanged" BorderBrush="#1E000000">
-                    <ComboBoxItem>25%</ComboBoxItem>
-                    <ComboBoxItem>50%</ComboBoxItem>
-                    <ComboBoxItem>75%</ComboBoxItem>
-                    <ComboBoxItem>100%</ComboBoxItem>
-                </ComboBox>
-                <TextBox Name="OpacityTextBox" IsHitTestVisible="False" Width="72" Height="30" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"
+                        <ComboBoxItem>25%</ComboBoxItem>
+                        <ComboBoxItem>50%</ComboBoxItem>
+                        <ComboBoxItem>75%</ComboBoxItem>
+                        <ComboBoxItem>100%</ComboBoxItem>
+                    </ComboBox>
+                    <TextBox Name="OpacityTextBox" IsHitTestVisible="False" Width="72" Height="30" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"
                              IsReadOnly="True" Background="White" Padding="0,0,15,0" FontSize="14">100%</TextBox>
                              IsReadOnly="True" Background="White" Padding="0,0,15,0" FontSize="14">100%</TextBox>
-                <Path Fill="#43474D" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,5,0" IsHitTestVisible="False">
-                    <Path.Data>
-                        M0.5 0.510248L4.5041 5.5L8.5 0.5L0.5 0.510248Z
-                    </Path.Data>
-                </Path>
+                    <Path Fill="#43474D" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,5,0" IsHitTestVisible="False">
+                        <Path.Data>
+                            M0.5 0.510248L4.5041 5.5L8.5 0.5L0.5 0.510248Z
+                        </Path.Data>
+                    </Path>
+                </Grid>
             </Grid>
             </Grid>
-        </Grid>
-    
-        <Grid Grid.Row="5" Margin="0,20,0,0">
-            <Grid.RowDefinitions>
-                <RowDefinition Height="auto"></RowDefinition>
-                <RowDefinition Height="auto"></RowDefinition>
-            </Grid.RowDefinitions>
-            <TextBlock VerticalAlignment="Center" FontSize="14" Foreground="#43474D" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Tool}"></TextBlock>
 
 
-            <Border  Grid.Row="1" BorderThickness="1" BorderBrush="#E1E3E5"  Margin="0,14,0,0" HorizontalAlignment="Left">
-                <StackPanel Orientation="Horizontal">
-                    <Button Name="ImageReplaceBtn" Width="40" Height="25" BorderThickness="0" Click="ImageReplaceBtn_Click" Background="White" Style="{StaticResource LightButtonStyle}"
+            <Grid  Margin="0,20,0,0" Visibility="{Binding OnlySingleVisible}">
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="auto"></RowDefinition>
+                    <RowDefinition Height="auto"></RowDefinition>
+                </Grid.RowDefinitions>
+                <TextBlock VerticalAlignment="Center" FontSize="14" Foreground="#43474D" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Tool}"></TextBlock>
+
+                <Border  Grid.Row="1" BorderThickness="1" BorderBrush="#E1E3E5"  Margin="0,14,0,0" HorizontalAlignment="Left">
+                    <StackPanel Orientation="Horizontal">
+                        <Button Name="ImageReplaceBtn" Width="40" Height="25" BorderThickness="0" Click="ImageReplaceBtn_Click" Background="White" Style="{StaticResource LightButtonStyle}"
                             ToolTip="{Binding Converter={StaticResource CommonResourceConverter},ConverterParameter=Menu_Replace}">
                             ToolTip="{Binding Converter={StaticResource CommonResourceConverter},ConverterParameter=Menu_Replace}">
-                        <Button.Content>
-                            <Path Fill="#43474D">
-                                <Path.Data>
-                                    M1.12988 1.88037H0.379883V2.63037V14.3971V15.1471H1.12988H4.47057V16.2589V17.7589H5.97057H11.9871V16.915L11.9995 16L8.64639 
+                            <Button.Content>
+                                <Path Fill="#43474D">
+                                    <Path.Data>
+                                        M1.12988 1.88037H0.379883V2.63037V14.3971V15.1471H1.12988H4.47057V16.2589V17.7589H5.97057H11.9871V16.915L11.9995 16L8.64639 
                                 14.3971L5.97057 15.9838V7.49225H18.0035V12.7161H19.5035V7.49225V5.99225H18.0035H16.9129V2.63037V1.88037H16.1629H1.12988ZM15.4129 
                                 14.3971L5.97057 15.9838V7.49225H18.0035V12.7161H19.5035V7.49225V5.99225H18.0035H16.9129V2.63037V1.88037H16.1629H1.12988ZM15.4129 
                                 5.99225V3.38037H1.87988V13.6471H4.47057V7.49225V5.99225H5.97057H15.4129ZM14.6574 10.5265C15.2097 10.5265 15.6574 10.0759 15.6574 
                                 5.99225V3.38037H1.87988V13.6471H4.47057V7.49225V5.99225H5.97057H15.4129ZM14.6574 10.5265C15.2097 10.5265 15.6574 10.0759 15.6574 
                                 9.5201C15.6574 8.9643 15.2097 8.51373 14.6574 8.51373C14.1051 8.51373 13.6574 8.9643 13.6574 9.5201C13.6574 10.0759 14.1051 10.5265 
                                 9.5201C15.6574 8.9643 15.2097 8.51373 14.6574 8.51373C14.1051 8.51373 13.6574 8.9643 13.6574 9.5201C13.6574 10.0759 14.1051 10.5265 
                                 14.6574 10.5265ZM15.3635 12.4771L14.8863 11.8985L16.0436 10.9442L16.5208 11.5229L17.9828 13.2959L18.9947 
                                 14.6574 10.5265ZM15.3635 12.4771L14.8863 11.8985L16.0436 10.9442L16.5208 11.5229L17.9828 13.2959L18.9947 
                                 14.5231H17.4042H12.9994H12.2494V13.0231H12.9994H15.8136L15.3635 12.4771ZM15.8007 17.2959L16.2779 17.8746L15.1206 18.8289L14.6434 
                                 14.5231H17.4042H12.9994H12.2494V13.0231H12.9994H15.8136L15.3635 12.4771ZM15.8007 17.2959L16.2779 17.8746L15.1206 18.8289L14.6434 
                                 18.2502L13.1814 16.4771L12.1695 15.25H13.76H18.1648H18.9148V16.75H18.1648H15.3506L15.8007 17.2959Z
                                 18.2502L13.1814 16.4771L12.1695 15.25H13.76H18.1648H18.9148V16.75H18.1648H15.3506L15.8007 17.2959Z
-                                </Path.Data>
-                            </Path>
-                        </Button.Content>
-                    </Button>
- 
-                    <Button Grid.Column="1" Width="40" Height="25" BorderThickness="0" Click="ImageExportBtn_Click" Background="White" Style="{StaticResource LightButtonStyle}"
+                                    </Path.Data>
+                                </Path>
+                            </Button.Content>
+                        </Button>
+
+                        <Button Grid.Column="1" Width="40" Height="25" BorderThickness="0" Click="ImageExportBtn_Click" Background="White" Style="{StaticResource LightButtonStyle}"
                             ToolTip="{Binding Converter={StaticResource CommonResourceConverter},ConverterParameter=Menu_Export}">
                             ToolTip="{Binding Converter={StaticResource CommonResourceConverter},ConverterParameter=Menu_Export}">
-                        <Button.Content>
-                            <Path Fill="#43474D">
-                                <Path.Data>
-                                    M12.3597 7.35973L8.75 10.9694L8.75 1V0.25H7.25V1L7.25 10.9694L3.6403 7.35973L3.10997 6.8294L2.04931 7.89006L2.57964 8.42039L7.46967 
+                            <Button.Content>
+                                <Path Fill="#43474D">
+                                    <Path.Data>
+                                        M12.3597 7.35973L8.75 10.9694L8.75 1V0.25H7.25V1L7.25 10.9694L3.6403 7.35973L3.10997 6.8294L2.04931 7.89006L2.57964 8.42039L7.46967 
                                     13.3104C7.76256 13.6033 8.23744 13.6033 8.53033 13.3104L13.4204 8.42039L13.9507 7.89006L12.89 6.8294L12.3597 7.35973ZM1 
                                     13.3104C7.76256 13.6033 8.23744 13.6033 8.53033 13.3104L13.4204 8.42039L13.9507 7.89006L12.89 6.8294L12.3597 7.35973ZM1 
                                     15.1538H0.25V16.6538H1H15.3077H16.0577V15.1538H15.3077H1Z
                                     15.1538H0.25V16.6538H1H15.3077H16.0577V15.1538H15.3077H1Z
-                                </Path.Data>
-                            </Path>
-                        </Button.Content>
-                    </Button>
+                                    </Path.Data>
+                                </Path>
+                            </Button.Content>
+                        </Button>
 
 
-                    <Button Name="ImageClipBtn" Grid.Column="1" Width="40" Height="25" BorderThickness="0" Click="ImageClipBtn_Click" Background="White" Style="{StaticResource LightButtonStyle}"
+                        <Button Name="ImageClipBtn" Grid.Column="1" Width="40" Height="25" BorderThickness="0" Click="ImageClipBtn_Click" Background="White" Style="{StaticResource LightButtonStyle}"
                             ToolTip="{Binding Converter={StaticResource CommonResourceConverter},ConverterParameter=Menu_Crop}">
                             ToolTip="{Binding Converter={StaticResource CommonResourceConverter},ConverterParameter=Menu_Crop}">
-                        <Button.Content>
-                            <Path Fill="#43474D">
-                                <Path.Data>
-                                    M4.75 15.75V4.25H14.4074L13.9517 4.73826L15.0483 5.76174L15.25 5.54562V15.75H4.75ZM3.25 
+                            <Button.Content>
+                                <Path Fill="#43474D">
+                                    <Path.Data>
+                                        M4.75 15.75V4.25H14.4074L13.9517 4.73826L15.0483 5.76174L15.25 5.54562V15.75H4.75ZM3.25 
                                 16.5V4.25H0V2.75H3.25V0.5H4.75V2.75H16H16.75V3.5V15.75H20V17.25H16.75V19.5H15.25V17.25H4H3.25V16.5ZM17.8483 2.76174L18.5483 
                                 16.5V4.25H0V2.75H3.25V0.5H4.75V2.75H16H16.75V3.5V15.75H20V17.25H16.75V19.5H15.25V17.25H4H3.25V16.5ZM17.8483 2.76174L18.5483 
                                 2.01174L17.4517 0.988261L16.7517 1.73826L17.8483 2.76174ZM12.2483 8.76174L13.6483 7.26174L12.5517 6.23826L11.1517 7.73826L12.2483 
                                 2.01174L17.4517 0.988261L16.7517 1.73826L17.8483 2.76174ZM12.2483 8.76174L13.6483 7.26174L12.5517 6.23826L11.1517 7.73826L12.2483 
                                 8.76174ZM9.44829 11.7617L10.8483 10.2617L9.75171 9.23826L8.35171 10.7383L9.44829 11.7617ZM6.64829 14.7617L8.04829 13.2617L6.95171 
                                 8.76174ZM9.44829 11.7617L10.8483 10.2617L9.75171 9.23826L8.35171 10.7383L9.44829 11.7617ZM6.64829 14.7617L8.04829 13.2617L6.95171 
                                 12.2383L5.55171 13.7383L6.64829 14.7617Z
                                 12.2383L5.55171 13.7383L6.64829 14.7617Z
-                                </Path.Data>
-                            </Path>
-                        </Button.Content>
-                    </Button>
-                </StackPanel>
-            </Border>
-          
-        </Grid>
-     
-    </Grid>
+                                    </Path.Data>
+                                </Path>
+                            </Button.Content>
+                        </Button>
+                    </StackPanel>
+                </Border>
+
+            </Grid>
+
+        </StackPanel>
+    </ScrollViewer>
 </UserControl>
 </UserControl>

+ 267 - 140
Demo/Examples/Compdfkit.Controls/Edit/PDFImageEdit/PDFImageEditControl/PDFImageEditControl.xaml.cs

@@ -17,25 +17,35 @@ using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Controls;
 using System.Windows.Controls.Primitives;
 using System.Windows.Controls.Primitives;
 using System.Windows.Input;
 using System.Windows.Input;
-using System.Windows.Media;
 using System.Windows.Media.Imaging;
 using System.Windows.Media.Imaging;
 using ComPDFKit.Tool.DrawTool;
 using ComPDFKit.Tool.DrawTool;
 using ComPDFKitViewer.Helper;
 using ComPDFKitViewer.Helper;
 using ComPDFKit.Tool.Help;
 using ComPDFKit.Tool.Help;
+using System.Linq;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
 
 
 namespace ComPDFKit.Controls.Edit
 namespace ComPDFKit.Controls.Edit
 {
 {
-    public partial class PDFImageEditControl : UserControl
+    public partial class PDFImageEditControl : UserControl, INotifyPropertyChanged
     {
     {
         #region property
         #region property
         public CPDFViewerTool ToolView { get; set; }
         public CPDFViewerTool ToolView { get; set; }
-        public ImageEditParam EditEvent { get; set; }
+        public List<ImageEditParam> EditEvents { get; set; } = new List<ImageEditParam>();
+
+        private Visibility _onlySingleVisible = Visibility.Collapsed;
+        public Visibility OnlySingleVisible
+        {
+            get => _onlySingleVisible;
+            set => UpdateProper(ref  _onlySingleVisible, value);
+        }
 
 
         //public List<PDFEditEvent> EditMultiEvents { get; set; }
         //public List<PDFEditEvent> EditMultiEvents { get; set; }
         #endregion 
         #endregion 
 
 
         public PDFImageEditControl()
         public PDFImageEditControl()
         {
         {
+            DataContext = this;
             InitializeComponent();
             InitializeComponent();
             Loaded += PDFImageEditControl_Loaded;
             Loaded += PDFImageEditControl_Loaded;
             Unloaded += PDFImageEditControl_Unloaded;
             Unloaded += PDFImageEditControl_Unloaded;
@@ -57,7 +67,7 @@ namespace ComPDFKit.Controls.Edit
         {
         {
             RotateUI.RotationChanged -= RotateUI_RotationChanged;
             RotateUI.RotationChanged -= RotateUI_RotationChanged;
             FlipUI.FlipChanged -= FlipUI_FlipChanged;
             FlipUI.FlipChanged -= FlipUI_FlipChanged;
-        } 
+        }
 
 
         #endregion
         #endregion
 
 
@@ -66,24 +76,33 @@ namespace ComPDFKit.Controls.Edit
         {
         {
             if (ToolView.GetIsCropMode())
             if (ToolView.GetIsCropMode())
             {
             {
-                GetImageArea(out CPDFEditImageArea imageArea, out CPDFPage pdfPage, out CPDFEditPage editPage);
-                SelectedRect selectedRect = ToolView.GetSelectedRectForEditAreaObject(imageArea);
-                if (selectedRect != null)
+                GetImageArea(out List<CPDFEditImageArea> imageAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+                if (imageAreas.Count == 0 || pdfPage == null || editPage == null)
+                    return;
+
+                SelectedRect selectedRect = ToolView.GetSelectedRectForEditAreaObject(imageAreas[0]);
+                if (selectedRect == null)
+                    return;
+
+                Rect oldRect = DataConversionForWPF.CRectConversionForRect(imageAreas[0].GetFrame());
+                double currentZoom = ToolView.GetCPDFViewer().CurrentRenderFrame.ZoomFactor;
+                Rect rect = selectedRect.GetRect();
+                Rect maxRect = selectedRect.GetMaxRect();
+                Rect pdfRect = new Rect((rect.X - maxRect.X) / currentZoom, (rect.Y - maxRect.Y) / currentZoom, rect.Width / currentZoom, rect.Height / currentZoom);
+                pdfRect = DpiHelper.StandardRectToPDFRect(pdfRect);
+                CRect newCRect = new CRect((float)pdfRect.Left, (float)pdfRect.Bottom, (float)pdfRect.Right, (float)pdfRect.Top);
+                if(imageAreas[0].CutWithRect(newCRect))
                 {
                 {
-                    Rect oldRect = DataConversionForWPF.CRectConversionForRect(imageArea.GetFrame());
-                    double currentZoom = ToolView.GetCPDFViewer().CurrentRenderFrame.ZoomFactor;
-                    Rect rect = selectedRect.GetRect();
-                    Rect maxRect = selectedRect.GetMaxRect();
-
-                    Rect pdfRect = new Rect((rect.X - maxRect.X) / currentZoom, (rect.Y - maxRect.Y) / currentZoom, rect.Width / currentZoom, rect.Height / currentZoom);
-                    pdfRect = DpiHelper.StandardRectToPDFRect(pdfRect);
-                    CRect newCRect = new CRect((float)pdfRect.Left, (float)pdfRect.Bottom, (float)pdfRect.Right, (float)pdfRect.Top);
-                    imageArea.CutWithRect(newCRect);
-
-                    SetImageThumb();
-                    ToolView.UpdateRender(oldRect, imageArea);
-                    editPage.EndEdit();
-                }
+                    PDFEditHistory editHistory = new PDFEditHistory();
+                    editHistory.EditPage = editPage;
+                    editHistory.PageIndex = pdfPage.PageIndex;
+
+                    ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                    ToolView.UpdateRender(oldRect, imageAreas[0]);
+                 }
+
+                editPage.EndEdit();
+                SetImageThumb();
             }
             }
         }
         }
 
 
@@ -110,16 +129,16 @@ namespace ComPDFKit.Controls.Edit
 
 
         public void SetImageThumb()
         public void SetImageThumb()
         {
         {
-            if (EditEvent != null)
+            if (EditEvents.Count == 1)
             {
             {
                 try
                 try
                 {
                 {
-                    GetImageArea(out CPDFEditImageArea imageArea, out CPDFPage pdfPage, out CPDFEditPage editPage);
+                    GetImageArea(out List<CPDFEditImageArea> imageAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
 
 
                     string path = Path.GetTempPath();
                     string path = Path.GetTempPath();
                     string uuid = Guid.NewGuid().ToString("N");
                     string uuid = Guid.NewGuid().ToString("N");
                     string imagePath = Path.Combine(path, uuid + ".tmp");
                     string imagePath = Path.Combine(path, uuid + ".tmp");
-                    imageArea.ExtractImage(imagePath);
+                    imageAreas.FirstOrDefault().ExtractImage(imagePath);
 
 
                     Bitmap bitmapImage = new Bitmap(imagePath);
                     Bitmap bitmapImage = new Bitmap(imagePath);
                     MemoryStream memoryStream = new MemoryStream();
                     MemoryStream memoryStream = new MemoryStream();
@@ -144,31 +163,33 @@ namespace ComPDFKit.Controls.Edit
             OpacityTextBox.Text = string.Format("{0}%", (int)(Math.Round(ImasgeOpacitySlider.Value * 100)));
             OpacityTextBox.Text = string.Format("{0}%", (int)(Math.Round(ImasgeOpacitySlider.Value * 100)));
         }
         }
 
 
-        public void SetPDFImageEditData(ImageEditParam newEvent)
+        public void SetPDFImageEditData(List<ImageEditParam> newEvents)
         {
         {
-            if (newEvent.EditIndex < 0)
+
+            EditEvents = newEvents.Where(newEvent => newEvent.EditIndex >= 0 && newEvent.EditType == CPDFEditType.EditImage).ToList();
+
+            if (EditEvents.Count > 0)
             {
             {
-                EditEvent = null;
+                SetImageTransparency(EditEvents.FirstOrDefault().Transparency);
             }
             }
-            else
+
+            if (RotationTxb != null && EditEvents.Count > 0)
             {
             {
-                EditEvent = newEvent;
+                GetImageArea(out List<CPDFEditImageArea> imageAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+                RotationTxb.Text = imageAreas?.FirstOrDefault()?.GetRotation().ToString();
             }
             }
-            if (newEvent != null && newEvent.EditType == CPDFEditType.EditImage)
+
+            if (EditEvents.Count == 1)
             {
             {
-                SetImageTransparency(newEvent.Transparency);
+                OnlySingleVisible = Visibility.Visible;
+                SetImageThumb();
             }
             }
-
-            if (RotationTxb != null && newEvent != null && newEvent.EditType == CPDFEditType.EditImage)
+            else
             {
             {
-                GetImageArea(out CPDFEditImageArea imageArea, out CPDFPage pdfPage, out CPDFEditPage editPage);
-                RotationTxb.Text = imageArea?.GetRotation().ToString();
-                //RotationTxb.Text = newEvent.Rotate.ToString(CultureInfo.CurrentCulture);
+                OnlySingleVisible = Visibility.Collapsed;
             }
             }
-
-            EditEvent = newEvent;
-            SetImageThumb();
         }
         }
+
         #endregion
         #endregion
 
 
         //public void SetPDFImageMultiEditData(List<PDFEditEvent> editEvents)
         //public void SetPDFImageMultiEditData(List<PDFEditEvent> editEvents)
@@ -213,36 +234,64 @@ namespace ComPDFKit.Controls.Edit
 
 
         private void FlipUI_FlipChanged(object sender, bool e)
         private void FlipUI_FlipChanged(object sender, bool e)
         {
         {
-            GetImageArea(out CPDFEditImageArea imageArea, out CPDFPage pdfPage, out CPDFEditPage editPage);
-            if (imageArea != null)
+            GetImageArea(out List<CPDFEditImageArea> imageAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+            if (imageAreas.Count == 0 || pdfPage == null || editPage == null)
+                return;
+
+            if(ToolView.CurrentEditAreaObject() != null)
             {
             {
-                Rect oldRect = DataConversionForWPF.CRectConversionForRect(imageArea.GetFrame());
-                bool result = false;
+                Rect oldRect = DataConversionForWPF.CRectConversionForRect(imageAreas[0].GetFrame());
+                bool result;
                 if (e)
                 if (e)
                 {
                 {
-                    result = imageArea.VerticalMirror();
+                    result = imageAreas[0].VerticalMirror();
                 }
                 }
                 else
                 else
                 {
                 {
-                    result = imageArea.HorizontalMirror();
+                    result = imageAreas[0].HorizontalMirror();
                 }
                 }
+
                 if (result)
                 if (result)
                 {
                 {
                     PDFEditHistory editHistory = new PDFEditHistory();
                     PDFEditHistory editHistory = new PDFEditHistory();
                     editHistory.EditPage = editPage;
                     editHistory.EditPage = editPage;
-                    if (pdfPage != null)
+                    editHistory.PageIndex = pdfPage.PageIndex;
+                    ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                    ToolView.UpdateRender(oldRect, imageAreas[0]);
+                }
+            }
+            else
+            {
+                GroupHistory groupHistory = new GroupHistory();
+                foreach (CPDFEditImageArea imageArea in imageAreas)
+                {
+                    bool result;
+                    if (e)
                     {
                     {
-                        editHistory.PageIndex = pdfPage.PageIndex;
+                        result = imageArea.VerticalMirror();
+                    }
+                    else
+                    {
+                        result = imageArea.HorizontalMirror();
                     }
                     }
 
 
-                    ToolView.GetCPDFViewer()?.UndoManager.AddHistory(editHistory);
-                    ToolView.UpdateRender(oldRect, imageArea);
-                    editPage.EndEdit();
+                    if (result)
+                    {
+                        PDFEditHistory editHistory = new PDFEditHistory();
+                        editHistory.EditPage = editPage;
+                        editHistory.PageIndex = pdfPage.PageIndex;
+                        groupHistory.Histories.Add(editHistory);
+                    }
                 }
                 }
 
 
-                SetImageThumb();
+                ToolView.GetCPDFViewer()?.UndoManager.AddHistory(groupHistory);
+                ToolView.GetCPDFViewer()?.UpdateRenderFrame();
             }
             }
 
 
+            editPage.EndEdit();
+            if (imageAreas.Count == 1)
+                SetImageThumb();
+
             //if (EditMultiEvents != null)
             //if (EditMultiEvents != null)
             //{
             //{
             //    foreach (PDFEditEvent editEvent in EditMultiEvents)
             //    foreach (PDFEditEvent editEvent in EditMultiEvents)
@@ -262,28 +311,45 @@ namespace ComPDFKit.Controls.Edit
 
 
         private void RotateUI_RotationChanged(object sender, double e)
         private void RotateUI_RotationChanged(object sender, double e)
         {
         {
-            GetImageArea(out CPDFEditImageArea imageArea, out CPDFPage pdfPage, out CPDFEditPage editPage);
-            if (imageArea != null)
+            GetImageArea(out List<CPDFEditImageArea> imageAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+            if (imageAreas.Count == 0 || pdfPage == null || editPage == null)
+                return;
+
+            if(ToolView.CurrentEditAreaObject() != null)
             {
             {
-                Rect oldRect = DataConversionForWPF.CRectConversionForRect(imageArea.GetFrame());
-                if (imageArea.Rotate((int)e))
+                Rect oldRect = DataConversionForWPF.CRectConversionForRect(imageAreas[0].GetFrame());
+                if (imageAreas[0].Rotate((int)e))
                 {
                 {
                     PDFEditHistory editHistory = new PDFEditHistory();
                     PDFEditHistory editHistory = new PDFEditHistory();
                     editHistory.EditPage = editPage;
                     editHistory.EditPage = editPage;
-                    if (pdfPage != null)
+                    editHistory.PageIndex = pdfPage.PageIndex;
+                    ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                    ToolView.UpdateRender(oldRect, imageAreas[0]);
+                }
+            }
+            else
+            {
+                GroupHistory groupHistory = new GroupHistory();
+                foreach (CPDFEditImageArea imageArea in imageAreas)
+                {
+                    if (imageArea.Rotate((int)e))
                     {
                     {
+                        PDFEditHistory editHistory = new PDFEditHistory();
+                        editHistory.EditPage = editPage;
                         editHistory.PageIndex = pdfPage.PageIndex;
                         editHistory.PageIndex = pdfPage.PageIndex;
+                        groupHistory.Histories.Add(editHistory);
                     }
                     }
-
-                    ToolView.GetCPDFViewer()?.UndoManager.AddHistory(editHistory);
-                    //SetRotationText(EditEvent.CurrentRotated);
-                    SetImageThumb();
-                    ToolView.UpdateRender(oldRect, imageArea);
-                    editPage.EndEdit();
-                    RotationTxb.Text = imageArea.GetRotation().ToString();
                 }
                 }
+
+                ToolView.GetCPDFViewer()?.UndoManager.AddHistory(groupHistory);
+                ToolView.GetCPDFViewer()?.UpdateRenderFrame();
             }
             }
 
 
+            editPage.EndEdit();
+            RotationTxb.Text = imageAreas.FirstOrDefault().GetRotation().ToString();
+            if (imageAreas.Count == 1)
+                SetImageThumb();
+
             //if (EditMultiEvents != null)
             //if (EditMultiEvents != null)
             //{
             //{
             //    foreach (PDFEditEvent editEvent in EditMultiEvents)
             //    foreach (PDFEditEvent editEvent in EditMultiEvents)
@@ -310,34 +376,44 @@ namespace ComPDFKit.Controls.Edit
             {
             {
                 slider.Tag = "true";
                 slider.Tag = "true";
             }
             }
-            GetImageArea(out CPDFEditImageArea imageArea, out CPDFPage pdfPage, out CPDFEditPage editPage);
-            if (imageArea != null)
+
+            GetImageArea(out List<CPDFEditImageArea> imageAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+            if (imageAreas.Count == 0 || pdfPage == null || editPage == null)
+                return;
+
+            if (ToolView.CurrentEditAreaObject() != null)
             {
             {
-                Rect oldRect = DataConversionForWPF.CRectConversionForRect(imageArea.GetFrame());
-                if (imageArea.SetImageTransparency((byte)(ImasgeOpacitySlider.Value * 255)))
+                Rect oldRect = DataConversionForWPF.CRectConversionForRect(imageAreas[0].GetFrame());
+                if (imageAreas[0].SetImageTransparency((byte)(ImasgeOpacitySlider.Value * 255)))
                 {
                 {
                     PDFEditHistory editHistory = new PDFEditHistory();
                     PDFEditHistory editHistory = new PDFEditHistory();
                     editHistory.EditPage = editPage;
                     editHistory.EditPage = editPage;
-                    if (pdfPage != null)
+                    editHistory.PageIndex = pdfPage.PageIndex;
+                    ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                    ToolView.UpdateRender(oldRect, imageAreas[0]);
+                }
+            }
+            else
+            {
+                GroupHistory groupHistory = new GroupHistory();
+                foreach (CPDFEditImageArea imageArea in imageAreas)
+                {
+                    if (imageArea.SetImageTransparency((byte)(ImasgeOpacitySlider.Value * 255)))
                     {
                     {
+                        PDFEditHistory editHistory = new PDFEditHistory();
+                        editHistory.EditPage = editPage;
                         editHistory.PageIndex = pdfPage.PageIndex;
                         editHistory.PageIndex = pdfPage.PageIndex;
+                        groupHistory.Histories.Add(editHistory);
                     }
                     }
-
-                    ToolView.GetCPDFViewer()?.UndoManager.AddHistory(editHistory);
-                    SetImageThumb();
-                    ToolView.UpdateRender(oldRect, imageArea);
-                    editPage.EndEdit();
                 }
                 }
+
+                ToolView.GetCPDFViewer()?.UndoManager.AddHistory(groupHistory);
+                ToolView.GetCPDFViewer()?.UpdateRenderFrame();
             }
             }
 
 
-            //if (EditMultiEvents != null)
-            //{
-            //    foreach (PDFEditEvent editEvent in EditMultiEvents)
-            //    {
-            //        editEvent.Transparency = (int)(ImageOpacitySlider.Value * 255);
-            //    }
-            //    PDFEditEvent.UpdatePDFEditList(EditMultiEvents);
-            //}
+            editPage.EndEdit();
+            if (imageAreas.Count == 1)
+                SetImageThumb();
         }
         }
 
 
         private void SliderOpacity_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
         private void SliderOpacity_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
@@ -352,25 +428,44 @@ namespace ComPDFKit.Controls.Edit
             {
             {
                 return;
                 return;
             }
             }
-            GetImageArea(out CPDFEditImageArea imageArea, out CPDFPage pdfPage, out CPDFEditPage editPage);
-            if (imageArea != null)
+
+            GetImageArea(out List<CPDFEditImageArea> imageAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+            if (imageAreas.Count == 0 || pdfPage == null || editPage == null)
+                return;
+
+            if (ToolView.CurrentEditAreaObject() != null)
             {
             {
-                Rect oldRect = DataConversionForWPF.CRectConversionForRect(imageArea.GetFrame());
-                if (imageArea.SetImageTransparency((byte)(ImasgeOpacitySlider.Value * 255)))
+                Rect oldRect = DataConversionForWPF.CRectConversionForRect(imageAreas[0].GetFrame());
+                if (imageAreas[0].SetImageTransparency((byte)(ImasgeOpacitySlider.Value * 255)))
                 {
                 {
                     PDFEditHistory editHistory = new PDFEditHistory();
                     PDFEditHistory editHistory = new PDFEditHistory();
                     editHistory.EditPage = editPage;
                     editHistory.EditPage = editPage;
-                    if (pdfPage != null)
+                    editHistory.PageIndex = pdfPage.PageIndex;
+                    ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                    ToolView.UpdateRender(oldRect, imageAreas[0]);
+                }
+            }
+            else
+            {
+                GroupHistory groupHistory = new GroupHistory();
+                foreach (CPDFEditImageArea imageArea in imageAreas)
+                {
+                    if (imageArea.SetImageTransparency((byte)(ImasgeOpacitySlider.Value * 255)))
                     {
                     {
+                        PDFEditHistory editHistory = new PDFEditHistory();
+                        editHistory.EditPage = editPage;
                         editHistory.PageIndex = pdfPage.PageIndex;
                         editHistory.PageIndex = pdfPage.PageIndex;
+                        groupHistory.Histories.Add(editHistory);
                     }
                     }
-
-                    ToolView.GetCPDFViewer()?.UndoManager.AddHistory(editHistory);
-                    SetImageThumb();
-                    ToolView.UpdateRender(oldRect, imageArea);
-                    editPage.EndEdit();
                 }
                 }
+
+                ToolView.GetCPDFViewer()?.UndoManager.AddHistory(groupHistory);
+                ToolView.GetCPDFViewer()?.UpdateRenderFrame();
             }
             }
+
+            editPage.EndEdit();
+            if (imageAreas.Count == 1)
+                SetImageThumb();
         }
         }
 
 
         private void ImageReplaceBtn_Click(object sender, RoutedEventArgs e)
         private void ImageReplaceBtn_Click(object sender, RoutedEventArgs e)
@@ -380,39 +475,35 @@ namespace ComPDFKit.Controls.Edit
             //    return;
             //    return;
             //}
             //}
 
 
-            if (EditEvent != null)
+            if (EditEvents.Count > 0)
             {
             {
                 OpenFileDialog openFileDialog = new OpenFileDialog();
                 OpenFileDialog openFileDialog = new OpenFileDialog();
                 openFileDialog.Filter = "Image Files(*.jpg;*.jpeg;*.png;*.bmp)|*.jpg;*.jpeg;*.png;*.bmp;";
                 openFileDialog.Filter = "Image Files(*.jpg;*.jpeg;*.png;*.bmp)|*.jpg;*.jpeg;*.png;*.bmp;";
                 if (openFileDialog.ShowDialog() == true)
                 if (openFileDialog.ShowDialog() == true)
                 {
                 {
-                    GetImageArea(out CPDFEditImageArea imageArea, out CPDFPage pdfPage, out CPDFEditPage editPage);
-                    if (imageArea != null)
+                    GetImageArea(out List<CPDFEditImageArea> imageAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+                    if (imageAreas.Count == 0 || pdfPage == null || editPage == null)
+                        return;
+
+                    int imageWidth = 0;
+                    int imageHeight = 0;
+                    byte[] imageData = null;
+                    PDFHelp.ImagePathToByte(openFileDialog.FileName, ref imageData, ref imageWidth, ref imageHeight);
+                    if (imageData != null && imageWidth > 0 && imageHeight > 0)
                     {
                     {
-                        int imageWidth = 0;
-                        int imageHeight = 0;
-                        byte[] imageData = null;
-                        PDFHelp.ImagePathToByte(openFileDialog.FileName, ref imageData, ref imageWidth, ref imageHeight);
-
-                        if (imageData != null && imageWidth > 0 && imageHeight > 0)
+                        Rect oldRect = DataConversionForWPF.CRectConversionForRect(imageAreas[0].GetFrame());
+                        CRect imageRect = imageAreas[0].GetClipRect();
+                        if (imageAreas[0].ReplaceImageArea(imageRect, imageData, imageWidth, imageHeight))
                         {
                         {
-                            Rect oldRect = DataConversionForWPF.CRectConversionForRect(imageArea.GetFrame());
-                            CRect imageRect = imageArea.GetClipRect();
-                            if (imageArea.ReplaceImageArea(imageRect, imageData, imageWidth, imageHeight))
-                            {
-                                PDFEditHistory editHistory = new PDFEditHistory();
-                                editHistory.EditPage = editPage;
-                                if (pdfPage != null)
-                                {
-                                    editHistory.PageIndex = pdfPage.PageIndex;
-                                }
-
-                                ToolView.GetCPDFViewer()?.UndoManager.AddHistory(editHistory);
-                                SetImageThumb();
-                                ToolView.UpdateRender(oldRect, imageArea);
-                                editPage.EndEdit();
-                            }
+                            PDFEditHistory editHistory = new PDFEditHistory();
+                            editHistory.EditPage = editPage;
+                            editHistory.PageIndex = pdfPage.PageIndex;
+                            ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                            ToolView.UpdateRender(oldRect, imageAreas[0]);
                         }
                         }
+
+                        editPage.EndEdit();
+                        SetImageThumb();
                     }
                     }
                 }
                 }
             }
             }
@@ -472,27 +563,29 @@ namespace ComPDFKit.Controls.Edit
             }
             }
         }
         }
 
 
-        private void GetImageArea(out CPDFEditImageArea imageArea, out CPDFPage pdfPage, out CPDFEditPage editPage)
+        private void GetImageArea(out List<CPDFEditImageArea> imageAreas, out CPDFPage pdfPage, out CPDFEditPage editPage)
         {
         {
-            imageArea = null;
+            imageAreas = new List<CPDFEditImageArea>();
             editPage = null;
             editPage = null;
             pdfPage = null;
             pdfPage = null;
-            if (ToolView == null || EditEvent == null)
+            if (ToolView == null || EditEvents.Count == 0)
             {
             {
                 return;
                 return;
             }
             }
-
             try
             try
             {
             {
-                CPDFViewer pdfViewer = ToolView.GetCPDFViewer();
-                CPDFDocument pdfDoc = pdfViewer.GetDocument();
-                pdfPage = pdfDoc.PageAtIndex(EditEvent.PageIndex);
-                editPage = pdfPage.GetEditPage();
-                List<CPDFEditArea> editAreas = editPage.GetEditAreaList();
-                if (editAreas != null && editAreas.Count > EditEvent.EditIndex)
+                foreach (var EditEvent in EditEvents)
                 {
                 {
-                    imageArea = editAreas[EditEvent.EditIndex] as CPDFEditImageArea;
-                }
+                    CPDFViewer pdfViewer = ToolView.GetCPDFViewer();
+                    CPDFDocument pdfDoc = pdfViewer.GetDocument();
+                    pdfPage = pdfDoc.PageAtIndex(EditEvent.PageIndex);
+                    editPage = pdfPage.GetEditPage();
+                    List<CPDFEditArea> editAreas = editPage.GetEditAreaList();
+                    if (editAreas != null && editAreas.Count > EditEvent.EditIndex)
+                    {
+                        imageAreas.Add(editAreas[EditEvent.EditIndex] as CPDFEditImageArea);
+                    }
+                } 
             }
             }
             catch (Exception ex)
             catch (Exception ex)
             {
             {
@@ -502,26 +595,45 @@ namespace ComPDFKit.Controls.Edit
 
 
         private void SetAbsRotation(double absRotation)
         private void SetAbsRotation(double absRotation)
         {
         {
-            GetImageArea(out CPDFEditImageArea imageArea, out CPDFPage pdfPage, out CPDFEditPage editPage);
-            if (imageArea != null)
+            GetImageArea(out List<CPDFEditImageArea> imageAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+            if (imageAreas.Count == 0 || pdfPage == null || editPage == null)
+                return;
+
+            if (ToolView.CurrentEditAreaObject() != null)
             {
             {
-                int rotation = (int)absRotation - imageArea.GetRotation();
-                Rect oldRect = DataConversionForWPF.CRectConversionForRect(imageArea.GetFrame());
-                if (imageArea.Rotate(rotation))
+                Rect oldRect = DataConversionForWPF.CRectConversionForRect(imageAreas[0].GetFrame());
+                int rotation = (int)absRotation - imageAreas[0].GetRotation();
+                if (imageAreas[0].Rotate(rotation))
                 {
                 {
                     PDFEditHistory editHistory = new PDFEditHistory();
                     PDFEditHistory editHistory = new PDFEditHistory();
                     editHistory.EditPage = editPage;
                     editHistory.EditPage = editPage;
-                    if (pdfPage != null)
+                    editHistory.PageIndex = pdfPage.PageIndex;
+                    ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                    ToolView.UpdateRender(oldRect, imageAreas[0]);
+                }
+            }
+            else
+            {
+                GroupHistory groupHistory = new GroupHistory();
+                foreach (CPDFEditImageArea imageArea in imageAreas)
+                {
+                    int rotation = (int)absRotation - imageArea.GetRotation();
+                    if (imageArea.Rotate(rotation))
                     {
                     {
+                        PDFEditHistory editHistory = new PDFEditHistory();
+                        editHistory.EditPage = editPage;
                         editHistory.PageIndex = pdfPage.PageIndex;
                         editHistory.PageIndex = pdfPage.PageIndex;
+                        groupHistory.Histories.Add(editHistory);
                     }
                     }
-
-                    ToolView.GetCPDFViewer()?.UndoManager.AddHistory(editHistory);
-                    SetImageThumb();
-                    ToolView.UpdateRender(oldRect, imageArea);
-                    editPage.EndEdit();
                 }
                 }
+
+                ToolView.GetCPDFViewer()?.UndoManager.AddHistory(groupHistory);
+                ToolView.GetCPDFViewer()?.UpdateRenderFrame();
             }
             }
+
+            editPage.EndEdit();
+            if(imageAreas.Count == 1)
+                SetImageThumb();
         }
         }
 
 
         private void RotationTxb_LostFocus(object sender, RoutedEventArgs e)
         private void RotationTxb_LostFocus(object sender, RoutedEventArgs e)
@@ -540,6 +652,21 @@ namespace ComPDFKit.Controls.Edit
                 RotationTxb_LostFocus(null, null);
                 RotationTxb_LostFocus(null, null);
             }
             }
         }
         }
-        #endregion 
+        #endregion
+
+        public event PropertyChangedEventHandler PropertyChanged;
+        protected bool UpdateProper<T>(ref T properValue,
+                                           T newValue,
+                                           [CallerMemberName] string properName = "")
+        {
+            if (object.Equals(properValue, newValue))
+                return false;
+
+            properValue = newValue;
+            OnPropertyChanged(properName);
+            return true;
+        }
+        protected void OnPropertyChanged([CallerMemberName] string propertyName = "") =>
+    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     }
     }
 }
 }

+ 53 - 44
Demo/Examples/Compdfkit.Controls/Edit/PDFTextEdit/PDFTextEditControl/PDFTextEditControl.xaml

@@ -15,46 +15,49 @@
             <common:PropertyPanelResourceConverter x:Key="PropertyPanelResourceConverter"></common:PropertyPanelResourceConverter>
             <common:PropertyPanelResourceConverter x:Key="PropertyPanelResourceConverter"></common:PropertyPanelResourceConverter>
         </ResourceDictionary>
         </ResourceDictionary>
     </UserControl.Resources>
     </UserControl.Resources>
-    <Grid>
-        <Grid.RowDefinitions>
-            <RowDefinition Height="auto"></RowDefinition>
-            <RowDefinition Height="auto"></RowDefinition>
-        </Grid.RowDefinitions>
-        
-        <Border Height="36" Background="White">
-            <TextBlock FontSize="14" FontWeight="Bold" HorizontalAlignment="Center" LineHeight="17" VerticalAlignment="Center"
-                       Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_TextProperty}"></TextBlock>
-        </Border>
+    <ScrollViewer VerticalScrollBarVisibility="Auto">
 
 
-        <Grid Grid.Row="1">
+        <Grid>
             <Grid.RowDefinitions>
             <Grid.RowDefinitions>
                 <RowDefinition Height="auto"></RowDefinition>
                 <RowDefinition Height="auto"></RowDefinition>
                 <RowDefinition Height="auto"></RowDefinition>
                 <RowDefinition Height="auto"></RowDefinition>
-                <RowDefinition Height="auto"></RowDefinition>
-                <RowDefinition Height="auto"></RowDefinition>
-                <RowDefinition Height="auto"></RowDefinition>
-                <RowDefinition Height="auto"></RowDefinition>
             </Grid.RowDefinitions>
             </Grid.RowDefinitions>
 
 
-            <TextBlock Margin="0,20,0,0" Foreground="#0E1114" FontSize="14"
-                       Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_FontColor}"></TextBlock>
-
-            <common:ColorPickerControl x:Name="FontColorUI" Grid.Row="1" Margin="0,20,0,0" TransparentBtnProperty="Collapsed"></common:ColorPickerControl>
+            <Border Height="36" Background="White">
+                <TextBlock FontSize="14" FontWeight="Bold" HorizontalAlignment="Center" LineHeight="17" VerticalAlignment="Center"
+                       Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_TextProperty}"></TextBlock>
+            </Border>
 
 
-            <Grid Grid.Row="2" Margin="0,20,0,0" Visibility="Visible">
-                <Grid.ColumnDefinitions>
-                    <ColumnDefinition Width="*"></ColumnDefinition>
-                    <ColumnDefinition Width="auto"></ColumnDefinition>
-                </Grid.ColumnDefinitions>
+            <Grid Grid.Row="1">
                 <Grid.RowDefinitions>
                 <Grid.RowDefinitions>
                     <RowDefinition Height="auto"></RowDefinition>
                     <RowDefinition Height="auto"></RowDefinition>
                     <RowDefinition Height="auto"></RowDefinition>
                     <RowDefinition Height="auto"></RowDefinition>
+                    <RowDefinition Height="auto"></RowDefinition>
+                    <RowDefinition Height="auto"></RowDefinition>
+                    <RowDefinition Height="auto"></RowDefinition>
+                    <RowDefinition Height="auto"></RowDefinition>
+                    <RowDefinition Height="auto"></RowDefinition>
                 </Grid.RowDefinitions>
                 </Grid.RowDefinitions>
 
 
-                <TextBlock FontSize="14" Foreground="#43474D"
+                <TextBlock Margin="0,20,0,0" Foreground="#0E1114" FontSize="14"
+                       Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_FontColor}"></TextBlock>
+
+                <common:ColorPickerControl x:Name="FontColorUI" Grid.Row="1" Margin="0,20,0,0" TransparentBtnProperty="Collapsed"></common:ColorPickerControl>
+
+                <Grid Grid.Row="2" Margin="0,20,0,0" Visibility="Visible">
+                    <Grid.ColumnDefinitions>
+                        <ColumnDefinition Width="*"></ColumnDefinition>
+                        <ColumnDefinition Width="auto"></ColumnDefinition>
+                    </Grid.ColumnDefinitions>
+                    <Grid.RowDefinitions>
+                        <RowDefinition Height="auto"></RowDefinition>
+                        <RowDefinition Height="auto"></RowDefinition>
+                    </Grid.RowDefinitions>
+
+                    <TextBlock FontSize="14" Foreground="#43474D"
                            Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Opacity}"></TextBlock>
                            Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Opacity}"></TextBlock>
 
 
-                <Slider Style="{StaticResource SliderStyle}" Grid.Row="1" Width="148" Height="28"
+                    <Slider Style="{StaticResource SliderStyle}" Grid.Row="1" Width="148" Height="28"
                     Name="FontOpacitySlider" 
                     Name="FontOpacitySlider" 
                     Value="14"  
                     Value="14"  
                     IsSelectionRangeEnabled="True" 
                     IsSelectionRangeEnabled="True" 
@@ -70,29 +73,35 @@
                     Tag="true"
                     Tag="true"
                     />
                     />
 
 
-                <Grid Grid.Row="1" Grid.Column="1" Margin="0,10,0,0">
-                    <ComboBox Name="OpacityComboBox" VerticalContentAlignment="Center" Width="72" Height="28" Foreground="#43474D" FontSize="14"
+                    <Grid Grid.Row="1" Grid.Column="1" Margin="0,10,0,0">
+                        <ComboBox Name="OpacityComboBox" VerticalContentAlignment="Center" Width="72" Height="28" Foreground="#43474D" FontSize="14"
                               SelectionChanged="OpacityComboBox_SelectionChanged" BorderBrush="#1E000000">
                               SelectionChanged="OpacityComboBox_SelectionChanged" BorderBrush="#1E000000">
-                        <ComboBoxItem>25%</ComboBoxItem>
-                        <ComboBoxItem>50%</ComboBoxItem>
-                        <ComboBoxItem>75%</ComboBoxItem>
-                        <ComboBoxItem>100%</ComboBoxItem>
-                    </ComboBox>
-                    <TextBox Name="OpacityTextBox" IsHitTestVisible="False" Width="72" Height="30" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"
+                            <ComboBoxItem>25%</ComboBoxItem>
+                            <ComboBoxItem>50%</ComboBoxItem>
+                            <ComboBoxItem>75%</ComboBoxItem>
+                            <ComboBoxItem>100%</ComboBoxItem>
+                        </ComboBox>
+                        <TextBox Name="OpacityTextBox" IsHitTestVisible="False" Width="72" Height="30" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"
                              IsReadOnly="True" Background="White" Padding="0,0,15,0" FontSize="14">100%</TextBox>
                              IsReadOnly="True" Background="White" Padding="0,0,15,0" FontSize="14">100%</TextBox>
-                    <Path Fill="#43474D" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,5,0" IsHitTestVisible="False">
-                        <Path.Data>
-                            M0.5 0.510248L4.5041 5.5L8.5 0.5L0.5 0.510248Z
-                        </Path.Data>
-                    </Path>
+                        <Path Fill="#43474D" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,5,0" IsHitTestVisible="False">
+                            <Path.Data>
+                                M0.5 0.510248L4.5041 5.5L8.5 0.5L0.5 0.510248Z
+                            </Path.Data>
+                        </Path>
+                    </Grid>
                 </Grid>
                 </Grid>
-            </Grid>
 
 
-            <local:CPDFTextStyleUI x:Name="TextStyleUI" Grid.Row="3" FontSize="16" Margin="0,20,0,0"></local:CPDFTextStyleUI>
+                <local:CPDFTextStyleUI x:Name="TextStyleUI" Grid.Row="3" FontSize="16" Margin="0,20,0,0"></local:CPDFTextStyleUI>
+
+                <local:CPDFTextAlignUI x:Name="TextAlignUI" Grid.Row="4" FontSize="16" Margin="0,20,0,0" Width="150" HorizontalAlignment="Left"></local:CPDFTextAlignUI>
+                <StackPanel Grid.Row="5">
+                    <CheckBox x:Name="chkMulti" IsChecked="{Binding IsMultiSelected}"  Content="Multi Selected" Margin="0,10,0,0" Click="chkMulti_Click"></CheckBox>
 
 
-            <local:CPDFTextAlignUI x:Name="TextAlignUI" Grid.Row="4" FontSize="16" Margin="0,20,0,0" Width="150" HorizontalAlignment="Left"></local:CPDFTextAlignUI>
-            
+                    <CheckBox x:Name="chkEditPen" IsChecked="{Binding ShowBorder}" Content="Show Border" Margin="0,10,0,0" Click="chkEditPen_Click"></CheckBox>
+
+                </StackPanel>
+            </Grid>
         </Grid>
         </Grid>
+    </ScrollViewer>
 
 
-    </Grid>
 </UserControl>
 </UserControl>

+ 360 - 151
Demo/Examples/Compdfkit.Controls/Edit/PDFTextEdit/PDFTextEditControl/PDFTextEditControl.xaml.cs

@@ -5,7 +5,6 @@ using ComPDFKit.Tool;
 using ComPDFKit.Tool.SettingParam;
 using ComPDFKit.Tool.SettingParam;
 using ComPDFKit.Tool.UndoManger;
 using ComPDFKit.Tool.UndoManger;
 using ComPDFKit.Viewer.Helper;
 using ComPDFKit.Viewer.Helper;
-using ComPDFKit.Controls.PDFControl;
 using ComPDFKitViewer;
 using ComPDFKitViewer;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
@@ -13,22 +12,48 @@ using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Controls;
 using System.Windows.Controls.Primitives;
 using System.Windows.Controls.Primitives;
 using System.Windows.Media;
 using System.Windows.Media;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using System.Linq;
+
 namespace ComPDFKit.Controls.Edit
 namespace ComPDFKit.Controls.Edit
 {
 {
-    public partial class PDFTextEditControl : UserControl
+    public partial class PDFTextEditControl : UserControl, INotifyPropertyChanged
     {
     {
         #region Property
         #region Property
         public CPDFViewerTool ToolView { get; private set; }
         public CPDFViewerTool ToolView { get; private set; }
-        public TextEditParam EditEvent { get; set; }
+        public List<TextEditParam> EditEvents { get; set; }
+
 
 
-        //public List<PDFEditEvent> EditMultiEvents { get; set; }
+        public event PropertyChangedEventHandler PropertyChanged;
+
+        private bool _isMultiSelected = true;
+        public bool IsMultiSelected
+        {
+            get => _isMultiSelected;
+            set
+            {
+                UpdateProper(ref _isMultiSelected, value);
+            }
+        }
 
 
+        private bool _showBorder;
+        public bool ShowBorder
+        {
+            get => _showBorder;
+            set
+            {
+                UpdateProper(ref _showBorder, value);
+            }
+        }
         #endregion 
         #endregion 
 
 
         public PDFTextEditControl()
         public PDFTextEditControl()
         {
         {
+            DataContext = this;
             InitializeComponent();
             InitializeComponent();
             Loaded += PDFTextEditControl_Loaded;
             Loaded += PDFTextEditControl_Loaded;
+
         }
         }
 
 
         #region Init PDFView
         #region Init PDFView
@@ -39,23 +64,18 @@ namespace ComPDFKit.Controls.Edit
         #endregion
         #endregion
 
 
         #region UI
         #region UI
-        public void SetPDFTextEditData(TextEditParam newEvent)
+        public void SetPDFTextEditData(List<TextEditParam> newEvents)
         {
         {
-            if (newEvent.EditIndex<0)
-            {
-                EditEvent = null;
-            }
-            else
+            EditEvents = newEvents.Where(newEvent => newEvent.EditIndex >= 0 && newEvent.EditType == CPDFEditType.EditText).ToList();
+            TextEditParam defaultEvent = EditEvents.FirstOrDefault();
+            if (EditEvents.Count > 0)
             {
             {
-                EditEvent = newEvent;
-            }
-            if (newEvent != null && newEvent.EditType == CPDFEditType.EditText)
-            {
-                GetTextArea(out CPDFEditTextArea textArea, out CPDFPage pdfPage, out CPDFEditPage editPage);
+                GetTextArea(out List<CPDFEditTextArea> textArea, out CPDFPage pdfPage, out CPDFEditPage editPage);
+
                 List<string> sysfontList = new List<string>();
                 List<string> sysfontList = new List<string>();
                 if (textArea != null)
                 if (textArea != null)
                 {
                 {
-                    sysfontList = textArea.GetFontList();
+                    sysfontList = textArea.FirstOrDefault().GetFontList();
                 }
                 }
                 if (sysfontList.Count == 0)
                 if (sysfontList.Count == 0)
                 {
                 {
@@ -63,28 +83,26 @@ namespace ComPDFKit.Controls.Edit
                     sysfontList.Add("Courier New");
                     sysfontList.Add("Courier New");
                     sysfontList.Add("Times New Roman");
                     sysfontList.Add("Times New Roman");
                 }
                 }
-                if (sysfontList.Contains(newEvent.FontName) == false && string.IsNullOrEmpty(newEvent.FontName) == false)
+                if (sysfontList.Contains(defaultEvent.FontName) == false && string.IsNullOrEmpty(defaultEvent.FontName) == false)
                 {
                 {
-                    sysfontList.Add(newEvent.FontName);
+                    sysfontList.Add(defaultEvent.FontName);
                 }
                 }
 
 
                 TextStyleUI.SetFontNames(sysfontList);
                 TextStyleUI.SetFontNames(sysfontList);
-                TextStyleUI.SelectFontName(newEvent.FontName);
-                TextStyleUI.SetFontStyle(newEvent.IsBold, newEvent.IsItalic);
-                TextStyleUI.SetFontSize(newEvent.FontSize);
-                OpacityTextBox.Text = string.Format("{0}%", (int)(Math.Ceiling(newEvent.Transparency * 100 / 255D)));
-                FontOpacitySlider.Value = ((int)(Math.Ceiling(newEvent.Transparency * 100 / 255D))) / 100D;
-                TextAlignUI.SetFontAlign(newEvent.TextAlign);
-                if (newEvent.FontColor != null && newEvent.FontColor.Length == 3)
+                TextStyleUI.SelectFontName(defaultEvent.FontName);
+                TextStyleUI.SetFontStyle(defaultEvent.IsBold, defaultEvent.IsItalic);
+                TextStyleUI.SetFontSize(defaultEvent.FontSize);
+                OpacityTextBox.Text = string.Format("{0}%", (int)(Math.Ceiling(defaultEvent.Transparency * 100 / 255D)));
+                FontOpacitySlider.Value = ((int)(Math.Ceiling(defaultEvent.Transparency * 100 / 255D))) / 100D;
+                TextAlignUI.SetFontAlign(defaultEvent.TextAlign);
+                if (defaultEvent.FontColor != null && defaultEvent.FontColor.Length == 3)
                 {
                 {
                     FontColorUI.SetCheckedForColor(Color.FromRgb(
                     FontColorUI.SetCheckedForColor(Color.FromRgb(
-                        newEvent.FontColor[0],
-                        newEvent.FontColor[1],
-                        newEvent.FontColor[2]));
+                        defaultEvent.FontColor[0],
+                        defaultEvent.FontColor[1],
+                        defaultEvent.FontColor[2]));
                 }
                 }
-
             }
             }
-            EditEvent = newEvent;
         }
         }
 
 
         //public void SetPDFTextMultiEditData(List<PDFEditEvent> editEvents)
         //public void SetPDFTextMultiEditData(List<PDFEditEvent> editEvents)
@@ -131,12 +149,15 @@ namespace ComPDFKit.Controls.Edit
                 slider.Tag = "true";
                 slider.Tag = "true";
             }
             }
 
 
-            GetTextArea(out CPDFEditTextArea textArea, out CPDFPage pdfPage, out CPDFEditPage editPage);
-            if (textArea != null)
+            GetTextArea(out List<CPDFEditTextArea> textAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+            if (textAreas.Count == 0 || pdfPage == null || editPage == null)
+                return;
+
+            if (ToolView.CurrentEditAreaObject() != null)
             {
             {
-                Rect oldRect = DataConversionForWPF.CRectConversionForRect(textArea.GetFrame());
                 bool result;
                 bool result;
-                if (string.IsNullOrEmpty(textArea.SelectText))
+                Rect oldRect = DataConversionForWPF.CRectConversionForRect(textAreas[0].GetFrame());
+                if (string.IsNullOrEmpty(textAreas[0].SelectText))
                 {
                 {
                     string fontName = "Helvetica";
                     string fontName = "Helvetica";
                     float fontSize = 14;
                     float fontSize = 14;
@@ -144,33 +165,47 @@ namespace ComPDFKit.Controls.Edit
                     byte transparency = 255;
                     byte transparency = 255;
                     bool isBold = false;
                     bool isBold = false;
                     bool isItalic = false;
                     bool isItalic = false;
-                    textArea.GetTextStyle(ref fontName, ref fontSize, ref fontColor, ref transparency, ref isBold, ref isItalic);
-                    result = textArea.SetCurTextStyle(fontName, fontSize, fontColor[0], fontColor[1], fontColor[2], (byte)(FontOpacitySlider.Value * 255), isBold, isItalic);
+                    textAreas[0].GetTextStyle(ref fontName, ref fontSize, ref fontColor, ref transparency, ref isBold, ref isItalic);
+                    result = textAreas[0].SetCurTextStyle(fontName, fontSize, fontColor[0], fontColor[1], fontColor[2], (byte)(FontOpacitySlider.Value * 255), isBold, isItalic);
                 }
                 }
                 else
                 else
                 {
                 {
-                    result = textArea.SetCharsFontTransparency((byte)(FontOpacitySlider.Value * 255));
+                    result = textAreas[0].SetCharsFontTransparency((byte)(FontOpacitySlider.Value * 255));
                 }
                 }
 
 
                 if (result)
                 if (result)
                 {
                 {
                     PDFEditHistory editHistory = new PDFEditHistory();
                     PDFEditHistory editHistory = new PDFEditHistory();
                     editHistory.EditPage = editPage;
                     editHistory.EditPage = editPage;
-                    if (pdfPage != null)
+                    editHistory.PageIndex = pdfPage.PageIndex;
+                    ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                    ToolView.UpdateRender(oldRect, textAreas[0]);
+                }
+            }
+            else
+            {
+                GroupHistory groupHistory = new GroupHistory();
+                foreach (CPDFEditTextArea textArea in textAreas)
+                {
+                    if (textArea.SetCharsFontTransparency((byte)(FontOpacitySlider.Value * 255)))
                     {
                     {
+                        PDFEditHistory editHistory = new PDFEditHistory();
+                        editHistory.EditPage = editPage;
                         editHistory.PageIndex = pdfPage.PageIndex;
                         editHistory.PageIndex = pdfPage.PageIndex;
+                        groupHistory.Histories.Add(editHistory);
                     }
                     }
-                    ToolView.GetCPDFViewer()?.UndoManager.AddHistory(editHistory);
-                    ToolView.UpdateRender(oldRect, textArea);
-                    editPage.EndEdit();
                 }
                 }
+
+                ToolView.GetCPDFViewer()?.UndoManager.AddHistory(groupHistory);
+                ToolView.GetCPDFViewer()?.UpdateRenderFrame();
             }
             }
 
 
-            if (EditEvent != null && textArea == null)
+            editPage.EndEdit();
+            if (EditEvents.Count > 0 && textAreas.Count > 0)
             {
             {
-                EditEvent.Transparency = (byte)(FontOpacitySlider.Value * 255);
+                EditEvents.FirstOrDefault().Transparency = (byte)(FontOpacitySlider.Value * 255);
                 DefaultSettingParam defaultSettingParam = ToolView.GetDefaultSettingParam();
                 DefaultSettingParam defaultSettingParam = ToolView.GetDefaultSettingParam();
-                defaultSettingParam.SetPDFEditParamm(EditEvent);
+                defaultSettingParam.SetPDFEditParamm(EditEvents.FirstOrDefault());
             }
             }
         }
         }
 
 
@@ -187,12 +222,15 @@ namespace ComPDFKit.Controls.Edit
                 return;
                 return;
             }
             }
 
 
-            GetTextArea(out CPDFEditTextArea textArea, out CPDFPage pdfPage, out CPDFEditPage editPage);
-            if (textArea != null)
+            GetTextArea(out List<CPDFEditTextArea> textAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+            if (textAreas.Count == 0 || pdfPage == null || editPage == null)
+                return;
+
+            if (ToolView.CurrentEditAreaObject() != null)
             {
             {
-                Rect oldRect = DataConversionForWPF.CRectConversionForRect(textArea.GetFrame());
                 bool result;
                 bool result;
-                if (string.IsNullOrEmpty(textArea.SelectText))
+                Rect oldRect = DataConversionForWPF.CRectConversionForRect(textAreas[0].GetFrame());
+                if (string.IsNullOrEmpty(textAreas[0].SelectText))
                 {
                 {
                     string fontName = "Helvetica";
                     string fontName = "Helvetica";
                     float fontSize = 14;
                     float fontSize = 14;
@@ -200,34 +238,47 @@ namespace ComPDFKit.Controls.Edit
                     byte transparency = 255;
                     byte transparency = 255;
                     bool isBold = false;
                     bool isBold = false;
                     bool isItalic = false;
                     bool isItalic = false;
-                    textArea.GetTextStyle(ref fontName, ref fontSize, ref fontColor, ref transparency, ref isBold, ref isItalic);
-                    result = textArea.SetCurTextStyle(fontName, fontSize, fontColor[0], fontColor[1], fontColor[2], (byte)(FontOpacitySlider.Value * 255), isBold, isItalic);
+                    textAreas[0].GetTextStyle(ref fontName, ref fontSize, ref fontColor, ref transparency, ref isBold, ref isItalic);
+                    result = textAreas[0].SetCurTextStyle(fontName, fontSize, fontColor[0], fontColor[1], fontColor[2], (byte)(FontOpacitySlider.Value * 255), isBold, isItalic);
                 }
                 }
                 else
                 else
                 {
                 {
-                    result = textArea.SetCharsFontTransparency((byte)(FontOpacitySlider.Value * 255));
+                    result = textAreas[0].SetCharsFontTransparency((byte)(FontOpacitySlider.Value * 255));
                 }
                 }
 
 
                 if (result)
                 if (result)
                 {
                 {
                     PDFEditHistory editHistory = new PDFEditHistory();
                     PDFEditHistory editHistory = new PDFEditHistory();
                     editHistory.EditPage = editPage;
                     editHistory.EditPage = editPage;
-                    if (pdfPage != null)
+                    editHistory.PageIndex = pdfPage.PageIndex;
+                    ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                    ToolView.UpdateRender(oldRect, textAreas[0]);
+                }
+            }
+            else
+            {
+                GroupHistory groupHistory = new GroupHistory();
+                foreach (CPDFEditTextArea textArea in textAreas)
+                {
+                    if (textArea.SetCharsFontTransparency((byte)(FontOpacitySlider.Value * 255)))
                     {
                     {
+                        PDFEditHistory editHistory = new PDFEditHistory();
+                        editHistory.EditPage = editPage;
                         editHistory.PageIndex = pdfPage.PageIndex;
                         editHistory.PageIndex = pdfPage.PageIndex;
+                        groupHistory.Histories.Add(editHistory);
                     }
                     }
-
-                    ToolView.GetCPDFViewer()?.UndoManager.AddHistory(editHistory);
-                    ToolView.UpdateRender(oldRect, textArea);
-                    editPage.EndEdit();
                 }
                 }
+
+                ToolView.GetCPDFViewer()?.UndoManager.AddHistory(groupHistory);
+                ToolView.GetCPDFViewer()?.UpdateRenderFrame();
             }
             }
 
 
-            if (EditEvent != null && textArea == null)
+            editPage.EndEdit();
+            if (EditEvents?.Count > 0 && textAreas.Count > 0)
             {
             {
-                EditEvent.Transparency = (byte)(FontOpacitySlider.Value * 255);
+                EditEvents.FirstOrDefault().Transparency = (byte)(FontOpacitySlider.Value * 255);
                 DefaultSettingParam defaultSettingParam = ToolView.GetDefaultSettingParam();
                 DefaultSettingParam defaultSettingParam = ToolView.GetDefaultSettingParam();
-                defaultSettingParam.SetPDFEditParamm(EditEvent);
+                defaultSettingParam.SetPDFEditParamm(EditEvents.FirstOrDefault());
             }
             }
         }
         }
 
 
@@ -258,6 +309,9 @@ namespace ComPDFKit.Controls.Edit
             TextStyleUI.TextSizeChanged += TextStyleUI_TextSizeChanged;
             TextStyleUI.TextSizeChanged += TextStyleUI_TextSizeChanged;
             TextAlignUI.TextAlignChanged += TextAlignUI_TextAlignChanged;
             TextAlignUI.TextAlignChanged += TextAlignUI_TextAlignChanged;
             FontColorUI.ColorChanged += FontColorUI_ColorChanged;
             FontColorUI.ColorChanged += FontColorUI_ColorChanged;
+
+            IsMultiSelected = ToolView.GetIsMultiSelected();
+            ShowBorder = ToolView.GetEditPen() == null || ToolView.GetEditPen().Thickness != 0;
         }
         }
 
 
         #endregion
         #endregion
@@ -266,12 +320,15 @@ namespace ComPDFKit.Controls.Edit
 
 
         private void TextStyleUI_TextSizeChanged(object sender, double e)
         private void TextStyleUI_TextSizeChanged(object sender, double e)
         {
         {
-            GetTextArea(out CPDFEditTextArea textArea, out CPDFPage pdfPage, out CPDFEditPage editPage);
-            if (textArea != null)
+            GetTextArea(out List<CPDFEditTextArea> textAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+            if (textAreas.Count == 0 || pdfPage == null || editPage == null)
+                return;
+
+            if (ToolView.CurrentEditAreaObject() != null)
             {
             {
-                Rect oldRect = DataConversionForWPF.CRectConversionForRect(textArea.GetFrame());
                 bool result;
                 bool result;
-                if (string.IsNullOrEmpty(textArea.SelectText))
+                Rect oldRect = DataConversionForWPF.CRectConversionForRect(textAreas[0].GetFrame());
+                if (string.IsNullOrEmpty(textAreas[0].SelectText))
                 {
                 {
                     string fontName = "Helvetica";
                     string fontName = "Helvetica";
                     float fontSize = 14;
                     float fontSize = 14;
@@ -279,33 +336,47 @@ namespace ComPDFKit.Controls.Edit
                     byte transparency = 255;
                     byte transparency = 255;
                     bool isBold = false;
                     bool isBold = false;
                     bool isItalic = false;
                     bool isItalic = false;
-                    textArea.GetTextStyle(ref fontName, ref fontSize, ref fontColor, ref transparency, ref isBold, ref isItalic);
-                    result = textArea.SetCurTextStyle(fontName, (float)e, fontColor[0], fontColor[1], fontColor[2], transparency, isBold, isItalic);
+                    textAreas[0].GetTextStyle(ref fontName, ref fontSize, ref fontColor, ref transparency, ref isBold, ref isItalic);
+                    result = textAreas[0].SetCurTextStyle(fontName, (float)e, fontColor[0], fontColor[1], fontColor[2], transparency, isBold, isItalic);
                 }
                 }
                 else
                 else
                 {
                 {
-                    result = textArea.SetCharsFontSize((float)e,true);
+                    result = textAreas[0].SetCharsFontSize((float)e, true);
                 }
                 }
 
 
                 if (result)
                 if (result)
                 {
                 {
                     PDFEditHistory editHistory = new PDFEditHistory();
                     PDFEditHistory editHistory = new PDFEditHistory();
                     editHistory.EditPage = editPage;
                     editHistory.EditPage = editPage;
-                    if (pdfPage != null)
+                    editHistory.PageIndex = pdfPage.PageIndex;
+                    ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                    ToolView.UpdateRender(oldRect, textAreas[0]);
+                }
+            }
+            else
+            {
+                GroupHistory groupHistory = new GroupHistory();
+                foreach (CPDFEditTextArea textArea in textAreas)
+                {
+                    if (textArea.SetCharsFontSize((float)e, true))
                     {
                     {
+                        PDFEditHistory editHistory = new PDFEditHistory();
+                        editHistory.EditPage = editPage;
                         editHistory.PageIndex = pdfPage.PageIndex;
                         editHistory.PageIndex = pdfPage.PageIndex;
+                        groupHistory.Histories.Add(editHistory);
                     }
                     }
-                    ToolView.GetCPDFViewer()?.UndoManager.AddHistory(editHistory);
-                    ToolView.UpdateRender(oldRect, textArea);
-                    editPage.EndEdit();
                 }
                 }
+
+                ToolView.GetCPDFViewer()?.UndoManager.AddHistory(groupHistory);
+                ToolView.GetCPDFViewer()?.UpdateRenderFrame();
             }
             }
 
 
-            if (EditEvent != null && textArea == null)
+            editPage.EndEdit();
+            if (EditEvents.Count > 0 && textAreas.Count > 0)
             {
             {
-                EditEvent.FontSize = e;
+                EditEvents.FirstOrDefault().FontSize = e;
                 DefaultSettingParam defaultSettingParam = ToolView.GetDefaultSettingParam();
                 DefaultSettingParam defaultSettingParam = ToolView.GetDefaultSettingParam();
-                defaultSettingParam.SetPDFEditParamm(EditEvent);
+                defaultSettingParam.SetPDFEditParamm(EditEvents.FirstOrDefault());
             }
             }
 
 
             //if (EditMultiEvents != null)
             //if (EditMultiEvents != null)
@@ -321,12 +392,15 @@ namespace ComPDFKit.Controls.Edit
         private void FontColorUI_ColorChanged(object sender, EventArgs e)
         private void FontColorUI_ColorChanged(object sender, EventArgs e)
         {
         {
             SolidColorBrush newBrush = FontColorUI.Brush as SolidColorBrush;
             SolidColorBrush newBrush = FontColorUI.Brush as SolidColorBrush;
-            GetTextArea(out CPDFEditTextArea textArea, out CPDFPage pdfPage, out CPDFEditPage editPage);
-            if (textArea != null && newBrush != null)
+            GetTextArea(out List<CPDFEditTextArea> textAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+            if (textAreas.Count == 0 || pdfPage == null || editPage == null)
+                return;
+
+            if (ToolView.CurrentEditAreaObject() != null)
             {
             {
-                Rect oldRect = DataConversionForWPF.CRectConversionForRect(textArea.GetFrame());
                 bool result;
                 bool result;
-                if (string.IsNullOrEmpty(textArea.SelectText))
+                Rect oldRect = DataConversionForWPF.CRectConversionForRect(textAreas[0].GetFrame());
+                if (string.IsNullOrEmpty(textAreas[0].SelectText))
                 {
                 {
                     string fontName = "Helvetica";
                     string fontName = "Helvetica";
                     float fontSize = 14;
                     float fontSize = 14;
@@ -334,75 +408,116 @@ namespace ComPDFKit.Controls.Edit
                     byte transparency = 255;
                     byte transparency = 255;
                     bool isBold = false;
                     bool isBold = false;
                     bool isItalic = false;
                     bool isItalic = false;
-                    textArea.GetTextStyle(ref fontName, ref fontSize, ref fontColor, ref transparency, ref isBold, ref isItalic);
-                    result = textArea.SetCurTextStyle(fontName, fontSize, newBrush.Color.R, newBrush.Color.G, newBrush.Color.B, transparency, isBold, isItalic);
+                    textAreas[0].GetTextStyle(ref fontName, ref fontSize, ref fontColor, ref transparency, ref isBold, ref isItalic);
+                    result = textAreas[0].SetCurTextStyle(fontName, fontSize, newBrush.Color.R, newBrush.Color.G, newBrush.Color.B, transparency, isBold, isItalic);
                 }
                 }
                 else
                 else
                 {
                 {
-                    result = textArea.SetCharsFontColor(newBrush.Color.R, newBrush.Color.G, newBrush.Color.B);
+                    result = textAreas[0].SetCharsFontColor(newBrush.Color.R, newBrush.Color.G, newBrush.Color.B);
                 }
                 }
 
 
-                if(result)
+                if (result)
                 {
                 {
                     PDFEditHistory editHistory = new PDFEditHistory();
                     PDFEditHistory editHistory = new PDFEditHistory();
                     editHistory.EditPage = editPage;
                     editHistory.EditPage = editPage;
-                    if (pdfPage != null)
+                    editHistory.PageIndex = pdfPage.PageIndex;
+                    ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                    ToolView.UpdateRender(oldRect, textAreas[0]);
+                }
+            }
+            else
+            {
+                GroupHistory groupHistory = new GroupHistory();
+                foreach (CPDFEditTextArea textArea in textAreas)
+                {
+                    if (textArea.SetCharsFontColor(newBrush.Color.R, newBrush.Color.G, newBrush.Color.B))
                     {
                     {
+                        PDFEditHistory editHistory = new PDFEditHistory();
+                        editHistory.EditPage = editPage;
                         editHistory.PageIndex = pdfPage.PageIndex;
                         editHistory.PageIndex = pdfPage.PageIndex;
+                        groupHistory.Histories.Add(editHistory);
                     }
                     }
 
 
-                    ToolView.GetCPDFViewer()?.UndoManager.AddHistory(editHistory);
-                    ToolView.UpdateRender(oldRect, textArea);
-                    editPage.EndEdit();
+                    ToolView.GetCPDFViewer()?.UndoManager.AddHistory(groupHistory);
+                    ToolView.GetCPDFViewer()?.UpdateRenderFrame();
                 }
                 }
             }
             }
 
 
-            if (EditEvent != null && textArea == null && newBrush != null)
+            editPage.EndEdit();
+            if (EditEvents.Count > 0 && newBrush != null)
             {
             {
                 byte[] Color = new byte[3];
                 byte[] Color = new byte[3];
                 Color[0] = newBrush.Color.R;
                 Color[0] = newBrush.Color.R;
                 Color[1] = newBrush.Color.G;
                 Color[1] = newBrush.Color.G;
                 Color[2] = newBrush.Color.B;
                 Color[2] = newBrush.Color.B;
-                EditEvent.FontColor = Color;
+                EditEvents.FirstOrDefault().FontColor = Color;
                 DefaultSettingParam defaultSettingParam = ToolView.GetDefaultSettingParam();
                 DefaultSettingParam defaultSettingParam = ToolView.GetDefaultSettingParam();
-                defaultSettingParam.SetPDFEditParamm(EditEvent);
+                defaultSettingParam.SetPDFEditParamm(EditEvents.FirstOrDefault());
             }
             }
         }
         }
 
 
         private void TextAlignUI_TextAlignChanged(object sender, TextAlignType e)
         private void TextAlignUI_TextAlignChanged(object sender, TextAlignType e)
         {
         {
-            GetTextArea(out CPDFEditTextArea textArea, out CPDFPage pdfPage, out CPDFEditPage editPage);
-            if (textArea != null)
+            GetTextArea(out List<CPDFEditTextArea> textAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+            if (textAreas.Count == 0 || pdfPage == null || editPage == null)
+                return;
+
+            if (ToolView.CurrentEditAreaObject() != null)
             {
             {
-                bool result = false;
-                Rect oldRect = DataConversionForWPF.CRectConversionForRect(textArea.GetFrame());
-                if (textArea.SelectLineRects != null && textArea.SelectLineRects.Count > 0)
+                bool result;
+                Rect oldRect = DataConversionForWPF.CRectConversionForRect(textAreas[0].GetFrame());
+                if (textAreas[0].SelectLineRects != null && textAreas[0].SelectLineRects.Count > 0)
                 {
                 {
-                    result = textArea.SetTextRangeAlign(e);
+                    result = textAreas[0].SetTextRangeAlign(e);
                 }
                 }
                 else
                 else
                 {
                 {
-                    result = textArea.SetTextAreaAlign(e);
+                    result = textAreas[0].SetTextAreaAlign(e);
                 }
                 }
+
                 if (result)
                 if (result)
                 {
                 {
                     PDFEditHistory editHistory = new PDFEditHistory();
                     PDFEditHistory editHistory = new PDFEditHistory();
                     editHistory.EditPage = editPage;
                     editHistory.EditPage = editPage;
-                    if (pdfPage != null)
+                    editHistory.PageIndex = pdfPage.PageIndex;
+                    ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                    ToolView.UpdateRender(oldRect, textAreas[0]);
+                }
+            }
+            else
+            {
+                GroupHistory groupHistory = new GroupHistory();
+                foreach (CPDFEditTextArea textArea in textAreas)
+                {
+                    bool result;
+                    if (textArea.SelectLineRects != null && textArea.SelectLineRects.Count > 0)
+                    {
+                        result = textArea.SetTextRangeAlign(e);
+                    }
+                    else
                     {
                     {
+                        result = textArea.SetTextAreaAlign(e);
+                    }
+
+                    if (result)
+                    {
+                        PDFEditHistory editHistory = new PDFEditHistory();
+                        editHistory.EditPage = editPage;
                         editHistory.PageIndex = pdfPage.PageIndex;
                         editHistory.PageIndex = pdfPage.PageIndex;
+                        groupHistory.Histories.Add(editHistory);
                     }
                     }
-                    ToolView.GetCPDFViewer()?.UndoManager.AddHistory(editHistory);
-                    ToolView.UpdateRender(oldRect, textArea);
-                    editPage.EndEdit();
                 }
                 }
+
+                ToolView.GetCPDFViewer()?.UndoManager.AddHistory(groupHistory);
+                ToolView.GetCPDFViewer()?.UpdateRenderFrame();
             }
             }
 
 
-            if (EditEvent != null && textArea == null)
+            editPage.EndEdit();
+            if (EditEvents.Count > 0 && textAreas.Count > 0)
             {
             {
-                EditEvent.TextAlign = e;
+                EditEvents.FirstOrDefault().TextAlign = e;
                 DefaultSettingParam defaultSettingParam = ToolView.GetDefaultSettingParam();
                 DefaultSettingParam defaultSettingParam = ToolView.GetDefaultSettingParam();
-                defaultSettingParam.SetPDFEditParamm(EditEvent);
+                defaultSettingParam.SetPDFEditParamm(EditEvents.FirstOrDefault());
             }
             }
 
 
             //if (EditMultiEvents != null)
             //if (EditMultiEvents != null)
@@ -417,12 +532,15 @@ namespace ComPDFKit.Controls.Edit
 
 
         private void TextStyleUI_TextItalicChanged(object sender, bool e)
         private void TextStyleUI_TextItalicChanged(object sender, bool e)
         {
         {
-            GetTextArea(out CPDFEditTextArea textArea, out CPDFPage pdfPage, out CPDFEditPage editPage);
-            if (textArea != null)
+            GetTextArea(out List<CPDFEditTextArea> textAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+            if (textAreas.Count == 0 || pdfPage == null || editPage == null)
+                return;
+
+            if (ToolView.CurrentEditAreaObject() != null)
             {
             {
-                Rect oldRect = DataConversionForWPF.CRectConversionForRect(textArea.GetFrame());
                 bool result;
                 bool result;
-                if (string.IsNullOrEmpty(textArea.SelectText))
+                Rect oldRect = DataConversionForWPF.CRectConversionForRect(textAreas[0].GetFrame());
+                if (string.IsNullOrEmpty(textAreas[0].SelectText))
                 {
                 {
                     string fontName = "Helvetica";
                     string fontName = "Helvetica";
                     float fontSize = 14;
                     float fontSize = 14;
@@ -430,34 +548,47 @@ namespace ComPDFKit.Controls.Edit
                     byte transparency = 255;
                     byte transparency = 255;
                     bool isBold = false;
                     bool isBold = false;
                     bool isItalic = false;
                     bool isItalic = false;
-                    textArea.GetTextStyle(ref fontName, ref fontSize, ref fontColor, ref transparency, ref isBold, ref isItalic);
-                    result = textArea.SetCurTextStyle(fontName, fontSize, fontColor[0], fontColor[1], fontColor[2], transparency, isBold, e);
+                    textAreas[0].GetTextStyle(ref fontName, ref fontSize, ref fontColor, ref transparency, ref isBold, ref isItalic);
+                    result = textAreas[0].SetCurTextStyle(fontName, fontSize, fontColor[0], fontColor[1], fontColor[2], transparency, isBold, e);
                 }
                 }
                 else
                 else
                 {
                 {
-                    result = textArea.SetCharsFontItalic(e);
+                    result = textAreas[0].SetCharsFontItalic(e);
                 }
                 }
 
 
                 if (result)
                 if (result)
                 {
                 {
                     PDFEditHistory editHistory = new PDFEditHistory();
                     PDFEditHistory editHistory = new PDFEditHistory();
                     editHistory.EditPage = editPage;
                     editHistory.EditPage = editPage;
-                    if (pdfPage != null)
+                    editHistory.PageIndex = pdfPage.PageIndex;
+                    ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                    ToolView.UpdateRender(oldRect, textAreas[0]);
+                }
+            }
+            else
+            {
+                GroupHistory groupHistory = new GroupHistory();
+                foreach (CPDFEditTextArea textArea in textAreas)
+                {
+                    if (textArea.SetCharsFontItalic(e))
                     {
                     {
+                        PDFEditHistory editHistory = new PDFEditHistory();
+                        editHistory.EditPage = editPage;
                         editHistory.PageIndex = pdfPage.PageIndex;
                         editHistory.PageIndex = pdfPage.PageIndex;
+                        groupHistory.Histories.Add(editHistory);
                     }
                     }
-
-                    ToolView.GetCPDFViewer()?.UndoManager.AddHistory(editHistory);
-                    ToolView.UpdateRender(oldRect, textArea);
-                    editPage.EndEdit();
                 }
                 }
+
+                ToolView.GetCPDFViewer()?.UndoManager.AddHistory(groupHistory);
+                ToolView.GetCPDFViewer()?.UpdateRenderFrame();
             }
             }
 
 
-            if (EditEvent != null && textArea == null)
+            editPage.EndEdit();
+            if (EditEvents.Count > 0 && textAreas.Count > 0)
             {
             {
-                EditEvent.IsItalic = e;
+                EditEvents.FirstOrDefault().IsItalic = e;
                 DefaultSettingParam defaultSettingParam = ToolView.GetDefaultSettingParam();
                 DefaultSettingParam defaultSettingParam = ToolView.GetDefaultSettingParam();
-                defaultSettingParam.SetPDFEditParamm(EditEvent);
+                defaultSettingParam.SetPDFEditParamm(EditEvents.FirstOrDefault());
             }
             }
 
 
             //if (EditMultiEvents != null)
             //if (EditMultiEvents != null)
@@ -472,12 +603,15 @@ namespace ComPDFKit.Controls.Edit
 
 
         private void TextStyleUI_TextBoldChanged(object sender, bool e)
         private void TextStyleUI_TextBoldChanged(object sender, bool e)
         {
         {
-            GetTextArea(out CPDFEditTextArea textArea, out CPDFPage pdfPage, out CPDFEditPage editPage);
-            if (textArea != null)
+            GetTextArea(out List<CPDFEditTextArea> textAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+            if (textAreas.Count == 0 || pdfPage == null || editPage == null)
+                return;
+
+            if (ToolView.CurrentEditAreaObject() != null)
             {
             {
-                Rect oldRect = DataConversionForWPF.CRectConversionForRect(textArea.GetFrame());
                 bool result;
                 bool result;
-                if (string.IsNullOrEmpty(textArea.SelectText))
+                Rect oldRect = DataConversionForWPF.CRectConversionForRect(textAreas[0].GetFrame());
+                if (string.IsNullOrEmpty(textAreas[0].SelectText))
                 {
                 {
                     string fontName = "Helvetica";
                     string fontName = "Helvetica";
                     float fontSize = 14;
                     float fontSize = 14;
@@ -485,33 +619,47 @@ namespace ComPDFKit.Controls.Edit
                     byte transparency = 255;
                     byte transparency = 255;
                     bool isBold = false;
                     bool isBold = false;
                     bool isItalic = false;
                     bool isItalic = false;
-                    textArea.GetTextStyle(ref fontName, ref fontSize, ref fontColor, ref transparency, ref isBold, ref isItalic);
-                    result = textArea.SetCurTextStyle(fontName, fontSize, fontColor[0], fontColor[1], fontColor[2], transparency, e, isItalic);
+                    textAreas[0].GetTextStyle(ref fontName, ref fontSize, ref fontColor, ref transparency, ref isBold, ref isItalic);
+                    result = textAreas[0].SetCurTextStyle(fontName, fontSize, fontColor[0], fontColor[1], fontColor[2], transparency, e, isItalic);
                 }
                 }
                 else
                 else
                 {
                 {
-                    result = textArea.SetCharsFontBold(e);
+                    result = textAreas[0].SetCharsFontBold(e);
                 }
                 }
 
 
                 if (result)
                 if (result)
                 {
                 {
                     PDFEditHistory editHistory = new PDFEditHistory();
                     PDFEditHistory editHistory = new PDFEditHistory();
                     editHistory.EditPage = editPage;
                     editHistory.EditPage = editPage;
-                    if (pdfPage != null)
+                    editHistory.PageIndex = pdfPage.PageIndex;
+                    ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                    ToolView.UpdateRender(oldRect, textAreas[0]);
+                }
+            }
+            else
+            {
+                GroupHistory groupHistory = new GroupHistory();
+                foreach (CPDFEditTextArea textArea in textAreas)
+                {
+                    if (textArea.SetCharsFontBold(e))
                     {
                     {
+                        PDFEditHistory editHistory = new PDFEditHistory();
+                        editHistory.EditPage = editPage;
                         editHistory.PageIndex = pdfPage.PageIndex;
                         editHistory.PageIndex = pdfPage.PageIndex;
+                        groupHistory.Histories.Add(editHistory);
                     }
                     }
-                    ToolView.GetCPDFViewer()?.UndoManager.AddHistory(editHistory);
-                    ToolView.UpdateRender(oldRect, textArea);
-                    editPage.EndEdit();
                 }
                 }
+
+                ToolView.GetCPDFViewer()?.UndoManager.AddHistory(groupHistory);
+                ToolView.GetCPDFViewer()?.UpdateRenderFrame();
             }
             }
 
 
-            if (EditEvent != null && textArea == null)
+            editPage.EndEdit();
+            if (EditEvents.Count > 0 && textAreas.Count > 0)
             {
             {
-                EditEvent.IsBold = e;
+                EditEvents.FirstOrDefault().IsBold = e;
                 DefaultSettingParam defaultSettingParam = ToolView.GetDefaultSettingParam();
                 DefaultSettingParam defaultSettingParam = ToolView.GetDefaultSettingParam();
-                defaultSettingParam.SetPDFEditParamm(EditEvent);
+                defaultSettingParam.SetPDFEditParamm(EditEvents.FirstOrDefault());
             }
             }
 
 
             //if (EditMultiEvents != null)
             //if (EditMultiEvents != null)
@@ -526,12 +674,15 @@ namespace ComPDFKit.Controls.Edit
 
 
         private void TextStyleUI_TextFontChanged(object sender, string e)
         private void TextStyleUI_TextFontChanged(object sender, string e)
         {
         {
-            GetTextArea(out CPDFEditTextArea textArea, out CPDFPage pdfPage, out CPDFEditPage editPage);
-            if (textArea != null)
+            GetTextArea(out List<CPDFEditTextArea> textAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+            if (textAreas.Count == 0 || pdfPage == null || editPage == null)
+                return;
+
+            if (ToolView.CurrentEditAreaObject() != null)
             {
             {
-                Rect oldRect = DataConversionForWPF.CRectConversionForRect(textArea.GetFrame());
                 bool result;
                 bool result;
-                if (string.IsNullOrEmpty(textArea.SelectText))
+                Rect oldRect = DataConversionForWPF.CRectConversionForRect(textAreas[0].GetFrame());
+                if (string.IsNullOrEmpty(textAreas[0].SelectText))
                 {
                 {
                     string fontName = "Helvetica";
                     string fontName = "Helvetica";
                     float fontSize = 14;
                     float fontSize = 14;
@@ -539,33 +690,47 @@ namespace ComPDFKit.Controls.Edit
                     byte transparency = 255;
                     byte transparency = 255;
                     bool isBold = false;
                     bool isBold = false;
                     bool isItalic = false;
                     bool isItalic = false;
-                    textArea.GetTextStyle(ref fontName, ref fontSize, ref fontColor, ref transparency, ref isBold, ref isItalic);
-                    result = textArea.SetCurTextStyle(e, fontSize, fontColor[0], fontColor[1], fontColor[2], transparency, isBold, isItalic);
+                    textAreas[0].GetTextStyle(ref fontName, ref fontSize, ref fontColor, ref transparency, ref isBold, ref isItalic);
+                    result = textAreas[0].SetCurTextStyle(e, fontSize, fontColor[0], fontColor[1], fontColor[2], transparency, isBold, isItalic);
                 }
                 }
                 else
                 else
                 {
                 {
-                    result = textArea.SetCharsFontName(e);
+                    result = textAreas[0].SetCharsFontName(e);
                 }
                 }
 
 
                 if (result)
                 if (result)
                 {
                 {
                     PDFEditHistory editHistory = new PDFEditHistory();
                     PDFEditHistory editHistory = new PDFEditHistory();
                     editHistory.EditPage = editPage;
                     editHistory.EditPage = editPage;
-                    if (pdfPage != null)
+                    editHistory.PageIndex = pdfPage.PageIndex;
+                    ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                    ToolView.UpdateRender(oldRect, textAreas[0]);
+                }
+            }
+            else
+            {
+                GroupHistory groupHistory = new GroupHistory();
+                foreach (CPDFEditTextArea textArea in textAreas)
+                {
+                    if (textArea.SetCharsFontName(e))
                     {
                     {
+                        PDFEditHistory editHistory = new PDFEditHistory();
+                        editHistory.EditPage = editPage;
                         editHistory.PageIndex = pdfPage.PageIndex;
                         editHistory.PageIndex = pdfPage.PageIndex;
+                        groupHistory.Histories.Add(editHistory);
                     }
                     }
-                    ToolView.GetCPDFViewer()?.UndoManager.AddHistory(editHistory);
-                    ToolView.UpdateRender(oldRect, textArea);
-                    editPage.EndEdit();
                 }
                 }
+
+                ToolView.GetCPDFViewer()?.UndoManager.AddHistory(groupHistory);
+                ToolView.GetCPDFViewer()?.UpdateRenderFrame();
             }
             }
 
 
-            if (EditEvent != null && textArea == null)
+            editPage.EndEdit();
+            if (EditEvents.Count > 0 && textAreas.Count > 0)
             {
             {
-                EditEvent.FontName = e;
+                EditEvents.FirstOrDefault().FontName = e;
                 DefaultSettingParam defaultSettingParam = ToolView.GetDefaultSettingParam();
                 DefaultSettingParam defaultSettingParam = ToolView.GetDefaultSettingParam();
-                defaultSettingParam.SetPDFEditParamm(EditEvent);
+                defaultSettingParam.SetPDFEditParamm(EditEvents.FirstOrDefault());
             }
             }
 
 
             //if (EditMultiEvents != null)
             //if (EditMultiEvents != null)
@@ -594,27 +759,30 @@ namespace ComPDFKit.Controls.Edit
         #endregion
         #endregion
 
 
         #region Text Edit
         #region Text Edit
-        private void GetTextArea(out CPDFEditTextArea textArea, out CPDFPage pdfPage, out CPDFEditPage editPage)
+        private void GetTextArea(out List<CPDFEditTextArea> textAreas, out CPDFPage pdfPage, out CPDFEditPage editPage)
         {
         {
-            textArea = null;
+            textAreas = new List<CPDFEditTextArea>();
             editPage = null;
             editPage = null;
             pdfPage = null;
             pdfPage = null;
             if (ToolView == null)
             if (ToolView == null)
             {
             {
                 return;
                 return;
             }
             }
-            if (EditEvent != null)
+            if (EditEvents != null && EditEvents.Count>0 )
             {
             {
                 try
                 try
                 {
                 {
                     CPDFViewer pdfViewer = ToolView.GetCPDFViewer();
                     CPDFViewer pdfViewer = ToolView.GetCPDFViewer();
                     CPDFDocument pdfDoc = pdfViewer.GetDocument();
                     CPDFDocument pdfDoc = pdfViewer.GetDocument();
-                    pdfPage = pdfDoc.PageAtIndex(EditEvent.PageIndex);
+                    pdfPage = pdfDoc.PageAtIndex(EditEvents.FirstOrDefault().PageIndex);
                     editPage = pdfPage.GetEditPage();
                     editPage = pdfPage.GetEditPage();
                     List<CPDFEditArea> editAreas = editPage.GetEditAreaList();
                     List<CPDFEditArea> editAreas = editPage.GetEditAreaList();
-                    if (editAreas != null && editAreas.Count > EditEvent.EditIndex)
+                    foreach (TextEditParam editEvent in EditEvents)
                     {
                     {
-                        textArea = editAreas[EditEvent.EditIndex] as CPDFEditTextArea;
+                        if (editAreas != null && editAreas.Count > editEvent.EditIndex)
+                        {
+                            textAreas.Add(editAreas[editEvent.EditIndex] as CPDFEditTextArea);
+                        }
                     }
                     }
                 }
                 }
                 catch (Exception ex)
                 catch (Exception ex)
@@ -633,5 +801,46 @@ namespace ComPDFKit.Controls.Edit
             }
             }
         }
         }
         #endregion
         #endregion
+
+        private void chkMulti_Click(object sender, RoutedEventArgs e)
+        {
+            ToolView.SetIsMultiSelected((e.Source as CheckBox).IsChecked.GetValueOrDefault());
+        }
+
+        private void chkEditPen_Click(object sender, RoutedEventArgs e)
+        {
+            if ((e.Source as CheckBox).IsChecked.GetValueOrDefault())
+            {
+                ToolView.SetEditPen(null);
+            }
+            else
+            {
+                ToolView.SetEditPen(new Pen()
+                {
+                    Brush = new SolidColorBrush(Colors.Black),
+                    Thickness = 0
+                });
+            }
+            ShowBorder = ToolView.GetEditPen() == null || ToolView.GetEditPen().Thickness != 0;
+
+            ToolView.GetCPDFViewer().UpdateRenderFrame();
+        }
+
+        protected bool UpdateProper<T>(ref T properValue,
+                               T newValue,
+                               [CallerMemberName] string properName = "")
+        {
+            if (object.Equals(properValue, newValue))
+                return false;
+
+            properValue = newValue;
+            OnPropertyChanged(properName);
+            return true;
+        }
+
+
+        protected void OnPropertyChanged([CallerMemberName] string propertyName = "") =>
+            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     }
     }
 }
 }
+

+ 80 - 77
Demo/Examples/Compdfkit.Controls/Form/Property/CheckBoxProperty.xaml

@@ -18,85 +18,88 @@
             <cpdfcommon:PropertyPanelResourceConverter x:Key="PropertyPanelResourceConverter"></cpdfcommon:PropertyPanelResourceConverter>
             <cpdfcommon:PropertyPanelResourceConverter x:Key="PropertyPanelResourceConverter"></cpdfcommon:PropertyPanelResourceConverter>
         </ResourceDictionary>
         </ResourceDictionary>
     </UserControl.Resources>
     </UserControl.Resources>
-    <Grid>
-        <Grid.RowDefinitions>
-            <RowDefinition Height="40"/>
-            <RowDefinition Height="*"/>
-        </Grid.RowDefinitions>
-        <Border BorderThickness="0" BorderBrush="#1A000000">
-            <Grid  Height="40" Background="White" >
-                <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_Chb}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-            </Grid>
-        </Border>
-        <TabControl Grid.Row="1" Style="{DynamicResource TabControlStyle1}" BorderThickness="0">
-            <TabItem Height="32" Style="{DynamicResource TabItemStyle1}" Header="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_General}">
-                <Grid>
-                    <Grid.ColumnDefinitions>
-                        <ColumnDefinition Width="16"/>
-                        <ColumnDefinition Width="*"/>
-                        <ColumnDefinition Width="16"/>
-                    </Grid.ColumnDefinitions>
-                    <StackPanel Grid.Column="1">
-                        <StackPanel  >
-                            <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Name}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-                            <TextBox x:Name="FieldNameText" Height="32" Margin="0,8,0,0" TextChanged="FieldNameText_TextChanged"/>
-                        </StackPanel>
-                        <StackPanel >
-                            <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Visibility}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-                            <ComboBox x:Name="FormFieldCmb" Margin="0,8,0,0" Height="32" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="FormFieldCmb_SelectionChanged">
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Visible}"/>
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Hidden}"/>
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_NoPrint}"/>
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Print}"/>
-                            </ComboBox>
-                        </StackPanel>
-                    </StackPanel>
+    <ScrollViewer VerticalScrollBarVisibility="Auto">
+
+        <Grid>
+            <Grid.RowDefinitions>
+                <RowDefinition Height="40"/>
+                <RowDefinition Height="*"/>
+            </Grid.RowDefinitions>
+            <Border BorderThickness="0" BorderBrush="#1A000000">
+                <Grid  Height="40" Background="White" >
+                    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_Chb}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
                 </Grid>
                 </Grid>
-            </TabItem>
-            <TabItem Height="32" Style="{DynamicResource TabItemStyle1}" Header="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_Appearance}">
-                <Grid>
-                    <Grid.ColumnDefinitions>
-                        <ColumnDefinition Width="16"/>
-                        <ColumnDefinition Width="*"/>
-                        <ColumnDefinition Width="16"/>
-                    </Grid.ColumnDefinitions>
-                    <StackPanel Grid.Column="1">
-                        <StackPanel>
-                            <TextBlock  Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_StrokeColor}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-                            <cpdfcommon:ColorPickerControl Margin="0,18,0,0" x:Name="BorderColorPickerControl" ColorChanged="BorderColorPickerControl_ColorChanged"/>
+            </Border>
+            <TabControl Grid.Row="1" Style="{DynamicResource TabControlStyle1}" BorderThickness="0">
+                <TabItem Height="32" Style="{DynamicResource TabItemStyle1}" Header="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_General}">
+                    <Grid>
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="16"/>
+                            <ColumnDefinition Width="*"/>
+                            <ColumnDefinition Width="16"/>
+                        </Grid.ColumnDefinitions>
+                        <StackPanel Grid.Column="1">
+                            <StackPanel  >
+                                <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Name}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
+                                <TextBox x:Name="FieldNameText" Height="32" Margin="0,8,0,0" TextChanged="FieldNameText_TextChanged"/>
+                            </StackPanel>
+                            <StackPanel >
+                                <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Visibility}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
+                                <ComboBox x:Name="FormFieldCmb" Margin="0,8,0,0" Height="32" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="FormFieldCmb_SelectionChanged">
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Visible}"/>
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Hidden}"/>
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_NoPrint}"/>
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Print}"/>
+                                </ComboBox>
+                            </StackPanel>
                         </StackPanel>
                         </StackPanel>
-                        <StackPanel>
-                            <TextBlock  Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_BgColor}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-                            <cpdfcommon:ColorPickerControl Margin="0,18,0,0" x:Name="BackgroundColorPickerControl" ColorChanged="BackgroundColorPickerControl_ColorChanged"/>
+                    </Grid>
+                </TabItem>
+                <TabItem Height="32" Style="{DynamicResource TabItemStyle1}" Header="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_Appearance}">
+                    <Grid>
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="16"/>
+                            <ColumnDefinition Width="*"/>
+                            <ColumnDefinition Width="16"/>
+                        </Grid.ColumnDefinitions>
+                        <StackPanel Grid.Column="1">
+                            <StackPanel>
+                                <TextBlock  Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_StrokeColor}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
+                                <cpdfcommon:ColorPickerControl Margin="0,18,0,0" x:Name="BorderColorPickerControl" ColorChanged="BorderColorPickerControl_ColorChanged"/>
+                            </StackPanel>
+                            <StackPanel>
+                                <TextBlock  Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_BgColor}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
+                                <cpdfcommon:ColorPickerControl Margin="0,18,0,0" x:Name="BackgroundColorPickerControl" ColorChanged="BackgroundColorPickerControl_ColorChanged"/>
+                            </StackPanel>
                         </StackPanel>
                         </StackPanel>
-                    </StackPanel>
-                </Grid>
-            </TabItem>
-            <TabItem Height="32" Style="{DynamicResource TabItemStyle1}" Header="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_Preferences}">
-                <Grid>
-                    <Grid.ColumnDefinitions>
-                        <ColumnDefinition Width="16"/>
-                        <ColumnDefinition Width="*"/>
-                        <ColumnDefinition Width="16"/>
-                    </Grid.ColumnDefinitions>
-                    <StackPanel Grid.Column="1">
-                        <StackPanel  >
-                            <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Check_Style}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-                            <ComboBox x:Name="CheckButtonStyleCmb" Height="32" Margin="0,8,0,0" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="CheckButtonStyleCmb_SelectionChanged">
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Style_Check}"/>
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Style_Circle}"/>
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Style_Cross}"/>
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Style_Diamond}"/>
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Style_Square}"/>
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Style_Star}"/>
-                            </ComboBox>
+                    </Grid>
+                </TabItem>
+                <TabItem Height="32" Style="{DynamicResource TabItemStyle1}" Header="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_Preferences}">
+                    <Grid>
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="16"/>
+                            <ColumnDefinition Width="*"/>
+                            <ColumnDefinition Width="16"/>
+                        </Grid.ColumnDefinitions>
+                        <StackPanel Grid.Column="1">
+                            <StackPanel  >
+                                <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Check_Style}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
+                                <ComboBox x:Name="CheckButtonStyleCmb" Height="32" Margin="0,8,0,0" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="CheckButtonStyleCmb_SelectionChanged">
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Style_Check}"/>
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Style_Circle}"/>
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Style_Cross}"/>
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Style_Diamond}"/>
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Style_Square}"/>
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Style_Star}"/>
+                                </ComboBox>
+                            </StackPanel>
+                            <StackPanel >
+                                <CheckBox x:Name="chkSelected" Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Style_Default}" FontSize="14" VerticalContentAlignment="Center" FontFamily="Microsoft YaHei" FontWeight="Bold" Margin="0 14 0 0" Checked="chkSelected_Checked"  Unchecked="chkSelected_Unchecked"/>
+                            </StackPanel>
                         </StackPanel>
                         </StackPanel>
-                        <StackPanel >
-                            <CheckBox x:Name="chkSelected" Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Style_Default}" FontSize="14" VerticalContentAlignment="Center" FontFamily="Microsoft YaHei" FontWeight="Bold" Margin="0 14 0 0" Checked="chkSelected_Checked"  Unchecked="chkSelected_Unchecked"/>
-                        </StackPanel>
-                    </StackPanel>
-                </Grid>
-            </TabItem>
-        </TabControl>
-    </Grid>
+                    </Grid>
+                </TabItem>
+            </TabControl>
+        </Grid>
+    </ScrollViewer>
 </UserControl>
 </UserControl>

File diff suppressed because it is too large
+ 104 - 101
Demo/Examples/Compdfkit.Controls/Form/Property/ComboBoxProperty.xaml


+ 1 - 1
Demo/Examples/Compdfkit.Controls/Form/Property/ComboBoxProperty.xaml.cs

@@ -65,7 +65,7 @@ namespace ComPDFKit.Controls.PDFControl
             string familyName = string.Empty;
             string familyName = string.Empty;
             string styleName = string.Empty;
             string styleName = string.Empty;
 
 
-            CPDFFont.GetFamlyStyleName(widgetParam.FontName, ref familyName, ref styleName);
+            CPDFFont.GetFamilyStyleName(widgetParam.FontName, ref familyName, ref styleName);
 
 
             FontCmb.ItemsSource = CPDFFont.GetFontNameDictionary().Keys.ToList();
             FontCmb.ItemsSource = CPDFFont.GetFontNameDictionary().Keys.ToList();
 
 

File diff suppressed because it is too large
+ 104 - 101
Demo/Examples/Compdfkit.Controls/Form/Property/ListBoxProperty.xaml


+ 1 - 1
Demo/Examples/Compdfkit.Controls/Form/Property/ListBoxProperty.xaml.cs

@@ -66,7 +66,7 @@ namespace ComPDFKit.Controls.PDFControl
             string familyName = string.Empty;
             string familyName = string.Empty;
             string styleName = string.Empty;
             string styleName = string.Empty;
 
 
-            CPDFFont.GetFamlyStyleName(widgetParam.FontName, ref familyName, ref styleName);
+            CPDFFont.GetFamilyStyleName(widgetParam.FontName, ref familyName, ref styleName);
 
 
             FontCmb.ItemsSource = CPDFFont.GetFontNameDictionary().Keys.ToList();
             FontCmb.ItemsSource = CPDFFont.GetFontNameDictionary().Keys.ToList();
 
 

+ 90 - 88
Demo/Examples/Compdfkit.Controls/Form/Property/PushButtonProperty.xaml

@@ -36,98 +36,100 @@
             </Style>
             </Style>
         </ResourceDictionary>
         </ResourceDictionary>
     </UserControl.Resources>
     </UserControl.Resources>
-    <Grid>
-        <Grid.RowDefinitions>
-            <RowDefinition Height="40"/>
-            <RowDefinition Height="*"/>
-        </Grid.RowDefinitions>
-        <Border BorderThickness="0" BorderBrush="#1A000000">
-            <Grid  Height="40" Background="White" >
-                <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_Btn}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-            </Grid>
-        </Border>
-        <TabControl x:Name="TopTabControl" Grid.Row="1" Style="{DynamicResource TabControlStyle1}" BorderThickness="0">
-            <TabItem Height="32" Style="{DynamicResource TabItemStyle1}" Header="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_General}">
-                <Grid>
-                    <Grid.ColumnDefinitions>
-                        <ColumnDefinition Width="16"/>
-                        <ColumnDefinition Width="*"/>
-                        <ColumnDefinition Width="16"/>
-                    </Grid.ColumnDefinitions>
-                    <StackPanel Grid.Column="1">
-                        <StackPanel>
-                            <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Name}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-                            <TextBox x:Name="FieldNameText" Height="32" Margin="0,8,0,0" TextChanged="FieldNameText_TextChanged"/>
-                        </StackPanel>
-                        <StackPanel >
-                            <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Visibility}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-                            <ComboBox x:Name="FormFieldCmb" Height="32" Margin="0,8,0,0" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="FormFieldCmb_SelectionChanged">
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Visible}"/>
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Hidden}"/>
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_NoPrint}"/>
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Print}"/>
-                            </ComboBox>
-                        </StackPanel>
-                    </StackPanel>
+    <ScrollViewer VerticalScrollBarVisibility="Auto">
+        <Grid>
+            <Grid.RowDefinitions>
+                <RowDefinition Height="40"/>
+                <RowDefinition Height="*"/>
+            </Grid.RowDefinitions>
+            <Border BorderThickness="0" BorderBrush="#1A000000">
+                <Grid  Height="40" Background="White" >
+                    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_Btn}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
                 </Grid>
                 </Grid>
-            </TabItem>
-            <TabItem Height="32" Style="{DynamicResource TabItemStyle1}" Header="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_Appearance}">
-                <Grid>
-                    <Grid.ColumnDefinitions>
-                        <ColumnDefinition Width="16"/>
-                        <ColumnDefinition Width="*"/>
-                        <ColumnDefinition Width="16"/>
-                    </Grid.ColumnDefinitions>
-                    <StackPanel Grid.Column="1">
-                        <StackPanel>
-                            <TextBlock  Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_StrokeColor}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-                            <cpdfcommon:ColorPickerControl Margin="0,18,0,0" x:Name="BorderColorPickerControl" ColorChanged="BorderColorPickerControl_ColorChanged"/>
-                        </StackPanel>
-                        <StackPanel>
-                            <TextBlock  Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_BgColor}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-                            <cpdfcommon:ColorPickerControl Margin="0,18,0,0" x:Name="BackgroundColorPickerControl" ColorChanged="BackgroundColorPickerControl_ColorChanged"/>
-                        </StackPanel>
-                        <StackPanel>
-                            <TextBlock  Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_FontColor}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-                            <cpdfcommon:ColorPickerControl Margin="0,18,0,0" x:Name="TextColorPickerControl" ColorChanged="TextColorPickerControl_ColorChanged"/>
-                        </StackPanel>
-                        <StackPanel>
-                            <TextBlock  Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Font}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold" />
-                            <ComboBox x:Name="FontCmb" Height="28" Margin="0,8,0,0" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" PreviewMouseDown="FontCmb_PreviewMouseDown" SelectionChanged="FontCmb_SelectionChanged">
-                            </ComboBox>
-                            <StackPanel Orientation="Horizontal"  Height="28" Margin="0,8,0,0">
-                                <ComboBox x:Name="FontStyleCmb" Width="148" Style="{StaticResource ComboBoxStyle1}" PreviewMouseDown="FontStyleCmb_PreviewMouseDown" SelectedIndex="0" SelectionChanged="FontStyleCmb_SelectionChanged">
+            </Border>
+            <TabControl x:Name="TopTabControl" Grid.Row="1" Style="{DynamicResource TabControlStyle1}" BorderThickness="0">
+                <TabItem Height="32" Style="{DynamicResource TabItemStyle1}" Header="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_General}">
+                    <Grid>
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="16"/>
+                            <ColumnDefinition Width="*"/>
+                            <ColumnDefinition Width="16"/>
+                        </Grid.ColumnDefinitions>
+                        <StackPanel Grid.Column="1">
+                            <StackPanel>
+                                <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Name}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
+                                <TextBox x:Name="FieldNameText" Height="32" Margin="0,8,0,0" TextChanged="FieldNameText_TextChanged"/>
+                            </StackPanel>
+                            <StackPanel >
+                                <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Visibility}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
+                                <ComboBox x:Name="FormFieldCmb" Height="32" Margin="0,8,0,0" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="FormFieldCmb_SelectionChanged">
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Visible}"/>
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Hidden}"/>
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_NoPrint}"/>
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Print}"/>
                                 </ComboBox>
                                 </ComboBox>
-                                <ComboBox x:Name="FontSizeCmb" Width="72" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="FontSizeCmb_SelectionChanged" Margin="12,0,0,0"/>
                             </StackPanel>
                             </StackPanel>
                         </StackPanel>
                         </StackPanel>
-                    </StackPanel>
-                </Grid>
-            </TabItem>
-            <TabItem Height="32" Style="{DynamicResource TabItemStyle1}" Header="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_Preferences}">
-                <Grid>
-                    <Grid.ColumnDefinitions>
-                        <ColumnDefinition Width="16"/>
-                        <ColumnDefinition Width="*"/>
-                        <ColumnDefinition Width="16"/>
-                    </Grid.ColumnDefinitions>
-                    <StackPanel Grid.Column="1">
-                        <StackPanel>
-                            <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_BtnContent}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-                            <TextBox x:Name="ItemText" Height="32" Margin="0,8,0,0" TextChanged="ItemText_TextChanged"/>
+                    </Grid>
+                </TabItem>
+                <TabItem Height="32" Style="{DynamicResource TabItemStyle1}" Header="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_Appearance}">
+                    <Grid>
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="16"/>
+                            <ColumnDefinition Width="*"/>
+                            <ColumnDefinition Width="16"/>
+                        </Grid.ColumnDefinitions>
+                        <StackPanel Grid.Column="1">
+                            <StackPanel>
+                                <TextBlock  Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_StrokeColor}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
+                                <cpdfcommon:ColorPickerControl Margin="0,18,0,0" x:Name="BorderColorPickerControl" ColorChanged="BorderColorPickerControl_ColorChanged"/>
+                            </StackPanel>
+                            <StackPanel>
+                                <TextBlock  Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_BgColor}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
+                                <cpdfcommon:ColorPickerControl Margin="0,18,0,0" x:Name="BackgroundColorPickerControl" ColorChanged="BackgroundColorPickerControl_ColorChanged"/>
+                            </StackPanel>
+                            <StackPanel>
+                                <TextBlock  Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_FontColor}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
+                                <cpdfcommon:ColorPickerControl Margin="0,18,0,0" x:Name="TextColorPickerControl" ColorChanged="TextColorPickerControl_ColorChanged"/>
+                            </StackPanel>
+                            <StackPanel>
+                                <TextBlock  Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Font}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold" />
+                                <ComboBox x:Name="FontCmb" Height="28" Margin="0,8,0,0" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" PreviewMouseDown="FontCmb_PreviewMouseDown" SelectionChanged="FontCmb_SelectionChanged">
+                                </ComboBox>
+                                <StackPanel Orientation="Horizontal"  Height="28" Margin="0,8,0,0">
+                                    <ComboBox x:Name="FontStyleCmb" Width="148" Style="{StaticResource ComboBoxStyle1}" PreviewMouseDown="FontStyleCmb_PreviewMouseDown" SelectedIndex="0" SelectionChanged="FontStyleCmb_SelectionChanged">
+                                    </ComboBox>
+                                    <ComboBox x:Name="FontSizeCmb" Width="72" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="FontSizeCmb_SelectionChanged" Margin="12,0,0,0"/>
+                                </StackPanel>
+                            </StackPanel>
                         </StackPanel>
                         </StackPanel>
-                        <StackPanel>
-                            <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Btn_Action}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-                            <ComboBox x:Name="TextAlignmentCmb" Height="32" Margin="0,8,0,0" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="TextAlignmentCmb_SelectionChanged">
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Action_None}"/>
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Action_Jump}"/>
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Action_Link}"/>
-                            </ComboBox>
-                            <TextBox x:Name="ActionContentText" Height="32" Margin="0,4,0,0" Text="123" TextChanged="ActionContentText_TextChanged" Visibility="Collapsed"/>
+                    </Grid>
+                </TabItem>
+                <TabItem Height="32" Style="{DynamicResource TabItemStyle1}" Header="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_Preferences}">
+                    <Grid>
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="16"/>
+                            <ColumnDefinition Width="*"/>
+                            <ColumnDefinition Width="16"/>
+                        </Grid.ColumnDefinitions>
+                        <StackPanel Grid.Column="1">
+                            <StackPanel>
+                                <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_BtnContent}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
+                                <TextBox x:Name="ItemText" Height="32" Margin="0,8,0,0" TextChanged="ItemText_TextChanged"/>
+                            </StackPanel>
+                            <StackPanel>
+                                <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Btn_Action}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
+                                <ComboBox x:Name="TextAlignmentCmb" Height="32" Margin="0,8,0,0" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="TextAlignmentCmb_SelectionChanged">
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Action_None}"/>
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Action_Jump}"/>
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Action_Link}"/>
+                                </ComboBox>
+                                <TextBox x:Name="ActionContentText" Height="32" Margin="0,4,0,0" Text="123" TextChanged="ActionContentText_TextChanged" Visibility="Collapsed"/>
+                            </StackPanel>
                         </StackPanel>
                         </StackPanel>
-                    </StackPanel>
-                </Grid>
-            </TabItem>
-        </TabControl>
-    </Grid>
+                    </Grid>
+                </TabItem>
+            </TabControl>
+        </Grid>
+    </ScrollViewer>
 </UserControl>
 </UserControl>

+ 1 - 1
Demo/Examples/Compdfkit.Controls/Form/Property/PushButtonProperty.xaml.cs

@@ -79,7 +79,7 @@ namespace ComPDFKit.Controls.PDFControl
             string familyName = string.Empty;
             string familyName = string.Empty;
             string styleName = string.Empty;
             string styleName = string.Empty;
 
 
-            CPDFFont.GetFamlyStyleName(widgetParam.FontName,ref familyName,ref styleName);
+            CPDFFont.GetFamilyStyleName(widgetParam.FontName,ref familyName,ref styleName);
 
 
             FontCmb.ItemsSource = CPDFFont.GetFontNameDictionary().Keys.ToList();
             FontCmb.ItemsSource = CPDFFont.GetFontNameDictionary().Keys.ToList();
 
 

+ 3 - 1
Demo/Examples/Compdfkit.Controls/Form/Property/RadioButtonProperty.xaml

@@ -19,7 +19,8 @@
             <cpdfcommon:PropertyPanelResourceConverter x:Key="PropertyPanelResourceConverter"></cpdfcommon:PropertyPanelResourceConverter>
             <cpdfcommon:PropertyPanelResourceConverter x:Key="PropertyPanelResourceConverter"></cpdfcommon:PropertyPanelResourceConverter>
         </ResourceDictionary>
         </ResourceDictionary>
     </UserControl.Resources>
     </UserControl.Resources>
-    <Grid>
+    <ScrollViewer VerticalScrollBarVisibility="Auto">
+        <Grid>
         <Grid.RowDefinitions>
         <Grid.RowDefinitions>
             <RowDefinition Height="40"/>
             <RowDefinition Height="40"/>
             <RowDefinition Height="*"/>
             <RowDefinition Height="*"/>
@@ -115,4 +116,5 @@
             </TabItem>
             </TabItem>
         </TabControl>
         </TabControl>
     </Grid>
     </Grid>
+    </ScrollViewer>
 </UserControl>
 </UserControl>

+ 29 - 26
Demo/Examples/Compdfkit.Controls/Form/Property/SignatureProperty.xaml

@@ -17,32 +17,35 @@
             <cpdfcommon:PropertyPanelResourceConverter x:Key="PropertyPanelResourceConverter"></cpdfcommon:PropertyPanelResourceConverter>
             <cpdfcommon:PropertyPanelResourceConverter x:Key="PropertyPanelResourceConverter"></cpdfcommon:PropertyPanelResourceConverter>
         </ResourceDictionary>
         </ResourceDictionary>
     </UserControl.Resources>
     </UserControl.Resources>
-    <Grid Background="White">
-        <Grid.RowDefinitions>
-            <RowDefinition Height="40"/>
-            <RowDefinition Height="*"/>
-        </Grid.RowDefinitions>
-        <Border BorderThickness="0" BorderBrush="#1A000000">
-            <Grid  Height="40" Background="White" >
-                <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_Sig}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-            </Grid>
-        </Border>
-        <Grid Grid.Row="1">
-            <Grid.ColumnDefinitions>
-                <ColumnDefinition Width="16"/>
-                <ColumnDefinition Width="*"/>
-                <ColumnDefinition Width="16"/>
-            </Grid.ColumnDefinitions>
+    <ScrollViewer VerticalScrollBarVisibility="Auto">
+
+        <Grid Background="White">
+            <Grid.RowDefinitions>
+                <RowDefinition Height="40"/>
+                <RowDefinition Height="*"/>
+            </Grid.RowDefinitions>
+            <Border BorderThickness="0" BorderBrush="#1A000000">
+                <Grid  Height="40" Background="White" >
+                    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_Sig}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
+                </Grid>
+            </Border>
+            <Grid Grid.Row="1">
+                <Grid.ColumnDefinitions>
+                    <ColumnDefinition Width="16"/>
+                    <ColumnDefinition Width="*"/>
+                    <ColumnDefinition Width="16"/>
+                </Grid.ColumnDefinitions>
 
 
-            <StackPanel Grid.Column="1">
-                <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Visibility}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-                <ComboBox x:Name="FormFieldCmb" Margin="0,8,0,0" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="FormFieldCmb_SelectionChanged" Height="32">
-                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Visible}"/>
-                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Hidden}"/>
-                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_NoPrint}"/>
-                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Print}"/>
-                </ComboBox>
-            </StackPanel>
+                <StackPanel Grid.Column="1">
+                    <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Visibility}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
+                    <ComboBox x:Name="FormFieldCmb" Margin="0,8,0,0" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="FormFieldCmb_SelectionChanged" Height="32">
+                        <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Visible}"/>
+                        <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Hidden}"/>
+                        <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_NoPrint}"/>
+                        <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Print}"/>
+                    </ComboBox>
+                </StackPanel>
+            </Grid>
         </Grid>
         </Grid>
-    </Grid>
+    </ScrollViewer>
 </UserControl>
 </UserControl>

+ 91 - 88
Demo/Examples/Compdfkit.Controls/Form/Property/TextFieldProperty.xaml

@@ -19,98 +19,101 @@
             <cpdfcommon:PropertyPanelResourceConverter x:Key="PropertyPanelResourceConverter"></cpdfcommon:PropertyPanelResourceConverter>
             <cpdfcommon:PropertyPanelResourceConverter x:Key="PropertyPanelResourceConverter"></cpdfcommon:PropertyPanelResourceConverter>
         </ResourceDictionary>
         </ResourceDictionary>
     </UserControl.Resources>
     </UserControl.Resources>
-    <Grid>
-        <Grid.RowDefinitions>
-            <RowDefinition Height="40"/>
-            <RowDefinition Height="*"/>
-        </Grid.RowDefinitions>
-        <Border BorderThickness="0" BorderBrush="#1A000000">
-            <Grid  Height="40" Background="White" >
-                <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_TextField}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-            </Grid>
-        </Border>
-        <TabControl Grid.Row="1" Style="{DynamicResource TabControlStyle1}" BorderThickness="0">
-            <TabItem Height="32" Style="{DynamicResource TabItemStyle1}" Header="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_General}">
-                <Grid>
-                    <Grid.ColumnDefinitions>
-                        <ColumnDefinition Width="16"/>
-                        <ColumnDefinition Width="*"/>
-                        <ColumnDefinition Width="16"/>
-                    </Grid.ColumnDefinitions>
-                    <StackPanel Grid.Column="1">
-                        <StackPanel  >
-                            <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Name}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-                            <TextBox x:Name="FieldNameText" Height="32" Margin="0,8,0,0" TextChanged="FieldNameText_TextChanged"/>
-                        </StackPanel>
-                        <StackPanel >
-                            <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Visibility}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-                            <ComboBox x:Name="FormFieldCmb" Height="32" Margin="0,8,0,0" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="FormFieldCmb_SelectionChanged">
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Visible}"/>
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Hidden}"/>
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_NoPrint}"/>
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Print}"/>
-                            </ComboBox>
-                        </StackPanel>
-                    </StackPanel>
+    <ScrollViewer VerticalScrollBarVisibility="Auto">
+
+        <Grid>
+            <Grid.RowDefinitions>
+                <RowDefinition Height="40"/>
+                <RowDefinition Height="*"/>
+            </Grid.RowDefinitions>
+            <Border BorderThickness="0" BorderBrush="#1A000000">
+                <Grid  Height="40" Background="White" >
+                    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_TextField}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
                 </Grid>
                 </Grid>
-            </TabItem>
-            <TabItem Height="32" Style="{DynamicResource TabItemStyle1}" Header="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_Appearance}">
-                <Grid>
-                    <Grid.ColumnDefinitions>
-                        <ColumnDefinition Width="16"/>
-                        <ColumnDefinition Width="*"/>
-                        <ColumnDefinition Width="16"/>
-                    </Grid.ColumnDefinitions>
-                    <StackPanel Grid.Column="1">
-                        <StackPanel>
-                            <TextBlock  Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_StrokeColor}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-                            <cpdfcommon:ColorPickerControl Margin="0,18,0,0" x:Name="BorderColorPickerControl" ColorChanged="BorderColorPickerControl_ColorChanged"/>
-                        </StackPanel>
-                        <StackPanel>
-                            <TextBlock  Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_BgColor}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-                            <cpdfcommon:ColorPickerControl Margin="0,18,0,0" x:Name="BackgroundColorPickerControl" ColorChanged="BackgroundColorPickerControl_ColorChanged"/>
-                        </StackPanel>
-                        <StackPanel>
-                            <TextBlock  Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_FontColor}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-                            <cpdfcommon:ColorPickerControl Margin="0,18,0,0" x:Name="TextColorPickerControl" ColorChanged="TextColorPickerControl_ColorChanged"/>
-                        </StackPanel>
-                        <StackPanel>
-                            <TextBlock  Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Font}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold" />
-                            <ComboBox x:Name="FontCmb" Height="28" Margin="0,8,0,0" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="FontCmb_SelectionChanged">
-                            </ComboBox>
-                            <StackPanel Orientation="Horizontal"  Height="28" Margin="0,8,0,0">
-                                <ComboBox x:Name="FontStyleCmb"  Margin="0,0,0,0" Width="148" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="FontStyleCmb_SelectionChanged">
+            </Border>
+            <TabControl Grid.Row="1" Style="{DynamicResource TabControlStyle1}" BorderThickness="0">
+                <TabItem Height="32" Style="{DynamicResource TabItemStyle1}" Header="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_General}">
+                    <Grid>
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="16"/>
+                            <ColumnDefinition Width="*"/>
+                            <ColumnDefinition Width="16"/>
+                        </Grid.ColumnDefinitions>
+                        <StackPanel Grid.Column="1">
+                            <StackPanel  >
+                                <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Name}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
+                                <TextBox x:Name="FieldNameText" Height="32" Margin="0,8,0,0" TextChanged="FieldNameText_TextChanged"/>
+                            </StackPanel>
+                            <StackPanel >
+                                <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Visibility}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
+                                <ComboBox x:Name="FormFieldCmb" Height="32" Margin="0,8,0,0" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="FormFieldCmb_SelectionChanged">
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Visible}"/>
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Hidden}"/>
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_NoPrint}"/>
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Option_Print}"/>
                                 </ComboBox>
                                 </ComboBox>
-                                <ComboBox x:Name="FontSizeCmb" Margin="4,0,0,0" Width="72" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="FontSizeCmb_SelectionChanged"/>
                             </StackPanel>
                             </StackPanel>
                         </StackPanel>
                         </StackPanel>
-                    </StackPanel>
-                </Grid>
-            </TabItem>
-            <TabItem Height="32" Style="{DynamicResource TabItemStyle1}" Header="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_Preferences}">
-                <Grid>
-                    <Grid.ColumnDefinitions>
-                        <ColumnDefinition Width="16"/>
-                        <ColumnDefinition Width="*"/>
-                        <ColumnDefinition Width="16"/>
-                    </Grid.ColumnDefinitions>
-                    <StackPanel Grid.Column="1">
-                        <StackPanel  >
-                            <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Alignment}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-                            <ComboBox x:Name="TextAlignmentCmb" Height="32" Margin="0,8,0,0" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="TextAlignmentCmb_SelectionChanged">
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Alignment_Left}"/>
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Alignment_Center}"/>
-                                <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Alignment_Right}"/>
-                            </ComboBox>
+                    </Grid>
+                </TabItem>
+                <TabItem Height="32" Style="{DynamicResource TabItemStyle1}" Header="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_Appearance}">
+                    <Grid>
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="16"/>
+                            <ColumnDefinition Width="*"/>
+                            <ColumnDefinition Width="16"/>
+                        </Grid.ColumnDefinitions>
+                        <StackPanel Grid.Column="1">
+                            <StackPanel>
+                                <TextBlock  Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_StrokeColor}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
+                                <cpdfcommon:ColorPickerControl Margin="0,18,0,0" x:Name="BorderColorPickerControl" ColorChanged="BorderColorPickerControl_ColorChanged"/>
+                            </StackPanel>
+                            <StackPanel>
+                                <TextBlock  Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_BgColor}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
+                                <cpdfcommon:ColorPickerControl Margin="0,18,0,0" x:Name="BackgroundColorPickerControl" ColorChanged="BackgroundColorPickerControl_ColorChanged"/>
+                            </StackPanel>
+                            <StackPanel>
+                                <TextBlock  Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_FontColor}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
+                                <cpdfcommon:ColorPickerControl Margin="0,18,0,0" x:Name="TextColorPickerControl" ColorChanged="TextColorPickerControl_ColorChanged"/>
+                            </StackPanel>
+                            <StackPanel>
+                                <TextBlock  Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Font}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold" />
+                                <ComboBox x:Name="FontCmb" Height="28" Margin="0,8,0,0" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="FontCmb_SelectionChanged">
+                                </ComboBox>
+                                <StackPanel Orientation="Horizontal"  Height="28" Margin="0,8,0,0">
+                                    <ComboBox x:Name="FontStyleCmb"  Margin="0,0,0,0" Width="148" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="FontStyleCmb_SelectionChanged">
+                                    </ComboBox>
+                                    <ComboBox x:Name="FontSizeCmb" Margin="4,0,0,0" Width="72" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="FontSizeCmb_SelectionChanged"/>
+                                </StackPanel>
+                            </StackPanel>
                         </StackPanel>
                         </StackPanel>
-                        <StackPanel >
-                            <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_DefaultValue}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
-                            <TextBox x:Name="DefaultText" Margin="0,8,0,0"  Width="224" Height="112" AcceptsReturn="True" TextWrapping="Wrap" TextChanged="DefaultText_TextChanged"/>
-                            <CheckBox x:Name="chkMutiline" Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_MultiLine}" FontSize="14" VerticalContentAlignment="Center" Margin="0 14 0 0" Checked="chkMutiline_Checked" Unchecked="chkMutiline_Unchecked"/>
+                    </Grid>
+                </TabItem>
+                <TabItem Height="32" Style="{DynamicResource TabItemStyle1}" Header="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Title_Preferences}">
+                    <Grid>
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="16"/>
+                            <ColumnDefinition Width="*"/>
+                            <ColumnDefinition Width="16"/>
+                        </Grid.ColumnDefinitions>
+                        <StackPanel Grid.Column="1">
+                            <StackPanel  >
+                                <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Alignment}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
+                                <ComboBox x:Name="TextAlignmentCmb" Height="32" Margin="0,8,0,0" Style="{StaticResource ComboBoxStyle1}" SelectedIndex="0" SelectionChanged="TextAlignmentCmb_SelectionChanged">
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Alignment_Left}"/>
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Alignment_Center}"/>
+                                    <ComboBoxItem Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Alignment_Right}"/>
+                                </ComboBox>
+                            </StackPanel>
+                            <StackPanel >
+                                <TextBlock Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_DefaultValue}" FontSize="14" FontFamily="Microsoft YaHei" FontWeight="Bold"/>
+                                <TextBox x:Name="DefaultText" Margin="0,8,0,0"  Width="224" Height="112" AcceptsReturn="True" TextWrapping="Wrap" TextChanged="DefaultText_TextChanged"/>
+                                <CheckBox x:Name="chkMutiline" Content="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_MultiLine}" FontSize="14" VerticalContentAlignment="Center" Margin="0 14 0 0" Checked="chkMutiline_Checked" Unchecked="chkMutiline_Unchecked"/>
+                            </StackPanel>
                         </StackPanel>
                         </StackPanel>
-                    </StackPanel>
-                </Grid>
-            </TabItem>
-        </TabControl>
-    </Grid>
+                    </Grid>
+                </TabItem>
+            </TabControl>
+        </Grid>
+    </ScrollViewer>
 </UserControl>
 </UserControl>

+ 1 - 1
Demo/Examples/Compdfkit.Controls/Form/Property/TextFieldProperty.xaml.cs

@@ -63,7 +63,7 @@ namespace ComPDFKit.Controls.PDFControl
             string familyName = string.Empty;
             string familyName = string.Empty;
             string styleName = string.Empty;
             string styleName = string.Empty;
 
 
-            CPDFFont.GetFamlyStyleName(widgetParam.FontName, ref familyName, ref styleName);
+            CPDFFont.GetFamilyStyleName(widgetParam.FontName, ref familyName, ref styleName);
 
 
             FontCmb.ItemsSource = CPDFFont.GetFontNameDictionary().Keys.ToList();
             FontCmb.ItemsSource = CPDFFont.GetFontNameDictionary().Keys.ToList();
 
 

+ 2 - 2
Demo/Examples/Compdfkit.Controls/Measure/MeasureControl.xaml.cs

@@ -292,7 +292,7 @@ namespace ComPDFKit.Controls.Measure
                 if (annot.Type == C_ANNOTATION_TYPE.C_ANNOTATION_LINE)
                 if (annot.Type == C_ANNOTATION_TYPE.C_ANNOTATION_LINE)
                 {
                 {
                     CPDFLineAnnotation lineAnnot = annot as CPDFLineAnnotation;
                     CPDFLineAnnotation lineAnnot = annot as CPDFLineAnnotation;
-                    if (lineAnnot.IsMersured() && lineAnnot.Points != null && lineAnnot.Points.Count() == 2)
+                    if (lineAnnot.IsMeasured() && lineAnnot.Points != null && lineAnnot.Points.Count() == 2)
                     {
                     {
                         InfoPanel.SetMeasureInfo(lineAnnot);
                         InfoPanel.SetMeasureInfo(lineAnnot);
                         SetMeasureInfoType(CPDFMeasureType.CPDF_DISTANCE_MEASURE);
                         SetMeasureInfoType(CPDFMeasureType.CPDF_DISTANCE_MEASURE);
@@ -302,7 +302,7 @@ namespace ComPDFKit.Controls.Measure
                 if (annot.Type == C_ANNOTATION_TYPE.C_ANNOTATION_POLYLINE)
                 if (annot.Type == C_ANNOTATION_TYPE.C_ANNOTATION_POLYLINE)
                 {
                 {
                     CPDFPolylineAnnotation polylineAnnot = annot as CPDFPolylineAnnotation;
                     CPDFPolylineAnnotation polylineAnnot = annot as CPDFPolylineAnnotation;
-                    if (polylineAnnot.IsMersured() && polylineAnnot.Points != null && polylineAnnot.Points.Count() >= 2)
+                    if (polylineAnnot.IsMeasured() && polylineAnnot.Points != null && polylineAnnot.Points.Count() >= 2)
                     {
                     {
                         InfoPanel.SetMeasureInfo(polylineAnnot);
                         InfoPanel.SetMeasureInfo(polylineAnnot);
                         SetMeasureInfoType(CPDFMeasureType.CPDF_PERIMETER_MEASURE);
                         SetMeasureInfoType(CPDFMeasureType.CPDF_PERIMETER_MEASURE);

+ 3 - 3
Demo/Examples/Compdfkit.Controls/Measure/MeasureSettingPanel.xaml.cs

@@ -219,7 +219,7 @@ namespace ComPDFKit.Controls.Measure
         {
         {
             if(annot is CPDFLineAnnotation lineAnnot)
             if(annot is CPDFLineAnnotation lineAnnot)
             {
             {
-                if (lineAnnot.IsMersured())
+                if (lineAnnot.IsMeasured())
                 {
                 {
                     CPDFDistanceMeasure lineMeasure = lineAnnot.GetDistanceMeasure();
                     CPDFDistanceMeasure lineMeasure = lineAnnot.GetDistanceMeasure();
                     CPDFMeasureInfo info = lineMeasure.MeasureInfo;
                     CPDFMeasureInfo info = lineMeasure.MeasureInfo;
@@ -240,7 +240,7 @@ namespace ComPDFKit.Controls.Measure
             }
             }
             else if(annot is CPDFPolylineAnnotation polylineAnnot)
             else if(annot is CPDFPolylineAnnotation polylineAnnot)
             {
             {
-                if (polylineAnnot.IsMersured())
+                if (polylineAnnot.IsMeasured())
                 {
                 {
                     CPDFPerimeterMeasure polylineMeasure = polylineAnnot.GetPerimeterMeasure();
                     CPDFPerimeterMeasure polylineMeasure = polylineAnnot.GetPerimeterMeasure();
                     CPDFMeasureInfo info = polylineMeasure.MeasureInfo;
                     CPDFMeasureInfo info = polylineMeasure.MeasureInfo;
@@ -258,7 +258,7 @@ namespace ComPDFKit.Controls.Measure
             }
             }
             else if(annot is CPDFPolygonAnnotation areaAnnot)
             else if(annot is CPDFPolygonAnnotation areaAnnot)
             {
             {
-                if (areaAnnot.IsMersured())
+                if (areaAnnot.IsMeasured())
                 {
                 {
                     CPDFAreaMeasure areaMeasure = areaAnnot.GetAreaMeasure();
                     CPDFAreaMeasure areaMeasure = areaAnnot.GetAreaMeasure();
                     CPDFMeasureInfo info = areaMeasure.MeasureInfo;
                     CPDFMeasureInfo info = areaMeasure.MeasureInfo;

+ 4 - 1
Demo/Examples/Compdfkit.Controls/PDFView/PDFDisplaySettings/PDFDisplaySettingsControl/CPDFDisplaySettingsControl.xaml

@@ -7,13 +7,15 @@
              xmlns:pdftoolsui="clr-namespace:ComPDFKit.Controls.PDFControlUI"
              xmlns:pdftoolsui="clr-namespace:ComPDFKit.Controls.PDFControlUI"
              xmlns:common="clr-namespace:ComPDFKit.Controls.Common"
              xmlns:common="clr-namespace:ComPDFKit.Controls.Common"
              mc:Ignorable="d" 
              mc:Ignorable="d" 
-             d:DesignHeight="450" d:DesignWidth="800" Width="260"
+             d:DesignHeight="720" d:DesignWidth="280" Width="260"
              Background="#ffffff">
              Background="#ffffff">
     <UserControl.Resources>
     <UserControl.Resources>
         <ResourceDictionary>
         <ResourceDictionary>
             <common:CommonResourceConverter x:Key="CommonResourceConverter"/>
             <common:CommonResourceConverter x:Key="CommonResourceConverter"/>
         </ResourceDictionary>
         </ResourceDictionary>
     </UserControl.Resources>
     </UserControl.Resources>
+    <ScrollViewer VerticalScrollBarVisibility="Auto">
+        
     <Grid>
     <Grid>
         <Grid.RowDefinitions>
         <Grid.RowDefinitions>
             <RowDefinition Height="auto"></RowDefinition>
             <RowDefinition Height="auto"></RowDefinition>
@@ -34,4 +36,5 @@
                 </StackPanel> 
                 </StackPanel> 
         </Border>
         </Border>
     </Grid>
     </Grid>
+    </ScrollViewer>
 </UserControl>
 </UserControl>

+ 0 - 0
Demo/Examples/Compdfkit.Controls/PDFView/PDFSearch/PDFSearchControl/CPDFSearchControl.xaml.cs


Some files were not shown because too many files changed in this diff