AnnotEdit.cs 42 KB

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