|
@@ -0,0 +1,756 @@
|
|
|
|
+using ComPDFKit.Import;
|
|
|
|
+using ComPDFKit.Tool.DrawTool;
|
|
|
|
+using ComPDFKitViewer;
|
|
|
|
+using ComPDFKitViewer.BaseObject;
|
|
|
|
+using ComPDFKitViewer.Helper;
|
|
|
|
+using ComPDFKitViewer.Layer;
|
|
|
|
+using System;
|
|
|
|
+using System.Collections.Generic;
|
|
|
|
+using System.Diagnostics;
|
|
|
|
+using System.Linq;
|
|
|
|
+using System.Net;
|
|
|
|
+using System.Text;
|
|
|
|
+using System.Threading.Tasks;
|
|
|
|
+using System.Windows;
|
|
|
|
+using System.Windows.Controls.Primitives;
|
|
|
|
+using System.Windows.Input;
|
|
|
|
+using System.Windows.Media;
|
|
|
|
+
|
|
|
|
+namespace ComPDFKit.Tool
|
|
|
|
+{
|
|
|
|
+ public partial class CPDFViewerTool
|
|
|
|
+ {
|
|
|
|
+ private class AnnotSelectAreaData
|
|
|
|
+ {
|
|
|
|
+ public Point HitAreaPos { get; set; }
|
|
|
|
+ public Point MoveAreaPos { get; set; }
|
|
|
|
+ public Rect HitAreaBound { get; set; }
|
|
|
|
+ public int HitPageIndex { get; set; } = -1;
|
|
|
|
+ }
|
|
|
|
+ private int AnnotSelectorIndex { get; set; } = -1;
|
|
|
|
+ private AnnotSelector Selector { get; set; }
|
|
|
|
+ private AnnotSelectAreaData AreaDrawData { get; set; } = new AnnotSelectAreaData();
|
|
|
|
+ private AnnotSelectAreaData AreaMoveData { get; set; } = new AnnotSelectAreaData();
|
|
|
|
+ private bool DrawSelect { get; set; } = true;
|
|
|
|
+ private bool AllowMultiSelect { get; set; }
|
|
|
|
+ private bool IsMoved { get; set; } = false;
|
|
|
|
+ private Point OffsetPos { get; set; }=new Point(0,0);
|
|
|
|
+ private void AnnotSelectInsert()
|
|
|
|
+ {
|
|
|
|
+ Selector = new AnnotSelector();
|
|
|
|
+ Selector.PDFViewer = PDFViewer;
|
|
|
|
+ int annotViewindex = PDFViewer.GetMaxViewIndex();
|
|
|
|
+ PDFViewer.InsertView(annotViewindex, Selector);
|
|
|
|
+ AnnotSelectorIndex = Selector.GetResTag();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void AnnotSelectUpdate()
|
|
|
|
+ {
|
|
|
|
+ if (!AllowMultiSelect)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if(Selector==null || Selector.SelectAnnots==null)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (PDFViewer == null || PDFViewer.CurrentRenderFrame == null)
|
|
|
|
+ {
|
|
|
|
+ Selector?.ClearItem();
|
|
|
|
+ Selector?.CleanDraw();
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ List<AnnotData> annotDatas = PDFViewer.CurrentRenderFrame.AnnotDataList;
|
|
|
|
+ if (annotDatas == null || annotDatas.Count == 0)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ foreach (AnnotData checkItem in Selector.SelectAnnots.ToList())
|
|
|
|
+ {
|
|
|
|
+ AnnotData saveItem = annotDatas.Where(x => x.PageIndex == checkItem.PageIndex && x.AnnotIndex == checkItem.AnnotIndex).FirstOrDefault();
|
|
|
|
+ if (saveItem != null)
|
|
|
|
+ {
|
|
|
|
+ Selector.RemoveItem(checkItem);
|
|
|
|
+ Selector.AddItem(saveItem);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void AnnotSelectDraw()
|
|
|
|
+ {
|
|
|
|
+ if (!AllowMultiSelect)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (DrawSelect==false)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (Selector?.GetSelectCount() > 1)
|
|
|
|
+ {
|
|
|
|
+ Selector?.Draw();
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ Selector?.CleanDraw();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void AnnotSelectAddItem(AnnotData annotData,bool clean=true)
|
|
|
|
+ {
|
|
|
|
+ if (!AllowMultiSelect || annotData==null)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
|
|
|
|
+ {
|
|
|
|
+ if (Selector?.HasItem(annotData) == true)
|
|
|
|
+ {
|
|
|
|
+ if(Selector?.GetSelectCount()!=1)
|
|
|
|
+ {
|
|
|
|
+ Selector?.RemoveItem(annotData);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ Selector?.AddItem(annotData);
|
|
|
|
+ }
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(clean)
|
|
|
|
+ {
|
|
|
|
+ Selector?.ClearItem();
|
|
|
|
+ Selector?.AddItem(annotData);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void AnnotSelectAreaHit()
|
|
|
|
+ {
|
|
|
|
+ if (!AllowMultiSelect)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ AreaDrawData.HitPageIndex = -1;
|
|
|
|
+ if (PDFViewer == null || Selector==null)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ AreaDrawData.HitAreaPos = Mouse.GetPosition(PDFViewer);
|
|
|
|
+ AreaDrawData.MoveAreaPos = AreaDrawData.HitAreaPos;
|
|
|
|
+ PDFViewer.GetPointPageInfo(AreaDrawData.HitAreaPos,out int pageIndex,out Rect paintRect, out Rect pageBound);
|
|
|
|
+ if (pageIndex >= 0)
|
|
|
|
+ {
|
|
|
|
+ AreaDrawData.HitPageIndex = pageIndex;
|
|
|
|
+ AreaDrawData.HitAreaBound =pageBound;
|
|
|
|
+ PDFViewer.CanHorizontallyScroll = false;
|
|
|
|
+ PDFViewer.CanVerticallyScroll = false;
|
|
|
|
+ PDFViewer.EnableZoom(false);
|
|
|
|
+ DrawSelect = false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void AnnotSelectMoveHit()
|
|
|
|
+ {
|
|
|
|
+ if (!AllowMultiSelect)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ AreaMoveData.HitPageIndex = -1;
|
|
|
|
+ if (PDFViewer == null || Selector == null)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ AreaMoveData.HitAreaPos = Mouse.GetPosition(PDFViewer);
|
|
|
|
+ AreaMoveData.MoveAreaPos = AreaMoveData.HitAreaPos;
|
|
|
|
+ PDFViewer.GetPointPageInfo(AreaMoveData.HitAreaPos, out int pageIndex, out Rect paintRect, out Rect pageBound);
|
|
|
|
+ if (pageIndex >= 0)
|
|
|
|
+ {
|
|
|
|
+ AreaMoveData.HitPageIndex = pageIndex;
|
|
|
|
+ AreaMoveData.HitAreaBound = pageBound;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void AnnotSelectAreaDraw()
|
|
|
|
+ {
|
|
|
|
+ if (!AllowMultiSelect)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (AreaDrawData.HitPageIndex <0 || PDFViewer==null || Selector==null)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ AreaDrawData.MoveAreaPos = Mouse.GetPosition(PDFViewer);
|
|
|
|
+ Rect moveRect = new Rect(AreaDrawData.HitAreaPos, AreaDrawData.MoveAreaPos);
|
|
|
|
+ moveRect.Intersect(AreaDrawData.HitAreaBound);
|
|
|
|
+ DrawingContext drawDC = Selector.RenderOpen();
|
|
|
|
+ drawDC.DrawRectangle(Selector.DrawBrush, Selector.DrawPen, moveRect);
|
|
|
|
+ drawDC.Close();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void AnnotSelectAreaSelect()
|
|
|
|
+ {
|
|
|
|
+ if (!AllowMultiSelect)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (AreaDrawData.HitPageIndex < 0 || PDFViewer == null || Selector == null)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ PDFViewer.CanHorizontallyScroll = true;
|
|
|
|
+ PDFViewer.CanVerticallyScroll = true;
|
|
|
|
+ PDFViewer.EnableZoom(true);
|
|
|
|
+ Selector.ClearItem();
|
|
|
|
+ Selector.CleanDraw();
|
|
|
|
+ AreaDrawData.HitPageIndex = -1;
|
|
|
|
+ DrawSelect=true;
|
|
|
|
+
|
|
|
|
+ if (PDFViewer.CurrentRenderFrame != null && PDFViewer.CurrentRenderFrame.AnnotDataList != null)
|
|
|
|
+ {
|
|
|
|
+ Rect areaRect = new Rect(AreaDrawData.HitAreaPos, AreaDrawData.MoveAreaPos);
|
|
|
|
+ areaRect.Intersect(AreaDrawData.HitAreaBound);
|
|
|
|
+ foreach (AnnotData checkItem in PDFViewer.CurrentRenderFrame.AnnotDataList)
|
|
|
|
+ {
|
|
|
|
+ if (areaRect.IntersectsWith(checkItem.PaintRect))
|
|
|
|
+ {
|
|
|
|
+ Selector.AddItem(checkItem);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Selector.Draw();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private BaseAnnot AnnotSelectGetAnnot()
|
|
|
|
+ {
|
|
|
|
+ if (PDFViewer != null && Selector != null && Selector.SelectAnnots!=null && Selector.SelectAnnots.Count==1)
|
|
|
|
+ {
|
|
|
|
+ AnnotData annotData = Selector.SelectAnnots[0];
|
|
|
|
+ BaseLayer checkLayer = PDFViewer.GetViewForTag(PDFViewer.GetAnnotViewTag());
|
|
|
|
+ if (checkLayer != null && checkLayer is AnnotLayer)
|
|
|
|
+ {
|
|
|
|
+ AnnotLayer annotLayer= (AnnotLayer)checkLayer;
|
|
|
|
+ return annotLayer.GetAnnotForIndex(annotData.PageIndex,annotData.AnnotIndex);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private int AnnotSelectGetCount()
|
|
|
|
+ {
|
|
|
|
+ if (Selector != null)
|
|
|
|
+ {
|
|
|
|
+ return Selector.GetSelectCount();
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void AnnotSelectAreaHover()
|
|
|
|
+ {
|
|
|
|
+ if (!AllowMultiSelect)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(PDFViewer==null || Selector==null || Selector.GetSelectCount()<2)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Point movePos = Mouse.GetPosition(PDFViewer);
|
|
|
|
+ PointControlType hitPoint= Selector.GetHitControlIndex(movePos);
|
|
|
|
+ Cursor oldCursor = this.Cursor;
|
|
|
|
+ Cursor newCursor = this.Cursor;
|
|
|
|
+
|
|
|
|
+ switch (hitPoint)
|
|
|
|
+ {
|
|
|
|
+ case PointControlType.LeftTop:
|
|
|
|
+ case PointControlType.RightBottom:
|
|
|
|
+ newCursor= Cursors.SizeNWSE;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.LeftMiddle:
|
|
|
|
+ case PointControlType.RightMiddle:
|
|
|
|
+ newCursor= Cursors.SizeWE;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.LeftBottom:
|
|
|
|
+ case PointControlType.RightTop:
|
|
|
|
+ newCursor= Cursors.SizeNESW;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.MiddlBottom:
|
|
|
|
+ case PointControlType.MiddleTop:
|
|
|
|
+ newCursor= Cursors.SizeNS;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.Body:
|
|
|
|
+ newCursor= Cursors.SizeAll;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ newCursor = Cursors.Arrow;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (oldCursor != newCursor)
|
|
|
|
+ {
|
|
|
|
+ PDFViewer.Cursor = newCursor;
|
|
|
|
+ this.Cursor = newCursor;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private bool AnnotSelectAreaHitTest()
|
|
|
|
+ {
|
|
|
|
+ if (!AllowMultiSelect)
|
|
|
|
+ {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (PDFViewer == null || Selector == null || Selector.GetSelectCount() < 2)
|
|
|
|
+ {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Point movePos = Mouse.GetPosition(PDFViewer);
|
|
|
|
+ HitTestResult hitResult = VisualTreeHelper.HitTest(PDFViewer, movePos);
|
|
|
|
+ if (hitResult != null && hitResult.VisualHit is AnnotSelector)
|
|
|
|
+ {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private bool AnnotSelectMoveDraw()
|
|
|
|
+ {
|
|
|
|
+ if (!AllowMultiSelect)
|
|
|
|
+ {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (AreaMoveData.HitPageIndex<0 || PDFViewer == null || Selector == null || Selector.GetSelectCount() < 2)
|
|
|
|
+ {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ if (Mouse.LeftButton != MouseButtonState.Pressed)
|
|
|
|
+ {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Point movePos = Mouse.GetPosition(PDFViewer);
|
|
|
|
+ Point moveOffset = new Point(movePos.X - AreaMoveData.HitAreaPos.X, movePos.Y - AreaMoveData.HitAreaPos.Y);
|
|
|
|
+ PointControlType hitPointType = Selector.GetHitControlIndex(AreaMoveData.HitAreaPos);
|
|
|
|
+
|
|
|
|
+ switch(hitPointType)
|
|
|
|
+ {
|
|
|
|
+ default:
|
|
|
|
+ case PointControlType.None:
|
|
|
|
+ return false;
|
|
|
|
+ case PointControlType.Body:
|
|
|
|
+ AnnotSelectMove();
|
|
|
|
+ return true;
|
|
|
|
+ case PointControlType.LeftTop:
|
|
|
|
+ case PointControlType.LeftMiddle:
|
|
|
|
+ case PointControlType.LeftBottom:
|
|
|
|
+ case PointControlType.MiddlBottom:
|
|
|
|
+ case PointControlType.RightBottom:
|
|
|
|
+ case PointControlType.RightMiddle:
|
|
|
|
+ case PointControlType.RightTop:
|
|
|
|
+ case PointControlType.MiddleTop:
|
|
|
|
+ if(CanResize(hitPointType, moveOffset, Selector.GetOutBoundRect(),AreaMoveData.HitAreaBound))
|
|
|
|
+ {
|
|
|
|
+ AnnotSelectResize(hitPointType, moveOffset, Selector.GetOutBoundRect(), AreaMoveData.HitAreaBound);
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void AnnotSelectMove()
|
|
|
|
+ {
|
|
|
|
+ Point movePos = Mouse.GetPosition(PDFViewer);
|
|
|
|
+ Vector offset = movePos - AreaMoveData.HitAreaPos;
|
|
|
|
+
|
|
|
|
+ Rect boundRect = Selector.GetOutBoundRect();
|
|
|
|
+ Point boundCenter = new Point(boundRect.Left + boundRect.Width / 2, boundRect.Top + boundRect.Height / 2);
|
|
|
|
+ Point moveCenter = new Point(boundCenter.X + offset.X, boundCenter.Y + offset.Y);
|
|
|
|
+
|
|
|
|
+ moveCenter.X = Math.Max(AreaMoveData.HitAreaBound.Left + boundRect.Width / 2, moveCenter.X);
|
|
|
|
+ moveCenter.X = Math.Min(AreaMoveData.HitAreaBound.Right - boundRect.Width / 2, moveCenter.X);
|
|
|
|
+ moveCenter.Y = Math.Max(AreaMoveData.HitAreaBound.Top + boundRect.Height / 2, moveCenter.Y);
|
|
|
|
+ moveCenter.Y = Math.Min(AreaMoveData.HitAreaBound.Bottom - boundRect.Height / 2, moveCenter.Y);
|
|
|
|
+
|
|
|
|
+ Rect moveRect = new Rect(moveCenter.X - boundRect.Width / 2, moveCenter.Y - boundRect.Height / 2, boundRect.Width, boundRect.Height);
|
|
|
|
+ OffsetPos = new Point(moveCenter.X - boundCenter.X, moveCenter.Y - boundCenter.Y);
|
|
|
|
+
|
|
|
|
+ DrawingContext drawDC = Selector.RenderOpen();
|
|
|
|
+ Selector.DrawOutBound(drawDC);
|
|
|
|
+ Selector.DrawIndividual(drawDC);
|
|
|
|
+ Selector.DrawControlPoint(drawDC);
|
|
|
|
+ drawDC.DrawRectangle(Selector.DrawBrush, Selector.DrawPen, moveRect);
|
|
|
|
+ foreach (AnnotData checkItem in Selector.SelectAnnots)
|
|
|
|
+ {
|
|
|
|
+ Rect childRect=new Rect(checkItem.PaintRect.X+OffsetPos.X,checkItem.PaintRect.Y+OffsetPos.Y,checkItem.PaintRect.Width,checkItem.PaintRect.Height);
|
|
|
|
+ drawDC.DrawRectangle(Selector.DrawBrush, Selector.DrawPen, childRect);
|
|
|
|
+ }
|
|
|
|
+ drawDC.Close();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void AnnotSelectResize(PointControlType controlType, Point moveOffset, Rect maxRect, Rect boundRect)
|
|
|
|
+ {
|
|
|
|
+ if (maxRect == Rect.Empty || maxRect.Width == 0 || maxRect.Height == 0)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ double ratioX = maxRect.Width > 0 ? maxRect.Height / maxRect.Width : 1;
|
|
|
|
+ double ratioY = maxRect.Height > 0 ? maxRect.Width / maxRect.Height : 1;
|
|
|
|
+ Point offsetPos = moveOffset;
|
|
|
|
+
|
|
|
|
+ switch (controlType)
|
|
|
|
+ {
|
|
|
|
+ case PointControlType.LeftTop:
|
|
|
|
+ case PointControlType.RightBottom:
|
|
|
|
+ offsetPos = new Point(moveOffset.X, Math.Abs(moveOffset.X) * ratioX * (moveOffset.X < 0 ? -1 : 1));
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.LeftBottom:
|
|
|
|
+ case PointControlType.RightTop:
|
|
|
|
+ offsetPos = new Point(moveOffset.X, Math.Abs(moveOffset.X) * ratioX * (moveOffset.X < 0 ? 1 : -1));
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.LeftMiddle:
|
|
|
|
+ offsetPos = new Point(moveOffset.X, Math.Abs(moveOffset.X) * ratioX * (moveOffset.X < 0 ? 1 : -1));
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.RightMiddle:
|
|
|
|
+ offsetPos = new Point(moveOffset.X, Math.Abs(moveOffset.X) * ratioX * (moveOffset.X < 0 ? -1 : 1));
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.MiddlBottom:
|
|
|
|
+ offsetPos = new Point(Math.Abs(moveOffset.Y) * ratioY * (moveOffset.Y < 0 ? 1 : -1), moveOffset.Y);
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.MiddleTop:
|
|
|
|
+ offsetPos = new Point(Math.Abs(moveOffset.Y) * ratioY * (moveOffset.Y < 0 ? -1 : 1), moveOffset.Y);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ OffsetPos = offsetPos;
|
|
|
|
+ double left = maxRect.Left;
|
|
|
|
+ double top = maxRect.Top;
|
|
|
|
+ double right = maxRect.Right;
|
|
|
|
+ double bottom = maxRect.Bottom;
|
|
|
|
+
|
|
|
|
+ switch (controlType)
|
|
|
|
+ {
|
|
|
|
+ case PointControlType.LeftTop://左上
|
|
|
|
+ left += offsetPos.X;
|
|
|
|
+ top += offsetPos.Y;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.LeftMiddle://左中
|
|
|
|
+ left += offsetPos.X;
|
|
|
|
+ top -= offsetPos.Y / 2;
|
|
|
|
+ bottom += offsetPos.Y / 2;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.LeftBottom://左下
|
|
|
|
+ left += offsetPos.X;
|
|
|
|
+ bottom += offsetPos.Y;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.MiddlBottom://中下
|
|
|
|
+ bottom += offsetPos.Y;
|
|
|
|
+ left += offsetPos.X / 2;
|
|
|
|
+ right -= offsetPos.X / 2;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.RightBottom://右下
|
|
|
|
+ right += offsetPos.X;
|
|
|
|
+ bottom += offsetPos.Y;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.RightMiddle://右中
|
|
|
|
+ right += offsetPos.X;
|
|
|
|
+ top -= offsetPos.Y / 2;
|
|
|
|
+ bottom += offsetPos.Y / 2;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.RightTop://右上
|
|
|
|
+ right += offsetPos.X;
|
|
|
|
+ top += offsetPos.Y;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.MiddleTop://中上
|
|
|
|
+ top += offsetPos.Y;
|
|
|
|
+ left += offsetPos.X / 2;
|
|
|
|
+ right -= offsetPos.X / 2;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Rect newRect = new Rect(new Point(left, top), new Point(right, bottom));
|
|
|
|
+
|
|
|
|
+ DrawingContext drawDC = Selector.RenderOpen();
|
|
|
|
+ Selector.DrawOutBound(drawDC);
|
|
|
|
+ Selector.DrawIndividual(drawDC);
|
|
|
|
+ Selector.DrawControlPoint(drawDC);
|
|
|
|
+ drawDC.DrawRectangle(Selector.DrawBrush, Selector.DrawPen, newRect);
|
|
|
|
+
|
|
|
|
+ foreach (AnnotData checkItem in Selector.SelectAnnots)
|
|
|
|
+ {
|
|
|
|
+ double distanceLeft = checkItem.PaintRect.Left - maxRect.Left;
|
|
|
|
+ double newLeft = newRect.Width * distanceLeft / maxRect.Width + newRect.Left;
|
|
|
|
+ double distanceRight = maxRect.Right - checkItem.PaintRect.Right;
|
|
|
|
+ double newRight = newRect.Right - newRect.Width / maxRect.Width * distanceRight;
|
|
|
|
+ double distanceTop = checkItem.PaintRect.Top - maxRect.Top;
|
|
|
|
+ double newTop = newRect.Height * distanceTop / maxRect.Height + newRect.Top;
|
|
|
|
+ double distanceBottom = maxRect.Bottom - checkItem.PaintRect.Bottom;
|
|
|
|
+ double newBottom = newRect.Bottom - newRect.Height / maxRect.Height * distanceBottom;
|
|
|
|
+
|
|
|
|
+ Rect newClient = new Rect(newLeft, newTop, newRight - newLeft, newBottom - newTop);
|
|
|
|
+
|
|
|
|
+ if (newClient != Rect.Empty && newClient.Width > 0 && newClient.Height > 0)
|
|
|
|
+ {
|
|
|
|
+ drawDC.DrawRectangle(Selector.DrawBrush, Selector.DrawPen, newClient);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ drawDC.Close();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private bool CanResize(PointControlType controlType, Point moveOffset, Rect maxRect, Rect boundRect)
|
|
|
|
+ {
|
|
|
|
+ if (maxRect == Rect.Empty || maxRect.Width == 0 || maxRect.Height == 0)
|
|
|
|
+ {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ double ratioX = maxRect.Width > 0 ? maxRect.Height / maxRect.Width : 1;
|
|
|
|
+ double ratioY = maxRect.Height > 0 ? maxRect.Width / maxRect.Height : 1;
|
|
|
|
+ Point offsetPos = moveOffset;
|
|
|
|
+
|
|
|
|
+ switch (controlType)
|
|
|
|
+ {
|
|
|
|
+ case PointControlType.LeftTop:
|
|
|
|
+ case PointControlType.RightBottom:
|
|
|
|
+ offsetPos = new Point(moveOffset.X, Math.Abs(moveOffset.X) * ratioX * (moveOffset.X < 0 ? -1 : 1));
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.LeftBottom:
|
|
|
|
+ case PointControlType.RightTop:
|
|
|
|
+ offsetPos = new Point(moveOffset.X, Math.Abs(moveOffset.X) * ratioX * (moveOffset.X < 0 ? 1 : -1));
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.LeftMiddle:
|
|
|
|
+ offsetPos = new Point(moveOffset.X, Math.Abs(moveOffset.X) * ratioX * (moveOffset.X < 0 ? 1 : -1));
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.RightMiddle:
|
|
|
|
+ offsetPos = new Point(moveOffset.X, Math.Abs(moveOffset.X) * ratioX * (moveOffset.X < 0 ? -1 : 1));
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.MiddlBottom:
|
|
|
|
+ offsetPos = new Point(Math.Abs(moveOffset.Y) * ratioY * (moveOffset.Y < 0 ? 1 : -1), moveOffset.Y);
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.MiddleTop:
|
|
|
|
+ offsetPos = new Point(Math.Abs(moveOffset.Y) * ratioY * (moveOffset.Y < 0 ? -1 : 1), moveOffset.Y);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ double left = maxRect.Left;
|
|
|
|
+ double top = maxRect.Top;
|
|
|
|
+ double right = maxRect.Right;
|
|
|
|
+ double bottom = maxRect.Bottom;
|
|
|
|
+
|
|
|
|
+ switch (controlType)
|
|
|
|
+ {
|
|
|
|
+ case PointControlType.LeftTop://左上
|
|
|
|
+ left += offsetPos.X;
|
|
|
|
+ top += offsetPos.Y;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.LeftMiddle://左中
|
|
|
|
+ left += offsetPos.X;
|
|
|
|
+ top -= offsetPos.Y / 2;
|
|
|
|
+ bottom += offsetPos.Y / 2;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.LeftBottom://左下
|
|
|
|
+ left += offsetPos.X;
|
|
|
|
+ bottom += offsetPos.Y;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.MiddlBottom://中下
|
|
|
|
+ bottom += offsetPos.Y;
|
|
|
|
+ left += offsetPos.X / 2;
|
|
|
|
+ right -= offsetPos.X / 2;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.RightBottom://右下
|
|
|
|
+ right += offsetPos.X;
|
|
|
|
+ bottom += offsetPos.Y;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.RightMiddle://右中
|
|
|
|
+ right += offsetPos.X;
|
|
|
|
+ top -= offsetPos.Y / 2;
|
|
|
|
+ bottom += offsetPos.Y / 2;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.RightTop://右上
|
|
|
|
+ right += offsetPos.X;
|
|
|
|
+ top += offsetPos.Y;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.MiddleTop://中上
|
|
|
|
+ top += offsetPos.Y;
|
|
|
|
+ left += offsetPos.X / 2;
|
|
|
|
+ right -= offsetPos.X / 2;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Rect newRect = new Rect(new Point(left, top), new Point(right, bottom));
|
|
|
|
+
|
|
|
|
+ if (newRect.Left < boundRect.Left || newRect.Top < boundRect.Top || newRect.Bottom > boundRect.Bottom || newRect.Right > boundRect.Right)
|
|
|
|
+ {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void AnnotSelectSave()
|
|
|
|
+ {
|
|
|
|
+ if (!AllowMultiSelect)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (AreaMoveData.HitPageIndex < 0 || PDFViewer == null || Selector == null || Selector.GetSelectCount() < 2)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (!IsMoved)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ PointControlType hitPointType = Selector.GetHitControlIndex(AreaMoveData.HitAreaPos);
|
|
|
|
+
|
|
|
|
+ switch (hitPointType)
|
|
|
|
+ {
|
|
|
|
+ default:
|
|
|
|
+ case PointControlType.None:
|
|
|
|
+ return;
|
|
|
|
+ case PointControlType.Body:
|
|
|
|
+ AnnotSelectMoveSave();
|
|
|
|
+ PDFViewer?.UpdateRenderFrame();
|
|
|
|
+ return;
|
|
|
|
+ case PointControlType.LeftTop:
|
|
|
|
+ case PointControlType.LeftMiddle:
|
|
|
|
+ case PointControlType.LeftBottom:
|
|
|
|
+ case PointControlType.MiddlBottom:
|
|
|
|
+ case PointControlType.RightBottom:
|
|
|
|
+ case PointControlType.RightMiddle:
|
|
|
|
+ case PointControlType.RightTop:
|
|
|
|
+ case PointControlType.MiddleTop:
|
|
|
|
+ AnnotSelectResizeSave(hitPointType, OffsetPos,Selector.GetOutBoundRect(), AreaMoveData.HitAreaBound);
|
|
|
|
+ PDFViewer?.UpdateRenderFrame();
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void AnnotSelectMoveSave()
|
|
|
|
+ {
|
|
|
|
+ foreach (AnnotData checkItem in Selector.SelectAnnots)
|
|
|
|
+ {
|
|
|
|
+ if(checkItem.Annot==null || checkItem.Annot.IsValid()==false)
|
|
|
|
+ {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ Rect childRect = new Rect(checkItem.PaintRect.X + OffsetPos.X, checkItem.PaintRect.Y + OffsetPos.Y, checkItem.PaintRect.Width, checkItem.PaintRect.Height);
|
|
|
|
+ Rect saveRect = new Rect(
|
|
|
|
+ childRect.Left - checkItem.PaintOffset.Left + checkItem.CropLeft * checkItem.CurrentZoom,
|
|
|
|
+ childRect.Top - checkItem.PaintOffset.Top + checkItem.CropTop * checkItem.CurrentZoom,
|
|
|
|
+ childRect.Width,
|
|
|
|
+ childRect.Height);
|
|
|
|
+
|
|
|
|
+ Rect noZoomRect=new Rect(
|
|
|
|
+ saveRect.Left/checkItem.CurrentZoom,
|
|
|
|
+ saveRect.Top/checkItem.CurrentZoom,
|
|
|
|
+ saveRect.Width/checkItem.CurrentZoom,
|
|
|
|
+ saveRect.Height/checkItem.CurrentZoom);
|
|
|
|
+ Rect rawRect= DpiHelper.StandardRectToPDFRect(noZoomRect);
|
|
|
|
+
|
|
|
|
+ checkItem.Annot.SetRect(new CRect((float)rawRect.Left, (float)rawRect.Bottom, (float)rawRect.Right, (float)rawRect.Top));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void AnnotSelectResizeSave(PointControlType controlType, Point offsetPos, Rect maxRect, Rect boundRect)
|
|
|
|
+ {
|
|
|
|
+ double left = maxRect.Left;
|
|
|
|
+ double top = maxRect.Top;
|
|
|
|
+ double right = maxRect.Right;
|
|
|
|
+ double bottom = maxRect.Bottom;
|
|
|
|
+
|
|
|
|
+ switch (controlType)
|
|
|
|
+ {
|
|
|
|
+ case PointControlType.LeftTop://左上
|
|
|
|
+ left += offsetPos.X;
|
|
|
|
+ top += offsetPos.Y;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.LeftMiddle://左中
|
|
|
|
+ left += offsetPos.X;
|
|
|
|
+ top -= offsetPos.Y / 2;
|
|
|
|
+ bottom += offsetPos.Y / 2;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.LeftBottom://左下
|
|
|
|
+ left += offsetPos.X;
|
|
|
|
+ bottom += offsetPos.Y;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.MiddlBottom://中下
|
|
|
|
+ bottom += offsetPos.Y;
|
|
|
|
+ left += offsetPos.X / 2;
|
|
|
|
+ right -= offsetPos.X / 2;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.RightBottom://右下
|
|
|
|
+ right += offsetPos.X;
|
|
|
|
+ bottom += offsetPos.Y;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.RightMiddle://右中
|
|
|
|
+ right += offsetPos.X;
|
|
|
|
+ top -= offsetPos.Y / 2;
|
|
|
|
+ bottom += offsetPos.Y / 2;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.RightTop://右上
|
|
|
|
+ right += offsetPos.X;
|
|
|
|
+ top += offsetPos.Y;
|
|
|
|
+ break;
|
|
|
|
+ case PointControlType.MiddleTop://中上
|
|
|
|
+ top += offsetPos.Y;
|
|
|
|
+ left += offsetPos.X / 2;
|
|
|
|
+ right -= offsetPos.X / 2;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Rect newRect = new Rect(new Point(left, top), new Point(right, bottom));
|
|
|
|
+
|
|
|
|
+ foreach (AnnotData checkItem in Selector.SelectAnnots)
|
|
|
|
+ {
|
|
|
|
+ if (checkItem.Annot == null || checkItem.Annot.IsValid() == false)
|
|
|
|
+ {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ double distanceLeft = checkItem.PaintRect.Left - maxRect.Left;
|
|
|
|
+ double newLeft = newRect.Width * distanceLeft / maxRect.Width + newRect.Left;
|
|
|
|
+ double distanceRight = maxRect.Right - checkItem.PaintRect.Right;
|
|
|
|
+ double newRight = newRect.Right - newRect.Width / maxRect.Width * distanceRight;
|
|
|
|
+ double distanceTop = checkItem.PaintRect.Top - maxRect.Top;
|
|
|
|
+ double newTop = newRect.Height * distanceTop / maxRect.Height + newRect.Top;
|
|
|
|
+ double distanceBottom = maxRect.Bottom - checkItem.PaintRect.Bottom;
|
|
|
|
+ double newBottom = newRect.Bottom - newRect.Height / maxRect.Height * distanceBottom;
|
|
|
|
+
|
|
|
|
+ Rect newClient = new Rect(newLeft, newTop, newRight - newLeft, newBottom - newTop);
|
|
|
|
+
|
|
|
|
+ if (newClient != Rect.Empty && newClient.Width > 0 && newClient.Height > 0)
|
|
|
|
+ {
|
|
|
|
+ Rect saveRect = new Rect(
|
|
|
|
+ newClient.Left - checkItem.PaintOffset.Left + checkItem.CropLeft * checkItem.CurrentZoom,
|
|
|
|
+ newClient.Top - checkItem.PaintOffset.Top + checkItem.CropTop * checkItem.CurrentZoom,
|
|
|
|
+ newClient.Width,
|
|
|
|
+ newClient.Height);
|
|
|
|
+
|
|
|
|
+ Rect noZoomRect = new Rect(
|
|
|
|
+ saveRect.Left / checkItem.CurrentZoom,
|
|
|
|
+ saveRect.Top / checkItem.CurrentZoom,
|
|
|
|
+ saveRect.Width / checkItem.CurrentZoom,
|
|
|
|
+ saveRect.Height / checkItem.CurrentZoom);
|
|
|
|
+ Rect rawRect = DpiHelper.StandardRectToPDFRect(noZoomRect);
|
|
|
|
+
|
|
|
|
+ checkItem.Annot.SetRect(new CRect((float)rawRect.Left, (float)rawRect.Bottom, (float)rawRect.Right, (float)rawRect.Top));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|