AnnotEdit.cs 37 KB

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