AnnotEdit.cs 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029
  1. using ComPDFKit.Import;
  2. using ComPDFKit.Measure;
  3. using ComPDFKit.PDFAnnotation;
  4. using ComPDFKit.Tool.SettingParam;
  5. using ComPDFKit.Viewer.Helper;
  6. using ComPDFKitViewer;
  7. using ComPDFKitViewer.Annot;
  8. using ComPDFKitViewer.Helper;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Diagnostics;
  12. using System.Linq;
  13. using System.Net;
  14. using System.Windows;
  15. using System.Windows.Controls;
  16. using System.Windows.Input;
  17. using System.Windows.Media;
  18. using System.Windows.Media.TextFormatting;
  19. using static ComPDFKit.Tool.Help.ImportWin32;
  20. namespace ComPDFKit.Tool.DrawTool
  21. {
  22. internal class AnnotEdit : DrawingVisual
  23. {
  24. #region public Attributes
  25. /// <summary>
  26. /// Data changing event
  27. /// </summary>
  28. public event EventHandler<SelectedAnnotData> DataChanging;
  29. /// <summary>
  30. /// Data changed event
  31. /// </summary>
  32. public event EventHandler<SelectedAnnotData> DataChanged;
  33. #endregion
  34. #region private Attributes
  35. protected DefaultDrawParam drawParam = new DefaultDrawParam();
  36. /// <summary>
  37. /// Max drawing range
  38. /// </summary>
  39. protected Rect maxRect { get; set; } = new Rect(0, 0, 0, 0);
  40. /// <summary>
  41. /// Is mouse down
  42. /// </summary>
  43. protected bool isMouseDown { get; set; }
  44. protected DrawingContext drawDC { get; set; }
  45. /// <summary>
  46. /// Current annotation's control points collection (96 DPI coordinate points, minus page offset)
  47. /// </summary>
  48. private PointCollection activePoints { get; set; } = new PointCollection();
  49. /// <summary>
  50. /// Current annotation's drawing range box (96 DPI coordinate points, minus page offset)
  51. /// </summary>
  52. private Rect activeRect { get; set; } = new Rect();
  53. private int hitIndex = -1;
  54. protected AnnotData annotData { get; set; }
  55. /// <summary>
  56. /// Position information recorded when the mouse is pressed
  57. /// </summary>
  58. protected Point mouseDownPoint { get; set; }
  59. /// <summary>
  60. /// Mouse last draw position information
  61. /// </summary>
  62. protected Point mouseEndDrawPoint { get; set; }
  63. /// <summary>
  64. /// Move offset during movement
  65. /// </summary>
  66. protected Point moveOffset { get; set; } = new Point(0, 0);
  67. private Point LineMeasureOffset { get; set; }= new Point(0, 0);
  68. /// <summary>
  69. /// Point size
  70. /// </summary>
  71. protected int pointSize { get; set; } = 6;
  72. protected SelectedAnnotData annotEditData = new SelectedAnnotData();
  73. //Measure
  74. private PointCollection leftLine { get; set; } = new PointCollection();
  75. private PointCollection rightLine { get; set; } = new PointCollection();
  76. private PointCollection crossLine { get; set; } = new PointCollection();
  77. private Point[] moveLeftLine;
  78. private Point[] moveRightLine;
  79. private Point[] moveCrossLine;
  80. #endregion
  81. /// <summary>
  82. /// Re-locate child elements
  83. /// </summary>
  84. public void Arrange()
  85. {
  86. foreach (Visual child in Children)
  87. {
  88. if (!(child is UIElement))
  89. {
  90. continue;
  91. }
  92. UIElement checkChild = child as UIElement;
  93. try
  94. {
  95. double left = Canvas.GetLeft(checkChild);
  96. double top = Canvas.GetTop(checkChild);
  97. double width = (double)checkChild.GetValue(FrameworkElement.WidthProperty);
  98. double height = (double)checkChild.GetValue(FrameworkElement.HeightProperty);
  99. checkChild.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
  100. checkChild.Arrange(new Rect(
  101. double.IsNaN(left) ? 0 : left,
  102. double.IsNaN(top) ? 0 : top,
  103. double.IsNaN(width) ? checkChild.DesiredSize.Width : width,
  104. double.IsNaN(height) ? checkChild.DesiredSize.Height : height));
  105. }
  106. catch (Exception ex)
  107. {
  108. }
  109. }
  110. }
  111. public AnnotEdit(DefaultDrawParam defaultDrawParam) : base()
  112. {
  113. drawParam = defaultDrawParam;
  114. }
  115. public bool SetAnnotObject(AnnotData Data)
  116. {
  117. activePoints.Clear();
  118. if (Data == null)
  119. {
  120. return false;
  121. }
  122. annotData = Data;
  123. annotEditData = new SelectedAnnotData();
  124. annotEditData.annotData = annotData;
  125. SetMaxRect(annotData.PaintOffset);
  126. switch (annotData.Annot.Type)
  127. {
  128. case C_ANNOTATION_TYPE.C_ANNOTATION_NONE:
  129. break;
  130. case C_ANNOTATION_TYPE.C_ANNOTATION_UNKOWN:
  131. break;
  132. case C_ANNOTATION_TYPE.C_ANNOTATION_TEXT:
  133. break;
  134. case C_ANNOTATION_TYPE.C_ANNOTATION_LINK:
  135. break;
  136. case C_ANNOTATION_TYPE.C_ANNOTATION_FREETEXT:
  137. break;
  138. case C_ANNOTATION_TYPE.C_ANNOTATION_LINE:
  139. List<Point> sortPointList= new List<Point>();
  140. for (int i = 0; i < (annotData.Annot as CPDFLineAnnotation).Points.Length; i++)
  141. {
  142. Point point = DpiHelper.PDFPointToStandardPoint(new Point((annotData.Annot as CPDFLineAnnotation).Points[i].x, (annotData.Annot as CPDFLineAnnotation).Points[i].y));
  143. point = new Point(
  144. point.X * annotData.CurrentZoom + annotData.PaintOffset.X - annotData.CropLeft * annotData.CurrentZoom,
  145. point.Y * annotData.CurrentZoom + annotData.PaintOffset.Y - annotData.CropTop * annotData.CurrentZoom
  146. );
  147. sortPointList.Add(point);
  148. }
  149. sortPointList.Sort((a, b) => { if (a.X > b.X) return 1; else return 0; });
  150. foreach (Point checkPoint in sortPointList)
  151. {
  152. activePoints.Add(checkPoint);
  153. }
  154. if ((annotData.Annot as CPDFLineAnnotation).IsMeasured())
  155. {
  156. CRect rawRect = annotData.Annot.GetRect();
  157. Rect rect = DataConversionForWPF.CRectConversionForRect(rawRect);
  158. rect = DpiHelper.PDFRectToStandardRect(rect);
  159. activeRect = new Rect(
  160. rect.X * annotData.CurrentZoom + annotData.PaintOffset.X - annotData.CropLeft * annotData.CurrentZoom,
  161. rect.Y * annotData.CurrentZoom + annotData.PaintOffset.Y - annotData.CropTop * annotData.CurrentZoom,
  162. rect.Width * annotData.CurrentZoom,
  163. rect.Height * annotData.CurrentZoom
  164. );
  165. CalcMeasurePoints(annotData.Annot as CPDFLineAnnotation);
  166. }
  167. break;
  168. case C_ANNOTATION_TYPE.C_ANNOTATION_SQUARE:
  169. break;
  170. case C_ANNOTATION_TYPE.C_ANNOTATION_CIRCLE:
  171. break;
  172. case C_ANNOTATION_TYPE.C_ANNOTATION_POLYGON:
  173. for (int i = 0; i < (annotData.Annot as CPDFPolygonAnnotation).Points.Count; i++)
  174. {
  175. Point point = DpiHelper.PDFPointToStandardPoint(new Point((annotData.Annot as CPDFPolygonAnnotation).Points[i].x, (annotData.Annot as CPDFPolygonAnnotation).Points[i].y));
  176. point = new Point(
  177. point.X * annotData.CurrentZoom + annotData.PaintOffset.X - annotData.CropLeft * annotData.CurrentZoom,
  178. point.Y * annotData.CurrentZoom + annotData.PaintOffset.Y - annotData.CropTop * annotData.CurrentZoom
  179. );
  180. activePoints.Add(point);
  181. }
  182. if ((annotData.Annot as CPDFPolygonAnnotation).IsMeasured())
  183. {
  184. CRect rawRect = annotData.Annot.GetRect();
  185. Rect rect = DataConversionForWPF.CRectConversionForRect(rawRect);
  186. rect = DpiHelper.PDFRectToStandardRect(rect);
  187. activeRect = new Rect(
  188. rect.X * annotData.CurrentZoom + annotData.PaintOffset.X - annotData.CropLeft * annotData.CurrentZoom,
  189. rect.Y * annotData.CurrentZoom + annotData.PaintOffset.Y - annotData.CropTop * annotData.CurrentZoom,
  190. rect.Width * annotData.CurrentZoom,
  191. rect.Height * annotData.CurrentZoom
  192. );
  193. }
  194. break;
  195. case C_ANNOTATION_TYPE.C_ANNOTATION_POLYLINE:
  196. for (int i = 0; i < (annotData.Annot as CPDFPolylineAnnotation).Points.Count; i++)
  197. {
  198. Point point = DpiHelper.PDFPointToStandardPoint(new Point((annotData.Annot as CPDFPolylineAnnotation).Points[i].x, (annotData.Annot as CPDFPolylineAnnotation).Points[i].y));
  199. point = new Point(
  200. point.X * annotData.CurrentZoom + annotData.PaintOffset.X - annotData.CropLeft * annotData.CurrentZoom,
  201. point.Y * annotData.CurrentZoom + annotData.PaintOffset.Y - annotData.CropTop * annotData.CurrentZoom
  202. );
  203. activePoints.Add(point);
  204. }
  205. if ((annotData.Annot as CPDFPolylineAnnotation).IsMeasured())
  206. {
  207. CRect rawRect = annotData.Annot.GetRect();
  208. Rect rect = DataConversionForWPF.CRectConversionForRect(rawRect);
  209. rect = DpiHelper.PDFRectToStandardRect(rect);
  210. activeRect = new Rect(
  211. rect.X * annotData.CurrentZoom + annotData.PaintOffset.X - annotData.CropLeft * annotData.CurrentZoom,
  212. rect.Y * annotData.CurrentZoom + annotData.PaintOffset.Y - annotData.CropTop * annotData.CurrentZoom,
  213. rect.Width * annotData.CurrentZoom,
  214. rect.Height * annotData.CurrentZoom
  215. );
  216. }
  217. break;
  218. case C_ANNOTATION_TYPE.C_ANNOTATION_HIGHLIGHT:
  219. break;
  220. case C_ANNOTATION_TYPE.C_ANNOTATION_UNDERLINE:
  221. break;
  222. case C_ANNOTATION_TYPE.C_ANNOTATION_SQUIGGLY:
  223. break;
  224. case C_ANNOTATION_TYPE.C_ANNOTATION_STRIKEOUT:
  225. break;
  226. case C_ANNOTATION_TYPE.C_ANNOTATION_STAMP:
  227. break;
  228. case C_ANNOTATION_TYPE.C_ANNOTATION_CARET:
  229. break;
  230. case C_ANNOTATION_TYPE.C_ANNOTATION_INK:
  231. break;
  232. case C_ANNOTATION_TYPE.C_ANNOTATION_POPUP:
  233. break;
  234. case C_ANNOTATION_TYPE.C_ANNOTATION_FILEATTACHMENT:
  235. break;
  236. case C_ANNOTATION_TYPE.C_ANNOTATION_SOUND:
  237. break;
  238. case C_ANNOTATION_TYPE.C_ANNOTATION_MOVIE:
  239. break;
  240. case C_ANNOTATION_TYPE.C_ANNOTATION_WIDGET:
  241. break;
  242. case C_ANNOTATION_TYPE.C_ANNOTATION_SCREEN:
  243. break;
  244. case C_ANNOTATION_TYPE.C_ANNOTATION_PRINTERMARK:
  245. break;
  246. case C_ANNOTATION_TYPE.C_ANNOTATION_TRAPNET:
  247. break;
  248. case C_ANNOTATION_TYPE.C_ANNOTATION_WATERMARK:
  249. break;
  250. case C_ANNOTATION_TYPE.C_ANNOTATION_3D:
  251. break;
  252. case C_ANNOTATION_TYPE.C_ANNOTATION_RICHMEDIA:
  253. break;
  254. case C_ANNOTATION_TYPE.C_ANNOTATION_REDACT:
  255. break;
  256. case C_ANNOTATION_TYPE.C_ANNOTATION_INTERCHANGE:
  257. break;
  258. default:
  259. break;
  260. }
  261. return true;
  262. }
  263. public void SetMaxRect(Rect rect)
  264. {
  265. maxRect = rect;
  266. }
  267. public int GetHitIndex(Point point)
  268. {
  269. for (int i = 0; i < activePoints.Count; i++)
  270. {
  271. Vector checkVector = activePoints[i] - point;
  272. if (checkVector.Length < pointSize)
  273. {
  274. return i;
  275. }
  276. }
  277. return -1;
  278. }
  279. /// <summary>
  280. /// Calculate the control points of the measurement annotation
  281. /// </summary>
  282. /// <param name="Annot">
  283. /// Measurement annotation object
  284. /// </param>
  285. private void CalcMeasurePoints(CPDFLineAnnotation Annot)
  286. {
  287. leftLine.Clear();
  288. crossLine.Clear();
  289. rightLine.Clear();
  290. CPDFDistanceMeasure LineMeasure = Annot.GetDistanceMeasure();
  291. double LeadLength = LineMeasure.GetLeadLength() / 72D * 96D;
  292. double LeadOffset = LineMeasure.GetLeadOffset() / 72D * 96D;
  293. double LeadExtension = LineMeasure.GetLeadExtension() / 72D * 96D;
  294. List<Point> orderPoints = activePoints.AsEnumerable().OrderBy(x => x.X).ToList();
  295. Vector lineVector = (activePoints[1] - activePoints[0]) * annotData.CurrentZoom;
  296. lineVector.Normalize();
  297. Vector leadEndVector = lineVector * (Math.Abs(LeadLength) + Math.Abs(LeadOffset) + Math.Abs(LeadExtension) * annotData.CurrentZoom);
  298. Vector leadStartVector = lineVector * (Math.Abs(LeadOffset)) * annotData.CurrentZoom;
  299. Vector leadCrossVector = lineVector * (Math.Abs(LeadLength) * annotData.CurrentZoom + Math.Abs(LeadOffset));
  300. Matrix rotateMatrix = new Matrix();
  301. double angle = LeadLength < 0 ? 90 : -90;
  302. rotateMatrix.Rotate(angle);
  303. Point leftEndPoint = rotateMatrix.Transform(leadEndVector) + activePoints[0];
  304. Point leftStartPoint = rotateMatrix.Transform(leadStartVector) + activePoints[0];
  305. Point leftCrossPoint = rotateMatrix.Transform(leadCrossVector) + activePoints[0];
  306. leftLine.Add(leftStartPoint);
  307. leftLine.Add(leftEndPoint);
  308. crossLine.Add(leftCrossPoint);
  309. lineVector = activePoints[1] - activePoints[0];
  310. rightLine.Add(leftStartPoint + lineVector);
  311. rightLine.Add(leftEndPoint + lineVector);
  312. crossLine.Add(leftCrossPoint + lineVector);
  313. activePoints.Insert(1, new Point(
  314. (crossLine[0].X + crossLine[1].X) / 2,
  315. (crossLine[0].Y + crossLine[1].Y) / 2
  316. ));
  317. }
  318. #region Event
  319. public virtual void OnMouseLeftButtonDown(Point downPoint)
  320. {
  321. isMouseDown = true;
  322. hitIndex = -1;
  323. mouseDownPoint = downPoint;
  324. moveOffset = new Point(0, 0);
  325. LineMeasureOffset=new Point(0, 0);
  326. HitTestResult hitResult = VisualTreeHelper.HitTest(this, downPoint);
  327. if (hitResult != null && hitResult.VisualHit is DrawingVisual)
  328. {
  329. hitIndex = GetHitIndex(downPoint);
  330. }
  331. }
  332. public virtual void OnMouseMove(Point mousePoint, out bool Tag)
  333. {
  334. Tag = false;
  335. if (Mouse.LeftButton==MouseButtonState.Pressed)
  336. {
  337. Tag = isMouseDown;
  338. mouseEndDrawPoint = mousePoint;
  339. Point newOffset = new Point(
  340. mouseEndDrawPoint.X - mouseDownPoint.X,
  341. mouseEndDrawPoint.Y - mouseDownPoint.Y
  342. );
  343. Point movePoint = CheckMoveOffSet(activePoints.ToList(), maxRect, newOffset);
  344. LineMeasureOffset=newOffset;
  345. if(movePoint.X==0)
  346. {
  347. newOffset.X=moveOffset.X;
  348. }
  349. if(movePoint.Y==0)
  350. {
  351. newOffset.Y=moveOffset.Y;
  352. }
  353. moveOffset = newOffset;
  354. Draw();
  355. InvokeDataChangEvent(false);
  356. }
  357. }
  358. public virtual void OnMouseLeftButtonUp(Point upPoint)
  359. {
  360. isMouseDown = false;
  361. Draw();
  362. if (annotData!=null&&annotData.AnnotType == C_ANNOTATION_TYPE.C_ANNOTATION_LINE)
  363. {
  364. if ((annotData.Annot as CPDFLineAnnotation).IsMeasured())
  365. {
  366. activePoints.Clear();
  367. if (moveLeftLine == null)
  368. {
  369. moveLeftLine = leftLine.ToArray();
  370. }
  371. if (moveRightLine == null)
  372. {
  373. moveRightLine = rightLine.ToArray();
  374. }
  375. if (moveCrossLine == null)
  376. {
  377. moveCrossLine = crossLine.ToArray();
  378. }
  379. activePoints.Add(moveLeftLine[0]);
  380. activePoints.Add(moveLeftLine[1]);
  381. activePoints.Add(moveRightLine[0]);
  382. activePoints.Add(moveRightLine[1]);
  383. activePoints.Add(moveCrossLine[0]);
  384. activePoints.Add(moveCrossLine[1]);
  385. }
  386. }
  387. moveLeftLine = null;
  388. moveRightLine = null;
  389. moveCrossLine = null;
  390. if (moveOffset!= new Point(0, 0))
  391. {
  392. InvokeDataChangEvent(true);
  393. }
  394. moveOffset = new Point(0, 0);
  395. mouseDownPoint = new Point();
  396. mouseEndDrawPoint = new Point();
  397. hitIndex = -1;
  398. }
  399. /// <summary>
  400. /// Used to notify events during/after drawing data
  401. /// </summary>
  402. /// <param name="isFinish">
  403. /// Is the data change complete
  404. /// </param>
  405. protected void InvokeDataChangEvent(bool isFinish)
  406. {
  407. PointCollection ActivePoints1 = new PointCollection();
  408. for (int i = 0; i < activePoints.Count; i++)
  409. {
  410. Point currentPoint = activePoints[i];
  411. if (hitIndex == -1)
  412. {
  413. if (annotData.AnnotType == C_ANNOTATION_TYPE.C_ANNOTATION_LINE)
  414. {
  415. if (!(annotData.Annot as CPDFLineAnnotation).IsMeasured())
  416. {
  417. currentPoint.X += moveOffset.X;
  418. currentPoint.Y += moveOffset.Y;
  419. }
  420. }
  421. else
  422. {
  423. currentPoint.X += moveOffset.X;
  424. currentPoint.Y += moveOffset.Y;
  425. }
  426. }
  427. ActivePoints1.Add(currentPoint);
  428. }
  429. annotEditData.Points = ActivePoints1;
  430. if (isFinish)
  431. {
  432. DataChanged?.Invoke(this, annotEditData);
  433. }
  434. else
  435. {
  436. DataChanging?.Invoke(this, annotEditData);
  437. }
  438. }
  439. #endregion
  440. #region Draw
  441. public void Draw()
  442. {
  443. Dispatcher.Invoke(() =>
  444. {
  445. if (annotData == null)
  446. {
  447. return;
  448. }
  449. drawDC = RenderOpen();
  450. switch (annotData.Annot.Type)
  451. {
  452. case C_ANNOTATION_TYPE.C_ANNOTATION_LINE:
  453. {
  454. if ((annotData.Annot as CPDFLineAnnotation).IsMeasured())
  455. {
  456. DrawLineMeasure(drawDC);
  457. }
  458. else
  459. {
  460. DrawLine(drawDC);
  461. }
  462. }
  463. break;
  464. case C_ANNOTATION_TYPE.C_ANNOTATION_POLYLINE:
  465. DrawPolyLineMeasure(drawDC);
  466. break;
  467. case C_ANNOTATION_TYPE.C_ANNOTATION_POLYGON:
  468. DrawPolygonMeasure(drawDC);
  469. break;
  470. default:
  471. break;
  472. }
  473. drawDC?.Close();
  474. drawDC = null;
  475. });
  476. }
  477. private Point CheckPointBound(Point checkPoint,Rect bound)
  478. {
  479. if (checkPoint.X < bound.Left)
  480. {
  481. checkPoint.X = bound.Left;
  482. }
  483. if (checkPoint.X > bound.Right)
  484. {
  485. checkPoint.X = bound.Right;
  486. }
  487. if (checkPoint.Y < bound.Top)
  488. {
  489. checkPoint.Y = bound.Top;
  490. }
  491. if (checkPoint.Y > bound.Bottom)
  492. {
  493. checkPoint.Y = bound.Bottom;
  494. }
  495. return checkPoint;
  496. }
  497. private Point CheckMoveOffSet(List<Point> checkPoints, Rect bound, Point moveOffset)
  498. {
  499. double left = 0;
  500. double top = 0;
  501. double right = 0;
  502. double bottom = 0;
  503. if (checkPoints != null && checkPoints.Count > 0)
  504. {
  505. left = checkPoints.AsEnumerable().Select(p => p.X).Min();
  506. right = checkPoints.AsEnumerable().Select(p => p.X).Max();
  507. top = checkPoints.AsEnumerable().Select(p => p.Y).Min();
  508. bottom = checkPoints.AsEnumerable().Select(p => p.Y).Max();
  509. }
  510. Point movePoint = moveOffset;
  511. if(left+moveOffset.X<bound.Left || right+moveOffset.X>bound.Right)
  512. {
  513. movePoint.X = 0;
  514. }
  515. if (top + moveOffset.Y < bound.Top || bottom + moveOffset.Y > bound.Bottom)
  516. {
  517. movePoint.Y = 0;
  518. }
  519. return movePoint;
  520. }
  521. private void DrawLine(DrawingContext drawingContext)
  522. {
  523. PathGeometry drawPath = new PathGeometry();
  524. PathFigure drawFigure = new PathFigure();
  525. PolyLineSegment polySegment = new PolyLineSegment();
  526. if (hitIndex != -1 && hitIndex < activePoints.Count)
  527. {
  528. if (mouseEndDrawPoint!=new Point() && !activePoints.Contains(mouseEndDrawPoint))
  529. {
  530. activePoints[hitIndex] = CheckPointBound(mouseEndDrawPoint, maxRect);
  531. }
  532. }
  533. Point StartPoint = activePoints[0];
  534. if (hitIndex == -1)
  535. {
  536. StartPoint.X += moveOffset.X;
  537. StartPoint.Y += moveOffset.Y;
  538. }
  539. drawFigure.StartPoint = StartPoint;
  540. for (int i = 1; i < activePoints.Count; i++)
  541. {
  542. Point currentPoint = activePoints[i];
  543. if (hitIndex == -1)
  544. {
  545. currentPoint.X += moveOffset.X;
  546. currentPoint.Y += moveOffset.Y;
  547. }
  548. polySegment.Points.Add(currentPoint);
  549. }
  550. if (polySegment.Points.Count > 0)
  551. {
  552. drawFigure.Segments.Add(polySegment);
  553. }
  554. if (drawFigure.Segments.Count > 0)
  555. {
  556. drawPath.Figures.Add(drawFigure);
  557. }
  558. foreach (Point controlPoint in activePoints)
  559. {
  560. Point drawPoint = new Point(
  561. controlPoint.X,
  562. controlPoint.Y);
  563. if (hitIndex == -1)
  564. {
  565. drawPoint.X += moveOffset.X;
  566. drawPoint.Y += moveOffset.Y;
  567. }
  568. drawingContext?.DrawEllipse(drawParam.EditControlLineBrush, drawParam.EditControlLinePen, (drawPoint), pointSize, pointSize);
  569. }
  570. if (isMouseDown)
  571. {
  572. drawingContext?.DrawGeometry(null, drawParam.EditLinePen, drawPath);
  573. }
  574. }
  575. private Point CalcRotateBound(Point rawPoint, Point moveOffset)
  576. {
  577. Point newPoint = rawPoint;
  578. Rect checkRect = annotData.PaintOffset;
  579. newPoint.X += moveOffset.X;
  580. newPoint.Y += moveOffset.Y;
  581. newPoint.X = Math.Max(checkRect.Left, newPoint.X);
  582. newPoint.X = Math.Min(checkRect.Right, newPoint.X);
  583. newPoint.Y = Math.Max(checkRect.Top, newPoint.Y);
  584. newPoint.Y = Math.Min(checkRect.Bottom, newPoint.Y);
  585. return newPoint;
  586. }
  587. private void DrawLineMeasure(DrawingContext drawDC)
  588. {
  589. foreach (Point controlPoint in activePoints)
  590. {
  591. Point drawPoint = new Point(controlPoint.X,controlPoint.Y);
  592. if (hitIndex == -1)
  593. {
  594. drawPoint.X += moveOffset.X;
  595. drawPoint.Y += moveOffset.Y;
  596. }
  597. drawDC?.DrawEllipse(drawParam.EditControlLineBrush, drawParam.EditControlLinePen, (drawPoint), pointSize, pointSize);
  598. }
  599. Rect drawRect = activeRect;
  600. drawRect.X += moveOffset.X;
  601. drawRect.Y += moveOffset.Y;
  602. if (isMouseDown)
  603. {
  604. PointCollection drawLeftPoints = new PointCollection();
  605. PointCollection drawRightPoints = new PointCollection();
  606. PointCollection drawCrossPoints = new PointCollection();
  607. moveLeftLine = leftLine.ToArray();
  608. moveRightLine = rightLine.ToArray();
  609. moveCrossLine = crossLine.ToArray();
  610. foreach(Point checkPoint in moveLeftLine)
  611. {
  612. drawLeftPoints.Add(checkPoint);
  613. }
  614. foreach (Point checkPoint in moveRightLine)
  615. {
  616. drawRightPoints.Add(checkPoint);
  617. }
  618. foreach (Point checkPoint in moveCrossLine)
  619. {
  620. drawCrossPoints.Add(checkPoint);
  621. }
  622. switch (hitIndex)
  623. {
  624. case 0:
  625. {
  626. moveLeftLine[0] = CalcRotateBound(drawLeftPoints[0], LineMeasureOffset);
  627. Vector newVector = moveLeftLine[0] - drawRightPoints[0];
  628. Vector leftVector = drawLeftPoints[1] - drawLeftPoints[0];
  629. double angle = drawLeftPoints[0].Y < drawCrossPoints[0].Y ? -90 : 90;
  630. newVector.Normalize();
  631. newVector = newVector * leftVector.Length;
  632. Matrix rotateMatrix = new Matrix();
  633. rotateMatrix.Rotate(angle);
  634. moveRightLine[0] = drawRightPoints[0];
  635. moveLeftLine[1] = moveLeftLine[0] + newVector * rotateMatrix;
  636. moveRightLine[1] = moveRightLine[0] + newVector * rotateMatrix;
  637. moveCrossLine[0] = moveLeftLine[1];
  638. moveCrossLine[1] = moveRightLine[1];
  639. drawDC?.DrawLine(drawParam.EditLinePen, moveLeftLine[0], moveLeftLine[1]);
  640. drawDC?.DrawLine(drawParam.EditLinePen, moveRightLine[0], moveRightLine[1]);
  641. drawDC?.DrawLine(drawParam.EditLinePen, moveLeftLine[1], moveRightLine[1]);
  642. }
  643. break;
  644. case 1:
  645. {
  646. Point centerPoint = new Point((drawCrossPoints[0].X + drawCrossPoints[1].X) / 2,(drawCrossPoints[0].Y + drawCrossPoints[1].Y) / 2);
  647. Point movePoint = CalcRotateBound(centerPoint, LineMeasureOffset);
  648. Vector ruleVector = drawCrossPoints[1] - drawCrossPoints[0];
  649. bool rateMove = true;
  650. if (ruleVector.X == 0)
  651. {
  652. movePoint.Y = centerPoint.Y;
  653. rateMove = false;
  654. }
  655. if (ruleVector.Y == 0)
  656. {
  657. movePoint.X = centerPoint.X;
  658. rateMove = false;
  659. }
  660. if (rateMove)
  661. {
  662. Vector moveVector = movePoint - centerPoint;
  663. double moveLength = moveVector.Length;
  664. double ruleLength = ruleVector.Length;
  665. ruleVector.Normalize();
  666. moveVector.Normalize();
  667. Vector crossVector = new Vector(-ruleVector.Y, ruleVector.X);
  668. crossVector.Normalize();
  669. if (Math.Abs(Vector.AngleBetween(moveVector, crossVector)) > 90)
  670. {
  671. crossVector.Negate();
  672. }
  673. Point saveCenter = crossVector * moveLength + centerPoint;
  674. double halfLenght = ruleLength / 2;
  675. Point SaveRight = ruleVector * halfLenght + saveCenter;
  676. Point saveLeft = saveCenter - ruleVector * halfLenght;
  677. moveCrossLine[0] = saveLeft;
  678. moveCrossLine[1] = SaveRight;
  679. moveLeftLine[1] = saveLeft;
  680. moveRightLine[1] = SaveRight;
  681. moveLeftLine[0] = drawLeftPoints[0];
  682. moveRightLine[0] = drawRightPoints[0];
  683. }
  684. else
  685. {
  686. Point moveOffset = new Point(
  687. movePoint.X - centerPoint.X,
  688. movePoint.Y - centerPoint.Y);
  689. moveCrossLine[0] = new Point(
  690. drawCrossPoints[0].X + moveOffset.X,
  691. drawCrossPoints[0].Y + moveOffset.Y);
  692. moveCrossLine[1] = new Point(
  693. drawCrossPoints[1].X + moveOffset.X,
  694. drawCrossPoints[1].Y + moveOffset.Y);
  695. moveLeftLine[0] = drawLeftPoints[0];
  696. moveRightLine[0] = drawRightPoints[0];
  697. moveLeftLine[1] = new Point(
  698. drawLeftPoints[1].X + moveOffset.X,
  699. drawLeftPoints[1].Y + moveOffset.Y);
  700. moveRightLine[1] = new Point(
  701. drawRightPoints[1].X + moveOffset.X,
  702. drawRightPoints[1].Y + moveOffset.Y);
  703. }
  704. drawDC?.DrawLine(drawParam.EditLinePen, moveCrossLine[0], moveCrossLine[1]);
  705. drawDC?.DrawLine(drawParam.EditLinePen, moveCrossLine[0], moveLeftLine[0]);
  706. drawDC?.DrawLine(drawParam.EditLinePen, moveCrossLine[1], moveRightLine[0]);
  707. }
  708. break;
  709. case 2:
  710. {
  711. moveRightLine[0] = CalcRotateBound(drawRightPoints[0], LineMeasureOffset);
  712. Vector newVector = moveRightLine[0] - drawLeftPoints[0];
  713. Vector rightVector = drawRightPoints[1] - drawRightPoints[0];
  714. double angle = (drawRightPoints[0].Y + drawLeftPoints[0].Y) / 2 > (drawCrossPoints[0].Y + drawCrossPoints[1].Y) / 2 ? -90 : 90;
  715. newVector.Normalize();
  716. newVector = newVector * rightVector.Length;
  717. Matrix rotateMatrix = new Matrix();
  718. rotateMatrix.Rotate(angle);
  719. moveLeftLine[0] = drawLeftPoints[0];
  720. moveLeftLine[1] = moveLeftLine[0] + newVector * rotateMatrix;
  721. moveRightLine[1] = moveRightLine[0] + newVector * rotateMatrix;
  722. moveCrossLine[0] = moveLeftLine[1];
  723. moveCrossLine[1] = moveRightLine[1];
  724. drawDC?.DrawLine(drawParam.EditLinePen, moveLeftLine[0], moveLeftLine[1]);
  725. drawDC?.DrawLine(drawParam.EditLinePen, moveRightLine[0], moveRightLine[1]);
  726. drawDC?.DrawLine(drawParam.EditLinePen, moveLeftLine[1], moveRightLine[1]);
  727. }
  728. break;
  729. case -1:
  730. {
  731. Rect moveRect = new Rect(moveLeftLine[0], moveRightLine[1]);
  732. moveRect.Union(moveLeftLine[1]);
  733. moveRect.Union(moveRightLine[0]);
  734. Point moveOffset = LineMeasureOffset;
  735. Rect pageBound = annotData.PaintOffset;
  736. if (moveRect.Left + LineMeasureOffset.X < pageBound.Left)
  737. {
  738. moveOffset.X = pageBound.Left - moveRect.Left;
  739. }
  740. if (moveRect.Right + moveOffset.X > pageBound.Right)
  741. {
  742. moveOffset.X = pageBound.Right - moveRect.Right;
  743. }
  744. if (moveRect.Top + moveOffset.Y < pageBound.Top)
  745. {
  746. moveOffset.Y = pageBound.Top - moveRect.Top;
  747. }
  748. if (moveRect.Bottom + moveOffset.Y > pageBound.Bottom)
  749. {
  750. moveOffset.X = pageBound.Bottom - moveRect.Bottom;
  751. }
  752. moveLeftLine[0].X = moveLeftLine[0].X + moveOffset.X;
  753. moveLeftLine[0].Y = moveLeftLine[0].Y + moveOffset.Y;
  754. moveLeftLine[1].X = moveLeftLine[1].X + moveOffset.X;
  755. moveLeftLine[1].Y = moveLeftLine[1].Y + moveOffset.Y;
  756. moveRightLine[0].X = moveRightLine[0].X + moveOffset.X;
  757. moveRightLine[0].Y = moveRightLine[0].Y + moveOffset.Y;
  758. moveRightLine[1].X = moveRightLine[1].X + moveOffset.X;
  759. moveRightLine[1].Y = moveRightLine[1].Y + moveOffset.Y;
  760. moveCrossLine[0].X = moveCrossLine[0].X + moveOffset.X;
  761. moveCrossLine[0].Y = moveCrossLine[0].Y + moveOffset.Y;
  762. moveCrossLine[1].X = moveCrossLine[1].X + moveOffset.X;
  763. moveCrossLine[1].Y = moveCrossLine[1].Y + moveOffset.Y;
  764. drawDC?.DrawLine(drawParam.EditLinePen, moveLeftLine[0], moveLeftLine[1]);
  765. drawDC?.DrawLine(drawParam.EditLinePen, moveRightLine[0], moveRightLine[1]);
  766. drawDC?.DrawLine(drawParam.EditLinePen, moveCrossLine[0], moveCrossLine[1]);
  767. }
  768. break;
  769. default:
  770. break;
  771. }
  772. if (moveLeftLine[0].X > moveRightLine[0].X)
  773. {
  774. Point tmpPoint = moveRightLine[0];
  775. moveRightLine[0] = moveLeftLine[0];
  776. moveLeftLine[0] = tmpPoint;
  777. }
  778. if (moveLeftLine[1].X > moveRightLine[1].X)
  779. {
  780. Point tmpPoint = moveRightLine[1];
  781. moveRightLine[1] = moveLeftLine[1];
  782. moveLeftLine[1] = tmpPoint;
  783. }
  784. if (crossLine[0].X > crossLine[1].X)
  785. {
  786. Point tmpPoint = crossLine[1];
  787. crossLine[1] = crossLine[0];
  788. crossLine[0] = tmpPoint;
  789. }
  790. }
  791. }
  792. private void DrawPolyLineMeasure(DrawingContext drawingContext)
  793. {
  794. PathGeometry drawPath = new PathGeometry();
  795. PathFigure drawFigure = new PathFigure();
  796. PolyLineSegment polySegment = new PolyLineSegment();
  797. if (hitIndex != -1 && hitIndex < activePoints.Count)
  798. {
  799. if (mouseEndDrawPoint != new Point())
  800. {
  801. activePoints[hitIndex] = mouseEndDrawPoint;
  802. }
  803. }
  804. Point StartPoint = activePoints[0];
  805. if (hitIndex == -1)
  806. {
  807. StartPoint.X += moveOffset.X;
  808. StartPoint.Y += moveOffset.Y;
  809. }
  810. drawFigure.StartPoint = StartPoint;
  811. for (int i = 1; i < activePoints.Count; i++)
  812. {
  813. Point currentPoint = activePoints[i];
  814. if (hitIndex == -1)
  815. {
  816. currentPoint.X += moveOffset.X;
  817. currentPoint.Y += moveOffset.Y;
  818. }
  819. polySegment.Points.Add(currentPoint);
  820. }
  821. if (polySegment.Points.Count > 0)
  822. {
  823. drawFigure.Segments.Add(polySegment);
  824. }
  825. if (drawFigure.Segments.Count > 0)
  826. {
  827. drawPath.Figures.Add(drawFigure);
  828. }
  829. foreach (Point controlPoint in activePoints)
  830. {
  831. Point drawPoint = new Point(
  832. controlPoint.X,
  833. controlPoint.Y);
  834. if (hitIndex == -1)
  835. {
  836. drawPoint.X += moveOffset.X;
  837. drawPoint.Y += moveOffset.Y;
  838. }
  839. drawingContext?.DrawEllipse(drawParam.EditControlLineBrush, drawParam.EditControlLinePen, (drawPoint), pointSize, pointSize);
  840. }
  841. Rect drawRect = activeRect;
  842. drawRect.X += moveOffset.X;
  843. drawRect.Y += moveOffset.Y;
  844. if (isMouseDown)
  845. {
  846. drawingContext?.DrawGeometry(null, drawParam.EditLinePen, drawPath);
  847. }
  848. else
  849. {
  850. drawingContext?.DrawRectangle(null, drawParam.EditLinePen, drawRect);
  851. }
  852. }
  853. private void DrawPolygonMeasure(DrawingContext drawingContext)
  854. {
  855. PathGeometry drawPath = new PathGeometry();
  856. PathFigure drawFigure = new PathFigure();
  857. PolyLineSegment polySegment = new PolyLineSegment();
  858. if (hitIndex != -1 && hitIndex < activePoints.Count)
  859. {
  860. if (mouseEndDrawPoint!=new Point())
  861. {
  862. activePoints[hitIndex] = mouseEndDrawPoint;
  863. }
  864. }
  865. Point StartPoint = activePoints[0];
  866. if (hitIndex == -1)
  867. {
  868. StartPoint.X += moveOffset.X;
  869. StartPoint.Y += moveOffset.Y;
  870. }
  871. drawFigure.StartPoint = StartPoint;
  872. for (int i = 1; i < activePoints.Count; i++)
  873. {
  874. Point currentPoint = activePoints[i];
  875. if (hitIndex == -1)
  876. {
  877. currentPoint.X += moveOffset.X;
  878. currentPoint.Y += moveOffset.Y;
  879. }
  880. polySegment.Points.Add(currentPoint);
  881. }
  882. if (polySegment.Points.Count > 0)
  883. {
  884. polySegment.Points.Add(drawFigure.StartPoint);
  885. drawFigure.Segments.Add(polySegment);
  886. }
  887. if (drawFigure.Segments.Count > 0)
  888. {
  889. drawPath.Figures.Add(drawFigure);
  890. }
  891. foreach (Point controlPoint in activePoints)
  892. {
  893. Point drawPoint = new Point(
  894. controlPoint.X,
  895. controlPoint.Y);
  896. if (hitIndex == -1)
  897. {
  898. drawPoint.X += moveOffset.X;
  899. drawPoint.Y += moveOffset.Y;
  900. }
  901. drawingContext?.DrawEllipse(drawParam.EditControlLineBrush, drawParam.EditControlLinePen, (drawPoint), pointSize, pointSize);
  902. }
  903. Rect drawRect = activeRect;
  904. drawRect.X += moveOffset.X;
  905. drawRect.Y += moveOffset.Y;
  906. if (isMouseDown)
  907. {
  908. drawingContext?.DrawGeometry(null, drawParam.EditLinePen, drawPath);
  909. }
  910. else
  911. {
  912. drawingContext?.DrawRectangle(null, drawParam.EditLinePen, drawRect);
  913. }
  914. }
  915. public virtual void ClearDraw()
  916. {
  917. drawDC = RenderOpen();
  918. drawDC?.Close();
  919. drawDC = null;
  920. }
  921. #endregion
  922. }
  923. }