Browse Source

ComPDFKit.Tool(win) - 优化Stamp旋转编辑问题

TangJinZhou 4 months ago
parent
commit
93d8fd8d7e

+ 50 - 22
Demo/Examples/ComPDFKit.Tool/DrawTool/SelectedRect.cs

@@ -1,7 +1,7 @@
 using ComPDFKit.Import;
 using ComPDFKit.PDFAnnotation;
-using ComPDFKit.Tool.Help;
 using ComPDFKit.Tool.SettingParam;
+using ComPDFKit.Viewer.Helper;
 using ComPDFKitViewer;
 using System;
 using System.Collections.Generic;
@@ -118,7 +118,7 @@ namespace ComPDFKit.Tool.DrawTool
 
         protected bool isSelected = false;
 
-        protected bool canRotation = false;
+        protected bool canRotate = false;
 
         protected SelectedType selectedType = SelectedType.None;
 
@@ -256,7 +256,7 @@ namespace ComPDFKit.Tool.DrawTool
                 case PointControlType.Line:
                     return Cursors.SizeAll;
                 case PointControlType.Rotate:
-                     return CommonHelper.RotationCursor;
+                     return Cursors.SizeAll;
                 default:
                     return Cursors.Arrow;
             }
@@ -643,7 +643,7 @@ namespace ComPDFKit.Tool.DrawTool
                     rotateRect.X += renderData.PageBound.X - renderData.CropLeft * annotData.CurrentZoom;
                     rotateRect.Y += renderData.PageBound.Y - renderData.CropTop * annotData.CurrentZoom;
                     SetRect(rotateRect, annotData.CurrentZoom);
-                    rotateAngle = (annotData.Annot as CPDFStampAnnotation).AnnotationRotator.GetRotation();
+                    rotateAngle = -(annotData.Annot as CPDFStampAnnotation).AnnotationRotator.GetRotation();
                 }
                 else
                 {
@@ -660,9 +660,9 @@ namespace ComPDFKit.Tool.DrawTool
             selectedRectData.annotData = annotData;
         }
 
-        private void SetRoationHandle(bool canRotation)
+        private void SetRoationHandle(bool canRotate)
         {
-            this.canRotation = canRotation;
+            this.canRotate = canRotate;
         }
 
         public void SetIsProportionalScaling(bool isProportionalScaling)
