SelectedRect.protected.cs 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216
  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
  14. {
  15. get;
  16. set;
  17. }
  18. /// <summary>
  19. /// Current drag drawing style.
  20. /// </summary>
  21. protected DrawMoveType currentDrawMoveType { get; set; }
  22. /// <summary>
  23. /// Current click hit control point.
  24. /// </summary>
  25. protected PointControlType hitControlType { get; set; }
  26. /// <summary>
  27. /// Mouse down position information.
  28. /// </summary>
  29. protected Point mouseDownPoint { get; set; }
  30. /// <summary>
  31. /// Whether the mouse is pressed.
  32. /// </summary>
  33. protected bool isMouseDown { get; set; }
  34. /// <summary>
  35. /// Whether proportional scaling is required.
  36. /// </summary>
  37. protected bool isProportionalScaling { get; set; } = false;
  38. /// <summary>
  39. /// Current control point size.
  40. /// </summary>
  41. protected int pointSize { get; set; } = 4;
  42. /// <summary>
  43. /// Rectangular minimum width.
  44. /// </summary>
  45. protected int rectMinWidth { get; set; } = 10;
  46. /// <summary>
  47. /// Rectangular minimum height.
  48. /// </summary>
  49. protected int RectMinHeight { get; set; } = 10;
  50. /// <summary>
  51. /// Current set of ignore points.
  52. /// </summary>
  53. protected List<PointControlType> ignorePoints { get; set; } = new List<PointControlType>();
  54. /// <summary>
  55. /// Current set of drawing rectangles (original data).
  56. /// </summary>
  57. protected Rect SetDrawRect { get; set; } = new Rect(0, 0, 0, 0);
  58. /// <summary>
  59. /// Current drawing rectangle (calculated during operation).
  60. /// </summary>
  61. protected Rect drawRect { get; set; } = new Rect(0, 0, 0, 0);
  62. /// <summary>
  63. /// Maximum range that can be drawn.
  64. /// </summary>
  65. protected Rect maxRect { get; set; } = new Rect(0, 0, 0, 0);
  66. /// <summary>
  67. /// Current center point of the drawing rectangle.
  68. /// </summary>
  69. protected Point drawCenterPoint { get; private set; } = new Point(0, 0);
  70. /// <summary>
  71. /// When the mouse is pressed, the cached rectangle.
  72. /// </summary>
  73. protected Rect cacheRect { get; set; } = new Rect(0, 0, 0, 0);
  74. /// <summary>
  75. /// Current control point coordinates.
  76. /// </summary>
  77. protected List<Point> controlPoints { get; set; } = new List<Point>();
  78. /// <summary>
  79. /// Move offset during movement.
  80. /// </summary>
  81. protected Point moveOffset { get; set; } = new Point(0, 0);
  82. /// <summary>
  83. /// Current drawing rectangle (calculated during operation).
  84. /// </summary>
  85. protected Thickness clipThickness = new Thickness(0, 0, 0, 0);
  86. private Pen editPen { get; set; } = new Pen(new SolidColorBrush(Color.FromRgb(71, 126, 222)), 2) { DashStyle = DashStyles.Dash };
  87. private Pen editHoverPen { get; set; } = new Pen(new SolidColorBrush(Color.FromRgb(71, 126, 222)), 2) { DashStyle = DashStyles.Dash };
  88. protected bool isOutSideScaling = false;
  89. /// <summary>
  90. /// Current actual display width and height of PDFVIewer.
  91. /// </summary>
  92. protected double PDFViewerActualWidth { get; set; } = 0;
  93. protected double PDFViewerActualHeight { get; set; } = 0;
  94. protected double rectPadding = 6;
  95. protected double currentZoom = 1;
  96. protected SelectedAnnotData selectedRectData = new SelectedAnnotData();
  97. protected bool disable = false;
  98. #endregion
  99. #region Functions
  100. /// <summary>
  101. /// Calcuate the control points
  102. /// </summary>
  103. /// <param name="currentRect">
  104. /// Control points in the target rectangle
  105. /// </param>
  106. protected void CalcControlPoint(Rect currentRect)
  107. {
  108. controlPoints.Clear();
  109. int centerX = (int)(currentRect.Left + currentRect.Right) / 2;
  110. int centerY = (int)(currentRect.Top + currentRect.Bottom) / 2;
  111. controlPoints.Add(new Point(currentRect.Left, currentRect.Top));
  112. controlPoints.Add(new Point(currentRect.Left, centerY));
  113. controlPoints.Add(new Point(currentRect.Left, currentRect.Bottom));
  114. controlPoints.Add(new Point(centerX, currentRect.Bottom));
  115. controlPoints.Add(new Point(currentRect.Right, currentRect.Bottom));
  116. controlPoints.Add(new Point(currentRect.Right, centerY));
  117. controlPoints.Add(new Point(currentRect.Right, currentRect.Top));
  118. controlPoints.Add(new Point(centerX, currentRect.Top));
  119. }
  120. protected List<Point> GetControlPoint(Rect currentRect)
  121. {
  122. List<Point> controlCurrentPoints = new List<Point>();
  123. controlCurrentPoints.Clear();
  124. int centerX = (int)(currentRect.Left + currentRect.Right) / 2;
  125. int centerY = (int)(currentRect.Top + currentRect.Bottom) / 2;
  126. controlCurrentPoints.Add(new Point(currentRect.Left, currentRect.Top));
  127. controlCurrentPoints.Add(new Point(currentRect.Left, centerY));
  128. controlCurrentPoints.Add(new Point(currentRect.Left, currentRect.Bottom));
  129. controlCurrentPoints.Add(new Point(centerX, currentRect.Bottom));
  130. controlCurrentPoints.Add(new Point(currentRect.Right, currentRect.Bottom));
  131. controlCurrentPoints.Add(new Point(currentRect.Right, centerY));
  132. controlCurrentPoints.Add(new Point(currentRect.Right, currentRect.Top));
  133. controlCurrentPoints.Add(new Point(centerX, currentRect.Top));
  134. return controlCurrentPoints;
  135. }
  136. /// <summary>
  137. /// Calcuate the offset of the current rectangle in the maximum rectangle range
  138. /// </summary>
  139. /// <param name="currentRect">
  140. /// The rectangle cached when pressed
  141. /// </param>
  142. /// <param name="offsetPoint">
  143. /// Equivalent to the offset value when pressed
  144. /// </param>
  145. /// <param name="maxRect">
  146. /// The maximum rectangle range.
  147. /// </param>
  148. /// <returns></returns>
  149. protected Point CalcMoveBound(Rect currentRect, Point offsetPoint, Rect maxRect)
  150. {
  151. double cLeft = currentRect.Left;
  152. double cRight = currentRect.Right;
  153. double cUp = currentRect.Top;
  154. double cDown = currentRect.Bottom;
  155. double TmpLeft = cLeft + offsetPoint.X;
  156. double TmpRight = cRight + offsetPoint.X;
  157. double TmpUp = cUp + offsetPoint.Y;
  158. double TmpDown = cDown + offsetPoint.Y;
  159. if (TmpLeft < maxRect.Left)
  160. {
  161. TmpRight = (cRight - cLeft) + maxRect.Left;
  162. TmpLeft = maxRect.Left;
  163. }
  164. if (TmpUp < maxRect.Top)
  165. {
  166. TmpDown = (cDown - cUp) + maxRect.Top;
  167. TmpUp = maxRect.Top;
  168. }
  169. if (TmpRight > maxRect.Right)
  170. {
  171. TmpLeft = maxRect.Right - (cRight - cLeft);
  172. TmpRight = maxRect.Right;
  173. }
  174. if (TmpDown > maxRect.Bottom)
  175. {
  176. TmpUp = maxRect.Bottom - (cDown - cUp);
  177. TmpDown = maxRect.Bottom;
  178. }
  179. offsetPoint = new Point(TmpLeft - cLeft, TmpUp - cUp);
  180. return offsetPoint;
  181. }
  182. /// <summary>
  183. /// Calculate the movement of the hit point
  184. /// </summary>
  185. /// <param name="mousePoint">
  186. /// Current mouse position
  187. /// </param>
  188. /// <returns>
  189. /// Whether the movement is successful
  190. /// </returns>
  191. protected bool CalcHitPointMove(Point mousePoint)
  192. {
  193. if (isMouseDown == false || hitControlType == PointControlType.None)
  194. {
  195. return false;
  196. }
  197. if (!isOutSideScaling)
  198. {
  199. return NormalScaling(mousePoint);
  200. }
  201. else
  202. {
  203. return OutSideScaling(mousePoint);
  204. }
  205. }
  206. public void SetOutSideScaling(bool IsOutSideScaling)
  207. {
  208. isOutSideScaling = IsOutSideScaling;
  209. }
  210. private Size GetProportionalScalingSize(double width, double height)
  211. {
  212. double minHeight = RectMinHeight + 2 * rectPadding * currentZoom;
  213. double minWidth = rectMinWidth + 2 * rectPadding * currentZoom;
  214. if (minWidth > width || minHeight > height)
  215. {
  216. if (cacheRect.Width >= cacheRect.Height)
  217. {
  218. width = cacheRect.Width * minHeight / cacheRect.Height;
  219. height = minHeight;
  220. }
  221. else
  222. {
  223. height = cacheRect.Height * minWidth / cacheRect.Width;
  224. width = minWidth;
  225. }
  226. }
  227. return new Size(width, height);
  228. }
  229. /// <summary>
  230. /// Draw the algorithm in the form of normal scaling (drag a point, only scale in one direction).
  231. /// </summary>
  232. /// <param name="mousePoint">Current mouse position.</param>
  233. /// <returns></returns>
  234. protected bool NormalScaling(Point mousePoint)
  235. {
  236. try
  237. {
  238. double left = 0, right = 0, top = 0, bottom = 0;
  239. double minHeight = RectMinHeight + 2 * rectPadding * currentZoom;
  240. double minWidth = rectMinWidth + 2 * rectPadding * currentZoom;
  241. Point centerPoint = new Point((cacheRect.Right + cacheRect.Left) / 2, (cacheRect.Bottom + cacheRect.Top) / 2);
  242. Point moveVector = (Point)(mousePoint - centerPoint);
  243. moveVector = ProportionalScalingOffsetPos(moveVector);
  244. switch (hitControlType)
  245. {
  246. case PointControlType.LeftTop:
  247. {
  248. left = centerPoint.X + moveVector.X;
  249. right = cacheRect.Right;
  250. top = centerPoint.Y + moveVector.Y;
  251. bottom = cacheRect.Bottom;
  252. if (isProportionalScaling)
  253. {
  254. Size size = GetProportionalScalingSize(right - left, bottom - top);
  255. left = right - size.Width;
  256. top = bottom - size.Height;
  257. if (left < maxRect.Left)
  258. {
  259. double tmpWidth = right - left;
  260. left = maxRect.Left;
  261. double width = right - left;
  262. double height = (bottom - top) * width / tmpWidth;
  263. top = bottom - height;
  264. }
  265. if (top < maxRect.Top)
  266. {
  267. double tmpHeight = bottom - top;
  268. top = maxRect.Top;
  269. double height = bottom - top;
  270. double width = (right - left) * height / tmpHeight;
  271. left = right - width;
  272. }
  273. }
  274. else
  275. {
  276. if (left + minWidth > right)
  277. {
  278. left = right - minWidth;
  279. }
  280. if (top + minHeight > bottom)
  281. {
  282. top = bottom - minHeight;
  283. }
  284. }
  285. }
  286. break;
  287. case PointControlType.LeftMiddle:
  288. {
  289. left = centerPoint.X + moveVector.X;
  290. right = cacheRect.Right;
  291. top = cacheRect.Top;
  292. bottom = cacheRect.Bottom;
  293. if (left + minWidth > right)
  294. {
  295. left = right - minWidth;
  296. }
  297. }
  298. break;
  299. case PointControlType.LeftBottom:
  300. {
  301. left = centerPoint.X + moveVector.X;
  302. right = cacheRect.Right;
  303. top = cacheRect.Top;
  304. bottom = centerPoint.Y + moveVector.Y;
  305. if (isProportionalScaling)
  306. {
  307. Size size = GetProportionalScalingSize(right - left, bottom - top);
  308. left = right - size.Width;
  309. bottom = top + size.Height;
  310. if (left < maxRect.Left)
  311. {
  312. double tmpWidth = right - left;
  313. left = maxRect.Left;
  314. double width = right - left;
  315. double height = (bottom - top) * width / tmpWidth;
  316. bottom = top + height;
  317. }
  318. if (bottom > maxRect.Bottom)
  319. {
  320. double tmpHeight = bottom - top;
  321. bottom = maxRect.Bottom;
  322. double height = bottom - top;
  323. double width = (right - left) * height / tmpHeight;
  324. left = right - width;
  325. }
  326. }
  327. else
  328. {
  329. if (left + minWidth > right)
  330. {
  331. left = right - minWidth;
  332. }
  333. if (top + minHeight > bottom)
  334. {
  335. bottom = top + minHeight;
  336. }
  337. }
  338. }
  339. break;
  340. case PointControlType.MiddlBottom:
  341. {
  342. left = cacheRect.Left;
  343. right = cacheRect.Right;
  344. top = cacheRect.Top;
  345. bottom = centerPoint.Y + moveVector.Y;
  346. if (top + minHeight > bottom)
  347. {
  348. bottom = top + minHeight;
  349. }
  350. }
  351. break;
  352. case PointControlType.RightBottom:
  353. {
  354. left = cacheRect.Left;
  355. right = centerPoint.X + moveVector.X;
  356. top = cacheRect.Top;
  357. bottom = centerPoint.Y + moveVector.Y;
  358. if (isProportionalScaling)
  359. {
  360. Size size = GetProportionalScalingSize(right - left, bottom - top);
  361. right = left + size.Width;
  362. bottom = top + size.Height;
  363. if (right > maxRect.Right)
  364. {
  365. double tmpWidth = right - left;
  366. right = maxRect.Right;
  367. double width = right - left;
  368. double height = (bottom - top) * width / tmpWidth;
  369. bottom = top + height;
  370. }
  371. if (bottom > maxRect.Bottom)
  372. {
  373. double tmpHeight = bottom - top;
  374. bottom = maxRect.Bottom;
  375. double height = bottom - top;
  376. double width = (right - left) * height / tmpHeight;
  377. right = left + width;
  378. }
  379. }
  380. else
  381. {
  382. if (left + minWidth > right)
  383. {
  384. right = left + minWidth;
  385. }
  386. if (top + minHeight > bottom)
  387. {
  388. bottom = top + minHeight;
  389. }
  390. }
  391. }
  392. break;
  393. case PointControlType.RightMiddle:
  394. {
  395. left = cacheRect.Left;
  396. right = centerPoint.X + moveVector.X;
  397. top = cacheRect.Top;
  398. bottom = cacheRect.Bottom;
  399. if (left + minWidth > right)
  400. {
  401. right = left + minWidth;
  402. }
  403. }
  404. break;
  405. case PointControlType.RightTop:
  406. {
  407. left = cacheRect.Left;
  408. right = centerPoint.X + moveVector.X;
  409. top = centerPoint.Y + moveVector.Y;
  410. bottom = cacheRect.Bottom;
  411. if (isProportionalScaling)
  412. {
  413. Size size = GetProportionalScalingSize(right - left, bottom - top);
  414. right = left + size.Width;
  415. top = bottom - size.Height;
  416. if (right > maxRect.Right)
  417. {
  418. double tmpWidth = right - left;
  419. right = maxRect.Right;
  420. double width = right - left;
  421. double height = (bottom - top) * width / tmpWidth;
  422. top = bottom - height;
  423. }
  424. if (top < maxRect.Top)
  425. {
  426. double tmpHeight = bottom - top;
  427. top = maxRect.Top;
  428. double height = bottom - top;
  429. double width = (right - left) * height / tmpHeight;
  430. right = left + width;
  431. }
  432. }
  433. else
  434. {
  435. if (left + minWidth > right)
  436. {
  437. right = left + minWidth;
  438. }
  439. if (top + minHeight > bottom)
  440. {
  441. top = bottom - minHeight;
  442. }
  443. }
  444. }
  445. break;
  446. case PointControlType.MiddleTop:
  447. {
  448. left = cacheRect.Left;
  449. right = cacheRect.Right;
  450. top = centerPoint.Y + moveVector.Y;
  451. bottom = cacheRect.Bottom;
  452. if (top + minHeight > bottom)
  453. {
  454. top = bottom - minHeight;
  455. }
  456. }
  457. break;
  458. case PointControlType.Body:
  459. case PointControlType.Line:
  460. {
  461. Point OffsetPos = CalcMoveBound(cacheRect, ((Point)(mousePoint - mouseDownPoint)), maxRect);
  462. left = cacheRect.Left + OffsetPos.X;
  463. right = cacheRect.Right + OffsetPos.X;
  464. top = cacheRect.Top + OffsetPos.Y;
  465. bottom = cacheRect.Bottom + OffsetPos.Y;
  466. }
  467. break;
  468. default:
  469. break;
  470. }
  471. if (left < maxRect.Left)
  472. {
  473. left = maxRect.Left;
  474. }
  475. if (top < maxRect.Top)
  476. {
  477. top = maxRect.Top;
  478. }
  479. if (right > maxRect.Right)
  480. {
  481. right = maxRect.Right;
  482. }
  483. if (bottom > maxRect.Bottom)
  484. {
  485. bottom = maxRect.Bottom;
  486. }
  487. drawRect = new Rect(left, top, right - left, bottom - top);
  488. moveOffset = new Point(drawRect.X - cacheRect.X, drawRect.Y - cacheRect.Y);
  489. return true;
  490. }
  491. catch (Exception ex)
  492. {
  493. }
  494. return false;
  495. }
  496. /// <summary>
  497. /// Provisional logic, to be further improved, not yet used: Draw the algorithm in the form of normal scaling (drag a point, only scale in one direction).
  498. /// </summary>
  499. /// <param name="mousePoint">Current mouse position.</param>
  500. /// <returns></returns>
  501. protected bool OutSideScaling(Point mousePoint)
  502. {
  503. try
  504. {
  505. double left = 0, right = 0, top = 0, bottom = 0;
  506. double minHeight = RectMinHeight + 2 * rectPadding * currentZoom;
  507. double minWidth = rectMinWidth + 2 * rectPadding * currentZoom;
  508. Point centerPoint = new Point((cacheRect.Right + cacheRect.Left) / 2, (cacheRect.Bottom + cacheRect.Top) / 2);
  509. Point moveVector = (Point)(mousePoint - centerPoint);
  510. moveVector = ProportionalScalingOffsetPos(moveVector);
  511. switch (hitControlType)
  512. {
  513. case PointControlType.LeftTop:
  514. {
  515. left = centerPoint.X + moveVector.X;
  516. right = cacheRect.Right;
  517. top = centerPoint.Y + moveVector.Y;
  518. bottom = cacheRect.Bottom;
  519. if (isProportionalScaling)
  520. {
  521. Size size = GetProportionalScalingSize(right - left, bottom - top);
  522. left = right - size.Width;
  523. top = bottom - size.Height;
  524. if (left < maxRect.Left)
  525. {
  526. double tmpWidth = right - left;
  527. left = maxRect.Left;
  528. double width = right - left;
  529. double height = (bottom - top) * width / tmpWidth;
  530. top = bottom - height;
  531. }
  532. if (top < maxRect.Top)
  533. {
  534. double tmpHeight = bottom - top;
  535. top = maxRect.Top;
  536. double height = bottom - top;
  537. double width = (right - left) * height / tmpHeight;
  538. left = right - width;
  539. }
  540. }
  541. else
  542. {
  543. if (left + minWidth > right)
  544. {
  545. left = right - minWidth;
  546. }
  547. if (top + minHeight > bottom)
  548. {
  549. top = bottom - minHeight;
  550. }
  551. }
  552. }
  553. break;
  554. case PointControlType.LeftMiddle:
  555. {
  556. left = centerPoint.X + moveVector.X;
  557. right = cacheRect.Right;
  558. top = cacheRect.Top;
  559. bottom = cacheRect.Bottom;
  560. if (left + minWidth > right)
  561. {
  562. left = right - minWidth;
  563. }
  564. }
  565. break;
  566. case PointControlType.LeftBottom:
  567. {
  568. left = centerPoint.X + moveVector.X;
  569. right = cacheRect.Right;
  570. top = cacheRect.Top;
  571. bottom = centerPoint.Y + moveVector.Y;
  572. if (isProportionalScaling)
  573. {
  574. Size size = GetProportionalScalingSize(right - left, bottom - top);
  575. left = right - size.Width;
  576. bottom = top + size.Height;
  577. if (left < maxRect.Left)
  578. {
  579. double tmpWidth = right - left;
  580. left = maxRect.Left;
  581. double width = right - left;
  582. double height = (bottom - top) * width / tmpWidth;
  583. bottom = top + height;
  584. }
  585. if (bottom > maxRect.Bottom)
  586. {
  587. double tmpHeight = bottom - top;
  588. bottom = maxRect.Bottom;
  589. double height = bottom - top;
  590. double width = (right - left) * height / tmpHeight;
  591. left = right - width;
  592. }
  593. }
  594. else
  595. {
  596. if (left + minWidth > right)
  597. {
  598. left = right - minWidth;
  599. }
  600. if (top + minHeight > bottom)
  601. {
  602. bottom = top + minHeight;
  603. }
  604. }
  605. }
  606. break;
  607. case PointControlType.MiddlBottom:
  608. {
  609. left = cacheRect.Left;
  610. right = cacheRect.Right;
  611. top = cacheRect.Top;
  612. bottom = centerPoint.Y + moveVector.Y;
  613. if (top + minHeight > bottom)
  614. {
  615. bottom = top + minHeight;
  616. }
  617. }
  618. break;
  619. case PointControlType.RightBottom:
  620. {
  621. left = cacheRect.Left;
  622. right = centerPoint.X + moveVector.X;
  623. top = cacheRect.Top;
  624. bottom = centerPoint.Y + moveVector.Y;
  625. if (isProportionalScaling)
  626. {
  627. Size size = GetProportionalScalingSize(right - left, bottom - top);
  628. right = left + size.Width;
  629. bottom = top + size.Height;
  630. if (right > maxRect.Right)
  631. {
  632. double tmpWidth = right - left;
  633. right = maxRect.Right;
  634. double width = right - left;
  635. double height = (bottom - top) * width / tmpWidth;
  636. bottom = top + height;
  637. }
  638. if (bottom > maxRect.Bottom)
  639. {
  640. double tmpHeight = bottom - top;
  641. bottom = maxRect.Bottom;
  642. double height = bottom - top;
  643. double width = (right - left) * height / tmpHeight;
  644. right = left + width;
  645. }
  646. }
  647. else
  648. {
  649. if (left + minWidth > right)
  650. {
  651. right = left + minWidth;
  652. }
  653. if (top + minHeight > bottom)
  654. {
  655. bottom = top + minHeight;
  656. }
  657. }
  658. }
  659. break;
  660. case PointControlType.RightMiddle:
  661. {
  662. left = cacheRect.Left;
  663. right = centerPoint.X + moveVector.X;
  664. top = cacheRect.Top;
  665. bottom = cacheRect.Bottom;
  666. if (left + minWidth > right)
  667. {
  668. right = left + minWidth;
  669. }
  670. }
  671. break;
  672. case PointControlType.RightTop:
  673. {
  674. left = cacheRect.Left;
  675. right = centerPoint.X + moveVector.X;
  676. top = centerPoint.Y + moveVector.Y;
  677. bottom = cacheRect.Bottom;
  678. if (isProportionalScaling)
  679. {
  680. Size size = GetProportionalScalingSize(right - left, bottom - top);
  681. right = left + size.Width;
  682. top = bottom - size.Height;
  683. if (right > maxRect.Right)
  684. {
  685. double tmpWidth = right - left;
  686. right = maxRect.Right;
  687. double width = right - left;
  688. double height = (bottom - top) * width / tmpWidth;
  689. top = bottom - height;
  690. }
  691. if (top < maxRect.Top)
  692. {
  693. double tmpHeight = bottom - top;
  694. top = maxRect.Top;
  695. double height = bottom - top;
  696. double width = (right - left) * height / tmpHeight;
  697. right = left + width;
  698. }
  699. }
  700. else
  701. {
  702. if (left + minWidth > right)
  703. {
  704. right = left + minWidth;
  705. }
  706. if (top + minHeight > bottom)
  707. {
  708. top = bottom - minHeight;
  709. }
  710. }
  711. }
  712. break;
  713. case PointControlType.MiddleTop:
  714. {
  715. left = cacheRect.Left;
  716. right = cacheRect.Right;
  717. top = centerPoint.Y + moveVector.Y;
  718. bottom = cacheRect.Bottom;
  719. if (top + minHeight > bottom)
  720. {
  721. top = bottom - minHeight;
  722. }
  723. }
  724. break;
  725. case PointControlType.Body:
  726. case PointControlType.Line:
  727. {
  728. double newleft = maxRect.Left - SetDrawRect.Width + 10;
  729. double newright = maxRect.Right + SetDrawRect.Width - 10;
  730. double newtop = maxRect.Top - SetDrawRect.Height + 10;
  731. double newbottom = maxRect.Bottom + SetDrawRect.Height - 10;
  732. if (newleft < 0)
  733. {
  734. newleft = 0;
  735. }
  736. Rect newMaxRect = new Rect(newleft, newtop, newright - newleft, newbottom - newtop);
  737. Point OffsetPos = CalcMoveBound(cacheRect, ((Point)(mousePoint - mouseDownPoint)), newMaxRect);
  738. left = cacheRect.Left + OffsetPos.X;
  739. right = cacheRect.Right + OffsetPos.X;
  740. top = cacheRect.Top + OffsetPos.Y;
  741. bottom = cacheRect.Bottom + OffsetPos.Y;
  742. }
  743. break;
  744. default:
  745. break;
  746. }
  747. //if (left < maxRect.Left)
  748. //{
  749. // left = maxRect.Left;
  750. //}
  751. //if (top < maxRect.Top)
  752. //{
  753. // top = maxRect.Top;
  754. //}
  755. if (right > maxRect.Right + SetDrawRect.Width - 10)
  756. {
  757. if (left > maxRect.Right - 10)
  758. {
  759. left = maxRect.Right - 10;
  760. }
  761. right = maxRect.Right + SetDrawRect.Width - 10;
  762. }
  763. if (bottom > maxRect.Bottom + SetDrawRect.Height - 10)
  764. {
  765. if (top > maxRect.Bottom - 10)
  766. {
  767. top = maxRect.Bottom - 10;
  768. }
  769. bottom = maxRect.Bottom + SetDrawRect.Height - 10;
  770. }
  771. drawRect = new Rect(left, top, right - left, bottom - top);
  772. moveOffset = new Point(drawRect.X - cacheRect.X, drawRect.Y - cacheRect.Y);
  773. return true;
  774. }
  775. catch (Exception ex)
  776. {
  777. }
  778. return false;
  779. }
  780. /// <summary>
  781. /// Proportional scaling offset calibration
  782. /// </summary>
  783. /// <param name="movePoint">
  784. /// The current movement point
  785. /// </param>
  786. /// <returns>
  787. /// The offset point after the proportional scaling
  788. /// </returns>
  789. protected Point ProportionalScalingOffsetPos(Point movePoint)
  790. {
  791. if (isProportionalScaling)
  792. {
  793. Point offsetPos = movePoint;
  794. double ratioX = cacheRect.Width > 0 ? cacheRect.Height / cacheRect.Width : 1;
  795. double ratioY = cacheRect.Height > 0 ? cacheRect.Width / cacheRect.Height : 1;
  796. switch (hitControlType)
  797. {
  798. case PointControlType.LeftTop:
  799. case PointControlType.RightBottom:
  800. offsetPos = new Point(movePoint.X, Math.Abs(movePoint.X) * ratioX * (movePoint.X < 0 ? -1 : 1));
  801. break;
  802. case PointControlType.LeftBottom:
  803. case PointControlType.RightTop:
  804. offsetPos = new Point(movePoint.X, Math.Abs(movePoint.X) * ratioX * (movePoint.X < 0 ? 1 : -1));
  805. break;
  806. case PointControlType.LeftMiddle:
  807. offsetPos = new Point(movePoint.X, Math.Abs(movePoint.X) * ratioX * (movePoint.X < 0 ? 1 : -1));
  808. break;
  809. case PointControlType.RightMiddle:
  810. offsetPos = new Point(movePoint.X, Math.Abs(movePoint.X) * ratioX * (movePoint.X < 0 ? -1 : 1));
  811. break;
  812. case PointControlType.MiddlBottom:
  813. offsetPos = new Point(Math.Abs(movePoint.Y) * ratioY * (movePoint.Y < 0 ? 1 : -1), movePoint.Y);
  814. break;
  815. case PointControlType.MiddleTop:
  816. offsetPos = new Point(Math.Abs(movePoint.Y) * ratioY * (movePoint.Y < 0 ? -1 : 1), movePoint.Y);
  817. break;
  818. default:
  819. break;
  820. }
  821. return offsetPos;
  822. }
  823. else
  824. {
  825. return movePoint;
  826. }
  827. }
  828. /// <summary>
  829. /// Inner drawing circle point
  830. /// </summary>
  831. /// <param name="drawingContext">
  832. /// Drawing context
  833. /// </param>
  834. /// <param name="ignoreList">
  835. /// Collection of positions that need to be drawn
  836. /// </param>
  837. /// <param name="PointSize">
  838. /// Size of the point
  839. /// </param>
  840. /// <param name="PointPen">
  841. /// Brush for drawing points
  842. /// </param>
  843. /// <param name="BorderBrush">
  844. /// Border brush for drawing points
  845. /// </param>
  846. protected void DrawCirclePoint(DrawingContext drawingContext, List<PointControlType> ignoreList, int PointSize, Pen PointPen, SolidColorBrush BorderBrush)
  847. {
  848. GeometryGroup controlGroup = new GeometryGroup();
  849. controlGroup.FillRule = FillRule.Nonzero;
  850. List<Point> ignorePointsList = new List<Point>();
  851. // Get specific points
  852. foreach (PointControlType type in ignoreList)
  853. {
  854. if ((int)type < controlPoints.Count)
  855. {
  856. ignorePointsList.Add(controlPoints[(int)type]);
  857. }
  858. }
  859. for (int i = 0; i < controlPoints.Count; i++)
  860. {
  861. Point controlPoint = controlPoints[i];
  862. if (ignorePointsList.Contains(controlPoint))
  863. {
  864. continue;
  865. }
  866. EllipseGeometry circlPoint = new EllipseGeometry(controlPoint, PointSize, PointSize);
  867. controlGroup.Children.Add(circlPoint);
  868. }
  869. drawingContext?.DrawGeometry(BorderBrush, PointPen, controlGroup);
  870. }
  871. /// <summary>
  872. /// Inner drawing square
  873. /// </summary>
  874. /// <param name="drawingContext">
  875. /// Drawing context
  876. /// </param>
  877. /// <param name="ControlPoints">
  878. /// Collection of positions that need to be drawn
  879. /// </param>
  880. /// <param name="PointSize">
  881. /// Size of the point
  882. /// </param>
  883. /// <param name="PointPen">
  884. /// Brush for drawing points
  885. /// </param>
  886. /// <param name="BorderBrush">
  887. /// Border brush for drawing points
  888. /// </param>
  889. protected void DrawSquarePoint(DrawingContext drawingContext, List<PointControlType> ignoreList, int PointSize, Pen PointPen, SolidColorBrush BorderBrush)
  890. {
  891. GeometryGroup controlGroup = new GeometryGroup();
  892. controlGroup.FillRule = FillRule.Nonzero;
  893. List<Point> ignorePointsList = new List<Point>();
  894. // Get specific points
  895. foreach (PointControlType type in ignoreList)
  896. {
  897. if ((int)type < controlPoints.Count)
  898. {
  899. ignorePointsList.Add(controlPoints[(int)type]);
  900. }
  901. }
  902. for (int i = 0; i < controlPoints.Count; i++)
  903. {
  904. Point controlPoint = controlPoints[i];
  905. if (ignorePointsList.Contains(controlPoint))
  906. {
  907. continue;
  908. }
  909. RectangleGeometry rectPoint = new RectangleGeometry(new Rect(controlPoint.X - PointSize, controlPoint.Y - PointSize,
  910. PointSize * 2, PointSize * 2), 1, 1);
  911. controlGroup.Children.Add(rectPoint);
  912. }
  913. drawingContext?.DrawGeometry(BorderBrush, PointPen, controlGroup);
  914. }
  915. protected void DrawCropPoint(DrawingContext drawingContext, List<PointControlType> ignoreList, int PointSize, Pen PointPen, SolidColorBrush BorderBrush)
  916. {
  917. //GeometryGroup controlGroup = new GeometryGroup();
  918. //controlGroup.FillRule = FillRule.Nonzero;
  919. clipThickness.Left = SetDrawRect.Left - drawRect.Left;
  920. clipThickness.Top = SetDrawRect.Top - drawRect.Top;
  921. clipThickness.Right = SetDrawRect.Right - drawRect.Right;
  922. clipThickness.Bottom = SetDrawRect.Bottom - drawRect.Bottom;
  923. List<Point> controlCurrentPoints = GetControlPoint(drawRect);
  924. CombinedGeometry controlGroup = new CombinedGeometry();
  925. RectangleGeometry paintGeometry = new RectangleGeometry();
  926. paintGeometry.Rect = SetDrawRect;
  927. controlGroup.Geometry1 = paintGeometry;
  928. RectangleGeometry moveGeometry = new RectangleGeometry();
  929. Rect clippedBorder = drawRect;
  930. if (clippedBorder.IsEmpty == false)
  931. {
  932. moveGeometry.Rect = drawRect;
  933. }
  934. controlGroup.Geometry2 = moveGeometry;
  935. controlGroup.GeometryCombineMode = GeometryCombineMode.Exclude;
  936. //Left Top Corner
  937. if (!ignoreList.Contains(PointControlType.LeftTop))
  938. {
  939. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[0].X - PointSize, controlCurrentPoints[0].Y - PointSize, PointSize, PointSize * 4));
  940. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[0].X - PointSize, controlCurrentPoints[0].Y - PointSize, PointSize * 4, PointSize));
  941. }
  942. //Left Center
  943. if (!ignoreList.Contains(PointControlType.LeftMiddle))
  944. {
  945. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[1].X - PointSize, (controlCurrentPoints[1].Y + controlCurrentPoints[1].Y - PointSize * 5) / 2, PointSize, PointSize * 5));
  946. }
  947. //Left Bottom Corner
  948. if (!ignoreList.Contains(PointControlType.LeftBottom))
  949. {
  950. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[2].X - PointSize, controlCurrentPoints[2].Y - PointSize * 3, PointSize, PointSize * 4));
  951. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[2].X - PointSize, controlCurrentPoints[2].Y, PointSize * 4, PointSize));
  952. }
  953. //Bottom Center
  954. if (!ignoreList.Contains(PointControlType.MiddlBottom))
  955. {
  956. drawingContext?.DrawRectangle(BorderBrush, null, new Rect((controlCurrentPoints[3].X + controlCurrentPoints[3].X - PointSize * 5) / 2, controlCurrentPoints[3].Y, PointSize * 5, PointSize));
  957. }
  958. //Bottom Right Corner
  959. if (!ignoreList.Contains(PointControlType.RightBottom))
  960. {
  961. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[4].X, controlCurrentPoints[4].Y - PointSize * 3, PointSize, PointSize * 4));
  962. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[4].X - PointSize * 3, controlCurrentPoints[4].Y, PointSize * 4, PointSize));
  963. }
  964. //Right Center
  965. if (!ignoreList.Contains(PointControlType.RightMiddle))
  966. {
  967. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[5].X, (controlCurrentPoints[5].Y + controlCurrentPoints[5].Y - PointSize * 5) / 2, PointSize, PointSize * 5));
  968. }
  969. //Right Top Corner
  970. if (!ignoreList.Contains(PointControlType.RightTop))
  971. {
  972. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[6].X, controlCurrentPoints[6].Y - PointSize, PointSize, PointSize * 4));
  973. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[6].X - PointSize * 4, controlCurrentPoints[6].Y - PointSize, PointSize * 4, PointSize));
  974. }
  975. //Top Center
  976. if (!ignoreList.Contains(PointControlType.MiddleTop))
  977. {
  978. drawingContext?.DrawRectangle(BorderBrush, null, new Rect((controlCurrentPoints[7].X + controlCurrentPoints[7].X - PointSize * 5) / 2, controlCurrentPoints[7].Y - PointSize, PointSize * 5, PointSize));
  979. }
  980. BorderBrush = new SolidColorBrush(Color.FromArgb(0x3F, 0x00, 0x00, 0x00));
  981. drawingContext?.DrawGeometry(BorderBrush, PointPen, controlGroup);
  982. }
  983. /// <summary>
  984. /// Draw the reference line in the moving state
  985. /// </summary>
  986. /// <param name="drawDc">
  987. /// Draw context handle
  988. /// </param>
  989. /// <param name="controltype">
  990. /// Current selected control point type
  991. /// </param>
  992. /// <param name="activePen">
  993. /// Brush for drawing lines
  994. /// </param>
  995. /// <param name="moveBrush">
  996. /// Brush for drawing rectangles
  997. /// </param>
  998. /// <param name="moveRect">
  999. /// Current rectangle to draw
  1000. /// </param>
  1001. protected void DrawMoveBounds(DrawingContext drawDc, PointControlType controltype, Pen activePen, Brush moveBrush, Rect moveRect, Pen RectPen = null)
  1002. {
  1003. switch (controltype)
  1004. {
  1005. case PointControlType.LeftTop:
  1006. drawDc?.DrawLine(activePen, new Point(0, moveRect.Top), new Point(PDFViewerActualWidth, moveRect.Top));
  1007. drawDc?.DrawLine(activePen, new Point(moveRect.Left, 0), new Point(moveRect.Left, PDFViewerActualHeight));
  1008. break;
  1009. case PointControlType.LeftMiddle:
  1010. drawDc?.DrawLine(activePen, new Point(moveRect.Left, 0), new Point(moveRect.Left, PDFViewerActualHeight));
  1011. break;
  1012. case PointControlType.LeftBottom:
  1013. drawDc?.DrawLine(activePen, new Point(0, moveRect.Bottom), new Point(PDFViewerActualWidth, moveRect.Bottom));
  1014. drawDc?.DrawLine(activePen, new Point(moveRect.Left, 0), new Point(moveRect.Left, PDFViewerActualHeight));
  1015. break;
  1016. case PointControlType.MiddlBottom:
  1017. drawDc?.DrawLine(activePen, new Point(0, moveRect.Bottom), new Point(PDFViewerActualWidth, moveRect.Bottom));
  1018. break;
  1019. case PointControlType.RightBottom:
  1020. drawDc?.DrawLine(activePen, new Point(0, moveRect.Bottom), new Point(PDFViewerActualWidth, moveRect.Bottom));
  1021. drawDc?.DrawLine(activePen, new Point(moveRect.Right, 0), new Point(moveRect.Right, PDFViewerActualHeight));
  1022. break;
  1023. case PointControlType.RightMiddle:
  1024. drawDc?.DrawLine(activePen, new Point(moveRect.Right, 0), new Point(moveRect.Right, PDFViewerActualHeight));
  1025. break;
  1026. case PointControlType.RightTop:
  1027. drawDc?.DrawLine(activePen, new Point(0, moveRect.Top), new Point(PDFViewerActualWidth, moveRect.Top));
  1028. drawDc?.DrawLine(activePen, new Point(moveRect.Right, 0), new Point(moveRect.Right, PDFViewerActualHeight));
  1029. break;
  1030. case PointControlType.MiddleTop:
  1031. drawDc?.DrawLine(activePen, new Point(0, moveRect.Top), new Point(PDFViewerActualWidth, moveRect.Top));
  1032. break;
  1033. case PointControlType.Rotate:
  1034. break;
  1035. case PointControlType.Body:
  1036. case PointControlType.Line:
  1037. drawDc?.DrawLine(activePen, new Point(0, moveRect.Top), new Point(moveRect.Left, moveRect.Top));
  1038. drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Top), new Point(PDFViewerActualWidth, moveRect.Top));
  1039. drawDc?.DrawLine(activePen, new Point(moveRect.Left, moveRect.Top), new Point(moveRect.Left, 0));
  1040. drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Top), new Point(moveRect.Right, 0));
  1041. drawDc?.DrawLine(activePen, new Point(0, moveRect.Bottom), new Point(moveRect.Left, moveRect.Bottom));
  1042. drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Bottom), new Point(PDFViewerActualWidth, moveRect.Bottom));
  1043. drawDc?.DrawLine(activePen, new Point(moveRect.Left, moveRect.Bottom), new Point(moveRect.Left, PDFViewerActualHeight));
  1044. drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Bottom), new Point(moveRect.Right, PDFViewerActualHeight));
  1045. break;
  1046. default:
  1047. break;
  1048. }
  1049. drawDc?.DrawRectangle(moveBrush, RectPen, moveRect);
  1050. }
  1051. /// <summary>
  1052. /// Notify the event during/after the drawing data
  1053. /// </summary>
  1054. /// <param name="isFinish">
  1055. /// Identifies whether the data change is complete
  1056. /// </param>
  1057. protected void InvokeDataChangEvent(bool isFinish)
  1058. {
  1059. selectedRectData.Square = GetRect();
  1060. if (isFinish)
  1061. {
  1062. DataChanged?.Invoke(this, selectedRectData);
  1063. }
  1064. else
  1065. {
  1066. DataChanging?.Invoke(this, selectedRectData);
  1067. }
  1068. }
  1069. /// <summary>
  1070. /// Align the rectangle drawing
  1071. /// </summary>
  1072. /// <param name="RectMovePoint">
  1073. /// Move distance required for the aligned algorithm to obtain the rectangle
  1074. /// </param>
  1075. private void DrawAlignRect(Point RectMovePoint)
  1076. {
  1077. double TmpLeft, TmpRight, TmpUp, TmpDown;
  1078. Point OffsetPos = CalcMoveBound(drawRect, RectMovePoint, maxRect);
  1079. TmpLeft = drawRect.Left + OffsetPos.X;
  1080. TmpRight = drawRect.Right + OffsetPos.X;
  1081. TmpUp = drawRect.Top + OffsetPos.Y;
  1082. TmpDown = drawRect.Bottom + OffsetPos.Y;
  1083. SetDrawRect = drawRect = new Rect(TmpLeft, TmpUp, TmpRight - TmpLeft, TmpDown - TmpUp);
  1084. Draw();
  1085. }
  1086. /// <summary>
  1087. /// Get the current set of ignore points
  1088. /// </summary>
  1089. /// <returns>
  1090. /// Data set of ignored points
  1091. /// </returns>
  1092. private List<PointControlType> GetIgnorePoints()
  1093. {
  1094. List<PointControlType> IgnorePointsList = new List<PointControlType>();
  1095. foreach (PointControlType type in ignorePoints)
  1096. {
  1097. IgnorePointsList.Add(type);
  1098. }
  1099. return IgnorePointsList;
  1100. }
  1101. #endregion
  1102. }
  1103. }