|
@@ -55,6 +55,9 @@ namespace ComPDFKit.Tool.DrawTool
|
|
public enum DrawMoveType
|
|
public enum DrawMoveType
|
|
{
|
|
{
|
|
kDefault,
|
|
kDefault,
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 移动画线
|
|
|
|
+ /// </summary>
|
|
kReferenceLine,
|
|
kReferenceLine,
|
|
}
|
|
}
|
|
|
|
|
|
@@ -72,42 +75,11 @@ namespace ComPDFKit.Tool.DrawTool
|
|
|
|
|
|
public AnnotData annotData { get; set; }
|
|
public AnnotData annotData { 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; }
|
|
@@ -127,7 +99,10 @@ 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; }
|
|
|
|
+ private double angle = 0;
|
|
|
|
+ private Point rotateCenter= new Point(0,0);
|
|
|
|
+ private int rotateline = 25;
|
|
public SelectedType GetSelectedType()
|
|
public SelectedType GetSelectedType()
|
|
{
|
|
{
|
|
return selectedType;
|
|
return selectedType;
|
|
@@ -177,6 +152,7 @@ namespace ComPDFKit.Tool.DrawTool
|
|
{
|
|
{
|
|
cacheRect = drawRect;
|
|
cacheRect = drawRect;
|
|
}
|
|
}
|
|
|
|
+ rotateCenter = new Point(drawRect.Left + drawRect.Width / 2, drawRect.Top + drawRect.Height / 2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -242,6 +218,8 @@ namespace ComPDFKit.Tool.DrawTool
|
|
return Cursors.Arrow;
|
|
return Cursors.Arrow;
|
|
case PointControlType.Line:
|
|
case PointControlType.Line:
|
|
return Cursors.SizeAll;
|
|
return Cursors.SizeAll;
|
|
|
|
+ case PointControlType.Rotate:
|
|
|
|
+ return Cursors.Arrow;
|
|
default:
|
|
default:
|
|
return Cursors.Arrow;
|
|
return Cursors.Arrow;
|
|
}
|
|
}
|
|
@@ -254,53 +232,101 @@ namespace ComPDFKit.Tool.DrawTool
|
|
selectedType = type;
|
|
selectedType = type;
|
|
}
|
|
}
|
|
|
|
|
|
- public void Draw()
|
|
|
|
|
|
+ private void DrawNormal(DrawingContext drawDC)
|
|
{
|
|
{
|
|
- Dispatcher.Invoke(() =>
|
|
|
|
|
|
+ Rect currentRect = SetDrawRect;
|
|
|
|
+
|
|
|
|
+ switch (currentDrawMoveType)
|
|
{
|
|
{
|
|
- Rect currentRect = SetDrawRect;
|
|
|
|
- drawDC = RenderOpen();
|
|
|
|
- switch (currentDrawMoveType)
|
|
|
|
- {
|
|
|
|
- case DrawMoveType.kDefault:
|
|
|
|
- currentRect = drawRect;
|
|
|
|
- CalcControlPoint(currentRect);
|
|
|
|
- break;
|
|
|
|
- case DrawMoveType.kReferenceLine:
|
|
|
|
- CalcControlPoint(currentRect);
|
|
|
|
- if (isMouseDown == true)
|
|
|
|
- {
|
|
|
|
- SolidColorBrush moveBrush = DrawParam.AnnotMoveBrush;
|
|
|
|
- Pen movepen = DrawParam.AnnotMovePen;
|
|
|
|
- GetMoveBrushAndPen(ref moveBrush, ref movepen);
|
|
|
|
- DrawMoveBounds(drawDC, hitControlType, movepen, moveBrush, drawRect);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- default:
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
|
|
+ case DrawMoveType.kDefault:
|
|
|
|
+ currentRect = drawRect;
|
|
|
|
+ CalcControlPoint(currentRect);
|
|
|
|
+ break;
|
|
|
|
+ case DrawMoveType.kReferenceLine:
|
|
|
|
+ CalcControlPoint(currentRect);
|
|
|
|
+ if (isMouseDown == true)
|
|
|
|
+ {
|
|
|
|
+ SolidColorBrush moveBrush = DrawParam.AnnotMoveBrush;
|
|
|
|
+ Pen movepen = DrawParam.AnnotMovePen;
|
|
|
|
+ GetMoveBrushAndPen(ref moveBrush, ref movepen);
|
|
|
|
+ DrawMoveBounds(drawDC, hitControlType, movepen, moveBrush, drawRect);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
|
|
- SolidColorBrush solidColorBrush = DrawParam.AnnotRectFillBrush;
|
|
|
|
- Pen pen = DrawParam.AnnotRectLinePen;
|
|
|
|
- GetBrushAndPen(ref solidColorBrush, ref pen);
|
|
|
|
- drawDC?.DrawRectangle(solidColorBrush, pen, currentRect);
|
|
|
|
|
|
+ SolidColorBrush solidColorBrush = DrawParam.AnnotRectFillBrush;
|
|
|
|
+ Pen pen = DrawParam.AnnotRectLinePen;
|
|
|
|
+ GetBrushAndPen(ref solidColorBrush, ref pen);
|
|
|
|
+ drawDC?.DrawRectangle(solidColorBrush, pen, currentRect);
|
|
|
|
|
|
- SolidColorBrush PointBrush = DrawParam.AnnotPointBorderBrush;
|
|
|
|
- Pen PointPen = DrawParam.AnnotPointPen;
|
|
|
|
- GetPointBrushAndPen(ref PointBrush, ref PointPen);
|
|
|
|
|
|
+ SolidColorBrush PointBrush = DrawParam.AnnotPointBorderBrush;
|
|
|
|
+ Pen PointPen = DrawParam.AnnotPointPen;
|
|
|
|
+ GetPointBrushAndPen(ref PointBrush, ref PointPen);
|
|
|
|
|
|
- switch (currentDrawPointType)
|
|
|
|
|
|
+ switch (currentDrawPointType)
|
|
|
|
+ {
|
|
|
|
+ case DrawPointType.Circle:
|
|
|
|
+ DrawCirclePoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);
|
|
|
|
+ break;
|
|
|
|
+ case DrawPointType.Square:
|
|
|
|
+ DrawSquarePoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);
|
|
|
|
+ break;
|
|
|
|
+ case DrawPointType.Crop:
|
|
|
|
+ DrawCropPoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void PushRotate(DrawingContext drawDC)
|
|
|
|
+ {
|
|
|
|
+ if (CanRotate)
|
|
|
|
+ {
|
|
|
|
+ RotateTransform transform = new RotateTransform();
|
|
|
|
+ transform.Angle = angle;
|
|
|
|
+ if(hitControlType==PointControlType.Body || hitControlType==PointControlType.Line)
|
|
{
|
|
{
|
|
- case DrawPointType.Circle:
|
|
|
|
- DrawCirclePoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);
|
|
|
|
- break;
|
|
|
|
- case DrawPointType.Square:
|
|
|
|
- DrawSquarePoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);
|
|
|
|
- break;
|
|
|
|
- case DrawPointType.Crop:
|
|
|
|
- DrawCropPoint(drawDC, GetIgnorePoints(), pointSize, PointPen, PointBrush);
|
|
|
|
- break;
|
|
|
|
|
|
+ rotateCenter.X = drawRect.Left + drawRect.Width / 2;
|
|
|
|
+ rotateCenter.Y = drawRect.Top + drawRect.Height / 2;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ transform.CenterX = rotateCenter.X;
|
|
|
|
+ transform.CenterY = rotateCenter.Y;
|
|
|
|
+
|
|
|
|
+ drawDC.PushTransform(transform);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void PopRotate(DrawingContext drawDC)
|
|
|
|
+ {
|
|
|
|
+ if (CanRotate)
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ drawDC.Pop();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void DrawRotate(DrawingContext drawDC)
|
|
|
|
+ {
|
|
|
|
+ double centerX = drawRect.Left + drawRect.Width / 2;
|
|
|
|
+ double centerY = drawRect.Top + drawRect.Height / 2;
|
|
|
|
+
|
|
|
|
+ Pen PointPen = DrawParam.AnnotPointPen;
|
|
|
|
+ drawDC.DrawLine(PointPen, new Point(centerX, drawRect.Top), new Point(centerX, drawRect.Top - rotateline));
|
|
|
|
+ drawDC.DrawEllipse(PointPen.Brush, PointPen, new Point(centerX, drawRect.Top - rotateline), pointSize * 2, pointSize * 2);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void Draw()
|
|
|
|
+ {
|
|
|
|
+ Dispatcher.Invoke(() =>
|
|
|
|
+ {
|
|
|
|
+ Rect currentRect = SetDrawRect;
|
|
|
|
+ drawDC = RenderOpen();
|
|
|
|
+ PushRotate(drawDC);
|
|
|
|
+ DrawRotate(drawDC);
|
|
|
|
+ DrawNormal(drawDC);
|
|
|
|
+ PopRotate(drawDC);
|
|
drawDC?.Close();
|
|
drawDC?.Close();
|
|
drawDC = null;
|
|
drawDC = null;
|
|
});
|
|
});
|
|
@@ -652,7 +678,17 @@ namespace ComPDFKit.Tool.DrawTool
|
|
/// <returns>
|
|
/// <returns>
|
|
/// The control point type
|
|
/// The control point type
|
|
/// </returns>
|
|
/// </returns>
|
|
- public PointControlType GetHitControlIndex(Point point, bool isIgnore=true)
|
|
|
|
|
|
+ public PointControlType GetHitControlIndex(Point point, bool isIgnore = true)
|
|
|
|
+ {
|
|
|
|
+ if (CanRotate)
|
|
|
|
+ {
|
|
|
|
+ return GetRotateHitIndex(point,isIgnore);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return GetNormalHitIndex(point, isIgnore);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private PointControlType GetNormalHitIndex(Point point, bool isIgnore = true)
|
|
{
|
|
{
|
|
HitTestResult hitResult = VisualTreeHelper.HitTest(this, point);
|
|
HitTestResult hitResult = VisualTreeHelper.HitTest(this, point);
|
|
if (hitResult != null && hitResult.VisualHit is DrawingVisual)
|
|
if (hitResult != null && hitResult.VisualHit is DrawingVisual)
|
|
@@ -671,7 +707,7 @@ namespace ComPDFKit.Tool.DrawTool
|
|
{
|
|
{
|
|
Point checkPoint = controlPoints[i];
|
|
Point checkPoint = controlPoints[i];
|
|
|
|
|
|
- if (isIgnore&&IgnorePointsList.Contains(checkPoint))
|
|
|
|
|
|
+ if (isIgnore && IgnorePointsList.Contains(checkPoint))
|
|
{
|
|
{
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
@@ -686,13 +722,13 @@ namespace ComPDFKit.Tool.DrawTool
|
|
break;
|
|
break;
|
|
case DrawPointType.Square:
|
|
case DrawPointType.Square:
|
|
|
|
|
|
- Rect checkRect = new Rect(Math.Max(checkPoint.X - pointSize,0), Math.Max(checkPoint.Y - pointSize,0), pointSize * 2, pointSize * 2);
|
|
|
|
|
|
+ Rect checkRect = new Rect(Math.Max(checkPoint.X - pointSize, 0), Math.Max(checkPoint.Y - pointSize, 0), pointSize * 2, pointSize * 2);
|
|
if (checkRect.Contains(point))
|
|
if (checkRect.Contains(point))
|
|
{
|
|
{
|
|
return (PointControlType)i;
|
|
return (PointControlType)i;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
-
|
|
|
|
|
|
+
|
|
case DrawPointType.Crop:
|
|
case DrawPointType.Crop:
|
|
Rect cropRect = new Rect(Math.Max(checkPoint.X - pointSize, 0), Math.Max(checkPoint.Y - pointSize, 0), pointSize * 2, pointSize * 2);
|
|
Rect cropRect = new Rect(Math.Max(checkPoint.X - pointSize, 0), Math.Max(checkPoint.Y - pointSize, 0), pointSize * 2, pointSize * 2);
|
|
if (cropRect.Contains(point))
|
|
if (cropRect.Contains(point))
|
|
@@ -704,11 +740,12 @@ 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 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);
|
|
|
|
|
|
+ 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 (rect.Contains(point))
|
|
{
|
|
{
|
|
if (!ignoreList.Contains(PointControlType.Body))
|
|
if (!ignoreList.Contains(PointControlType.Body))
|
|
@@ -724,5 +761,99 @@ namespace ComPDFKit.Tool.DrawTool
|
|
}
|
|
}
|
|
return PointControlType.None;
|
|
return PointControlType.None;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ private PointControlType GetRotateHitIndex(Point point, bool isIgnore = true)
|
|
|
|
+ {
|
|
|
|
+ HitTestResult hitResult = VisualTreeHelper.HitTest(this, point);
|
|
|
|
+ if (hitResult != null && hitResult.VisualHit is DrawingVisual)
|
|
|
|
+ {
|
|
|
|
+ //旋转回去
|
|
|
|
+ Point centerPoint = rotateCenter;
|
|
|
|
+ Vector currentVector = point - centerPoint;
|
|
|
|
+
|
|
|
|
+ Matrix matrix = new Matrix();
|
|
|
|
+ matrix.Rotate(-angle);
|
|
|
|
+ Vector transVector = matrix.Transform(currentVector);
|
|
|
|
+ Point checkPos = new Point(centerPoint.X + transVector.X, centerPoint.Y + transVector.Y);
|
|
|
|
+
|
|
|
|
+ point= checkPos;
|
|
|
|
+ List<PointControlType> ignoreList = GetIgnorePoints();
|
|
|
|
+
|
|
|
|
+ List<Point> IgnorePointsList = new List<Point>();
|
|
|
|
+ foreach (PointControlType type in ignoreList)
|
|
|
|
+ {
|
|
|
|
+ if ((int)type < controlPoints.Count)
|
|
|
|
+ {
|
|
|
|
+ IgnorePointsList.Add(controlPoints[(int)type]);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ for (int i = 0; i < controlPoints.Count; i++)
|
|
|
|
+ {
|
|
|
|
+ Point checkPoint = controlPoints[i];
|
|
|
|
+
|
|
|
|
+ if (isIgnore && IgnorePointsList.Contains(checkPoint))
|
|
|
|
+ {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ switch (currentDrawPointType)
|
|
|
|
+ {
|
|
|
|
+ case DrawPointType.Circle:
|
|
|
|
+ Vector checkCircle = checkPoint - point;
|
|
|
|
+ if (checkCircle.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;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ double centerX = drawRect.Left + drawRect.Width / 2;
|
|
|
|
+ double centerY = drawRect.Top + drawRect.Height / 2;
|
|
|
|
+
|
|
|
|
+ Point rotatePoint = new Point(centerX, drawRect.Top - rotateline);
|
|
|
|
+ Vector checkVector = point - rotatePoint;
|
|
|
|
+ if (checkVector.Length <= pointSize * 2)
|
|
|
|
+ {
|
|
|
|
+ return PointControlType.Rotate;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return PointControlType.None;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|