SelectedRect.protected.cs 38 KB

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