SelectedRect.protected.cs 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Windows;
  4. using System.Windows.Media;
  5. namespace ComPDFKit.Tool.DrawTool
  6. {
  7. public partial class SelectedRect
  8. {
  9. #region Properties
  10. /// <summary>
  11. /// Current control point drawing style.
  12. /// </summary>
  13. protected DrawPointType currentDrawPointType { get;
  14. set; }
  15. /// <summary>
  16. /// Current drag drawing style.
  17. /// </summary>
  18. protected DrawMoveType currentDrawMoveType { get; set; }
  19. /// <summary>
  20. /// Current click hit control point.
  21. /// </summary>
  22. protected PointControlType hitControlType { get; set; }
  23. /// <summary>
  24. /// Mouse down position information.
  25. /// </summary>
  26. protected Point mouseDownPoint { get; set; }
  27. /// <summary>
  28. /// Whether the mouse is pressed.
  29. /// </summary>
  30. protected bool isMouseDown { get; set; }
  31. /// <summary>
  32. /// Whether proportional scaling is required.
  33. /// </summary>
  34. protected bool isProportionalScaling { get; set; } = false;
  35. /// <summary>
  36. /// Current control point size.
  37. /// </summary>
  38. protected int pointSize { get; set; } = 4;
  39. /// <summary>
  40. /// Rectangular minimum width.
  41. /// </summary>
  42. protected int rectMinWidth { get; set; } = 10;
  43. /// <summary>
  44. /// Rectangular minimum height.
  45. /// </summary>
  46. protected int RectMinHeight { get; set; } = 10;
  47. /// <summary>
  48. /// Current set of ignore points.
  49. /// </summary>
  50. protected List<PointControlType> ignorePoints { get; set; } = new List<PointControlType>();
  51. /// <summary>
  52. /// Current set of drawing rectangles (original data).
  53. /// </summary>
  54. protected Rect SetDrawRect { get; set; } = new Rect(0, 0, 0, 0);
  55. /// <summary>
  56. /// Current drawing rectangle (calculated during operation).
  57. /// </summary>
  58. protected Rect drawRect { get; set; } = new Rect(0, 0, 0, 0);
  59. /// <summary>
  60. /// Maximum range that can be drawn.
  61. /// </summary>
  62. protected Rect maxRect { get; set; } = new Rect(0, 0, 0, 0);
  63. /// <summary>
  64. /// Current center point of the drawing rectangle.
  65. /// </summary>
  66. protected Point drawCenterPoint { get; private set; } = new Point(0, 0);
  67. /// <summary>
  68. /// When the mouse is pressed, the cached rectangle.
  69. /// </summary>
  70. protected Rect cacheRect { get; set; } = new Rect(0, 0, 0, 0);
  71. /// <summary>
  72. /// Current control point coordinates.
  73. /// </summary>
  74. protected List<Point> controlPoints { get; set; } = new List<Point>();
  75. /// <summary>
  76. /// Move offset during movement.
  77. /// </summary>
  78. protected Point moveOffset { get; set; } = new Point(0, 0);
  79. /// <summary>
  80. /// Current drawing rectangle (calculated during operation).
  81. /// </summary>
  82. protected Rect clipRect { get; set; } = new Rect(0, 0, 0, 0);
  83. /// <summary>
  84. /// Current actual display width and height of PDFVIewer.
  85. /// </summary>
  86. protected double PDFViewerActualWidth { get; set; } = 0;
  87. protected double PDFViewerActualHeight { get; set; } = 0;
  88. protected double rectPadding = 6;
  89. protected double currentZoom = 1;
  90. protected SelectedAnnotData selectedRectData = new SelectedAnnotData();
  91. protected bool disable = false;
  92. #endregion
  93. #region Functions
  94. /// <summary>
  95. /// Calcuate the control points
  96. /// </summary>
  97. /// <param name="currentRect">
  98. /// Control points in the target rectangle
  99. /// </param>
  100. protected void CalcControlPoint(Rect currentRect)
  101. {
  102. controlPoints.Clear();
  103. int centerX = (int)(currentRect.Left + currentRect.Right) / 2;
  104. int centerY = (int)(currentRect.Top + currentRect.Bottom) / 2;
  105. controlPoints.Add(new Point(currentRect.Left, currentRect.Top));
  106. controlPoints.Add(new Point(currentRect.Left, centerY));
  107. controlPoints.Add(new Point(currentRect.Left, currentRect.Bottom));
  108. controlPoints.Add(new Point(centerX, currentRect.Bottom));
  109. controlPoints.Add(new Point(currentRect.Right, currentRect.Bottom));
  110. controlPoints.Add(new Point(currentRect.Right, centerY));
  111. controlPoints.Add(new Point(currentRect.Right, currentRect.Top));
  112. controlPoints.Add(new Point(centerX, currentRect.Top));
  113. }
  114. protected List<Point> GetControlPoint(Rect currentRect)
  115. { List<Point> controlCurrentPoints = new List<Point>();
  116. controlCurrentPoints.Clear();
  117. int centerX = (int)(currentRect.Left + currentRect.Right) / 2;
  118. int centerY = (int)(currentRect.Top + currentRect.Bottom) / 2;
  119. controlCurrentPoints.Add(new Point(currentRect.Left, currentRect.Top));
  120. controlCurrentPoints.Add(new Point(currentRect.Left, centerY));
  121. controlCurrentPoints.Add(new Point(currentRect.Left, currentRect.Bottom));
  122. controlCurrentPoints.Add(new Point(centerX, currentRect.Bottom));
  123. controlCurrentPoints.Add(new Point(currentRect.Right, currentRect.Bottom));
  124. controlCurrentPoints.Add(new Point(currentRect.Right, centerY));
  125. controlCurrentPoints.Add(new Point(currentRect.Right, currentRect.Top));
  126. controlCurrentPoints.Add(new Point(centerX, currentRect.Top));
  127. return controlCurrentPoints;
  128. }
  129. /// <summary>
  130. /// Calcuate the offset of the current rectangle in the maximum rectangle range
  131. /// </summary>
  132. /// <param name="currentRect">
  133. /// The rectangle cached when pressed
  134. /// </param>
  135. /// <param name="offsetPoint">
  136. /// Equivalent to the offset value when pressed
  137. /// </param>
  138. /// <param name="maxRect">
  139. /// The maximum rectangle range.
  140. /// </param>
  141. /// <returns></returns>
  142. protected Point CalcMoveBound(Rect currentRect, Point offsetPoint, Rect maxRect)
  143. {
  144. double cLeft = currentRect.Left;
  145. double cRight = currentRect.Right;
  146. double cUp = currentRect.Top;
  147. double cDown = currentRect.Bottom;
  148. double TmpLeft = cLeft + offsetPoint.X;
  149. double TmpRight = cRight + offsetPoint.X;
  150. double TmpUp = cUp + offsetPoint.Y;
  151. double TmpDown = cDown + offsetPoint.Y;
  152. if (TmpLeft < maxRect.Left)
  153. {
  154. TmpRight = (cRight - cLeft) + maxRect.Left;
  155. TmpLeft = maxRect.Left;
  156. }
  157. if (TmpUp < maxRect.Top)
  158. {
  159. TmpDown = (cDown - cUp) + maxRect.Top;
  160. TmpUp = maxRect.Top;
  161. }
  162. if (TmpRight > maxRect.Right)
  163. {
  164. TmpLeft = maxRect.Right - (cRight - cLeft);
  165. TmpRight = maxRect.Right;
  166. }
  167. if (TmpDown > maxRect.Bottom)
  168. {
  169. TmpUp = maxRect.Bottom - (cDown - cUp);
  170. TmpDown = maxRect.Bottom;
  171. }
  172. offsetPoint = new Point(TmpLeft - cLeft, TmpUp - cUp);
  173. return offsetPoint;
  174. }
  175. /// <summary>
  176. /// Calculate the movement of the hit point
  177. /// </summary>
  178. /// <param name="mousePoint">
  179. /// Current mouse position
  180. /// </param>
  181. /// <returns>
  182. /// Whether the movement is successful
  183. /// </returns>
  184. protected bool CalcHitPointMove(Point mousePoint)
  185. {
  186. if (isMouseDown == false || hitControlType == PointControlType.None)
  187. {
  188. return false;
  189. }
  190. return NormalScaling(mousePoint);
  191. }
  192. private Size GetProportionalScalingSize(double width, double height)
  193. {
  194. double minHeight = RectMinHeight + 2 * rectPadding * currentZoom;
  195. double minWidth = rectMinWidth + 2 * rectPadding * currentZoom;
  196. if (minWidth > width || minHeight > height)
  197. {
  198. if (cacheRect.Width >= cacheRect.Height)
  199. {
  200. width = cacheRect.Width * minHeight / cacheRect.Height;
  201. height = minHeight;
  202. }
  203. else
  204. {
  205. height = cacheRect.Height * minWidth / cacheRect.Width;
  206. width = minWidth;
  207. }
  208. }
  209. return new Size(width, height);
  210. }
  211. /// <summary>
  212. /// Draw the algorithm in the form of normal scaling (drag a point, only scale in one direction).
  213. /// </summary>
  214. /// <param name="mousePoint">Current mouse position.</param>
  215. /// <returns></returns>
  216. protected bool NormalScaling(Point mousePoint)
  217. {
  218. try
  219. {
  220. double left = 0, right = 0, top = 0, bottom = 0;
  221. double minHeight = RectMinHeight + 2 * rectPadding * currentZoom;
  222. double minWidth = rectMinWidth + 2 * rectPadding * currentZoom;
  223. Point centerPoint = new Point((cacheRect.Right + cacheRect.Left) / 2, (cacheRect.Bottom + cacheRect.Top) / 2);
  224. Point moveVector = (Point)(mousePoint - centerPoint);
  225. moveVector = ProportionalScalingOffsetPos(moveVector);
  226. switch (hitControlType)
  227. {
  228. case PointControlType.LeftTop:
  229. {
  230. left = centerPoint.X + moveVector.X;
  231. right = cacheRect.Right;
  232. top = centerPoint.Y + moveVector.Y;
  233. bottom = cacheRect.Bottom;
  234. if (isProportionalScaling)
  235. {
  236. Size size = GetProportionalScalingSize(right - left, bottom - top);
  237. left = right - size.Width;
  238. top = bottom - size.Height;
  239. if (left < maxRect.Left)
  240. {
  241. double tmpWidth = right - left;
  242. left = maxRect.Left;
  243. double width = right - left;
  244. double height = (bottom - top) * width / tmpWidth;
  245. top = bottom - height;
  246. }
  247. if (top < maxRect.Top)
  248. {
  249. double tmpHeight = bottom - top;
  250. top = maxRect.Top;
  251. double height = bottom - top;
  252. double width = (right - left) * height / tmpHeight;
  253. left = right - width;
  254. }
  255. }
  256. else
  257. {
  258. if (left + minWidth > right)
  259. {
  260. left = right - minWidth;
  261. }
  262. if (top + minHeight > bottom)
  263. {
  264. top = bottom - minHeight;
  265. }
  266. }
  267. }
  268. break;
  269. case PointControlType.LeftMiddle:
  270. {
  271. left = centerPoint.X + moveVector.X;
  272. right = cacheRect.Right;
  273. top = cacheRect.Top;
  274. bottom = cacheRect.Bottom;
  275. if (left + minWidth > right)
  276. {
  277. left = right - minWidth;
  278. }
  279. }
  280. break;
  281. case PointControlType.LeftBottom:
  282. {
  283. left = centerPoint.X + moveVector.X;
  284. right = cacheRect.Right;
  285. top = cacheRect.Top;
  286. bottom = centerPoint.Y + moveVector.Y;
  287. if (isProportionalScaling)
  288. {
  289. Size size = GetProportionalScalingSize(right - left, bottom - top);
  290. left = right - size.Width;
  291. bottom = top + size.Height;
  292. if (left < maxRect.Left)
  293. {
  294. double tmpWidth = right - left;
  295. left = maxRect.Left;
  296. double width = right - left;
  297. double height = (bottom - top) * width / tmpWidth;
  298. bottom = top + height;
  299. }
  300. if (bottom > maxRect.Bottom)
  301. {
  302. double tmpHeight = bottom - top;
  303. bottom = maxRect.Bottom;
  304. double height = bottom - top;
  305. double width = (right - left) * height / tmpHeight;
  306. left = right - width;
  307. }
  308. }
  309. else
  310. {
  311. if (left + minWidth > right)
  312. {
  313. left = right - minWidth;
  314. }
  315. if (top + minHeight > bottom)
  316. {
  317. bottom = top + minHeight;
  318. }
  319. }
  320. }
  321. break;
  322. case PointControlType.MiddlBottom:
  323. {
  324. left = cacheRect.Left;
  325. right = cacheRect.Right;
  326. top = cacheRect.Top;
  327. bottom = centerPoint.Y + moveVector.Y;
  328. if (top + minHeight > bottom)
  329. {
  330. bottom = top + minHeight;
  331. }
  332. }
  333. break;
  334. case PointControlType.RightBottom:
  335. {
  336. left = cacheRect.Left;
  337. right = centerPoint.X + moveVector.X;
  338. top = cacheRect.Top;
  339. bottom = centerPoint.Y + moveVector.Y;
  340. if (isProportionalScaling)
  341. {
  342. Size size = GetProportionalScalingSize(right - left, bottom - top);
  343. right = left + size.Width;
  344. bottom = top + size.Height;
  345. if (right > maxRect.Right)
  346. {
  347. double tmpWidth = right - left;
  348. right = maxRect.Right;
  349. double width = right - left;
  350. double height = (bottom - top) * width / tmpWidth;
  351. bottom = top + height;
  352. }
  353. if (bottom > maxRect.Bottom)
  354. {
  355. double tmpHeight = bottom - top;
  356. bottom = maxRect.Bottom;
  357. double height = bottom - top;
  358. double width = (right - left) * height / tmpHeight;
  359. right = left + width;
  360. }
  361. }
  362. else
  363. {
  364. if (left + minWidth > right)
  365. {
  366. right = left + minWidth;
  367. }
  368. if (top + minHeight > bottom)
  369. {
  370. bottom = top + minHeight;
  371. }
  372. }
  373. }
  374. break;
  375. case PointControlType.RightMiddle:
  376. {
  377. left = cacheRect.Left;
  378. right = centerPoint.X + moveVector.X;
  379. top = cacheRect.Top;
  380. bottom = cacheRect.Bottom;
  381. if (left + minWidth > right)
  382. {
  383. right = left + minWidth;
  384. }
  385. }
  386. break;
  387. case PointControlType.RightTop:
  388. {
  389. left = cacheRect.Left;
  390. right = centerPoint.X + moveVector.X;
  391. top = centerPoint.Y + moveVector.Y;
  392. bottom = cacheRect.Bottom;
  393. if (isProportionalScaling)
  394. {
  395. Size size = GetProportionalScalingSize(right - left, bottom - top);
  396. right = left + size.Width;
  397. top = bottom - size.Height;
  398. if (right > maxRect.Right)
  399. {
  400. double tmpWidth = right - left;
  401. right = maxRect.Right;
  402. double width = right - left;
  403. double height = (bottom - top) * width / tmpWidth;
  404. top = bottom - height;
  405. }
  406. if (top < maxRect.Top)
  407. {
  408. double tmpHeight = bottom - top;
  409. top = maxRect.Top;
  410. double height = bottom - top;
  411. double width = (right - left) * height / tmpHeight;
  412. right = left + width;
  413. }
  414. }
  415. else
  416. {
  417. if (left + minWidth > right)
  418. {
  419. right = left + minWidth;
  420. }
  421. if (top + minHeight > bottom)
  422. {
  423. top = bottom - minHeight;
  424. }
  425. }
  426. }
  427. break;
  428. case PointControlType.MiddleTop:
  429. {
  430. left = cacheRect.Left;
  431. right = cacheRect.Right;
  432. top = centerPoint.Y + moveVector.Y;
  433. bottom = cacheRect.Bottom;
  434. if (top + minHeight > bottom)
  435. {
  436. top = bottom - minHeight;
  437. }
  438. }
  439. break;
  440. case PointControlType.Body:
  441. case PointControlType.Line:
  442. {
  443. Point OffsetPos = CalcMoveBound(cacheRect, ((Point)(mousePoint - mouseDownPoint)), maxRect);
  444. left = cacheRect.Left + OffsetPos.X;
  445. right = cacheRect.Right + OffsetPos.X;
  446. top = cacheRect.Top + OffsetPos.Y;
  447. bottom = cacheRect.Bottom + OffsetPos.Y;
  448. }
  449. break;
  450. default:
  451. break;
  452. }
  453. if (left < maxRect.Left)
  454. {
  455. left = maxRect.Left;
  456. }
  457. if (top < maxRect.Top)
  458. {
  459. top = maxRect.Top;
  460. }
  461. if (right > maxRect.Right)
  462. {
  463. right = maxRect.Right;
  464. }
  465. if (bottom > maxRect.Bottom)
  466. {
  467. bottom = maxRect.Bottom;
  468. }
  469. drawRect = new Rect(left, top, right - left, bottom - top);
  470. moveOffset = new Point(drawRect.X - cacheRect.X, drawRect.Y - cacheRect.Y);
  471. return true;
  472. }
  473. catch (Exception ex)
  474. {
  475. }
  476. return false;
  477. }
  478. /// <summary>
  479. /// Proportional scaling offset calibration
  480. /// </summary>
  481. /// <param name="movePoint">
  482. /// The current movement point
  483. /// </param>
  484. /// <returns>
  485. /// The offset point after the proportional scaling
  486. /// </returns>
  487. protected Point ProportionalScalingOffsetPos(Point movePoint)
  488. {
  489. if (isProportionalScaling)
  490. {
  491. Point offsetPos = movePoint;
  492. double ratioX = cacheRect.Width > 0 ? cacheRect.Height / cacheRect.Width : 1;
  493. double ratioY = cacheRect.Height > 0 ? cacheRect.Width / cacheRect.Height : 1;
  494. switch (hitControlType)
  495. {
  496. case PointControlType.LeftTop:
  497. case PointControlType.RightBottom:
  498. offsetPos = new Point(movePoint.X, Math.Abs(movePoint.X) * ratioX * (movePoint.X < 0 ? -1 : 1));
  499. break;
  500. case PointControlType.LeftBottom:
  501. case PointControlType.RightTop:
  502. offsetPos = new Point(movePoint.X, Math.Abs(movePoint.X) * ratioX * (movePoint.X < 0 ? 1 : -1));
  503. break;
  504. case PointControlType.LeftMiddle:
  505. offsetPos = new Point(movePoint.X, Math.Abs(movePoint.X) * ratioX * (movePoint.X < 0 ? 1 : -1));
  506. break;
  507. case PointControlType.RightMiddle:
  508. offsetPos = new Point(movePoint.X, Math.Abs(movePoint.X) * ratioX * (movePoint.X < 0 ? -1 : 1));
  509. break;
  510. case PointControlType.MiddlBottom:
  511. offsetPos = new Point(Math.Abs(movePoint.Y) * ratioY * (movePoint.Y < 0 ? 1 : -1), movePoint.Y);
  512. break;
  513. case PointControlType.MiddleTop:
  514. offsetPos = new Point(Math.Abs(movePoint.Y) * ratioY * (movePoint.Y < 0 ? -1 : 1), movePoint.Y);
  515. break;
  516. default:
  517. break;
  518. }
  519. return offsetPos;
  520. }
  521. else
  522. {
  523. return movePoint;
  524. }
  525. }
  526. /// <summary>
  527. /// Inner drawing circle point
  528. /// </summary>
  529. /// <param name="drawingContext">
  530. /// Drawing context
  531. /// </param>
  532. /// <param name="ignoreList">
  533. /// Collection of positions that need to be drawn
  534. /// </param>
  535. /// <param name="PointSize">
  536. /// Size of the point
  537. /// </param>
  538. /// <param name="PointPen">
  539. /// Brush for drawing points
  540. /// </param>
  541. /// <param name="BorderBrush">
  542. /// Border brush for drawing points
  543. /// </param>
  544. protected void DrawCirclePoint(DrawingContext drawingContext, List<PointControlType> ignoreList, int PointSize, Pen PointPen, SolidColorBrush BorderBrush)
  545. {
  546. GeometryGroup controlGroup = new GeometryGroup();
  547. controlGroup.FillRule = FillRule.Nonzero;
  548. List<Point> ignorePointsList = new List<Point>();
  549. // Get specific points
  550. foreach (PointControlType type in ignoreList)
  551. {
  552. if ((int)type < controlPoints.Count)
  553. {
  554. ignorePointsList.Add(controlPoints[(int)type]);
  555. }
  556. }
  557. for (int i = 0; i < controlPoints.Count; i++)
  558. {
  559. Point controlPoint = controlPoints[i];
  560. if (ignorePointsList.Contains(controlPoint))
  561. {
  562. continue;
  563. }
  564. EllipseGeometry circlPoint = new EllipseGeometry(controlPoint, PointSize, PointSize);
  565. controlGroup.Children.Add(circlPoint);
  566. }
  567. drawingContext?.DrawGeometry(BorderBrush, PointPen, controlGroup);
  568. }
  569. /// <summary>
  570. /// Inner drawing square
  571. /// </summary>
  572. /// <param name="drawingContext">
  573. /// Drawing context
  574. /// </param>
  575. /// <param name="ControlPoints">
  576. /// Collection of positions that need to be drawn
  577. /// </param>
  578. /// <param name="PointSize">
  579. /// Size of the point
  580. /// </param>
  581. /// <param name="PointPen">
  582. /// Brush for drawing points
  583. /// </param>
  584. /// <param name="BorderBrush">
  585. /// Border brush for drawing points
  586. /// </param>
  587. protected void DrawSquarePoint(DrawingContext drawingContext, List<PointControlType> ignoreList, int PointSize, Pen PointPen, SolidColorBrush BorderBrush)
  588. {
  589. GeometryGroup controlGroup = new GeometryGroup();
  590. controlGroup.FillRule = FillRule.Nonzero;
  591. List<Point> ignorePointsList = new List<Point>();
  592. // Get specific points
  593. foreach (PointControlType type in ignoreList)
  594. {
  595. if ((int)type < controlPoints.Count)
  596. {
  597. ignorePointsList.Add(controlPoints[(int)type]);
  598. }
  599. }
  600. for (int i = 0; i < controlPoints.Count; i++)
  601. {
  602. Point controlPoint = controlPoints[i];
  603. if (ignorePointsList.Contains(controlPoint))
  604. {
  605. continue;
  606. }
  607. RectangleGeometry rectPoint = new RectangleGeometry(new Rect(controlPoint.X - PointSize, controlPoint.Y - PointSize,
  608. PointSize * 2, PointSize * 2), 1, 1);
  609. controlGroup.Children.Add(rectPoint);
  610. }
  611. drawingContext?.DrawGeometry(BorderBrush, PointPen, controlGroup);
  612. }
  613. protected void DrawCropPoint(DrawingContext drawingContext, List<PointControlType> ignoreList, int PointSize, Pen PointPen, SolidColorBrush BorderBrush)
  614. {
  615. //GeometryGroup controlGroup = new GeometryGroup();
  616. //controlGroup.FillRule = FillRule.Nonzero;
  617. clipRect = drawRect;
  618. List<Point> controlCurrentPoints=GetControlPoint(drawRect);
  619. CombinedGeometry controlGroup = new CombinedGeometry();
  620. RectangleGeometry paintGeometry = new RectangleGeometry();
  621. paintGeometry.Rect = SetDrawRect;
  622. controlGroup.Geometry1 = paintGeometry;
  623. RectangleGeometry moveGeometry = new RectangleGeometry();
  624. Rect clippedBorder = drawRect;
  625. if (clippedBorder.IsEmpty == false)
  626. {
  627. moveGeometry.Rect = drawRect;
  628. }
  629. controlGroup.Geometry2 = moveGeometry;
  630. controlGroup.GeometryCombineMode = GeometryCombineMode.Exclude;
  631. //Left Top Corner
  632. if (!ignoreList.Contains(PointControlType.LeftTop))
  633. {
  634. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[0].X - PointSize, controlCurrentPoints[0].Y - PointSize, PointSize, PointSize * 4));
  635. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[0].X - PointSize, controlCurrentPoints[0].Y - PointSize, PointSize * 4, PointSize));
  636. }
  637. //Left Center
  638. if (!ignoreList.Contains(PointControlType.LeftMiddle))
  639. {
  640. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[1].X - PointSize, (controlCurrentPoints[1].Y + controlCurrentPoints[1].Y - PointSize * 5) / 2, PointSize, PointSize * 5));
  641. }
  642. //Left Bottom Corner
  643. if (!ignoreList.Contains(PointControlType.LeftBottom))
  644. {
  645. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[2].X - PointSize, controlCurrentPoints[2].Y - PointSize * 3, PointSize, PointSize * 4));
  646. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[2].X - PointSize, controlCurrentPoints[2].Y, PointSize * 4, PointSize));
  647. }
  648. //Bottom Center
  649. if (!ignoreList.Contains(PointControlType.MiddlBottom))
  650. {
  651. drawingContext?.DrawRectangle(BorderBrush, null, new Rect((controlCurrentPoints[3].X + controlCurrentPoints[3].X - PointSize * 5) / 2, controlCurrentPoints[3].Y, PointSize * 5, PointSize));
  652. }
  653. //Bottom Right Corner
  654. if (!ignoreList.Contains(PointControlType.RightBottom))
  655. {
  656. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[4].X, controlCurrentPoints[4].Y - PointSize * 3, PointSize, PointSize * 4));
  657. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[4].X - PointSize * 3, controlCurrentPoints[4].Y, PointSize * 4, PointSize));
  658. }
  659. //Right Center
  660. if (!ignoreList.Contains(PointControlType.RightMiddle))
  661. {
  662. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[5].X, (controlCurrentPoints[5].Y + controlCurrentPoints[5].Y - PointSize * 5) / 2, PointSize, PointSize * 5));
  663. }
  664. //Right Top Corner
  665. if (!ignoreList.Contains(PointControlType.RightTop))
  666. {
  667. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[6].X, controlCurrentPoints[6].Y - PointSize, PointSize, PointSize * 4));
  668. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[6].X - PointSize * 4, controlCurrentPoints[6].Y - PointSize, PointSize * 4, PointSize));
  669. }
  670. //Top Center
  671. if (!ignoreList.Contains(PointControlType.MiddleTop))
  672. {
  673. drawingContext?.DrawRectangle(BorderBrush, null, new Rect((controlCurrentPoints[7].X + controlCurrentPoints[7].X - PointSize * 5) / 2, controlCurrentPoints[7].Y - PointSize, PointSize * 5, PointSize));
  674. }
  675. BorderBrush = new SolidColorBrush(Color.FromArgb(0x3F, 0x00, 0x00, 0x00));
  676. drawingContext?.DrawGeometry(BorderBrush, PointPen, controlGroup);
  677. }
  678. /// <summary>
  679. /// Draw the reference line in the moving state
  680. /// </summary>
  681. /// <param name="drawDc">
  682. /// Draw context handle
  683. /// </param>
  684. /// <param name="controltype">
  685. /// Current selected control point type
  686. /// </param>
  687. /// <param name="activePen">
  688. /// Brush for drawing lines
  689. /// </param>
  690. /// <param name="moveBrush">
  691. /// Brush for drawing rectangles
  692. /// </param>
  693. /// <param name="moveRect">
  694. /// Current rectangle to draw
  695. /// </param>
  696. protected void DrawMoveBounds(DrawingContext drawDc, PointControlType controltype, Pen activePen, Brush moveBrush, Rect moveRect)
  697. {
  698. switch (controltype)
  699. {
  700. case PointControlType.LeftTop:
  701. drawDc?.DrawLine(activePen, new Point(0, moveRect.Top), new Point(PDFViewerActualWidth, moveRect.Top));
  702. drawDc?.DrawLine(activePen, new Point(moveRect.Left, 0), new Point(moveRect.Left, PDFViewerActualHeight));
  703. break;
  704. case PointControlType.LeftMiddle:
  705. drawDc?.DrawLine(activePen, new Point(moveRect.Left, 0), new Point(moveRect.Left, PDFViewerActualHeight));
  706. break;
  707. case PointControlType.LeftBottom:
  708. drawDc?.DrawLine(activePen, new Point(0, moveRect.Bottom), new Point(PDFViewerActualWidth, moveRect.Bottom));
  709. drawDc?.DrawLine(activePen, new Point(moveRect.Left, 0), new Point(moveRect.Left, PDFViewerActualHeight));
  710. break;
  711. case PointControlType.MiddlBottom:
  712. drawDc?.DrawLine(activePen, new Point(0, moveRect.Bottom), new Point(PDFViewerActualWidth, moveRect.Bottom));
  713. break;
  714. case PointControlType.RightBottom:
  715. drawDc?.DrawLine(activePen, new Point(0, moveRect.Bottom), new Point(PDFViewerActualWidth, moveRect.Bottom));
  716. drawDc?.DrawLine(activePen, new Point(moveRect.Right, 0), new Point(moveRect.Right, PDFViewerActualHeight));
  717. break;
  718. case PointControlType.RightMiddle:
  719. drawDc?.DrawLine(activePen, new Point(moveRect.Right, 0), new Point(moveRect.Right, PDFViewerActualHeight));
  720. break;
  721. case PointControlType.RightTop:
  722. drawDc?.DrawLine(activePen, new Point(0, moveRect.Top), new Point(PDFViewerActualWidth, moveRect.Top));
  723. drawDc?.DrawLine(activePen, new Point(moveRect.Right, 0), new Point(moveRect.Right, PDFViewerActualHeight));
  724. break;
  725. case PointControlType.MiddleTop:
  726. drawDc?.DrawLine(activePen, new Point(0, moveRect.Top), new Point(PDFViewerActualWidth, moveRect.Top));
  727. break;
  728. case PointControlType.Rotate:
  729. break;
  730. case PointControlType.Body:
  731. case PointControlType.Line:
  732. drawDc?.DrawLine(activePen, new Point(0, moveRect.Top), new Point(PDFViewerActualWidth, moveRect.Top));
  733. drawDc?.DrawLine(activePen, new Point(0, moveRect.Bottom), new Point(PDFViewerActualWidth, moveRect.Bottom));
  734. drawDc?.DrawLine(activePen, new Point(moveRect.Left, 0), new Point(moveRect.Left, PDFViewerActualHeight));
  735. drawDc?.DrawLine(activePen, new Point(moveRect.Right, 0), new Point(moveRect.Right, PDFViewerActualHeight));
  736. break;
  737. default:
  738. break;
  739. }
  740. drawDc?.DrawRectangle(moveBrush, null, moveRect);
  741. }
  742. /// <summary>
  743. /// Notify the event during/after the drawing data
  744. /// </summary>
  745. /// <param name="isFinish">
  746. /// Identifies whether the data change is complete
  747. /// </param>
  748. protected void InvokeDataChangEvent(bool isFinish)
  749. {
  750. selectedRectData.Square = GetRect();
  751. if (isFinish)
  752. {
  753. DataChanged?.Invoke(this, selectedRectData);
  754. }
  755. else
  756. {
  757. DataChanging?.Invoke(this, selectedRectData);
  758. }
  759. }
  760. /// <summary>
  761. /// Align the rectangle drawing
  762. /// </summary>
  763. /// <param name="RectMovePoint">
  764. /// Move distance required for the aligned algorithm to obtain the rectangle
  765. /// </param>
  766. private void DrawAlignRect(Point RectMovePoint)
  767. {
  768. double TmpLeft, TmpRight, TmpUp, TmpDown;
  769. Point OffsetPos = CalcMoveBound(drawRect, RectMovePoint, maxRect);
  770. TmpLeft = drawRect.Left + OffsetPos.X;
  771. TmpRight = drawRect.Right + OffsetPos.X;
  772. TmpUp = drawRect.Top + OffsetPos.Y;
  773. TmpDown = drawRect.Bottom + OffsetPos.Y;
  774. SetDrawRect = drawRect = new Rect(TmpLeft, TmpUp, TmpRight - TmpLeft, TmpDown - TmpUp);
  775. Draw();
  776. }
  777. /// <summary>
  778. /// Get the current set of ignore points
  779. /// </summary>
  780. /// <returns>
  781. /// Data set of ignored points
  782. /// </returns>
  783. private List<PointControlType> GetIgnorePoints()
  784. {
  785. List<PointControlType> IgnorePointsList = new List<PointControlType>();
  786. foreach (PointControlType type in ignorePoints)
  787. {
  788. IgnorePointsList.Add(type);
  789. }
  790. return IgnorePointsList;
  791. }
  792. #endregion
  793. }
  794. }