@@ -838,7 +838,6 @@ namespace ComPDFKit.Tool.DrawTool
             if (hitResult != null && hitResult.VisualHit is DrawingVisual)
             {
                 List<PointControlType> ignoreList = GetIgnorePoints();
-
                 List<Point> IgnorePointsList = new List<Point>();
                 foreach (PointControlType type in ignoreList)
                 {
@@ -851,7 +850,7 @@ namespace ComPDFKit.Tool.DrawTool
                 {
                     Point checkPoint = controlPoints[i];
 
-                    if (canRotation)
+                    if (canRotate)
                     {
                         // Convert the rotation angle from degrees to radians
                         double angleRad = rotateAngle * Math.PI / 180.0;
@@ -877,6 +876,7 @@ namespace ComPDFKit.Tool.DrawTool
                     {
                         continue;
                     }
+
                     switch (currentDrawPointType)
                     {
                         case DrawPointType.Circle:
@@ -905,7 +905,6 @@ namespace ComPDFKit.Tool.DrawTool
                             }
                             if ((PointControlType)i == PointControlType.RightMiddle)
                             {
-
                                 if (Math.Abs(point.X - checkPoint.X) < wlen && checkVector.Length < drawRect.Height/3)
                                 {
                                     return (PointControlType)i;
@@ -939,17 +938,16 @@ namespace ComPDFKit.Tool.DrawTool
                                 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;
                             }
-                            if (canRotation)
-                            { 
-                                // rotationPoint 围绕centerPoint旋转angle度
-                                
+
+                            if (canRotate)
+                            {
                                 Point hitRotationPoint = new Point(centerPoint.X + (rotationPoint.X - centerPoint.X) * Math.Cos(rotateAngle * Math.PI / 180) - (rotationPoint.Y - centerPoint.Y) * Math.Sin(rotateAngle * Math.PI / 180),
                                     centerPoint.Y + (rotationPoint.X - centerPoint.X) * Math.Sin(rotateAngle * Math.PI / 180) + (rotationPoint.Y - centerPoint.Y) * Math.Cos(rotateAngle * Math.PI / 180));
                                 Vector checkVector1 = point - hitRotationPoint;
@@ -968,28 +966,58 @@ namespace ComPDFKit.Tool.DrawTool
                                 return (PointControlType)i;
                             }
                             break;
+
                         default:
                             break;
                     }
                 }
-                if (drawRect.Contains(point))
+
+                if (canRotate)
                 {
-                    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))
+                    bool isIn = DataConversionForWPF.IsPointInRotatedRectangle(point, drawRect, rotateAngle);
+                    if(isIn)
                     {
+                        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);
+                        isIn = DataConversionForWPF.IsPointInRotatedRectangle(point, rect, rotateAngle);
+                        if (isIn)
+                        {
+                            if (!ignoreList.Contains(PointControlType.Body))
+                            {
+                                return PointControlType.Body;
+                            }
+                        }
+
                         if (!ignoreList.Contains(PointControlType.Body))
                         {
-                            return PointControlType.Body;
+                            return PointControlType.Line;
                         }
                     }
-                    if (!ignoreList.Contains(PointControlType.Body))
+                }
+                else
+                {
+                    if (drawRect.Contains(point))
                     {
-                        return PointControlType.Line;
+                        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;
         }
 

+ 80 - 20
Demo/Examples/ComPDFKit.Tool/DrawTool/SelectedRect.protected.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using System.Windows;
 using System.Windows.Media;
 
@@ -8,7 +9,6 @@ namespace ComPDFKit.Tool.DrawTool
     public partial class SelectedRect
     {
         #region Properties
-
         /// <summary>
         /// Current control point drawing style.
         /// </summary>
@@ -18,7 +18,6 @@ namespace ComPDFKit.Tool.DrawTool
             set;
         }
 
-
         /// <summary>
         /// Current drag drawing style.
         /// </summary>
@@ -180,7 +179,7 @@ namespace ComPDFKit.Tool.DrawTool
             controlPoints.Add(new Point(currentRect.Right, currentRect.Top));
             controlPoints.Add(new Point(centerPoint.X, currentRect.Top));
 
-            if (canRotation)
+            if (canRotate)
             {
                 rotationPoint = new Point(centerPoint.X, currentRect.Top - 30);
             }
@@ -274,7 +273,7 @@ namespace ComPDFKit.Tool.DrawTool
 
             if (!isOutSideScaling)
             {
-                if (selectedRectData.rotationAngle != 0 && (hitControlType >= PointControlType.LeftTop && hitControlType <= PointControlType.MiddleTop))
+                if (selectedRectData.rotationAngle != 0)
                 {
                     return RotateScaling(mousePoint);
                 }
@@ -321,7 +320,6 @@ namespace ComPDFKit.Tool.DrawTool
             Vector moveVector = (mousePoint - centerPoint);
 
             rotateAngle = (int)(Math.Atan2(moveVector.X, -moveVector.Y) * 180 / Math.PI);
-
             return false;
         }
 
@@ -575,11 +573,11 @@ namespace ComPDFKit.Tool.DrawTool
                     case PointControlType.Body:
                     case PointControlType.Line:
                         {
-                            Point OffsetPos = CalcMoveBound(cacheRect, ((Point)(mousePoint - mouseDownPoint)), maxRect);
-                            left = cacheRect.Left + OffsetPos.X;
-                            right = cacheRect.Right + OffsetPos.X;
-                            top = cacheRect.Top + OffsetPos.Y;
-                            bottom = cacheRect.Bottom + OffsetPos.Y;
+                            Point offsetPos = CalcMoveBound(cacheRect, ((Point)(mousePoint - mouseDownPoint)), maxRect);
+                            left = cacheRect.Left + offsetPos.X;
+                            right = cacheRect.Right + offsetPos.X;
+                            top = cacheRect.Top + offsetPos.Y;
+                            bottom = cacheRect.Bottom + offsetPos.Y;
                         }
                         break;
 
@@ -624,8 +622,6 @@ namespace ComPDFKit.Tool.DrawTool
             if (hitControlType < PointControlType.Body)
             {
                 hitControlUIPos = rotateControlPoints[(int)hitControlType];
-                //Debug.WriteLine(hitControlUIPos.ToString());
-                //Debug.WriteLine(rotateRect.ToString());
             }
 
             hitControlUIPos = GetRotateUIPoint(hitControlUIPos);
@@ -633,6 +629,7 @@ namespace ComPDFKit.Tool.DrawTool
             Vector moveVector = mouseMovePoint - mouseDownPoint;
             Vector hitVector = hitControlUIPos - centerPoint;
 
+            Rect tmpRect = cacheRect;
             if (hitControlType == PointControlType.LeftTop
                 || hitControlType == PointControlType.LeftBottom
                 || hitControlType == PointControlType.RightTop
@@ -663,7 +660,7 @@ namespace ComPDFKit.Tool.DrawTool
 
                         Point leftTopPoint = rotateMatrix.Transform(rotatePoint);
                         rightBottomPoint = rotateMatrix.Transform(rightBottomUIPos);
-                        drawRect = new Rect(leftTopPoint, rightBottomPoint);
+                        tmpRect = new Rect(leftTopPoint, rightBottomPoint);
                     }
                     break;
 
@@ -678,7 +675,7 @@ namespace ComPDFKit.Tool.DrawTool
 
                         Point leftBottomPoint = rotateMatrix.Transform(rotatePoint);
                         rightTopPoint = rotateMatrix.Transform(rightTopUIPos);
-                        drawRect = new Rect(leftBottomPoint, rightTopPoint);
+                        tmpRect = new Rect(leftBottomPoint, rightTopPoint);
                     }
                     break;
 
@@ -693,8 +690,7 @@ namespace ComPDFKit.Tool.DrawTool
 
                         Point rightTopPoint = rotateMatrix.Transform(rotatePoint);
                         leftBottomPoint = rotateMatrix.Transform(leftBottomUIPos);
-
-                        drawRect = new Rect(leftBottomPoint, rightTopPoint);
+                        tmpRect = new Rect(leftBottomPoint, rightTopPoint);
                     }
                     break;
 
