SelectedRect.protected.cs 68 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Windows;
  5. using System.Windows.Media;
  6. namespace ComPDFKit.Tool.DrawTool
  7. {
  8. public partial class SelectedRect
  9. {
  10. #region Properties
  11. /// <summary>
  12. /// Current control point drawing style.
  13. /// </summary>
  14. protected DrawPointType currentDrawPointType
  15. {
  16. get;
  17. set;
  18. }
  19. /// <summary>
  20. /// Current drag drawing style.
  21. /// </summary>
  22. protected DrawMoveType currentDrawMoveType { get; set; }
  23. /// <summary>
  24. /// Current click hit control point.
  25. /// </summary>
  26. protected PointControlType hitControlType
  27. {
  28. get;
  29. set;
  30. }
  31. /// <summary>
  32. /// Mouse down position information.
  33. /// </summary>
  34. protected Point mouseDownPoint { get; set; }
  35. /// <summary>
  36. /// Whether the mouse is pressed.
  37. /// </summary>
  38. protected bool isMouseDown { get; set; }
  39. protected bool isInRotate { get; set; } = false;
  40. protected bool isInScaling { get; set; } = false;
  41. /// <summary>
  42. /// Whether proportional scaling is required.
  43. /// </summary>
  44. protected bool isProportionalScaling { get; set; } = false;
  45. /// <summary>
  46. /// Current control point size.
  47. /// </summary>
  48. protected int pointSize { get; set; } = 4;
  49. /// <summary>
  50. /// Rectangular minimum width.
  51. /// </summary>
  52. public int RectMinWidth { get; set; } = 10;
  53. /// <summary>
  54. /// Rectangular minimum height.
  55. /// </summary>
  56. public int RectMinHeight { get; set; } = 10;
  57. /// <summary>
  58. /// Current set of ignore points.
  59. /// </summary>
  60. protected List<PointControlType> ignorePoints { get; set; } = new List<PointControlType>();
  61. /// <summary>
  62. /// Current set of drawing rectangles (original data).
  63. /// </summary>
  64. protected Rect SetDrawRect
  65. {
  66. get;
  67. set;
  68. } = new Rect(0, 0, 0, 0);
  69. /// <summary>
  70. /// Current drawing rectangle (calculated during operation).
  71. /// </summary>
  72. protected Rect drawRect
  73. {
  74. get;
  75. set;
  76. } = new Rect(0, 0, 0, 0);
  77. /// <summary>
  78. /// Maximum range that can be drawn.
  79. /// </summary>
  80. protected Rect maxRect { get; set; } = new Rect(0, 0, 0, 0);
  81. /// <summary>
  82. /// Current center point of the drawing rectangle.
  83. /// </summary>
  84. protected Point drawCenterPoint { get; private set; } = new Point(0, 0);
  85. /// <summary>
  86. /// When the mouse is pressed, the cached rectangle.
  87. /// </summary>
  88. protected Rect cacheRect { get; set; } = new Rect(0, 0, 0, 0);
  89. /// <summary>
  90. /// Current control point coordinates.
  91. /// </summary>
  92. protected List<Point> controlPoints { get; set; } = new List<Point>();
  93. protected Point centerPoint = new Point();
  94. protected Point rotationPoint = new Point();
  95. protected Point dragRotationPoint = new Point();
  96. /// <summary>
  97. /// Move offset during movement.
  98. /// </summary>
  99. protected Point moveOffset { get; set; } = new Point(0, 0);
  100. /// <summary>
  101. /// Current drawing rectangle (calculated during operation).
  102. /// </summary>
  103. protected Thickness clipThickness = new Thickness(0, 0, 0, 0);
  104. private Pen editPen { get; set; } = new Pen(new SolidColorBrush(Color.FromRgb(71, 126, 222)), 2) { DashStyle = DashStyles.Dash };
  105. private Pen editHoverPen { get; set; } = new Pen(new SolidColorBrush(Color.FromRgb(71, 126, 222)), 2) { DashStyle = DashStyles.Dash };
  106. private bool showCreatTextRect = false;
  107. protected bool isOutSideScaling = false;
  108. /// <summary>
  109. /// Current actual display width and height of PDFVIewer.
  110. /// </summary>
  111. protected double PDFViewerActualWidth { get; set; } = 0;
  112. protected double PDFViewerActualHeight { get; set; } = 0;
  113. protected int rotateAngle { get; set; } = 0;
  114. protected int pageRotation { get; set; } = 0;
  115. protected double rectPadding = 6;
  116. protected double currentZoom = 1;
  117. protected SelectedAnnotData selectedRectData = new SelectedAnnotData();
  118. protected bool disable = false;
  119. protected List<Point> rotateControlPoints = new List<Point>();
  120. protected Rect rotateRect = new Rect();
  121. public bool IsPath { get; set; } = false;
  122. #endregion
  123. #region Functions
  124. /// <summary>
  125. /// Calcuate the control points
  126. /// </summary>
  127. /// <param name="currentRect">
  128. /// Control points in the target rectangle
  129. /// </param>
  130. protected void CalcControlPoint(Rect currentRect)
  131. {
  132. controlPoints.Clear();
  133. centerPoint.X = (int)(currentRect.Left + currentRect.Right) / 2;
  134. centerPoint.Y = (int)(currentRect.Top + currentRect.Bottom) / 2;
  135. controlPoints.Add(new Point(currentRect.Left, currentRect.Top));
  136. controlPoints.Add(new Point(currentRect.Left, centerPoint.Y));
  137. controlPoints.Add(new Point(currentRect.Left, currentRect.Bottom));
  138. controlPoints.Add(new Point(centerPoint.X, currentRect.Bottom));
  139. controlPoints.Add(new Point(currentRect.Right, currentRect.Bottom));
  140. controlPoints.Add(new Point(currentRect.Right, centerPoint.Y));
  141. controlPoints.Add(new Point(currentRect.Right, currentRect.Top));
  142. controlPoints.Add(new Point(centerPoint.X, currentRect.Top));
  143. if (canRotate)
  144. {
  145. rotationPoint = new Point(centerPoint.X, currentRect.Top - 30);
  146. switch (pageRotation)
  147. {
  148. case 0:
  149. rotationPoint = new Point(centerPoint.X, currentRect.Top - 30);
  150. break;
  151. case 1:
  152. rotationPoint = new Point(currentRect.Right + 30, centerPoint.Y);
  153. break;
  154. case 2:
  155. rotationPoint = new Point(centerPoint.X, currentRect.Bottom + 30);
  156. break;
  157. case 3:
  158. rotationPoint = new Point(currentRect.Left - 30, centerPoint.Y);
  159. break;
  160. default:
  161. break;
  162. }
  163. }
  164. }
  165. protected List<Point> GetControlPoint(Rect currentRect)
  166. {
  167. List<Point> controlCurrentPoints = new List<Point>();
  168. controlCurrentPoints.Clear();
  169. int centerX = (int)(currentRect.Left + currentRect.Right) / 2;
  170. int centerY = (int)(currentRect.Top + currentRect.Bottom) / 2;
  171. controlCurrentPoints.Add(new Point(currentRect.Left, currentRect.Top));
  172. controlCurrentPoints.Add(new Point(currentRect.Left, centerY));
  173. controlCurrentPoints.Add(new Point(currentRect.Left, currentRect.Bottom));
  174. controlCurrentPoints.Add(new Point(centerX, currentRect.Bottom));
  175. controlCurrentPoints.Add(new Point(currentRect.Right, currentRect.Bottom));
  176. controlCurrentPoints.Add(new Point(currentRect.Right, centerY));
  177. controlCurrentPoints.Add(new Point(currentRect.Right, currentRect.Top));
  178. controlCurrentPoints.Add(new Point(centerX, currentRect.Top));
  179. return controlCurrentPoints;
  180. }
  181. /// <summary>
  182. /// Calcuate the offset of the current rectangle in the maximum rectangle range
  183. /// </summary>
  184. /// <param name="currentRect">
  185. /// The rectangle cached when pressed
  186. /// </param>
  187. /// <param name="offsetPoint">
  188. /// Equivalent to the offset value when pressed
  189. /// </param>
  190. /// <param name="maxRect">
  191. /// The maximum rectangle range.
  192. /// </param>
  193. /// <returns></returns>
  194. protected Point CalcMoveBound(Rect currentRect, Point offsetPoint, Rect maxRect)
  195. {
  196. double cLeft = currentRect.Left;
  197. double cRight = currentRect.Right;
  198. double cUp = currentRect.Top;
  199. double cDown = currentRect.Bottom;
  200. double TmpLeft = cLeft + offsetPoint.X;
  201. double TmpRight = cRight + offsetPoint.X;
  202. double TmpUp = cUp + offsetPoint.Y;
  203. double TmpDown = cDown + offsetPoint.Y;
  204. if (TmpLeft < maxRect.Left)
  205. {
  206. TmpRight = (cRight - cLeft) + maxRect.Left;
  207. TmpLeft = maxRect.Left;
  208. }
  209. if (TmpUp < maxRect.Top)
  210. {
  211. TmpDown = (cDown - cUp) + maxRect.Top;
  212. TmpUp = maxRect.Top;
  213. }
  214. if (TmpRight > maxRect.Right)
  215. {
  216. TmpLeft = maxRect.Right - (cRight - cLeft);
  217. TmpRight = maxRect.Right;
  218. }
  219. if (TmpDown > maxRect.Bottom)
  220. {
  221. TmpUp = maxRect.Bottom - (cDown - cUp);
  222. TmpDown = maxRect.Bottom;
  223. }
  224. offsetPoint = new Point(TmpLeft - cLeft, TmpUp - cUp);
  225. return offsetPoint;
  226. }
  227. /// <summary>
  228. /// Calculate the movement of the hit point
  229. /// </summary>
  230. /// <param name="mousePoint">
  231. /// Current mouse position
  232. /// </param>
  233. /// <returns>
  234. /// Whether the movement is successful
  235. /// </returns>
  236. protected bool CalcHitPointMove(Point mousePoint)
  237. {
  238. if (isMouseDown == false || hitControlType == PointControlType.None)
  239. {
  240. return false;
  241. }
  242. if (hitControlType == PointControlType.Rotate)
  243. {
  244. SetRotateByMousePoint(mousePoint);
  245. return false;
  246. }
  247. if (!isOutSideScaling)
  248. {
  249. if (selectedRectData.rotationAngle != 0)
  250. {
  251. return RotateScaling(mousePoint);
  252. }
  253. else
  254. {
  255. return NormalScaling(mousePoint);
  256. }
  257. }
  258. else
  259. {
  260. return OutSideScaling(mousePoint);
  261. }
  262. }
  263. public void SetOutSideScaling(bool IsOutSideScaling)
  264. {
  265. isOutSideScaling = IsOutSideScaling;
  266. }
  267. private Size GetProportionalScalingSize(double width, double height)
  268. {
  269. double minHeight = RectMinHeight + 2 * rectPadding * currentZoom;
  270. double minWidth = RectMinWidth + 2 * rectPadding * currentZoom;
  271. if (minWidth > width || minHeight > height)
  272. {
  273. if (cacheRect.Width >= cacheRect.Height)
  274. {
  275. width = cacheRect.Width * minHeight / cacheRect.Height;
  276. height = minHeight;
  277. }
  278. else
  279. {
  280. height = cacheRect.Height * minWidth / cacheRect.Width;
  281. width = minWidth;
  282. }
  283. }
  284. return new Size(width, height);
  285. }
  286. private void SetRotateByMousePoint(Point mousePoint)
  287. {
  288. dragRotationPoint = mousePoint;
  289. Vector moveVector = (mousePoint - centerPoint);
  290. rotateAngle = (int)(Math.Atan2(moveVector.X, -moveVector.Y) * 180 / Math.PI) - pageRotation * 90;
  291. }
  292. /// <summary>
  293. /// Draw the algorithm in the form of normal scaling (drag a point, only scale in one direction).
  294. /// </summary>
  295. /// <param name="mousePoint">Current mouse position.</param>
  296. /// <returns></returns>
  297. protected bool NormalScaling(Point mousePoint)
  298. {
  299. try
  300. {
  301. double left = 0, right = 0, top = 0, bottom = 0;
  302. double minHeight = RectMinHeight + 2 * rectPadding * currentZoom;
  303. double minWidth = RectMinWidth + 2 * rectPadding * currentZoom;
  304. Point centerPoint = new Point((cacheRect.Right + cacheRect.Left) / 2, (cacheRect.Bottom + cacheRect.Top) / 2);
  305. Point moveVector = (Point)(mousePoint - centerPoint);
  306. moveVector = ProportionalScalingOffsetPos(moveVector);
  307. switch (hitControlType)
  308. {
  309. case PointControlType.LeftTop:
  310. {
  311. left = centerPoint.X + moveVector.X;
  312. right = cacheRect.Right;
  313. top = centerPoint.Y + moveVector.Y;
  314. bottom = cacheRect.Bottom;
  315. if (isProportionalScaling)
  316. {
  317. Size size = GetProportionalScalingSize(right - left, bottom - top);
  318. left = right - size.Width;
  319. top = bottom - size.Height;
  320. if (left < maxRect.Left)
  321. {
  322. double tmpWidth = right - left;
  323. left = maxRect.Left;
  324. double width = right - left;
  325. double height = (bottom - top) * width / tmpWidth;
  326. top = bottom - height;
  327. }
  328. if (top < maxRect.Top)
  329. {
  330. double tmpHeight = bottom - top;
  331. top = maxRect.Top;
  332. double height = bottom - top;
  333. double width = (right - left) * height / tmpHeight;
  334. left = right - width;
  335. }
  336. }
  337. else
  338. {
  339. if (left + minWidth > right)
  340. {
  341. left = right - minWidth;
  342. }
  343. if (top + minHeight > bottom)
  344. {
  345. top = bottom - minHeight;
  346. }
  347. }
  348. }
  349. break;
  350. case PointControlType.LeftMiddle:
  351. {
  352. left = centerPoint.X + moveVector.X;
  353. right = cacheRect.Right;
  354. top = cacheRect.Top;
  355. bottom = cacheRect.Bottom;
  356. if (left + minWidth > right)
  357. {
  358. left = right - minWidth;
  359. }
  360. }
  361. break;
  362. case PointControlType.LeftBottom:
  363. {
  364. left = centerPoint.X + moveVector.X;
  365. right = cacheRect.Right;
  366. top = cacheRect.Top;
  367. bottom = centerPoint.Y + moveVector.Y;
  368. if (isProportionalScaling)
  369. {
  370. Size size = GetProportionalScalingSize(right - left, bottom - top);
  371. left = right - size.Width;
  372. bottom = top + size.Height;
  373. if (left < maxRect.Left)
  374. {
  375. double tmpWidth = right - left;
  376. left = maxRect.Left;
  377. double width = right - left;
  378. double height = (bottom - top) * width / tmpWidth;
  379. bottom = top + height;
  380. }
  381. if (bottom > maxRect.Bottom)
  382. {
  383. double tmpHeight = bottom - top;
  384. bottom = maxRect.Bottom;
  385. double height = bottom - top;
  386. double width = (right - left) * height / tmpHeight;
  387. left = right - width;
  388. }
  389. }
  390. else
  391. {
  392. if (left + minWidth > right)
  393. {
  394. left = right - minWidth;
  395. }
  396. if (top + minHeight > bottom)
  397. {
  398. bottom = top + minHeight;
  399. }
  400. }
  401. }
  402. break;
  403. case PointControlType.MiddleBottom:
  404. {
  405. left = cacheRect.Left;
  406. right = cacheRect.Right;
  407. top = cacheRect.Top;
  408. bottom = centerPoint.Y + moveVector.Y;
  409. if (top + minHeight > bottom)
  410. {
  411. bottom = top + minHeight;
  412. }
  413. }
  414. break;
  415. case PointControlType.RightBottom:
  416. {
  417. left = cacheRect.Left;
  418. right = centerPoint.X + moveVector.X;
  419. top = cacheRect.Top;
  420. bottom = centerPoint.Y + moveVector.Y;
  421. if (isProportionalScaling)
  422. {
  423. Size size = GetProportionalScalingSize(right - left, bottom - top);
  424. right = left + size.Width;
  425. bottom = top + size.Height;
  426. if (right > maxRect.Right)
  427. {
  428. double tmpWidth = right - left;
  429. right = maxRect.Right;
  430. double width = right - left;
  431. double height = (bottom - top) * width / tmpWidth;
  432. bottom = top + height;
  433. }
  434. if (bottom > maxRect.Bottom)
  435. {
  436. double tmpHeight = bottom - top;
  437. bottom = maxRect.Bottom;
  438. double height = bottom - top;
  439. double width = (right - left) * height / tmpHeight;
  440. right = left + width;
  441. }
  442. }
  443. else
  444. {
  445. if (left + minWidth > right)
  446. {
  447. right = left + minWidth;
  448. }
  449. if (top + minHeight > bottom)
  450. {
  451. bottom = top + minHeight;
  452. }
  453. }
  454. }
  455. break;
  456. case PointControlType.RightMiddle:
  457. {
  458. left = cacheRect.Left;
  459. right = centerPoint.X + moveVector.X;
  460. top = cacheRect.Top;
  461. bottom = cacheRect.Bottom;
  462. if (left + minWidth > right)
  463. {
  464. right = left + minWidth;
  465. }
  466. }
  467. break;
  468. case PointControlType.RightTop:
  469. {
  470. left = cacheRect.Left;
  471. right = centerPoint.X + moveVector.X;
  472. top = centerPoint.Y + moveVector.Y;
  473. bottom = cacheRect.Bottom;
  474. if (isProportionalScaling)
  475. {
  476. Size size = GetProportionalScalingSize(right - left, bottom - top);
  477. right = left + size.Width;
  478. top = bottom - size.Height;
  479. if (right > maxRect.Right)
  480. {
  481. double tmpWidth = right - left;
  482. right = maxRect.Right;
  483. double width = right - left;
  484. double height = (bottom - top) * width / tmpWidth;
  485. top = bottom - height;
  486. }
  487. if (top < maxRect.Top)
  488. {
  489. double tmpHeight = bottom - top;
  490. top = maxRect.Top;
  491. double height = bottom - top;
  492. double width = (right - left) * height / tmpHeight;
  493. right = left + width;
  494. }
  495. }
  496. else
  497. {
  498. if (left + minWidth > right)
  499. {
  500. right = left + minWidth;
  501. }
  502. if (top + minHeight > bottom)
  503. {
  504. top = bottom - minHeight;
  505. }
  506. }
  507. }
  508. break;
  509. case PointControlType.MiddleTop:
  510. {
  511. left = cacheRect.Left;
  512. right = cacheRect.Right;
  513. top = centerPoint.Y + moveVector.Y;
  514. bottom = cacheRect.Bottom;
  515. if (top + minHeight > bottom)
  516. {
  517. top = bottom - minHeight;
  518. }
  519. }
  520. break;
  521. case PointControlType.Body:
  522. case PointControlType.Line:
  523. {
  524. Point offsetPos = CalcMoveBound(cacheRect, ((Point)(mousePoint - mouseDownPoint)), maxRect);
  525. left = cacheRect.Left + offsetPos.X;
  526. right = cacheRect.Right + offsetPos.X;
  527. top = cacheRect.Top + offsetPos.Y;
  528. bottom = cacheRect.Bottom + offsetPos.Y;
  529. }
  530. break;
  531. default:
  532. break;
  533. }
  534. if (left < maxRect.Left)
  535. {
  536. left = maxRect.Left;
  537. }
  538. if (top < maxRect.Top)
  539. {
  540. top = maxRect.Top;
  541. }
  542. if (right > maxRect.Right)
  543. {
  544. right = maxRect.Right;
  545. }
  546. if (bottom > maxRect.Bottom)
  547. {
  548. bottom = maxRect.Bottom;
  549. }
  550. drawRect = new Rect(left, top, right - left, bottom - top);
  551. moveOffset = new Point(drawRect.X - cacheRect.X, drawRect.Y - cacheRect.Y);
  552. return true;
  553. }
  554. catch (Exception ex)
  555. {
  556. }
  557. return false;
  558. }
  559. protected bool RotateScaling(Point mouseMovePoint)
  560. {
  561. Point rotatePoint = new Point();
  562. Point hitControlUIPos = new Point();
  563. if (hitControlType < PointControlType.Body)
  564. {
  565. hitControlUIPos = rotateControlPoints[(int)hitControlType];
  566. }
  567. hitControlUIPos = GetRotateUIPoint(hitControlUIPos);
  568. Point centerPoint = new Point((rotateRect.Left + rotateRect.Right) / 2, (rotateRect.Top + rotateRect.Bottom) / 2);
  569. Vector moveVector = mouseMovePoint - mouseDownPoint;
  570. Vector hitVector = hitControlUIPos - centerPoint;
  571. Rect tmpRect = cacheRect;
  572. if (hitControlType == PointControlType.LeftTop
  573. || hitControlType == PointControlType.LeftBottom
  574. || hitControlType == PointControlType.RightTop
  575. || hitControlType == PointControlType.RightBottom)
  576. {
  577. if (isProportionalScaling)
  578. {
  579. double vectorAngle = Vector.AngleBetween(moveVector, hitVector);
  580. double newLenght = Math.Cos(Math.PI / 180.0 * vectorAngle) * moveVector.Length;
  581. hitVector.Normalize();
  582. hitVector.X *= newLenght;
  583. hitVector.Y *= newLenght;
  584. rotatePoint = new Point(hitControlUIPos.X + hitVector.X, hitControlUIPos.Y + hitVector.Y);
  585. }
  586. }
  587. switch (hitControlType)
  588. {
  589. case PointControlType.LeftTop:
  590. {
  591. Point rightBottomPoint = rotateControlPoints[(int)PointControlType.RightBottom];
  592. Point rightBottomUIPos = GetRotateUIPoint(rightBottomPoint);
  593. centerPoint = new Point((rotatePoint.X + rightBottomUIPos.X) / 2, (rotatePoint.Y + rightBottomUIPos.Y) / 2);
  594. Matrix rotateMatrix = new Matrix();
  595. rotateMatrix.RotateAt(-rotateAngle, centerPoint.X, centerPoint.Y);
  596. Point leftTopPoint = rotateMatrix.Transform(rotatePoint);
  597. rightBottomPoint = rotateMatrix.Transform(rightBottomUIPos);
  598. tmpRect = new Rect(leftTopPoint, rightBottomPoint);
  599. }
  600. break;
  601. case PointControlType.LeftBottom:
  602. {
  603. Point rightTopPoint = rotateControlPoints[(int)PointControlType.RightTop];
  604. Point rightTopUIPos = GetRotateUIPoint(rightTopPoint);
  605. centerPoint = new Point((rotatePoint.X + rightTopUIPos.X) / 2, (rotatePoint.Y + rightTopUIPos.Y) / 2);
  606. Matrix rotateMatrix = new Matrix();
  607. rotateMatrix.RotateAt(-rotateAngle, centerPoint.X, centerPoint.Y);
  608. Point leftBottomPoint = rotateMatrix.Transform(rotatePoint);
  609. rightTopPoint = rotateMatrix.Transform(rightTopUIPos);
  610. tmpRect = new Rect(leftBottomPoint, rightTopPoint);
  611. }
  612. break;
  613. case PointControlType.RightTop:
  614. {
  615. Point leftBottomPoint = rotateControlPoints[(int)PointControlType.LeftBottom];
  616. Point leftBottomUIPos = GetRotateUIPoint(leftBottomPoint);
  617. centerPoint = new Point((rotatePoint.X + leftBottomUIPos.X) / 2, (rotatePoint.Y + leftBottomUIPos.Y) / 2);
  618. Matrix rotateMatrix = new Matrix();
  619. rotateMatrix.RotateAt(-rotateAngle, centerPoint.X, centerPoint.Y);
  620. Point rightTopPoint = rotateMatrix.Transform(rotatePoint);
  621. leftBottomPoint = rotateMatrix.Transform(leftBottomUIPos);
  622. tmpRect = new Rect(leftBottomPoint, rightTopPoint);
  623. }
  624. break;
  625. case PointControlType.RightBottom:
  626. {
  627. Point leftTopPoint = rotateControlPoints[(int)PointControlType.LeftTop];
  628. Point leftTopUIPos = GetRotateUIPoint(leftTopPoint);
  629. centerPoint = new Point((rotatePoint.X + leftTopUIPos.X) / 2, (rotatePoint.Y + leftTopUIPos.Y) / 2);
  630. Matrix rotateMatrix = new Matrix();
  631. rotateMatrix.RotateAt(-rotateAngle, centerPoint.X, centerPoint.Y);
  632. Point rightBottomPoint = rotateMatrix.Transform(rotatePoint);
  633. leftTopPoint = rotateMatrix.Transform(leftTopUIPos);
  634. tmpRect = new Rect(leftTopPoint, rightBottomPoint);
  635. }
  636. break;
  637. case PointControlType.Body:
  638. case PointControlType.Line:
  639. {
  640. Point offsetPos = (Point)(mouseMovePoint - mouseDownPoint);
  641. double left = cacheRect.Left + offsetPos.X;
  642. double right = cacheRect.Right + offsetPos.X;
  643. double top = cacheRect.Top + offsetPos.Y;
  644. double bottom = cacheRect.Bottom + offsetPos.Y;
  645. tmpRect = new Rect(new Point(left, top), new Point(right, bottom));
  646. }
  647. break;
  648. default:
  649. break;
  650. }
  651. List<Point> tempPoints = new List<Point>
  652. {
  653. new Point(tmpRect.Left, tmpRect.Top),
  654. new Point(tmpRect.Right, tmpRect.Top),
  655. new Point(tmpRect.Right, tmpRect.Bottom),
  656. new Point(tmpRect.Left, tmpRect.Bottom)
  657. };
  658. List<Point> boundPoint = new List<Point>();
  659. Point center = new Point((tmpRect.Left + tmpRect.Right) / 2, (tmpRect.Top + tmpRect.Bottom) / 2);
  660. foreach (Point point in tempPoints)
  661. {
  662. float x = (float)(center.X + (point.X - center.X) * Math.Cos(rotateAngle * Math.PI / 180) - (point.Y - center.Y) * Math.Sin(rotateAngle * Math.PI / 180));
  663. float y = (float)(center.Y + (point.X - center.X) * Math.Sin(rotateAngle * Math.PI / 180) + (point.Y - center.Y) * Math.Cos(rotateAngle * Math.PI / 180));
  664. boundPoint.Add(new Point(x, y));
  665. }
  666. Rect boundRect = new Rect(new Point(boundPoint.Min(p => p.X), boundPoint.Min(p => p.Y)), new Point(boundPoint.Max(p => p.X), boundPoint.Max(p => p.Y)));
  667. if (maxRect.Contains(boundRect))
  668. {
  669. drawRect = tmpRect;
  670. }
  671. else
  672. {
  673. if (hitControlType == PointControlType.Body || hitControlType == PointControlType.Line)
  674. {
  675. Point boundRectCenterPos = new Point((boundRect.Left + boundRect.Right) / 2, (boundRect.Top + boundRect.Bottom) / 2);
  676. Point maxRectCenterPos = new Point((maxRect.Left + maxRect.Right) / 2, (maxRect.Top + maxRect.Bottom) / 2);
  677. Vector moveCenterVector = boundRectCenterPos - maxRectCenterPos;
  678. Point moveOffsetPos = new Point(0, 0);
  679. if (Math.Abs(moveCenterVector.X) > (maxRect.Width - boundRect.Width) / 2)
  680. {
  681. double moveLength = maxRectCenterPos.X - boundRectCenterPos.X;
  682. moveOffsetPos.X = Math.Abs(moveLength) - (maxRect.Width - boundRect.Width) / 2;
  683. if (moveLength < 0)
  684. {
  685. moveOffsetPos.X *= -1;
  686. }
  687. }
  688. if (Math.Abs(moveCenterVector.Y) > (maxRect.Height - boundRect.Height) / 2)
  689. {
  690. double moveLength = maxRectCenterPos.Y - boundRectCenterPos.Y;
  691. moveOffsetPos.Y = Math.Abs(moveLength) - (maxRect.Height - boundRect.Height) / 2;
  692. if (moveLength < 0)
  693. {
  694. moveOffsetPos.Y *= -1;
  695. }
  696. }
  697. drawRect = new Rect(tmpRect.Left + moveOffsetPos.X, tmpRect.Top + moveOffsetPos.Y, tmpRect.Width, tmpRect.Height);
  698. }
  699. }
  700. moveOffset = new Point(drawRect.X - cacheRect.X, drawRect.Y - cacheRect.Y);
  701. return true;
  702. }
  703. private Point GetRotateUIPoint(Point point)
  704. {
  705. Point centerPoint = new Point((rotateRect.Left + rotateRect.Right) / 2, (rotateRect.Top + rotateRect.Bottom) / 2);
  706. Matrix rotateMatrix = new Matrix();
  707. rotateMatrix.RotateAt(rotateAngle, centerPoint.X, centerPoint.Y);
  708. return rotateMatrix.Transform(point);
  709. }
  710. /// <summary>
  711. /// 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).
  712. /// </summary>
  713. /// <param name="mousePoint">Current mouse position.</param>
  714. /// <returns></returns>
  715. protected bool OutSideScaling(Point mousePoint)
  716. {
  717. try
  718. {
  719. double left = 0, right = 0, top = 0, bottom = 0;
  720. double minHeight = RectMinHeight + 2 * rectPadding * currentZoom;
  721. double minWidth = RectMinWidth + 2 * rectPadding * currentZoom;
  722. Point centerPoint = new Point((cacheRect.Right + cacheRect.Left) / 2, (cacheRect.Bottom + cacheRect.Top) / 2);
  723. Point moveVector = (Point)(mousePoint - centerPoint);
  724. moveVector = ProportionalScalingOffsetPos(moveVector);
  725. switch (hitControlType)
  726. {
  727. case PointControlType.LeftTop:
  728. {
  729. left = centerPoint.X + moveVector.X;
  730. right = cacheRect.Right;
  731. top = centerPoint.Y + moveVector.Y;
  732. bottom = cacheRect.Bottom;
  733. if (isProportionalScaling)
  734. {
  735. Size size = GetProportionalScalingSize(right - left, bottom - top);
  736. left = right - size.Width;
  737. top = bottom - size.Height;
  738. if (left < maxRect.Left)
  739. {
  740. double tmpWidth = right - left;
  741. left = maxRect.Left;
  742. double width = right - left;
  743. double height = (bottom - top) * width / tmpWidth;
  744. top = bottom - height;
  745. }
  746. if (top < maxRect.Top)
  747. {
  748. double tmpHeight = bottom - top;
  749. top = maxRect.Top;
  750. double height = bottom - top;
  751. double width = (right - left) * height / tmpHeight;
  752. left = right - width;
  753. }
  754. }
  755. else
  756. {
  757. if (left + minWidth > right)
  758. {
  759. left = right - minWidth;
  760. }
  761. if (top + minHeight > bottom)
  762. {
  763. top = bottom - minHeight;
  764. }
  765. }
  766. }
  767. break;
  768. case PointControlType.LeftMiddle:
  769. {
  770. left = centerPoint.X + moveVector.X;
  771. right = cacheRect.Right;
  772. top = cacheRect.Top;
  773. bottom = cacheRect.Bottom;
  774. if (left + minWidth > right)
  775. {
  776. left = right - minWidth;
  777. }
  778. }
  779. break;
  780. case PointControlType.LeftBottom:
  781. {
  782. left = centerPoint.X + moveVector.X;
  783. right = cacheRect.Right;
  784. top = cacheRect.Top;
  785. bottom = centerPoint.Y + moveVector.Y;
  786. if (isProportionalScaling)
  787. {
  788. Size size = GetProportionalScalingSize(right - left, bottom - top);
  789. left = right - size.Width;
  790. bottom = top + size.Height;
  791. if (left < maxRect.Left)
  792. {
  793. double tmpWidth = right - left;
  794. left = maxRect.Left;
  795. double width = right - left;
  796. double height = (bottom - top) * width / tmpWidth;
  797. bottom = top + height;
  798. }
  799. if (bottom > maxRect.Bottom)
  800. {
  801. double tmpHeight = bottom - top;
  802. bottom = maxRect.Bottom;
  803. double height = bottom - top;
  804. double width = (right - left) * height / tmpHeight;
  805. left = right - width;
  806. }
  807. }
  808. else
  809. {
  810. if (left + minWidth > right)
  811. {
  812. left = right - minWidth;
  813. }
  814. if (top + minHeight > bottom)
  815. {
  816. bottom = top + minHeight;
  817. }
  818. }
  819. }
  820. break;
  821. case PointControlType.MiddleBottom:
  822. {
  823. left = cacheRect.Left;
  824. right = cacheRect.Right;
  825. top = cacheRect.Top;
  826. bottom = centerPoint.Y + moveVector.Y;
  827. if (top + minHeight > bottom)
  828. {
  829. bottom = top + minHeight;
  830. }
  831. }
  832. break;
  833. case PointControlType.RightBottom:
  834. {
  835. left = cacheRect.Left;
  836. right = centerPoint.X + moveVector.X;
  837. top = cacheRect.Top;
  838. bottom = centerPoint.Y + moveVector.Y;
  839. if (isProportionalScaling)
  840. {
  841. Size size = GetProportionalScalingSize(right - left, bottom - top);
  842. right = left + size.Width;
  843. bottom = top + size.Height;
  844. if (right > maxRect.Right)
  845. {
  846. double tmpWidth = right - left;
  847. right = maxRect.Right;
  848. double width = right - left;
  849. double height = (bottom - top) * width / tmpWidth;
  850. bottom = top + height;
  851. }
  852. if (bottom > maxRect.Bottom)
  853. {
  854. double tmpHeight = bottom - top;
  855. bottom = maxRect.Bottom;
  856. double height = bottom - top;
  857. double width = (right - left) * height / tmpHeight;
  858. right = left + width;
  859. }
  860. }
  861. else
  862. {
  863. if (left + minWidth > right)
  864. {
  865. right = left + minWidth;
  866. }
  867. if (top + minHeight > bottom)
  868. {
  869. bottom = top + minHeight;
  870. }
  871. }
  872. }
  873. break;
  874. case PointControlType.RightMiddle:
  875. {
  876. left = cacheRect.Left;
  877. right = centerPoint.X + moveVector.X;
  878. top = cacheRect.Top;
  879. bottom = cacheRect.Bottom;
  880. if (left + minWidth > right)
  881. {
  882. right = left + minWidth;
  883. }
  884. }
  885. break;
  886. case PointControlType.RightTop:
  887. {
  888. left = cacheRect.Left;
  889. right = centerPoint.X + moveVector.X;
  890. top = centerPoint.Y + moveVector.Y;
  891. bottom = cacheRect.Bottom;
  892. if (isProportionalScaling)
  893. {
  894. Size size = GetProportionalScalingSize(right - left, bottom - top);
  895. right = left + size.Width;
  896. top = bottom - size.Height;
  897. if (right > maxRect.Right)
  898. {
  899. double tmpWidth = right - left;
  900. right = maxRect.Right;
  901. double width = right - left;
  902. double height = (bottom - top) * width / tmpWidth;
  903. top = bottom - height;
  904. }
  905. if (top < maxRect.Top)
  906. {
  907. double tmpHeight = bottom - top;
  908. top = maxRect.Top;
  909. double height = bottom - top;
  910. double width = (right - left) * height / tmpHeight;
  911. right = left + width;
  912. }
  913. }
  914. else
  915. {
  916. if (left + minWidth > right)
  917. {
  918. right = left + minWidth;
  919. }
  920. if (top + minHeight > bottom)
  921. {
  922. top = bottom - minHeight;
  923. }
  924. }
  925. }
  926. break;
  927. case PointControlType.MiddleTop:
  928. {
  929. left = cacheRect.Left;
  930. right = cacheRect.Right;
  931. top = centerPoint.Y + moveVector.Y;
  932. bottom = cacheRect.Bottom;
  933. if (top + minHeight > bottom)
  934. {
  935. top = bottom - minHeight;
  936. }
  937. }
  938. break;
  939. case PointControlType.Body:
  940. case PointControlType.Line:
  941. {
  942. double newleft = maxRect.Left - SetDrawRect.Width + 10;
  943. double newright = maxRect.Right + SetDrawRect.Width - 10;
  944. double newtop = maxRect.Top - SetDrawRect.Height + 10;
  945. double newbottom = maxRect.Bottom + SetDrawRect.Height - 10;
  946. if (newleft < 0)
  947. {
  948. newleft = 0;
  949. }
  950. Rect newMaxRect = new Rect(newleft, newtop, newright - newleft, newbottom - newtop);
  951. Point OffsetPos = CalcMoveBound(cacheRect, ((Point)(mousePoint - mouseDownPoint)), newMaxRect);
  952. left = cacheRect.Left + OffsetPos.X;
  953. right = cacheRect.Right + OffsetPos.X;
  954. top = cacheRect.Top + OffsetPos.Y;
  955. bottom = cacheRect.Bottom + OffsetPos.Y;
  956. }
  957. break;
  958. default:
  959. break;
  960. }
  961. //if (left < maxRect.Left)
  962. //{
  963. // left = maxRect.Left;
  964. //}
  965. //if (top < maxRect.Top)
  966. //{
  967. // top = maxRect.Top;
  968. //}
  969. if (right > maxRect.Right + SetDrawRect.Width - 10)
  970. {
  971. if (left > maxRect.Right - 10)
  972. {
  973. left = maxRect.Right - 10;
  974. }
  975. right = maxRect.Right + SetDrawRect.Width - 10;
  976. }
  977. if (bottom > maxRect.Bottom + SetDrawRect.Height - 10)
  978. {
  979. if (top > maxRect.Bottom - 10)
  980. {
  981. top = maxRect.Bottom - 10;
  982. }
  983. bottom = maxRect.Bottom + SetDrawRect.Height - 10;
  984. }
  985. drawRect = new Rect(left, top, right - left, bottom - top);
  986. moveOffset = new Point(drawRect.X - cacheRect.X, drawRect.Y - cacheRect.Y);
  987. return true;
  988. }
  989. catch (Exception ex)
  990. {
  991. }
  992. return false;
  993. }
  994. /// <summary>
  995. /// Proportional scaling offset calibration
  996. /// </summary>
  997. /// <param name="movePoint">
  998. /// The current movement point
  999. /// </param>
  1000. /// <returns>
  1001. /// The offset point after the proportional scaling
  1002. /// </returns>
  1003. protected Point ProportionalScalingOffsetPos(Point movePoint)
  1004. {
  1005. if (isProportionalScaling)
  1006. {
  1007. Point offsetPos = movePoint;
  1008. double ratioX = cacheRect.Width > 0 ? cacheRect.Height / cacheRect.Width : 1;
  1009. double ratioY = cacheRect.Height > 0 ? cacheRect.Width / cacheRect.Height : 1;
  1010. switch (hitControlType)
  1011. {
  1012. case PointControlType.LeftTop:
  1013. case PointControlType.RightBottom:
  1014. offsetPos = new Point(movePoint.X, Math.Abs(movePoint.X) * ratioX * (movePoint.X < 0 ? -1 : 1));
  1015. break;
  1016. case PointControlType.LeftBottom:
  1017. case PointControlType.RightTop:
  1018. offsetPos = new Point(movePoint.X, Math.Abs(movePoint.X) * ratioX * (movePoint.X < 0 ? 1 : -1));
  1019. break;
  1020. case PointControlType.LeftMiddle:
  1021. offsetPos = new Point(movePoint.X, Math.Abs(movePoint.X) * ratioX * (movePoint.X < 0 ? 1 : -1));
  1022. break;
  1023. case PointControlType.RightMiddle:
  1024. offsetPos = new Point(movePoint.X, Math.Abs(movePoint.X) * ratioX * (movePoint.X < 0 ? -1 : 1));
  1025. break;
  1026. case PointControlType.MiddleBottom:
  1027. offsetPos = new Point(Math.Abs(movePoint.Y) * ratioY * (movePoint.Y < 0 ? 1 : -1), movePoint.Y);
  1028. break;
  1029. case PointControlType.MiddleTop:
  1030. offsetPos = new Point(Math.Abs(movePoint.Y) * ratioY * (movePoint.Y < 0 ? -1 : 1), movePoint.Y);
  1031. break;
  1032. default:
  1033. break;
  1034. }
  1035. return offsetPos;
  1036. }
  1037. else
  1038. {
  1039. return movePoint;
  1040. }
  1041. }
  1042. /// <summary>
  1043. /// Inner drawing circle point
  1044. /// </summary>
  1045. /// <param name="drawingContext">
  1046. /// Drawing context
  1047. /// </param>
  1048. /// <param name="ignoreList">
  1049. /// Collection of positions that need to be drawn
  1050. /// </param>
  1051. /// <param name="PointSize">
  1052. /// Size of the point
  1053. /// </param>
  1054. /// <param name="PointPen">
  1055. /// Brush for drawing points
  1056. /// </param>
  1057. /// <param name="BorderBrush">
  1058. /// Border brush for drawing points
  1059. /// </param>
  1060. protected void DrawCirclePoint(DrawingContext drawingContext, List<PointControlType> ignoreList, int PointSize, Pen PointPen, SolidColorBrush BorderBrush)
  1061. {
  1062. GeometryGroup controlGroup = new GeometryGroup();
  1063. controlGroup.FillRule = FillRule.Nonzero;
  1064. List<Point> ignorePointsList = new List<Point>();
  1065. // Get specific points
  1066. foreach (PointControlType type in ignoreList)
  1067. {
  1068. if ((int)type < controlPoints.Count)
  1069. {
  1070. ignorePointsList.Add(controlPoints[(int)type]);
  1071. }
  1072. }
  1073. for (int i = 0; i < controlPoints.Count; i++)
  1074. {
  1075. Point controlPoint = controlPoints[i];
  1076. if (ignorePointsList.Contains(controlPoint))
  1077. {
  1078. continue;
  1079. }
  1080. EllipseGeometry circlPoint = new EllipseGeometry(controlPoint, PointSize, PointSize);
  1081. controlGroup.Children.Add(circlPoint);
  1082. }
  1083. drawingContext?.DrawGeometry(BorderBrush, PointPen, controlGroup);
  1084. }
  1085. /// <summary>
  1086. /// Inner drawing square
  1087. /// </summary>
  1088. /// <param name="drawingContext">
  1089. /// Drawing context
  1090. /// </param>
  1091. /// <param name="ControlPoints">
  1092. /// Collection of positions that need to be drawn
  1093. /// </param>
  1094. /// <param name="PointSize">
  1095. /// Size of the point
  1096. /// </param>
  1097. /// <param name="PointPen">
  1098. /// Brush for drawing points
  1099. /// </param>
  1100. /// <param name="BorderBrush">
  1101. /// Border brush for drawing points
  1102. /// </param>
  1103. protected void DrawSquarePoint(DrawingContext drawingContext, List<PointControlType> ignoreList, int PointSize, Pen PointPen, SolidColorBrush BorderBrush)
  1104. {
  1105. RotateTransform rotateTransform = new RotateTransform(rotateAngle, centerPoint.X, centerPoint.Y);
  1106. if (canRotate && !isInScaling)
  1107. {
  1108. Point currentRotationPoint = isInRotate ? dragRotationPoint : rotationPoint;
  1109. double angleInRadians = rotateAngle * (Math.PI / 180);
  1110. double sinValue = Math.Sin(angleInRadians);
  1111. double cosValue = Math.Cos(angleInRadians);
  1112. double rotatedX = 0;
  1113. double rotatedY = 0;
  1114. switch (pageRotation)
  1115. {
  1116. case 0:
  1117. rotatedX = currentRotationPoint.X - pointSize * sinValue;
  1118. rotatedY = currentRotationPoint.Y + pointSize * cosValue;
  1119. break;
  1120. case 1:
  1121. rotatedX = currentRotationPoint.X - pointSize * cosValue;
  1122. rotatedY = currentRotationPoint.Y + pointSize * sinValue;
  1123. break;
  1124. case 2:
  1125. rotatedX = currentRotationPoint.X + pointSize * sinValue;
  1126. rotatedY = currentRotationPoint.Y - pointSize * cosValue;
  1127. break;
  1128. case 3:
  1129. rotatedX = currentRotationPoint.X + pointSize * sinValue;
  1130. rotatedY = currentRotationPoint.Y - pointSize * cosValue;
  1131. break;
  1132. default:
  1133. break;
  1134. }
  1135. GeometryGroup rotateGroup = new GeometryGroup();
  1136. LineGeometry moveLineGeometry = new LineGeometry(centerPoint, new Point(rotatedX, rotatedY));
  1137. EllipseGeometry ellipseGeometry = new EllipseGeometry(currentRotationPoint, PointSize, pointSize);
  1138. rotateGroup.Children.Add(moveLineGeometry);
  1139. rotateGroup.Children.Add(ellipseGeometry);
  1140. if (!isInRotate)
  1141. {
  1142. rotateGroup.Children.Remove(moveLineGeometry);
  1143. LineGeometry stopLineGeometry = new LineGeometry(centerPoint, new Point(currentRotationPoint.X, currentRotationPoint.Y + pointSize));
  1144. switch (pageRotation)
  1145. {
  1146. case 0:
  1147. stopLineGeometry = new LineGeometry(centerPoint, new Point(currentRotationPoint.X, currentRotationPoint.Y + pointSize));
  1148. break;
  1149. case 1:
  1150. stopLineGeometry = new LineGeometry(centerPoint, new Point(currentRotationPoint.X - pointSize, currentRotationPoint.Y));
  1151. break;
  1152. case 2:
  1153. stopLineGeometry = new LineGeometry(centerPoint, new Point(currentRotationPoint.X, currentRotationPoint.Y - pointSize));
  1154. break;
  1155. case 3:
  1156. stopLineGeometry = new LineGeometry(centerPoint, new Point(currentRotationPoint.X + pointSize, currentRotationPoint.Y));
  1157. break;
  1158. default:
  1159. break;
  1160. }
  1161. rotateGroup.Children.Add(stopLineGeometry);
  1162. drawingContext.PushTransform(rotateTransform);
  1163. }
  1164. drawingContext?.DrawGeometry(BorderBrush, PointPen, rotateGroup);
  1165. if (!isInRotate)
  1166. {
  1167. drawingContext.Pop();
  1168. }
  1169. }
  1170. if (!isInRotate)
  1171. {
  1172. GeometryGroup controlGroup = new GeometryGroup();
  1173. controlGroup.FillRule = FillRule.Nonzero;
  1174. List<Point> ignorePointsList = new List<Point>();
  1175. // Get specific points
  1176. foreach (PointControlType type in ignoreList)
  1177. {
  1178. if ((int)type < controlPoints.Count)
  1179. {
  1180. ignorePointsList.Add(controlPoints[(int)type]);
  1181. }
  1182. }
  1183. for (int i = 0; i < controlPoints.Count; i++)
  1184. {
  1185. Point controlPoint = controlPoints[i];
  1186. if (ignorePointsList.Contains(controlPoint))
  1187. {
  1188. continue;
  1189. }
  1190. RectangleGeometry rectPoint = new RectangleGeometry(new Rect(controlPoint.X - PointSize, controlPoint.Y - PointSize,
  1191. PointSize * 2, PointSize * 2), 1, 1);
  1192. controlGroup.Children.Add(rectPoint);
  1193. }
  1194. drawingContext.PushTransform(rotateTransform);
  1195. drawingContext?.DrawGeometry(BorderBrush, PointPen, controlGroup);
  1196. drawingContext.Pop();
  1197. }
  1198. }
  1199. protected void DrawCropPoint(DrawingContext drawingContext, List<PointControlType> ignoreList, int PointSize, Pen PointPen, SolidColorBrush BorderBrush)
  1200. {
  1201. //GeometryGroup controlGroup = new GeometryGroup();
  1202. //controlGroup.FillRule = FillRule.Nonzero;
  1203. clipThickness.Left = (SetDrawRect.Left - drawRect.Left) / currentZoom;
  1204. clipThickness.Top = (SetDrawRect.Top - drawRect.Top) / currentZoom;
  1205. clipThickness.Right = (SetDrawRect.Right - drawRect.Right) / currentZoom;
  1206. clipThickness.Bottom = (SetDrawRect.Bottom - drawRect.Bottom) / currentZoom;
  1207. List<Point> controlCurrentPoints = GetControlPoint(drawRect);
  1208. CombinedGeometry controlGroup = new CombinedGeometry();
  1209. RectangleGeometry paintGeometry = new RectangleGeometry();
  1210. paintGeometry.Rect = SetDrawRect;
  1211. controlGroup.Geometry1 = paintGeometry;
  1212. RectangleGeometry moveGeometry = new RectangleGeometry();
  1213. Rect clippedBorder = drawRect;
  1214. if (clippedBorder.IsEmpty == false)
  1215. {
  1216. moveGeometry.Rect = drawRect;
  1217. }
  1218. controlGroup.Geometry2 = moveGeometry;
  1219. controlGroup.GeometryCombineMode = GeometryCombineMode.Exclude;
  1220. //Left Top Corner
  1221. if (!ignoreList.Contains(PointControlType.LeftTop))
  1222. {
  1223. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[0].X - PointSize, controlCurrentPoints[0].Y - PointSize, PointSize, PointSize * 4));
  1224. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[0].X - PointSize, controlCurrentPoints[0].Y - PointSize, PointSize * 4, PointSize));
  1225. }
  1226. //Left Center
  1227. if (!ignoreList.Contains(PointControlType.LeftMiddle))
  1228. {
  1229. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[1].X - PointSize, (controlCurrentPoints[1].Y + controlCurrentPoints[1].Y - PointSize * 5) / 2, PointSize, PointSize * 5));
  1230. }
  1231. //Left Bottom Corner
  1232. if (!ignoreList.Contains(PointControlType.LeftBottom))
  1233. {
  1234. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[2].X - PointSize, controlCurrentPoints[2].Y - PointSize * 3, PointSize, PointSize * 4));
  1235. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[2].X - PointSize, controlCurrentPoints[2].Y, PointSize * 4, PointSize));
  1236. }
  1237. //Bottom Center
  1238. if (!ignoreList.Contains(PointControlType.MiddleBottom))
  1239. {
  1240. drawingContext?.DrawRectangle(BorderBrush, null, new Rect((controlCurrentPoints[3].X + controlCurrentPoints[3].X - PointSize * 5) / 2, controlCurrentPoints[3].Y, PointSize * 5, PointSize));
  1241. }
  1242. //Bottom Right Corner
  1243. if (!ignoreList.Contains(PointControlType.RightBottom))
  1244. {
  1245. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[4].X, controlCurrentPoints[4].Y - PointSize * 3, PointSize, PointSize * 4));
  1246. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[4].X - PointSize * 3, controlCurrentPoints[4].Y, PointSize * 4, PointSize));
  1247. }
  1248. //Right Center
  1249. if (!ignoreList.Contains(PointControlType.RightMiddle))
  1250. {
  1251. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[5].X, (controlCurrentPoints[5].Y + controlCurrentPoints[5].Y - PointSize * 5) / 2, PointSize, PointSize * 5));
  1252. }
  1253. //Right Top Corner
  1254. if (!ignoreList.Contains(PointControlType.RightTop))
  1255. {
  1256. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[6].X, controlCurrentPoints[6].Y - PointSize, PointSize, PointSize * 4));
  1257. drawingContext?.DrawRectangle(BorderBrush, null, new Rect(controlCurrentPoints[6].X - PointSize * 4, controlCurrentPoints[6].Y - PointSize, PointSize * 4, PointSize));
  1258. }
  1259. //Top Center
  1260. if (!ignoreList.Contains(PointControlType.MiddleTop))
  1261. {
  1262. drawingContext?.DrawRectangle(BorderBrush, null, new Rect((controlCurrentPoints[7].X + controlCurrentPoints[7].X - PointSize * 5) / 2, controlCurrentPoints[7].Y - PointSize, PointSize * 5, PointSize));
  1263. }
  1264. BorderBrush = new SolidColorBrush(Color.FromArgb(0x3F, 0x00, 0x00, 0x00));
  1265. drawingContext?.DrawGeometry(BorderBrush, PointPen, controlGroup);
  1266. }
  1267. /// <summary>
  1268. /// Draw the reference line in the moving state
  1269. /// </summary>
  1270. /// <param name="drawDc">
  1271. /// Draw context handle
  1272. /// </param>
  1273. /// <param name="controltype">
  1274. /// Current selected control point type
  1275. /// </param>
  1276. /// <param name="activePen">
  1277. /// Brush for drawing lines
  1278. /// </param>
  1279. /// <param name="moveBrush">
  1280. /// Brush for drawing rectangles
  1281. /// </param>
  1282. /// <param name="moveRect">
  1283. /// Current rectangle to draw
  1284. /// </param>
  1285. protected void DrawMoveBounds(DrawingContext drawDc, PointControlType controltype, Pen activePen, Brush moveBrush, Rect moveRect, Pen RectPen = null)
  1286. {
  1287. switch (controltype)
  1288. {
  1289. case PointControlType.LeftTop:
  1290. drawDc?.DrawLine(activePen, new Point(0, moveRect.Top), new Point(PDFViewerActualWidth, moveRect.Top));
  1291. drawDc?.DrawLine(activePen, new Point(moveRect.Left, 0), new Point(moveRect.Left, PDFViewerActualHeight));
  1292. break;
  1293. case PointControlType.LeftMiddle:
  1294. drawDc?.DrawLine(activePen, new Point(moveRect.Left, 0), new Point(moveRect.Left, PDFViewerActualHeight));
  1295. break;
  1296. case PointControlType.LeftBottom:
  1297. drawDc?.DrawLine(activePen, new Point(0, moveRect.Bottom), new Point(PDFViewerActualWidth, moveRect.Bottom));
  1298. drawDc?.DrawLine(activePen, new Point(moveRect.Left, 0), new Point(moveRect.Left, PDFViewerActualHeight));
  1299. break;
  1300. case PointControlType.MiddleBottom:
  1301. drawDc?.DrawLine(activePen, new Point(0, moveRect.Bottom), new Point(PDFViewerActualWidth, moveRect.Bottom));
  1302. break;
  1303. case PointControlType.RightBottom:
  1304. drawDc?.DrawLine(activePen, new Point(0, moveRect.Bottom), new Point(PDFViewerActualWidth, moveRect.Bottom));
  1305. drawDc?.DrawLine(activePen, new Point(moveRect.Right, 0), new Point(moveRect.Right, PDFViewerActualHeight));
  1306. break;
  1307. case PointControlType.RightMiddle:
  1308. drawDc?.DrawLine(activePen, new Point(moveRect.Right, 0), new Point(moveRect.Right, PDFViewerActualHeight));
  1309. break;
  1310. case PointControlType.RightTop:
  1311. drawDc?.DrawLine(activePen, new Point(0, moveRect.Top), new Point(PDFViewerActualWidth, moveRect.Top));
  1312. drawDc?.DrawLine(activePen, new Point(moveRect.Right, 0), new Point(moveRect.Right, PDFViewerActualHeight));
  1313. break;
  1314. case PointControlType.MiddleTop:
  1315. drawDc?.DrawLine(activePen, new Point(0, moveRect.Top), new Point(PDFViewerActualWidth, moveRect.Top));
  1316. break;
  1317. case PointControlType.Rotate:
  1318. drawDc?.DrawLine(activePen, new Point(0, moveRect.Top), new Point(moveRect.Left, moveRect.Top));
  1319. drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Top), new Point(PDFViewerActualWidth, moveRect.Top));
  1320. drawDc?.DrawLine(activePen, new Point(moveRect.Left, moveRect.Top), new Point(moveRect.Left, 0));
  1321. drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Top), new Point(moveRect.Right, 0));
  1322. drawDc?.DrawLine(activePen, new Point(0, moveRect.Bottom), new Point(moveRect.Left, moveRect.Bottom));
  1323. drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Bottom), new Point(PDFViewerActualWidth, moveRect.Bottom));
  1324. drawDc?.DrawLine(activePen, new Point(moveRect.Left, moveRect.Bottom), new Point(moveRect.Left, PDFViewerActualHeight));
  1325. drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Bottom), new Point(moveRect.Right, PDFViewerActualHeight));
  1326. break;
  1327. case PointControlType.Body:
  1328. case PointControlType.Line:
  1329. drawDc?.DrawLine(activePen, new Point(0, moveRect.Top), new Point(moveRect.Left, moveRect.Top));
  1330. drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Top), new Point(PDFViewerActualWidth, moveRect.Top));
  1331. drawDc?.DrawLine(activePen, new Point(moveRect.Left, moveRect.Top), new Point(moveRect.Left, 0));
  1332. drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Top), new Point(moveRect.Right, 0));
  1333. drawDc?.DrawLine(activePen, new Point(0, moveRect.Bottom), new Point(moveRect.Left, moveRect.Bottom));
  1334. drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Bottom), new Point(PDFViewerActualWidth, moveRect.Bottom));
  1335. drawDc?.DrawLine(activePen, new Point(moveRect.Left, moveRect.Bottom), new Point(moveRect.Left, PDFViewerActualHeight));
  1336. drawDc?.DrawLine(activePen, new Point(moveRect.Right, moveRect.Bottom), new Point(moveRect.Right, PDFViewerActualHeight));
  1337. break;
  1338. default:
  1339. break;
  1340. }
  1341. drawDc?.DrawRectangle(moveBrush, RectPen, moveRect);
  1342. }
  1343. /// <summary>
  1344. /// Notify the event during/after the drawing data
  1345. /// </summary>
  1346. /// <param name="isFinish">
  1347. /// Identifies whether the data change is complete
  1348. /// </param>
  1349. protected void InvokeDataChangEvent(bool isFinish)
  1350. {
  1351. selectedRectData.Square = GetRect();
  1352. selectedRectData.rotationAngle = rotateAngle;
  1353. if (isFinish)
  1354. {
  1355. DataChanged?.Invoke(this, selectedRectData);
  1356. }
  1357. else
  1358. {
  1359. DataChanging?.Invoke(this, selectedRectData);
  1360. }
  1361. }
  1362. /// <summary>
  1363. /// Align the rectangle drawing
  1364. /// </summary>
  1365. /// <param name="RectMovePoint">
  1366. /// Move distance required for the aligned algorithm to obtain the rectangle
  1367. /// </param>
  1368. private void DrawAlignRect(Point RectMovePoint)
  1369. {
  1370. double TmpLeft, TmpRight, TmpUp, TmpDown;
  1371. Point OffsetPos = CalcMoveBound(drawRect, RectMovePoint, maxRect);
  1372. TmpLeft = drawRect.Left + OffsetPos.X;
  1373. TmpRight = drawRect.Right + OffsetPos.X;
  1374. TmpUp = drawRect.Top + OffsetPos.Y;
  1375. TmpDown = drawRect.Bottom + OffsetPos.Y;
  1376. SetDrawRect = drawRect = new Rect(TmpLeft, TmpUp, TmpRight - TmpLeft, TmpDown - TmpUp);
  1377. Draw();
  1378. }
  1379. /// <summary>
  1380. /// Get the current set of ignore points
  1381. /// </summary>
  1382. /// <returns>
  1383. /// Data set of ignored points
  1384. /// </returns>
  1385. private List<PointControlType> GetIgnorePoints()
  1386. {
  1387. List<PointControlType> IgnorePointsList = new List<PointControlType>();
  1388. foreach (PointControlType type in ignorePoints)
  1389. {
  1390. IgnorePointsList.Add(type);
  1391. }
  1392. return IgnorePointsList;
  1393. }
  1394. #endregion
  1395. }
  1396. }