AnnotEdit.cs 42 KB

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