AnnotEdit.cs 42 KB

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