@@ -709,8 +705,19 @@ namespace ComPDFKit.Tool.DrawTool
 
                         Point rightBottomPoint = rotateMatrix.Transform(rotatePoint);
                         leftTopPoint = rotateMatrix.Transform(leftTopUIPos);
+                        tmpRect = new Rect(leftTopPoint, rightBottomPoint);
+                    }
+                    break;
 
-                        drawRect = new Rect(leftTopPoint, rightBottomPoint);
+                case PointControlType.Body:
+                case PointControlType.Line:
+                    {
+                        Point offsetPos = (Point)(mouseMovePoint - mouseDownPoint);
+                        double left = cacheRect.Left + offsetPos.X;
+                        double right = cacheRect.Right + offsetPos.X;
+                        double top = cacheRect.Top + offsetPos.Y;
+                        double bottom = cacheRect.Bottom + offsetPos.Y;
+                        tmpRect = new Rect(new Point(left,top), new Point(right,bottom));
                     }
                     break;
 
@@ -718,6 +725,60 @@ namespace ComPDFKit.Tool.DrawTool
                     break;
             }
 
+            List<Point> tempPoints = new List<Point>
+            {
+                new Point(tmpRect.Left, tmpRect.Top),
+                new Point(tmpRect.Right, tmpRect.Top),
+                new Point(tmpRect.Right, tmpRect.Bottom),
+                new Point(tmpRect.Left, tmpRect.Bottom)
+            };
+
+            List<Point> boundPoint = new List<Point>();
+            Point center = new Point((tmpRect.Left + tmpRect.Right) / 2, (tmpRect.Top + tmpRect.Bottom) / 2);
+            foreach (Point point in tempPoints)
+            {
+                float x = (float)(center.X + (point.X - center.X) * Math.Cos(rotateAngle * Math.PI / 180) - (point.Y - center.Y) * Math.Sin(rotateAngle * Math.PI / 180));
+                float y = (float)(center.Y + (point.X - center.X) * Math.Sin(rotateAngle * Math.PI / 180) + (point.Y - center.Y) * Math.Cos(rotateAngle * Math.PI / 180));
+                boundPoint.Add(new Point(x, y));
+            }
+
+            Rect boundRect = new Rect(new Point(boundPoint.Min(p => p.X), boundPoint.Min(p => p.Y)), new Point(boundPoint.Max(p => p.X), boundPoint.Max(p => p.Y)));
+            if (maxRect.Contains(boundRect))
+            {
+                drawRect = tmpRect;
+            }
+            else
+            {
+                if(hitControlType == PointControlType.Body || hitControlType == PointControlType.Line)
+                {
+                    Point boundRectCenterPos = new Point((boundRect.Left + boundRect.Right) / 2, (boundRect.Top + boundRect.Bottom) / 2);
+                    Point maxRectCenterPos = new Point((maxRect.Left + maxRect.Right) / 2, (maxRect.Top + maxRect.Bottom) / 2);
+                    Vector moveCenterVector = boundRectCenterPos - maxRectCenterPos;
+                    Point moveOffsetPos = new Point(0, 0);
+                    if (Math.Abs(moveCenterVector.X) > (maxRect.Width - boundRect.Width) / 2)
+                    {
+                        double moveLength = maxRectCenterPos.X - boundRectCenterPos.X;
+                        moveOffsetPos.X = Math.Abs(moveLength) - (maxRect.Width - boundRect.Width) / 2;
+                        if (moveLength < 0)
+                        {
+                            moveOffsetPos.X *= -1;
+                        }
+                    }
+
+                    if (Math.Abs(moveCenterVector.Y) > (maxRect.Height - boundRect.Height) / 2)
+                    {
+                        double moveLength = maxRectCenterPos.Y - boundRectCenterPos.Y;
+                        moveOffsetPos.Y = Math.Abs(moveLength) - (maxRect.Height - boundRect.Height) / 2;
+                        if (moveLength < 0)
+                        {
+                            moveOffsetPos.Y *= -1;
+                        }
+                    }
+
+                    drawRect = new Rect(tmpRect.Left + moveOffsetPos.X, tmpRect.Top + moveOffsetPos.Y, tmpRect.Width, tmpRect.Height);
+                }
+            }
+
             moveOffset = new Point(drawRect.X - cacheRect.X, drawRect.Y - cacheRect.Y);
             return true;
         }
