Parcourir la source

ComPDFKit.Tool(win)-多选样式,框选辅助工具

liyijie il y a 8 mois
Parent
commit
713399f6ee

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

@@ -119,6 +119,7 @@
     <Compile Include="DrawTool\CreateAnnotTool.cs" />
     <Compile Include="DrawTool\CreateCustomizeTool.cs" />
     <Compile Include="DrawTool\CreateWidgetTool.cs" />
+    <Compile Include="DrawTool\FrameSelectTool.cs" />
     <Compile Include="DrawTool\MultiSelectedRect.cs" />
     <Compile Include="DrawTool\PageSelectedRect.cs" />
     <Compile Include="DrawTool\SelectedRect.cs" />

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

@@ -0,0 +1,445 @@
+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 (!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);
+            }
+            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
+}

+ 10 - 2
Demo/Examples/ComPDFKit.Tool/DrawTool/MultiSelectedRect.cs

@@ -207,7 +207,7 @@ namespace ComPDFKit.Tool.DrawTool
         public MultiSelectedRect(DefaultDrawParam defaultDrawParam, SelectedType type) : base()
         {
             drawParam = defaultDrawParam;
-            currentDrawPointType = DrawPointType.Square;
+            currentDrawPointType = DrawPointType.Circle;
             selectedType = type;
         }
 
@@ -349,7 +349,15 @@ namespace ComPDFKit.Tool.DrawTool
                             switch (currentDrawPointType)
                             {
                                 case DrawPointType.Circle:
-                                    DrawCirclePoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);
+                                    if (selectedType == SelectedType.PDFEdit)
+                                    {
+                                        //Edit Settings Frame
+                                        DrawCirclePoint(drawDC, GetIgnorePoints(), pointSize, PointPen, new SolidColorBrush(Color.FromRgb(71, 126, 222)));
+                                    }
+                                    else
+                                    {
+                                        DrawCirclePoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);
+                                    }
                                     break;
                                 case DrawPointType.Square:
                                     DrawSquarePoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);