AnnotEdit.cs 38 KB

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