AnnotEdit.cs 37 KB

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