@@ -1156,17 +1217,16 @@ namespace ComPDFKit.Tool.DrawTool
         protected void DrawSquarePoint(DrawingContext drawingContext, List<PointControlType> ignoreList, int PointSize, Pen PointPen, SolidColorBrush BorderBrush)
         {
             RotateTransform rotateTransform = new RotateTransform(rotateAngle, centerPoint.X, centerPoint.Y);
-            if (canRotation && !isInScaling)
+            if (canRotate && !isInScaling)
             {
                 Point currentRotationPoint = isInRotate ? dragRotationPoint : rotationPoint;
-                GeometryGroup rotateGroup = new GeometryGroup();
-
                 double angleInRadians = rotateAngle * (Math.PI / 180);
                 double sinValue = Math.Sin(angleInRadians);
                 double cosValue = Math.Cos(angleInRadians);
                 double rotatedX = currentRotationPoint.X - pointSize * sinValue;
                 double rotatedY = currentRotationPoint.Y + pointSize * cosValue;
 
+                GeometryGroup rotateGroup = new GeometryGroup();
                 LineGeometry moveLineGeometry = new LineGeometry(centerPoint, new Point(rotatedX, rotatedY));
                 EllipseGeometry ellipseGeometry = new EllipseGeometry(currentRotationPoint, PointSize, pointSize);
                 rotateGroup.Children.Add(moveLineGeometry);