CreateAnnotTool.cs 85 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976
  1. using ComPDFKit.Import;
  2. using ComPDFKit.Measure;
  3. using ComPDFKit.PDFAnnotation;
  4. using ComPDFKit.PDFDocument;
  5. using ComPDFKit.PDFPage;
  6. using ComPDFKit.Tool.Help;
  7. using ComPDFKit.Tool.SettingParam;
  8. using ComPDFKit.Tool.UndoManger;
  9. using ComPDFKit.Viewer.Helper;
  10. using ComPDFKit.Viewer.Layer;
  11. using ComPDFKitViewer;
  12. using ComPDFKitViewer.Helper;
  13. using ComPDFKitViewer.Layer;
  14. using System;
  15. using System.Collections.Generic;
  16. using System.Globalization;
  17. using System.Linq;
  18. using System.Windows;
  19. using System.Windows.Controls;
  20. using System.Windows.Media;
  21. using static ComPDFKit.PDFAnnotation.CTextAttribute.CFontNameHelper;
  22. namespace ComPDFKit.Tool.DrawTool
  23. {
  24. internal class CreateAnnotTool : CustomizeLayer
  25. {
  26. public event EventHandler<bool> UpdateAnnotHandler;
  27. public event EventHandler<AnnotParam> CreateFreetextCanceled;
  28. public event EventHandler<MeasureEventArgs> MeasureChanged;
  29. public static DependencyProperty PopupTextAttachDataProperty = DependencyProperty.Register("PopupTextAttachData", typeof(CPDFAnnotation), typeof(CPDFViewerTool));
  30. #region Attributes
  31. /// <summary>
  32. /// Indicates whether proportional scaling is required
  33. /// </summary>
  34. protected bool isProportionalScaling { get; set; } = false;
  35. /// <summary>
  36. /// Mouse start point
  37. /// </summary>
  38. protected Point mouseStartPoint { get; set; }
  39. /// <summary>
  40. /// Mouse end point
  41. /// </summary>
  42. protected Point mouseEndPoint { get; set; }
  43. /// <summary>
  44. /// Crop point
  45. /// </summary>
  46. protected Point cropPoint { get; set; }
  47. /// <summary>
  48. ///Is drawing annotation
  49. /// </summary>
  50. protected bool isDrawAnnot { get; set; }
  51. /// <summary>
  52. /// Current zoom factor
  53. /// </summary>
  54. private double zoomFactor { get; set; } = 1;
  55. /// <summary>
  56. /// Draw rectangle
  57. /// </summary>
  58. protected Rect drawRect { get; set; }
  59. /// <summary>
  60. /// The rectangle representing the maximum drawing area
  61. /// </summary>
  62. protected Rect maxRect { get; set; }
  63. /// <summary>
  64. /// The rectangle representing the original page range (calculated offset in continuous mode)
  65. /// </summary>
  66. protected Rect pageBound { get; set; }
  67. /// <summary>
  68. /// The rectangle at standard DPI (without subtracting half of the pen thickness)
  69. /// </summary>
  70. protected Rect DPIRect { get; set; }
  71. /// <summary>
  72. /// The offset value during movement
  73. /// </summary>
  74. protected Point moveOffset { get; set; } = new Point(0, 0);
  75. protected DrawingContext drawDC { get; set; }
  76. protected CPDFAnnotation cPDFAnnotation
  77. {
  78. get;
  79. set;
  80. }
  81. protected CPDFViewer cPDFViewer { get; set; }
  82. protected List<Point> inkDrawPoints = new List<Point>();
  83. /// <summary>
  84. /// The collection of points measured for annotation drawing
  85. /// </summary>
  86. protected PointCollection drawPoints { get; set; } = new PointCollection();
  87. protected double textPadding { get; set; } = 10;
  88. protected Border lastTextBorder;
  89. protected TextBox lastTextui;
  90. protected Point freeTextPoint { get; set; }
  91. protected MeasureSetting measureSetting = new MeasureSetting();
  92. protected DefaultDrawParam defaultDrawParam = new DefaultDrawParam();
  93. protected DefaultSettingParam defaultSettingParam = new DefaultSettingParam();
  94. #endregion
  95. public CreateAnnotTool(MeasureSetting setting, DefaultDrawParam drawParam, DefaultSettingParam settingParam)
  96. {
  97. measureSetting = setting;
  98. defaultDrawParam = drawParam;
  99. defaultSettingParam = settingParam;
  100. }
  101. public Point GetStartPoint()
  102. {
  103. return DpiHelper.StandardPointToPDFPoint(new Point((mouseStartPoint.X - pageBound.X + (cropPoint.X * zoomFactor)) / zoomFactor, (mouseStartPoint.Y - pageBound.Y + (cropPoint.Y * zoomFactor)) / zoomFactor));
  104. }
  105. public Point GetEndPoint()
  106. {
  107. if (moveOffset == new Point())
  108. {
  109. return new Point(-1, -1);
  110. }
  111. else
  112. {
  113. return DpiHelper.StandardPointToPDFPoint(new Point((mouseEndPoint.X - pageBound.X + (cropPoint.X * zoomFactor)) / zoomFactor, (mouseEndPoint.Y - pageBound.Y + (cropPoint.Y * zoomFactor)) / zoomFactor));
  114. }
  115. }
  116. public double GetMoveLength()
  117. {
  118. if (mouseEndPoint == new Point())
  119. {
  120. return 0;
  121. }
  122. Point checkPoint = mouseEndPoint;
  123. checkPoint.X = Math.Max(pageBound.Left, checkPoint.X);
  124. checkPoint.X = Math.Min(pageBound.Right, checkPoint.X);
  125. checkPoint.Y = Math.Max(pageBound.Top, checkPoint.Y);
  126. checkPoint.Y = Math.Min(pageBound.Bottom, checkPoint.Y);
  127. Vector moveOffset = checkPoint - mouseStartPoint;
  128. return moveOffset.Length;
  129. }
  130. public List<Point> GetInkDrawPoints()
  131. {
  132. List<Point> points = new List<Point>
  133. {
  134. new Point((mouseStartPoint.X - pageBound.Left+(cropPoint.X*zoomFactor)) / zoomFactor,
  135. (mouseStartPoint.Y - pageBound.Top + (cropPoint.Y*zoomFactor)) / zoomFactor)
  136. };
  137. foreach (Point item in inkDrawPoints)
  138. {
  139. points.Add(new Point((item.X - pageBound.Left + (cropPoint.X * zoomFactor)) / zoomFactor,
  140. (item.Y - pageBound.Top + (cropPoint.Y * zoomFactor)) / zoomFactor));
  141. }
  142. return points;
  143. }
  144. public List<Point> GetMeasureDrawPoints()
  145. {
  146. List<Point> points = new List<Point>();
  147. foreach (Point item in drawPoints)
  148. {
  149. points.Add(new Point((item.X - pageBound.Left + (cropPoint.X * zoomFactor)) / zoomFactor,
  150. (item.Y - pageBound.Top + (cropPoint.Y * zoomFactor)) / zoomFactor));
  151. }
  152. if (defaultSettingParam.IsCreateSquarePolygonMeasure)
  153. {
  154. if (points.Count == 2)
  155. {
  156. Rect rect = new Rect(points[0], points[1]);
  157. points.Clear();
  158. points.Add(rect.TopLeft);
  159. points.Add(rect.BottomLeft);
  160. points.Add(rect.BottomRight);
  161. points.Add(rect.TopRight);
  162. }
  163. else if (points.Count == 1)
  164. {
  165. Rect checkRect = pageBound;
  166. // Current drawing during the movement process.
  167. Point checkPoint = mouseEndPoint;
  168. checkPoint.X = Math.Max(checkRect.Left, checkPoint.X);
  169. checkPoint.X = Math.Min(checkRect.Right, checkPoint.X);
  170. checkPoint.Y = Math.Max(checkRect.Top, checkPoint.Y);
  171. checkPoint.Y = Math.Min(checkRect.Bottom, checkPoint.Y);
  172. List<Point> drawPointsList = new List<Point>
  173. {
  174. new Point((drawPoints[0].X - pageBound.Left + (cropPoint.X * zoomFactor)) / zoomFactor,
  175. (drawPoints[0].Y - pageBound.Top + (cropPoint.Y * zoomFactor)) / zoomFactor),
  176. new Point((checkPoint.X - pageBound.Left + (cropPoint.X * zoomFactor)) / zoomFactor,
  177. (checkPoint.Y - pageBound.Top + (cropPoint.Y * zoomFactor)) / zoomFactor)
  178. };
  179. Rect rect = new Rect(drawPointsList[0], drawPointsList[1]);
  180. points.Clear();
  181. points.Add(rect.TopLeft);
  182. points.Add(rect.BottomLeft);
  183. points.Add(rect.BottomRight);
  184. points.Add(rect.TopRight);
  185. }
  186. }
  187. return points;
  188. }
  189. public void SetIsProportionalScaling(bool isOpen)
  190. {
  191. isProportionalScaling = isOpen;
  192. }
  193. #region Draw
  194. public CPDFAnnotation StartDraw(Point downPoint, Point cropPoint, CPDFPage cPDFPage, Rect maxRect, Rect pageBound, C_ANNOTATION_TYPE annotType, CPDFViewer viewer, double zoom)
  195. {
  196. RemoveTextBox();
  197. mouseStartPoint = downPoint;
  198. mouseEndPoint = downPoint;
  199. isDrawAnnot = true;
  200. this.maxRect = maxRect;
  201. zoomFactor = zoom;
  202. moveOffset = new Point();
  203. int newIndex = cPDFPage.GetAnnotCount();
  204. cPDFAnnotation = cPDFPage.CreateAnnot(annotType);
  205. if (cPDFAnnotation != null)
  206. {
  207. cPDFAnnotation.SetCreationDate(PDFHelp.GetCurrentPdfTime());
  208. cPDFAnnotation.SetModifyDate(PDFHelp.GetCurrentPdfTime());
  209. List<CPDFAnnotation> annotList = cPDFPage.GetAnnotations();
  210. cPDFAnnotation = annotList[newIndex];
  211. cPDFViewer = viewer;
  212. drawPoints.Add(downPoint);
  213. this.cropPoint = cropPoint;
  214. this.pageBound = pageBound;
  215. DPIRect = new Rect();
  216. if (annotType != C_ANNOTATION_TYPE.C_ANNOTATION_POLYGON)
  217. {
  218. defaultSettingParam.IsCreateSquarePolygonMeasure = false;
  219. }
  220. }
  221. return cPDFAnnotation;
  222. }
  223. public void MoveDraw(Point downPoint, double zoom)
  224. {
  225. if (isDrawAnnot)
  226. {
  227. moveOffset = new Point(
  228. mouseEndPoint.X - downPoint.X,
  229. mouseEndPoint.Y - downPoint.Y
  230. );
  231. mouseEndPoint = downPoint;
  232. zoomFactor = zoom;
  233. Draw();
  234. }
  235. }
  236. public Rect EndDraw()
  237. {
  238. if (isDrawAnnot)
  239. {
  240. if (cPDFAnnotation != null && cPDFAnnotation.Type == C_ANNOTATION_TYPE.C_ANNOTATION_TEXT)
  241. {
  242. if (DPIRect.Equals(new Rect()))
  243. {
  244. DPIRect = drawRect = new Rect(mouseStartPoint.X, mouseStartPoint.Y, 32 * zoomFactor, 32 * zoomFactor);
  245. }
  246. else
  247. {
  248. DPIRect = drawRect = new Rect(mouseEndPoint.X, mouseEndPoint.Y, 32 * zoomFactor, 32 * zoomFactor);
  249. }
  250. }
  251. if (cPDFAnnotation is CPDFPolylineAnnotation)
  252. {
  253. double left = drawPoints.AsEnumerable().Select(x => x.X).Min();
  254. double right = drawPoints.AsEnumerable().Select(x => x.X).Max();
  255. double top = drawPoints.AsEnumerable().Select(x => x.Y).Min();
  256. double bottom = drawPoints.AsEnumerable().Select(x => x.Y).Max();
  257. DPIRect = new Rect(left, top, right - left, bottom - top);
  258. }
  259. Rect standardRect = new Rect(
  260. (DPIRect.Left - pageBound.X + (cropPoint.X * zoomFactor)) / zoomFactor, (DPIRect.Top - pageBound.Y + (cropPoint.Y * zoomFactor)) / zoomFactor,
  261. DPIRect.Width / zoomFactor, DPIRect.Height / zoomFactor);
  262. isDrawAnnot = false;
  263. freeTextPoint = new Point((mouseStartPoint.X - pageBound.X) / zoomFactor, (mouseStartPoint.Y - pageBound.Y) / zoomFactor);
  264. mouseStartPoint = new Point();
  265. mouseEndPoint = new Point();
  266. moveOffset = new Point();
  267. pageBound = new Rect();
  268. DPIRect = new Rect();
  269. cPDFAnnotation = null;
  270. inkDrawPoints.Clear();
  271. drawPoints.Clear();
  272. return DpiHelper.StandardRectToPDFRect(standardRect);
  273. }
  274. return new Rect();
  275. }
  276. public override void Draw()
  277. {
  278. Dispatcher.Invoke(() =>
  279. {
  280. if (cPDFAnnotation == null)
  281. {
  282. return;
  283. }
  284. drawDC = Open();
  285. switch (cPDFAnnotation.Type)
  286. {
  287. case C_ANNOTATION_TYPE.C_ANNOTATION_TEXT:
  288. DPIRect = drawRect = new Rect(mouseStartPoint.X, mouseStartPoint.Y, 32, 32);
  289. break;
  290. case C_ANNOTATION_TYPE.C_ANNOTATION_FREETEXT:
  291. DrawText();
  292. break;
  293. case C_ANNOTATION_TYPE.C_ANNOTATION_LINE:
  294. if ((cPDFAnnotation as CPDFLineAnnotation).IsMeasured())
  295. {
  296. DrawLineMeasure(drawDC);
  297. }
  298. else
  299. {
  300. DrawLine(drawDC);
  301. }
  302. break;
  303. case C_ANNOTATION_TYPE.C_ANNOTATION_SQUARE:
  304. DrawSquare(drawDC);
  305. break;
  306. case C_ANNOTATION_TYPE.C_ANNOTATION_CIRCLE:
  307. DrawCircle(drawDC);
  308. break;
  309. case C_ANNOTATION_TYPE.C_ANNOTATION_INK:
  310. DrawInk(drawDC);
  311. break;
  312. case C_ANNOTATION_TYPE.C_ANNOTATION_LINK:
  313. DrawLink(drawDC);
  314. break;
  315. case C_ANNOTATION_TYPE.C_ANNOTATION_POLYGON:
  316. DrawPolygonMeasure(drawDC);
  317. break;
  318. case C_ANNOTATION_TYPE.C_ANNOTATION_POLYLINE:
  319. DrawPolyLineMeasure(drawDC);
  320. break;
  321. case C_ANNOTATION_TYPE.C_ANNOTATION_REDACT:
  322. DrawRedact(drawDC);
  323. break;
  324. default:
  325. break;
  326. }
  327. Present();
  328. });
  329. }
  330. public virtual void ClearDraw()
  331. {
  332. RemoveTextBox();
  333. Open();
  334. Present();
  335. }
  336. private void DrawCircle(DrawingContext drawingContext)
  337. {
  338. CPDFCircleAnnotation circleAnnot = (cPDFAnnotation as CPDFCircleAnnotation);
  339. Pen DrawPen = new Pen(new SolidColorBrush(Color.FromRgb(circleAnnot.LineColor[0], circleAnnot.LineColor[1], circleAnnot.LineColor[2])), (int)Math.Ceiling(circleAnnot.LineWidth / 72 * 96 * zoomFactor));
  340. SolidColorBrush FillBrush = new SolidColorBrush(Colors.Transparent);
  341. if (circleAnnot.HasBgColor)
  342. {
  343. FillBrush = new SolidColorBrush(Color.FromRgb(circleAnnot.BgColor[0], circleAnnot.BgColor[1], circleAnnot.BgColor[2]));
  344. }
  345. DrawPen.Brush.Opacity = circleAnnot.Transparency / 255D;
  346. FillBrush.Opacity = circleAnnot.Transparency / 255D;
  347. if (circleAnnot.Dash != null && circleAnnot.Dash.Length > 0 && circleAnnot.LineWidth > 0)
  348. {
  349. DashStyle dash = new DashStyle();
  350. foreach (var offset in circleAnnot.Dash)
  351. {
  352. dash.Dashes.Add(offset / circleAnnot.LineWidth);
  353. }
  354. DrawPen.DashStyle = dash;
  355. DrawPen.DashCap = PenLineCap.Flat;
  356. }
  357. if (isProportionalScaling)
  358. {
  359. Point mouseOffset = (Point)(mouseStartPoint - mouseEndPoint);
  360. if (mouseOffset.X < 0)
  361. {
  362. if (mouseOffset.Y > 0)
  363. {
  364. mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseStartPoint.X - mouseEndPoint.X);
  365. }
  366. else
  367. {
  368. mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseEndPoint.X - mouseStartPoint.X);
  369. }
  370. }
  371. else
  372. {
  373. if (mouseOffset.Y > 0)
  374. {
  375. mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseEndPoint.X - mouseStartPoint.X);
  376. }
  377. else
  378. {
  379. mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseStartPoint.X - mouseEndPoint.X);
  380. }
  381. }
  382. }
  383. Rect rect = new Rect(mouseStartPoint, mouseEndPoint);
  384. double mLeft = rect.Left;
  385. double mRight = rect.Right;
  386. double mUp = rect.Top;
  387. double mDown = rect.Bottom;
  388. if (rect.Left < maxRect.Left)
  389. {
  390. mLeft = maxRect.Left;
  391. }
  392. if (rect.Right > maxRect.Right)
  393. {
  394. mRight = maxRect.Right;
  395. }
  396. if (rect.Top < maxRect.Top)
  397. {
  398. mUp = maxRect.Top;
  399. }
  400. if (rect.Bottom > maxRect.Bottom)
  401. {
  402. mDown = maxRect.Bottom;
  403. }
  404. DPIRect = drawRect = new Rect(mLeft, mUp, mRight - mLeft, mDown - mUp);
  405. double centerX = (drawRect.Left + drawRect.Width / 2);
  406. double centerY = (drawRect.Top + drawRect.Height / 2);
  407. double radiusX = drawRect.Width / 2 - DrawPen.Thickness;
  408. double radiusY = drawRect.Height / 2 - DrawPen.Thickness;
  409. if (radiusX <= 0 || radiusY <= 0)
  410. {
  411. drawingContext.DrawEllipse(DrawPen.Brush, null, new Point(centerX, centerY), (drawRect.Width / 2), (drawRect.Height / 2));
  412. }
  413. else
  414. {
  415. drawingContext?.DrawEllipse(null, DrawPen, new Point(centerX, centerY), radiusX, radiusY);
  416. if ((int)(drawRect.Width / 2 - DrawPen.Thickness) > 0 && (int)(drawRect.Height / 2 - DrawPen.Thickness) > 0)
  417. {
  418. drawingContext?.DrawEllipse(FillBrush, null, new Point(centerX, centerY), (drawRect.Width / 2 - DrawPen.Thickness), (drawRect.Height / 2 - DrawPen.Thickness));
  419. }
  420. }
  421. }
  422. private void DrawSquare(DrawingContext drawingContext)
  423. {
  424. CPDFSquareAnnotation squareAnnot = (cPDFAnnotation as CPDFSquareAnnotation);
  425. Pen DrawPen = new Pen(new SolidColorBrush(Color.FromRgb(squareAnnot.LineColor[0], squareAnnot.LineColor[1], squareAnnot.LineColor[2])), (int)Math.Ceiling(squareAnnot.LineWidth / 72 * 96 * zoomFactor));
  426. SolidColorBrush FillBrush = new SolidColorBrush(Colors.Transparent);
  427. if (squareAnnot.HasBgColor)
  428. {
  429. FillBrush = new SolidColorBrush(Color.FromRgb(squareAnnot.BgColor[0], squareAnnot.BgColor[1], squareAnnot.BgColor[2]));
  430. }
  431. DrawPen.Brush.Opacity = squareAnnot.Transparency / 255D;
  432. FillBrush.Opacity = squareAnnot.Transparency / 255D;
  433. if (squareAnnot.Dash != null && squareAnnot.Dash.Length > 0 && squareAnnot.LineWidth > 0)
  434. {
  435. DashStyle dash = new DashStyle();
  436. foreach (var offset in squareAnnot.Dash)
  437. {
  438. dash.Dashes.Add(offset / squareAnnot.LineWidth);
  439. }
  440. DrawPen.DashStyle = dash;
  441. DrawPen.DashCap = PenLineCap.Flat;
  442. }
  443. if (isProportionalScaling)
  444. {
  445. Point mouseOffset = (Point)(mouseStartPoint - mouseEndPoint);
  446. if (mouseOffset.X < 0)
  447. {
  448. if (mouseOffset.Y > 0)
  449. {
  450. mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseStartPoint.X - mouseEndPoint.X);
  451. }
  452. else
  453. {
  454. mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseEndPoint.X - mouseStartPoint.X);
  455. }
  456. }
  457. else
  458. {
  459. if (mouseOffset.Y > 0)
  460. {
  461. mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseEndPoint.X - mouseStartPoint.X);
  462. }
  463. else
  464. {
  465. mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseStartPoint.X - mouseEndPoint.X);
  466. }
  467. }
  468. }
  469. Rect rect = new Rect(mouseStartPoint, mouseEndPoint);
  470. double mLeft = rect.Left;
  471. double mRight = rect.Right;
  472. double mUp = rect.Top;
  473. double mDown = rect.Bottom;
  474. if (rect.Left < maxRect.Left)
  475. {
  476. mLeft = maxRect.Left;
  477. }
  478. if (rect.Right > maxRect.Right)
  479. {
  480. mRight = maxRect.Right;
  481. }
  482. if (rect.Top < maxRect.Top)
  483. {
  484. mUp = maxRect.Top;
  485. }
  486. if (rect.Bottom > maxRect.Bottom)
  487. {
  488. mDown = maxRect.Bottom;
  489. }
  490. DPIRect = new Rect(mLeft, mUp, mRight - mLeft, mDown - mUp);
  491. int halfPenWidth = (int)Math.Ceiling(DrawPen.Thickness / 2);
  492. double drawWidth = DPIRect.Width - halfPenWidth * 2;
  493. double drawHeight = DPIRect.Height - halfPenWidth * 2;
  494. if (drawWidth > 0 && drawHeight > 0)
  495. {
  496. drawRect = new Rect(
  497. (int)DPIRect.Left + halfPenWidth,
  498. (int)DPIRect.Top + halfPenWidth,
  499. (int)DPIRect.Width - halfPenWidth * 2,
  500. (int)DPIRect.Height - halfPenWidth * 2);
  501. drawingContext?.DrawRectangle(null, DrawPen, drawRect);
  502. halfPenWidth = (int)Math.Floor(DrawPen.Thickness / 2);
  503. if (drawRect.Width - halfPenWidth * 2 > 0 && drawRect.Height - halfPenWidth * 2 > 0)
  504. {
  505. Rect innerRect = new Rect(drawRect.Left + halfPenWidth, drawRect.Top + halfPenWidth, drawRect.Width - 2 * halfPenWidth, drawRect.Height - 2 * halfPenWidth);
  506. drawingContext?.DrawRectangle(FillBrush, null, innerRect);
  507. }
  508. }
  509. }
  510. private void DrawLine(DrawingContext drawingContext)
  511. {
  512. CPDFLineAnnotation annotLine = (cPDFAnnotation as CPDFLineAnnotation);
  513. Pen DrawPen = new Pen(new SolidColorBrush(
  514. Color.FromRgb(
  515. annotLine.LineColor[0],
  516. annotLine.LineColor[1],
  517. annotLine.LineColor[2])),
  518. (int)Math.Ceiling(annotLine.LineWidth == 0 ? 0.5 : annotLine.LineWidth * zoomFactor));
  519. DrawPen.Brush.Opacity = annotLine.Transparency / 255D;
  520. if (annotLine.Dash != null && annotLine.Dash.Length > 0 && annotLine.LineWidth > 0)
  521. {
  522. DashStyle dash = new DashStyle();
  523. foreach (var offset in annotLine.Dash)
  524. {
  525. dash.Dashes.Add(offset / annotLine.LineWidth);
  526. }
  527. DrawPen.DashStyle = dash;
  528. DrawPen.DashCap = PenLineCap.Flat;
  529. }
  530. ArrowHelper drawLine = new ArrowHelper();
  531. if (isProportionalScaling)
  532. {
  533. mouseEndPoint = CalcAnglePoint(mouseEndPoint, mouseStartPoint, pageBound);
  534. DPIRect = new Rect(mouseStartPoint, mouseEndPoint);
  535. drawLine.LineStart = mouseStartPoint;
  536. drawLine.LineEnd = mouseEndPoint;
  537. drawLine.ArrowLength = (uint)Math.Max(DrawPen.Thickness * 3, 12 * zoomFactor);
  538. drawLine.StartSharp = annotLine.HeadLineType;
  539. drawLine.EndSharp = annotLine.TailLineType;
  540. drawingContext.DrawGeometry(null, DrawPen, drawLine.BuildArrowBody());
  541. }
  542. else
  543. {
  544. Point checkPoint = mouseEndPoint;
  545. if (mouseEndPoint.X < maxRect.Left)
  546. {
  547. checkPoint.X = maxRect.Left;
  548. }
  549. if (mouseEndPoint.X > maxRect.Right)
  550. {
  551. checkPoint.X = maxRect.Right;
  552. }
  553. if (mouseEndPoint.Y < maxRect.Top)
  554. {
  555. checkPoint.Y = maxRect.Top;
  556. }
  557. if (mouseEndPoint.Y > maxRect.Bottom)
  558. {
  559. checkPoint.Y = maxRect.Bottom;
  560. }
  561. mouseEndPoint = checkPoint;
  562. DPIRect = new Rect(mouseStartPoint, mouseEndPoint);
  563. drawLine.LineStart = mouseStartPoint;
  564. drawLine.LineEnd = mouseEndPoint;
  565. drawLine.ArrowLength = (uint)Math.Max(DrawPen.Thickness * 3, 12 * zoomFactor);
  566. drawLine.StartSharp = annotLine.HeadLineType;
  567. drawLine.EndSharp = annotLine.TailLineType;
  568. drawingContext.DrawGeometry(null, DrawPen, drawLine.BuildArrowBody());
  569. }
  570. }
  571. private void DrawInk(DrawingContext drawingContext)
  572. {
  573. CPDFInkAnnotation annotLine = (cPDFAnnotation as CPDFInkAnnotation);
  574. if (annotLine == null || annotLine.IsValid() == false)
  575. {
  576. return;
  577. }
  578. byte transparent = annotLine.GetTransparency();
  579. Pen DrawPen = new Pen(new SolidColorBrush(Color.FromArgb(transparent, annotLine.InkColor[0], annotLine.InkColor[1], annotLine.InkColor[2])), annotLine.Thickness * zoomFactor);
  580. DrawPen.StartLineCap = PenLineCap.Round;
  581. DrawPen.EndLineCap = PenLineCap.Round;
  582. PathGeometry pathDraw = new PathGeometry();
  583. Point CurrentPoint = mouseEndPoint;
  584. Rect MaxRect = pageBound;
  585. if (CurrentPoint.X > MaxRect.Right)
  586. {
  587. CurrentPoint.X = MaxRect.Right;
  588. }
  589. if (CurrentPoint.X < MaxRect.Left)
  590. {
  591. CurrentPoint.X = MaxRect.Left;
  592. }
  593. if (CurrentPoint.Y > MaxRect.Bottom)
  594. {
  595. CurrentPoint.Y = MaxRect.Bottom;
  596. }
  597. if (CurrentPoint.Y < MaxRect.Top)
  598. {
  599. CurrentPoint.Y = MaxRect.Top;
  600. }
  601. inkDrawPoints.Add(CurrentPoint);
  602. pathDraw.Figures = new PathFigureCollection();
  603. PathFigure pathFigure = new PathFigure();
  604. pathDraw.Figures.Add(pathFigure);
  605. pathFigure.StartPoint = mouseStartPoint;
  606. foreach (Point addPoint in inkDrawPoints)
  607. {
  608. LineSegment lineSegment = new LineSegment(addPoint, true);
  609. lineSegment.IsSmoothJoin = true;
  610. pathFigure.Segments.Add(lineSegment);
  611. }
  612. if (annotLine.Dash != null && annotLine.Dash.Length > 0)
  613. {
  614. DashStyle dash = new DashStyle();
  615. foreach (var offset in annotLine.Dash)
  616. {
  617. dash.Dashes.Add(offset);
  618. }
  619. DrawPen.DashStyle = dash;
  620. DrawPen.DashCap = PenLineCap.Flat;
  621. }
  622. Rect checkRect = pageBound;
  623. RectangleGeometry rectGeometry = new RectangleGeometry();
  624. drawRect = rectGeometry.Rect = checkRect;
  625. drawingContext?.PushClip(rectGeometry);
  626. drawingContext?.DrawGeometry(null, DrawPen, pathDraw);
  627. }
  628. private void DrawLink(DrawingContext drawingContext)
  629. {
  630. Pen DrawPen = defaultDrawParam.LinkPen;
  631. DrawPen.Thickness *= zoomFactor;
  632. SolidColorBrush FillBrush = defaultDrawParam.LinkBrush;
  633. if (isProportionalScaling)
  634. {
  635. Point mouseOffset = (Point)(mouseStartPoint - mouseEndPoint);
  636. if (mouseOffset.X < 0)
  637. {
  638. if (mouseOffset.Y > 0)
  639. {
  640. mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseStartPoint.X - mouseEndPoint.X);
  641. }
  642. else
  643. {
  644. mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseEndPoint.X - mouseStartPoint.X);
  645. }
  646. }
  647. else
  648. {
  649. if (mouseOffset.Y > 0)
  650. {
  651. mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseEndPoint.X - mouseStartPoint.X);
  652. }
  653. else
  654. {
  655. mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseStartPoint.X - mouseEndPoint.X);
  656. }
  657. }
  658. }
  659. Rect rect = new Rect(mouseStartPoint, mouseEndPoint);
  660. double mLeft = rect.Left;
  661. double mRight = rect.Right;
  662. double mUp = rect.Top;
  663. double mDown = rect.Bottom;
  664. if (rect.Left < maxRect.Left)
  665. {
  666. mLeft = maxRect.Left;
  667. }
  668. if (rect.Right > maxRect.Right)
  669. {
  670. mRight = maxRect.Right;
  671. }
  672. if (rect.Top < maxRect.Top)
  673. {
  674. mUp = maxRect.Top;
  675. }
  676. if (rect.Bottom > maxRect.Bottom)
  677. {
  678. mDown = maxRect.Bottom;
  679. }
  680. DPIRect = new Rect(mLeft, mUp, mRight - mLeft, mDown - mUp);
  681. int halfPenWidth = (int)Math.Ceiling(DrawPen.Thickness / 2);
  682. double drawWidth = DPIRect.Width - halfPenWidth * 2;
  683. double drawHeight = DPIRect.Height - halfPenWidth * 2;
  684. if (drawWidth > 0 && drawHeight > 0)
  685. {
  686. drawRect = new Rect(
  687. (int)DPIRect.Left + halfPenWidth,
  688. (int)DPIRect.Top + halfPenWidth,
  689. (int)DPIRect.Width - halfPenWidth * 2,
  690. (int)DPIRect.Height - halfPenWidth * 2);
  691. drawingContext?.DrawRectangle(null, DrawPen, drawRect);
  692. halfPenWidth = (int)Math.Floor(DrawPen.Thickness / 2);
  693. if (drawRect.Width - halfPenWidth * 2 > 0 && drawRect.Height - halfPenWidth * 2 > 0)
  694. {
  695. Rect innerRect = new Rect(drawRect.Left + halfPenWidth, drawRect.Top + halfPenWidth, drawRect.Width - 2 * halfPenWidth, drawRect.Height - 2 * halfPenWidth);
  696. drawingContext?.DrawRectangle(FillBrush, null, innerRect);
  697. }
  698. }
  699. }
  700. private void DrawRedact(DrawingContext drawingContext)
  701. {
  702. Pen DrawPen = defaultDrawParam.RedactPen;
  703. if (cPDFAnnotation != null && cPDFAnnotation.IsValid() && cPDFAnnotation.Type == C_ANNOTATION_TYPE.C_ANNOTATION_REDACT)
  704. {
  705. CPDFRedactAnnotation redactAnnot = cPDFAnnotation as CPDFRedactAnnotation;
  706. if (redactAnnot.OutlineColor != null && redactAnnot.OutlineColor.Length == 3)
  707. {
  708. DrawPen = new Pen(new SolidColorBrush(Color.FromRgb(redactAnnot.OutlineColor[0], redactAnnot.OutlineColor[1], redactAnnot.OutlineColor[2])), DrawPen.Thickness);
  709. }
  710. }
  711. SolidColorBrush FillBrush = new SolidColorBrush(Color.FromArgb(0x46, 0x46, 0x82, 0xB4));
  712. if (isProportionalScaling)
  713. {
  714. Point mouseOffset = (Point)(mouseStartPoint - mouseEndPoint);
  715. if (mouseOffset.X < 0)
  716. {
  717. if (mouseOffset.Y > 0)
  718. {
  719. mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseStartPoint.X - mouseEndPoint.X);
  720. }
  721. else
  722. {
  723. mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseEndPoint.X - mouseStartPoint.X);
  724. }
  725. }
  726. else
  727. {
  728. if (mouseOffset.Y > 0)
  729. {
  730. mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseEndPoint.X - mouseStartPoint.X);
  731. }
  732. else
  733. {
  734. mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseStartPoint.X - mouseEndPoint.X);
  735. }
  736. }
  737. }
  738. Rect rect = new Rect(mouseStartPoint, mouseEndPoint);
  739. double mLeft = rect.Left;
  740. double mRight = rect.Right;
  741. double mUp = rect.Top;
  742. double mDown = rect.Bottom;
  743. if (rect.Left < maxRect.Left)
  744. {
  745. mLeft = maxRect.Left;
  746. }
  747. if (rect.Right > maxRect.Right)
  748. {
  749. mRight = maxRect.Right;
  750. }
  751. if (rect.Top < maxRect.Top)
  752. {
  753. mUp = maxRect.Top;
  754. }
  755. if (rect.Bottom > maxRect.Bottom)
  756. {
  757. mDown = maxRect.Bottom;
  758. }
  759. DPIRect = new Rect(mLeft, mUp, mRight - mLeft, mDown - mUp);
  760. int halfPenWidth = (int)Math.Ceiling(DrawPen.Thickness / 2);
  761. double drawWidth = DPIRect.Width - halfPenWidth * 2;
  762. double drawHeight = DPIRect.Height - halfPenWidth * 2;
  763. if (drawWidth > 0 && drawHeight > 0)
  764. {
  765. drawRect = new Rect(
  766. (int)DPIRect.Left + halfPenWidth,
  767. (int)DPIRect.Top + halfPenWidth,
  768. (int)DPIRect.Width - halfPenWidth * 2,
  769. (int)DPIRect.Height - halfPenWidth * 2);
  770. drawingContext?.DrawRectangle(null, DrawPen, drawRect);
  771. halfPenWidth = (int)Math.Floor(DrawPen.Thickness / 2);
  772. if (drawRect.Width - halfPenWidth * 2 > 0 && drawRect.Height - halfPenWidth * 2 > 0)
  773. {
  774. Rect innerRect = new Rect(drawRect.Left + halfPenWidth, drawRect.Top + halfPenWidth, drawRect.Width - 2 * halfPenWidth, drawRect.Height - 2 * halfPenWidth);
  775. drawingContext?.DrawRectangle(FillBrush, null, innerRect);
  776. }
  777. }
  778. }
  779. private void DrawPolyLineMeasure(DrawingContext drawingContext)
  780. {
  781. CPDFPolylineAnnotation polyLine = (cPDFAnnotation as CPDFPolylineAnnotation);
  782. byte[] bytes = polyLine.LineColor;
  783. Color color = ParamConverter.ConverterByteForColor(bytes);
  784. color.A = polyLine.GetTransparency();
  785. Pen DrawPen = new Pen(new SolidColorBrush(color), polyLine.GetBorderWidth());
  786. SolidColorBrush TextBrush = Brushes.Red;
  787. if (polyLine.IsMeasured())
  788. {
  789. CPDFPerimeterMeasure measureInfo = polyLine.GetPerimeterMeasure();
  790. if (measureInfo != null && measureInfo.TextAttribute != null && measureInfo.TextAttribute.FontColor != null && measureInfo.TextAttribute.FontColor.Length >= 3)
  791. {
  792. byte[] fontColor = measureInfo.TextAttribute.FontColor;
  793. TextBrush = new SolidColorBrush(Color.FromRgb(fontColor[0], fontColor[1], fontColor[2]));
  794. }
  795. if (polyLine.Dash != null && polyLine.Dash.Length > 0)
  796. {
  797. DashStyle dash = new DashStyle();
  798. foreach (var offset in polyLine.Dash)
  799. {
  800. dash.Dashes.Add(offset / polyLine.LineWidth);
  801. }
  802. DrawPen.DashStyle = dash;
  803. DrawPen.DashCap = PenLineCap.Flat;
  804. }
  805. }
  806. if (isProportionalScaling)
  807. {
  808. if (drawPoints != null && drawPoints.Count > 0)
  809. {
  810. mouseEndPoint = CalcAnglePoint(mouseEndPoint, drawPoints[drawPoints.Count - 1], pageBound);
  811. }
  812. }
  813. Point checkPoint = mouseEndPoint;
  814. checkPoint.X = Math.Max(pageBound.Left, checkPoint.X);
  815. checkPoint.X = Math.Min(pageBound.Right, checkPoint.X);
  816. checkPoint.Y = Math.Max(pageBound.Top, checkPoint.Y);
  817. checkPoint.Y = Math.Min(pageBound.Bottom, checkPoint.Y);
  818. if (drawPoints.Count > 0)
  819. {
  820. PathGeometry drawPath = new PathGeometry();
  821. PathFigure drawFigure = new PathFigure();
  822. drawFigure.StartPoint = drawPoints[0];
  823. PolyLineSegment polySegment = new PolyLineSegment();
  824. for (int i = 1; i < drawPoints.Count; i++)
  825. {
  826. polySegment.Points.Add(drawPoints[i]);
  827. }
  828. polySegment.Points.Add(checkPoint);
  829. if (polySegment.Points.Count > 0)
  830. {
  831. drawFigure.Segments.Add(polySegment);
  832. }
  833. if (drawFigure.Segments.Count > 0)
  834. {
  835. drawPath.Figures.Add(drawFigure);
  836. }
  837. double totalInch = 0;
  838. if (drawPoints.Count > 1)
  839. {
  840. for (int i = 0; i < drawPoints.Count - 1; i++)
  841. {
  842. totalInch += measureSetting.GetMeasureLength(drawPoints[i], drawPoints[i + 1], zoomFactor);
  843. }
  844. }
  845. double currentInch = measureSetting.GetMeasureLength(drawPoints[drawPoints.Count - 1], checkPoint, zoomFactor);
  846. totalInch += currentInch;
  847. drawingContext?.DrawGeometry(null, DrawPen, drawPath);
  848. Point closePoint = drawPoints[drawPoints.Count - 1];
  849. Vector movevector = checkPoint - closePoint;
  850. FormattedText moveText = new FormattedText(
  851. string.Format("{0} {1}", measureSetting.GetPrecisionData(currentInch), measureSetting.RulerTranslateUnit),
  852. CultureInfo.GetCultureInfo("en-us"),
  853. FlowDirection.LeftToRight,
  854. new Typeface("YaHei"),
  855. 16,
  856. TextBrush);
  857. FormattedText totalText = new FormattedText(
  858. string.Format("{0} {1}", measureSetting.GetPrecisionData(totalInch), measureSetting.RulerTranslateUnit),
  859. CultureInfo.GetCultureInfo("en-us"),
  860. FlowDirection.LeftToRight,
  861. new Typeface("YaHei"),
  862. 16,
  863. TextBrush);
  864. if (movevector.Length > moveText.Width + textPadding)
  865. {
  866. if (checkPoint.X >= closePoint.X)
  867. {
  868. Point linePoint = new Point(closePoint.X + movevector.Length, closePoint.Y);
  869. Point drawPoint = new Point(
  870. linePoint.X - moveText.Width - textPadding,
  871. linePoint.Y - moveText.Height);
  872. Vector anglevector = linePoint - closePoint;
  873. RotateTransform transform = new RotateTransform();
  874. transform.CenterX = closePoint.X;
  875. transform.CenterY = closePoint.Y;
  876. double angle = Vector.AngleBetween(movevector, anglevector);
  877. transform.Angle = -angle;
  878. drawingContext?.PushTransform(transform);
  879. drawingContext?.DrawText(moveText, drawPoint);
  880. if (totalInch > currentInch)
  881. {
  882. drawingContext?.DrawText(totalText, new Point(
  883. drawPoint.X + moveText.Width + textPadding * 2,
  884. drawPoint.Y
  885. ));
  886. }
  887. drawingContext.Pop();
  888. }
  889. else
  890. {
  891. Point linePoint = new Point(closePoint.X - movevector.Length, closePoint.Y);
  892. Point drawPoint = new Point(
  893. linePoint.X + textPadding,
  894. linePoint.Y - moveText.Height);
  895. Vector anglevector = linePoint - closePoint;
  896. RotateTransform transform = new RotateTransform();
  897. transform.CenterX = closePoint.X;
  898. transform.CenterY = closePoint.Y;
  899. double angle = Vector.AngleBetween(movevector, anglevector);
  900. transform.Angle = -angle;
  901. drawingContext?.PushTransform(transform);
  902. drawingContext?.DrawText(moveText, drawPoint);
  903. if (totalInch > currentInch)
  904. {
  905. drawingContext?.DrawText(totalText,
  906. new Point(
  907. drawPoint.X - totalText.Width - textPadding * 2,
  908. drawPoint.Y
  909. ));
  910. }
  911. drawingContext.Pop();
  912. }
  913. }
  914. double left = drawPoints.AsEnumerable().Select(x => x.X).Min();
  915. double right = drawPoints.AsEnumerable().Select(x => x.X).Max();
  916. double top = drawPoints.AsEnumerable().Select(x => x.Y).Min();
  917. double bottom = drawPoints.AsEnumerable().Select(x => x.Y).Max();
  918. DPIRect = new Rect(left, top, right - left, bottom - top);
  919. MeasureEventArgs measureEvent = new MeasureEventArgs();
  920. if (drawPoints.Count < 2)
  921. {
  922. measureEvent.Angle = 0;
  923. }
  924. else
  925. {
  926. Vector standVector = drawPoints[drawPoints.Count - 1] - drawPoints[drawPoints.Count - 2];
  927. Vector endvector = closePoint - checkPoint;
  928. measureEvent.Angle = (int)Math.Abs(Vector.AngleBetween(endvector, standVector));
  929. }
  930. measureEvent.RulerTranslateUnit = measureSetting.RulerTranslateUnit;
  931. measureEvent.RulerTranslate = measureSetting.RulerTranslate;
  932. measureEvent.RulerBase = measureSetting.RulerBase;
  933. measureEvent.RulerBaseUnit = measureSetting.RulerBaseUnit;
  934. measureEvent.Precision = measureSetting.Precision;
  935. measureEvent.Type = CPDFMeasureType.CPDF_PERIMETER_MEASURE;
  936. measureEvent.Distance = totalText.Text;
  937. MeasureChanged?.Invoke(this, measureEvent);
  938. }
  939. }
  940. private void DrawPolygonMeasure(DrawingContext drawingContext)
  941. {
  942. CPDFPolygonAnnotation polygonAnnot = (cPDFAnnotation as CPDFPolygonAnnotation);
  943. byte[] bytes = polygonAnnot.LineColor;
  944. Color color = ParamConverter.ConverterByteForColor(bytes);
  945. color.A = polygonAnnot.GetTransparency();
  946. Pen DrawPen = new Pen(new SolidColorBrush(color), polygonAnnot.GetBorderWidth());
  947. Pen EndDrawPen = new Pen(Brushes.Black, polygonAnnot.GetBorderWidth());
  948. SolidColorBrush TextBrush = Brushes.Red;
  949. if (polygonAnnot.IsMeasured())
  950. {
  951. CPDFAreaMeasure measureInfo = polygonAnnot.GetAreaMeasure();
  952. if (measureInfo != null && measureInfo.TextAttribute != null && measureInfo.TextAttribute.FontColor != null && measureInfo.TextAttribute.FontColor.Length >= 3)
  953. {
  954. byte[] fontColor = measureInfo.TextAttribute.FontColor;
  955. TextBrush = new SolidColorBrush(Color.FromRgb(fontColor[0], fontColor[1], fontColor[2]));
  956. }
  957. if (polygonAnnot.Dash != null && polygonAnnot.Dash.Length > 0)
  958. {
  959. DashStyle dash = new DashStyle();
  960. foreach (var offset in polygonAnnot.Dash)
  961. {
  962. dash.Dashes.Add(offset / polygonAnnot.LineWidth);
  963. }
  964. DrawPen.DashStyle = dash;
  965. DrawPen.DashCap = PenLineCap.Flat;
  966. }
  967. }
  968. if (isProportionalScaling)
  969. {
  970. if (drawPoints != null && drawPoints.Count > 0)
  971. {
  972. mouseEndPoint = CalcAnglePoint(mouseEndPoint, drawPoints[drawPoints.Count - 1], pageBound);
  973. }
  974. }
  975. Point checkPoint = mouseEndPoint;
  976. checkPoint.X = Math.Max(pageBound.Left, checkPoint.X);
  977. checkPoint.X = Math.Min(pageBound.Right, checkPoint.X);
  978. checkPoint.Y = Math.Max(pageBound.Top, checkPoint.Y);
  979. checkPoint.Y = Math.Min(pageBound.Bottom, checkPoint.Y);
  980. PointCollection points = drawPoints.Clone();
  981. if (defaultSettingParam.IsCreateSquarePolygonMeasure && drawPoints.Count == 1)
  982. {
  983. Point star = points[0];
  984. Rect rect = new Rect(star, checkPoint);
  985. points.Clear();
  986. points.Add(rect.TopLeft);
  987. points.Add(rect.BottomLeft);
  988. points.Add(rect.BottomRight);
  989. points.Add(rect.TopRight);
  990. }
  991. if (points.Count > 0)
  992. {
  993. CPDFBorderEffector borderEffector = polygonAnnot.GetAnnotBorderEffector();
  994. if (borderEffector != null && borderEffector.BorderIntensity != C_BORDER_INTENSITY.C_INTENSITY_ZERO && borderEffector.BorderType != C_BORDER_TYPE.C_BORDER_TYPE_STRAIGHT)
  995. {
  996. //Draw the example line connected by the start point and the end point.
  997. if (points.Count == 1)
  998. {
  999. Pen dashedPen = new Pen(Brushes.Gray, 1);
  1000. dashedPen.DashStyle = new DashStyle(new double[] { 2, 2 }, 0);
  1001. drawingContext?.DrawLine(dashedPen, points[0], checkPoint);
  1002. }
  1003. double left = drawPoints.AsEnumerable().Select(x => x.X).Min();
  1004. double right = drawPoints.AsEnumerable().Select(x => x.X).Max();
  1005. double top = drawPoints.AsEnumerable().Select(x => x.Y).Min();
  1006. double bottom = drawPoints.AsEnumerable().Select(x => x.Y).Max();
  1007. DPIRect = new Rect(left, top, right - left, bottom - top);
  1008. polygonAnnot.SetAnnotBorderEffector(borderEffector);
  1009. drawPoints.Add(checkPoint);
  1010. List<Point> measurePoint = new List<Point>();
  1011. measurePoint = GetMeasureDrawPoints();
  1012. drawPoints.RemoveAt(drawPoints.Count - 1);
  1013. List<CPoint> cPoints = new List<CPoint>();
  1014. foreach (Point item in measurePoint)
  1015. {
  1016. cPoints.Add(DataConversionForWPF.PointConversionForCPoint(DpiHelper.StandardPointToPDFPoint(item)));
  1017. }
  1018. polygonAnnot.SetPoints(cPoints);
  1019. polygonAnnot.UpdateAp();
  1020. cPDFViewer.UpdateAnnotFrame();
  1021. }
  1022. else
  1023. {
  1024. PathGeometry drawPath = new PathGeometry();
  1025. PathFigure drawFigure = new PathFigure();
  1026. drawFigure.StartPoint = points[0];
  1027. PolyLineSegment polySegment = new PolyLineSegment();
  1028. for (int i = 1; i < points.Count; i++)
  1029. {
  1030. polySegment.Points.Add(points[i]);
  1031. }
  1032. if (defaultSettingParam.IsCreateSquarePolygonMeasure)
  1033. {
  1034. polySegment.Points.Add(points[0]);
  1035. }
  1036. else
  1037. {
  1038. //Add the current point during the movement.
  1039. polySegment.Points.Add(checkPoint);
  1040. }
  1041. if (polySegment.Points.Count > 0)
  1042. {
  1043. drawFigure.Segments.Add(polySegment);
  1044. }
  1045. if (drawFigure.Segments.Count > 0)
  1046. {
  1047. drawPath.Figures.Add(drawFigure);
  1048. }
  1049. //Draw the line segment.
  1050. drawingContext?.DrawGeometry(null, DrawPen, drawPath);
  1051. //Draw the example line connected by the start point and the end point.
  1052. if (points.Count > 1)
  1053. {
  1054. if (defaultSettingParam.IsCreateSquarePolygonMeasure)
  1055. {
  1056. drawingContext?.DrawLine(DrawPen, points[0], polySegment.Points.Last());
  1057. }
  1058. else
  1059. {
  1060. drawingContext?.DrawLine(EndDrawPen, points[0], polySegment.Points.Last());
  1061. }
  1062. }
  1063. //Calculate the length.
  1064. double totalInch = 0;
  1065. if (points.Count > 1)
  1066. {
  1067. for (int i = 0; i < points.Count - 1; i++)
  1068. {
  1069. totalInch += measureSetting.GetMeasureLength(points[i], points[i + 1], zoomFactor);
  1070. }
  1071. }
  1072. double currentInch = measureSetting.GetMeasureLength(points[points.Count - 1], checkPoint, zoomFactor);
  1073. if (defaultSettingParam.IsCreateSquarePolygonMeasure)
  1074. {
  1075. currentInch = measureSetting.GetMeasureLength(points[points.Count - 1], points[0], zoomFactor);
  1076. }
  1077. totalInch += currentInch;
  1078. Point closePoint = points[points.Count - 1];
  1079. Vector movevector = checkPoint - closePoint;
  1080. if (polygonAnnot.IsMeasured())
  1081. {
  1082. FormattedText moveText = new FormattedText(
  1083. string.Format("{0} {1}", measureSetting.GetPrecisionData(currentInch), measureSetting.RulerTranslateUnit),
  1084. CultureInfo.GetCultureInfo("en-us"),
  1085. FlowDirection.LeftToRight,
  1086. new Typeface("YaHei"),
  1087. 16,
  1088. TextBrush);
  1089. FormattedText totalText = new FormattedText(
  1090. string.Format("{0} {1}", measureSetting.GetPrecisionData(totalInch), measureSetting.RulerTranslateUnit),
  1091. CultureInfo.GetCultureInfo("en-us"),
  1092. FlowDirection.LeftToRight,
  1093. new Typeface("YaHei"),
  1094. 16,
  1095. TextBrush);
  1096. //Judge the text display form.
  1097. if (movevector.Length > moveText.Width + textPadding || defaultSettingParam.IsCreateSquarePolygonMeasure)
  1098. {
  1099. if (checkPoint.X >= closePoint.X)
  1100. {
  1101. Point linePoint = new Point(closePoint.X + movevector.Length, closePoint.Y);
  1102. Point drawPoint = new Point(
  1103. linePoint.X - moveText.Width - textPadding,
  1104. linePoint.Y - moveText.Height);
  1105. Vector anglevector = linePoint - closePoint;
  1106. RotateTransform transform = new RotateTransform();
  1107. transform.CenterX = closePoint.X;
  1108. transform.CenterY = closePoint.Y;
  1109. double angle = Vector.AngleBetween(movevector, anglevector);
  1110. transform.Angle = -angle;
  1111. drawingContext?.PushTransform(transform);
  1112. if (!defaultSettingParam.IsCreateSquarePolygonMeasure)
  1113. {
  1114. drawingContext?.DrawText(moveText, drawPoint);
  1115. }
  1116. if (totalInch > currentInch)
  1117. {
  1118. drawingContext?.DrawText(totalText, new Point(
  1119. drawPoint.X + moveText.Width + textPadding * 2,
  1120. drawPoint.Y
  1121. ));
  1122. }
  1123. drawingContext.Pop();
  1124. }
  1125. else
  1126. {
  1127. Point linePoint = new Point(closePoint.X - movevector.Length, closePoint.Y);
  1128. Point drawPoint = new Point(
  1129. linePoint.X + textPadding,
  1130. linePoint.Y - moveText.Height);
  1131. Vector anglevector = linePoint - closePoint;
  1132. RotateTransform transform = new RotateTransform();
  1133. transform.CenterX = closePoint.X;
  1134. transform.CenterY = closePoint.Y;
  1135. double angle = Vector.AngleBetween(movevector, anglevector);
  1136. transform.Angle = -angle;
  1137. drawingContext?.PushTransform(transform);
  1138. if (!defaultSettingParam.IsCreateSquarePolygonMeasure)
  1139. {
  1140. drawingContext?.DrawText(moveText, drawPoint);
  1141. }
  1142. if (totalInch > currentInch)
  1143. {
  1144. drawingContext?.DrawText(totalText,
  1145. new Point(
  1146. drawPoint.X - totalText.Width - textPadding * 2,
  1147. drawPoint.Y
  1148. ));
  1149. }
  1150. drawingContext.Pop();
  1151. }
  1152. }
  1153. }
  1154. if (defaultSettingParam.IsCreateSquarePolygonMeasure)
  1155. {
  1156. double deleft = points.AsEnumerable().Select(x => x.X).Min();
  1157. double deright = points.AsEnumerable().Select(x => x.X).Max();
  1158. double detop = points.AsEnumerable().Select(x => x.Y).Min();
  1159. double debottom = points.AsEnumerable().Select(x => x.Y).Max();
  1160. DPIRect = new Rect(deleft, detop, deright - deleft, debottom - detop);
  1161. }
  1162. else
  1163. {
  1164. double left = drawPoints.AsEnumerable().Select(x => x.X).Min();
  1165. double right = drawPoints.AsEnumerable().Select(x => x.X).Max();
  1166. double top = drawPoints.AsEnumerable().Select(x => x.Y).Min();
  1167. double bottom = drawPoints.AsEnumerable().Select(x => x.Y).Max();
  1168. DPIRect = new Rect(left, top, right - left, bottom - top);
  1169. }
  1170. MeasureEventArgs measureEvent = new MeasureEventArgs();
  1171. if (points.Count < 2)
  1172. {
  1173. measureEvent.Angle = 0;
  1174. }
  1175. else
  1176. {
  1177. Vector standVector = points[points.Count - 1] - points[points.Count - 2];
  1178. Vector endvector = closePoint - checkPoint;
  1179. measureEvent.Angle = (int)Math.Abs(Vector.AngleBetween(endvector, standVector));
  1180. if (defaultSettingParam.IsCreateSquarePolygonMeasure)
  1181. {
  1182. measureEvent.Angle = 90;
  1183. }
  1184. }
  1185. List<Point> pon = new List<Point>();
  1186. if (!defaultSettingParam.IsCreateSquarePolygonMeasure)
  1187. {
  1188. points.Add(checkPoint);
  1189. }
  1190. foreach (Point drawPoint in points)
  1191. {
  1192. Point savePoint = new Point(
  1193. (drawPoint.X - pageBound.Left) + cropPoint.X,
  1194. (drawPoint.Y - pageBound.Top) + cropPoint.Y);
  1195. pon.Add(DpiHelper.StandardPointToPDFPoint(new Point(
  1196. (float)drawPoint.X / zoomFactor,
  1197. (float)drawPoint.Y / zoomFactor
  1198. )));
  1199. }
  1200. double area = measureSetting.ComputePolygonArea(pon.ToList());
  1201. double ratio = measureSetting.GetMeasureAreaRatio();
  1202. double rate = measureSetting.RulerTranslate / measureSetting.RulerBase;
  1203. double inch = area * ratio * ratio * rate * rate;
  1204. //measureEvent.RulerTranslateUnit = measureSetting.RulerTranslateUnit;
  1205. //measureEvent.RulerTranslate = measureSetting.RulerTranslate;
  1206. //measureEvent.RulerBase = measureSetting.RulerBase;
  1207. //measureEvent.RulerBaseUnit = measureSetting.RulerBaseUnit;
  1208. //measureEvent.Precision = measureSetting.Precision;
  1209. //measureEvent.Type = CPDFMeasureType.CPDF_AREA_MEASURE;
  1210. //measureEvent.Distance = totalText.Text;
  1211. // measureEvent.Area = string.Format("{0} sq {1}", measureSetting.GetPrecisionData(inch), measureSetting.RulerTranslateUnit);
  1212. MeasureChanged?.Invoke(this, measureEvent);
  1213. }
  1214. }
  1215. }
  1216. private void DrawLineMeasure(DrawingContext drawingContext)
  1217. {
  1218. CPDFLineAnnotation polyLine = (cPDFAnnotation as CPDFLineAnnotation);
  1219. byte[] bytes = polyLine.LineColor;
  1220. Color color = ParamConverter.ConverterByteForColor(bytes);
  1221. color.A = polyLine.GetTransparency();
  1222. Pen DrawPen = new Pen(new SolidColorBrush(color), polyLine.GetBorderWidth());
  1223. SolidColorBrush TextBrush = Brushes.Red;
  1224. if (polyLine.IsMeasured())
  1225. {
  1226. CPDFDistanceMeasure measureInfo = polyLine.GetDistanceMeasure();
  1227. if (measureInfo != null && measureInfo.TextAttribute != null && measureInfo.TextAttribute.FontColor != null && measureInfo.TextAttribute.FontColor.Length >= 3)
  1228. {
  1229. byte[] fontColor = measureInfo.TextAttribute.FontColor;
  1230. TextBrush = new SolidColorBrush(Color.FromRgb(fontColor[0], fontColor[1], fontColor[2]));
  1231. }
  1232. if (polyLine.Dash != null && polyLine.Dash.Length > 0)
  1233. {
  1234. DashStyle dash = new DashStyle();
  1235. foreach (var offset in polyLine.Dash)
  1236. {
  1237. dash.Dashes.Add(offset / polyLine.LineWidth);
  1238. }
  1239. DrawPen.DashStyle = dash;
  1240. DrawPen.DashCap = PenLineCap.Flat;
  1241. }
  1242. }
  1243. if (isProportionalScaling)
  1244. {
  1245. mouseEndPoint = CalcAnglePoint(mouseEndPoint, mouseStartPoint, pageBound);
  1246. }
  1247. Point checkPoint = mouseEndPoint;
  1248. checkPoint.X = Math.Max(pageBound.Left, checkPoint.X);
  1249. checkPoint.X = Math.Min(pageBound.Right, checkPoint.X);
  1250. checkPoint.Y = Math.Max(pageBound.Top, checkPoint.Y);
  1251. checkPoint.Y = Math.Min(pageBound.Bottom, checkPoint.Y);
  1252. double inch = measureSetting.GetMeasureLength(mouseStartPoint, checkPoint, zoomFactor);
  1253. ArrowHelper drawLine = new ArrowHelper();
  1254. drawLine.LineStart = mouseStartPoint;
  1255. drawLine.LineEnd = checkPoint;
  1256. drawLine.ArrowLength = (uint)Math.Max(DrawPen.Thickness * 3, 12 * zoomFactor * zoomFactor);
  1257. drawLine.StartSharp = polyLine.HeadLineType;
  1258. drawLine.EndSharp = polyLine.TailLineType;
  1259. drawLine.BuildArrowBody();
  1260. drawingContext?.DrawGeometry(null, DrawPen, drawLine.Body);
  1261. drawingContext.DrawGeometry(null, DrawPen, drawLine.BuildArrowBody());
  1262. FormattedText formattedText = new FormattedText(
  1263. string.Format("{0} {1}", measureSetting.GetPrecisionData(inch), measureSetting.RulerTranslateUnit),
  1264. CultureInfo.GetCultureInfo("en-us"),
  1265. FlowDirection.LeftToRight,
  1266. new Typeface("YaHei"),
  1267. 16,
  1268. TextBrush);
  1269. Vector movevector = checkPoint - mouseStartPoint;
  1270. if (movevector.Length > formattedText.Width + textPadding)
  1271. {
  1272. if (checkPoint.X >= mouseStartPoint.X)
  1273. {
  1274. Point linePoint = new Point(mouseStartPoint.X + movevector.Length, mouseStartPoint.Y);
  1275. Point drawPoint = new Point(
  1276. linePoint.X - formattedText.Width - textPadding,
  1277. linePoint.Y - formattedText.Height);
  1278. Vector anglevector = linePoint - mouseStartPoint;
  1279. RotateTransform transform = new RotateTransform();
  1280. transform.CenterX = mouseStartPoint.X;
  1281. transform.CenterY = mouseStartPoint.Y;
  1282. double angle = Vector.AngleBetween(movevector, anglevector);
  1283. transform.Angle = -angle;
  1284. drawingContext?.PushTransform(transform);
  1285. drawingContext?.DrawText(formattedText, drawPoint);
  1286. drawingContext.Pop();
  1287. }
  1288. else
  1289. {
  1290. Point linePoint = new Point(mouseStartPoint.X - movevector.Length, mouseStartPoint.Y);
  1291. Point drawPoint = new Point(
  1292. linePoint.X + textPadding,
  1293. linePoint.Y - formattedText.Height);
  1294. Vector anglevector = linePoint - mouseStartPoint;
  1295. RotateTransform transform = new RotateTransform();
  1296. transform.CenterX = mouseStartPoint.X;
  1297. transform.CenterY = mouseStartPoint.Y;
  1298. double angle = Vector.AngleBetween(movevector, anglevector);
  1299. transform.Angle = -angle;
  1300. drawingContext?.PushTransform(transform);
  1301. drawingContext?.DrawText(formattedText, drawPoint);
  1302. drawingContext.Pop();
  1303. }
  1304. }
  1305. DPIRect = new Rect(mouseStartPoint, checkPoint);
  1306. if (drawPoints.Count <= 1)
  1307. {
  1308. drawPoints.Add(checkPoint);
  1309. }
  1310. else
  1311. {
  1312. drawPoints[1] = checkPoint;
  1313. }
  1314. Vector standVector = new Vector(1, 0);
  1315. MeasureEventArgs measureEvent = new MeasureEventArgs();
  1316. measureEvent.Angle = (int)Math.Abs(Vector.AngleBetween(movevector, standVector));
  1317. measureEvent.RulerTranslateUnit = measureSetting.RulerTranslateUnit;
  1318. measureEvent.RulerTranslate = measureSetting.RulerTranslate;
  1319. measureEvent.RulerBase = measureSetting.RulerBase;
  1320. measureEvent.RulerBaseUnit = measureSetting.RulerBaseUnit;
  1321. measureEvent.Precision = measureSetting.Precision;
  1322. Vector moveVector = checkPoint - mouseStartPoint;
  1323. measureEvent.MousePos = new Point(
  1324. (int)Math.Abs(moveVector.X / zoomFactor / 96D * 72D),
  1325. (int)Math.Abs(moveVector.Y / zoomFactor / 96D * 72D));
  1326. measureEvent.Type = CPDFMeasureType.CPDF_DISTANCE_MEASURE;
  1327. measureEvent.Distance = formattedText.Text;
  1328. MeasureChanged?.Invoke(this, measureEvent);
  1329. }
  1330. #endregion
  1331. public void MultipleClick(Point downPoint)
  1332. {
  1333. if(!drawPoints.Contains(downPoint))
  1334. {
  1335. drawPoints.Add(downPoint);
  1336. }
  1337. }
  1338. public Rect GetMaxRect()
  1339. {
  1340. return maxRect;
  1341. }
  1342. public void CreateTextBox()
  1343. {
  1344. try
  1345. {
  1346. if (cPDFAnnotation != null && cPDFAnnotation.Type == C_ANNOTATION_TYPE.C_ANNOTATION_FREETEXT)
  1347. {
  1348. CPDFFreeTextAnnotation annotFreeText = (cPDFAnnotation as CPDFFreeTextAnnotation);
  1349. TextBox textui = new TextBox();
  1350. DashedBorder textBorder = new DashedBorder();
  1351. textBorder.Child = textui;
  1352. textui.Width = 200;
  1353. CTextAttribute textAttribute = annotFreeText.FreeTextDa;
  1354. byte transparency = annotFreeText.GetTransparency();
  1355. textui.FontSize = DpiHelper.PDFNumToStandardNum(textAttribute.FontSize * zoomFactor);
  1356. Color textColor = Color.FromArgb(
  1357. transparency,
  1358. textAttribute.FontColor[0],
  1359. textAttribute.FontColor[1],
  1360. textAttribute.FontColor[2]);
  1361. Color borderColor = Colors.Transparent;
  1362. Color backgroundColor = Colors.White;
  1363. byte[] colorArray = new byte[3];
  1364. if (annotFreeText.Transparency > 0)
  1365. {
  1366. borderColor = Color.FromRgb(annotFreeText.LineColor[0], annotFreeText.LineColor[1], annotFreeText.LineColor[2]);
  1367. }
  1368. if (annotFreeText.HasBgColor)
  1369. {
  1370. backgroundColor = Color.FromRgb(annotFreeText.BgColor[0], annotFreeText.BgColor[1], annotFreeText.BgColor[2]);
  1371. }
  1372. Point MousePoint = new Point((mouseStartPoint.X - pageBound.X), (mouseStartPoint.Y - pageBound.Y));
  1373. textBorder.MaxWidth = (pageBound.Width - MousePoint.X - cropPoint.X);
  1374. textBorder.MaxHeight = (pageBound.Height - MousePoint.Y - cropPoint.Y);
  1375. textui.Foreground = new SolidColorBrush(textColor);
  1376. textui.Background = new SolidColorBrush(backgroundColor);
  1377. textui.MinHeight = 40;
  1378. textui.MinWidth = 200;
  1379. textBorder.Padding = new Thickness(0);
  1380. textBorder.BorderBrush = new SolidColorBrush(borderColor);
  1381. double rawWidth = annotFreeText.GetBorderWidth();
  1382. double drawWidth = DpiHelper.PDFNumToStandardNum(rawWidth * zoomFactor);
  1383. textBorder.BorderThickness = new Thickness(drawWidth);
  1384. if (annotFreeText.BorderStyle != C_BORDER_STYLE.BS_SOLID && annotFreeText.Dash != null && annotFreeText.Dash.Length > 0)
  1385. {
  1386. //补充保存虚线样式
  1387. DoubleCollection dashCollection = new DoubleCollection();
  1388. foreach (float num in annotFreeText.Dash)
  1389. {
  1390. dashCollection.Add(num);
  1391. }
  1392. textBorder?.DrawDashBorder(true, drawWidth, rawWidth, dashCollection);
  1393. }
  1394. textui.BorderThickness = new Thickness(0);
  1395. textui.Text = annotFreeText.Content;
  1396. string fontName = string.Empty;
  1397. string fontFamily = string.Empty;
  1398. CPDFFont.GetFamilyStyleName(annotFreeText.FreeTextDa.FontName, ref fontFamily, ref fontName);
  1399. textui.FontFamily = new FontFamily(fontFamily);
  1400. textui.AcceptsReturn = true;
  1401. textui.TextWrapping = TextWrapping.Wrap;
  1402. textui.TextAlignment = TextAlignment.Left;
  1403. switch (annotFreeText.Alignment)
  1404. {
  1405. case C_TEXT_ALIGNMENT.ALIGNMENT_LEFT:
  1406. textui.TextAlignment = TextAlignment.Left;
  1407. break;
  1408. case C_TEXT_ALIGNMENT.ALIGNMENT_RIGHT:
  1409. textui.TextAlignment = TextAlignment.Right;
  1410. break;
  1411. case C_TEXT_ALIGNMENT.ALIGNMENT_CENTER:
  1412. textui.TextAlignment = TextAlignment.Center;
  1413. break;
  1414. default:
  1415. break;
  1416. }
  1417. textBorder.SetValue(Canvas.LeftProperty, mouseStartPoint.X);
  1418. textBorder.SetValue(Canvas.TopProperty, mouseStartPoint.Y);
  1419. lastTextui = textui;
  1420. lastTextBorder = textBorder;
  1421. textui.Loaded += (object sender, RoutedEventArgs e) =>
  1422. {
  1423. textui.Focus();
  1424. textui.CaretIndex = textui.Text.Length;
  1425. textui.SetValue(PopupTextAttachDataProperty, cPDFAnnotation);
  1426. UpdateAnnotHandler?.Invoke(this, false);
  1427. };
  1428. textui.LostFocus += (object sender, RoutedEventArgs e) =>
  1429. {
  1430. CPDFAnnotation currentAnnot = textui.GetValue(PopupTextAttachDataProperty) as CPDFAnnotation;
  1431. AnnotParam annotParam = ParamConverter.AnnotConverter(cPDFViewer.GetDocument(), currentAnnot);
  1432. if (currentAnnot != null && currentAnnot.IsValid())
  1433. {
  1434. CPDFFreeTextAnnotation updateFreeText = currentAnnot as CPDFFreeTextAnnotation;
  1435. if (textui.Text != string.Empty || updateFreeText.GetBorderWidth() != 0)
  1436. {
  1437. updateFreeText.SetContent(textui.Text);
  1438. Rect changeRect = new Rect(
  1439. DpiHelper.StandardNumToPDFNum(freeTextPoint.X),
  1440. DpiHelper.StandardNumToPDFNum(freeTextPoint.Y),
  1441. DpiHelper.StandardNumToPDFNum(textBorder.ActualWidth / zoomFactor),
  1442. DpiHelper.StandardNumToPDFNum(textBorder.ActualHeight / zoomFactor));
  1443. updateFreeText.SetRect(new CRect(
  1444. (float)changeRect.Left,
  1445. (float)changeRect.Bottom,
  1446. (float)changeRect.Right,
  1447. (float)changeRect.Top
  1448. ));
  1449. updateFreeText.UpdateAp();
  1450. FreeTextAnnotHistory freeTextAnnotHistory = new FreeTextAnnotHistory();
  1451. annotParam = ParamConverter.AnnotConverter(cPDFViewer.GetDocument(), currentAnnot);
  1452. annotParam.AnnotIndex = currentAnnot.Page.GetAnnotCount() - 1;
  1453. freeTextAnnotHistory.CurrentParam = (FreeTextParam)annotParam;
  1454. freeTextAnnotHistory.PDFDoc = cPDFViewer.GetDocument();
  1455. cPDFViewer.UndoManager.AddHistory(freeTextAnnotHistory);
  1456. UpdateAnnotHandler?.Invoke(this, true);
  1457. cPDFViewer.UndoManager?.InvokeHistoryChanged(this, new KeyValuePair<ComPDFKitViewer.Helper.UndoAction, IHistory>(ComPDFKitViewer.Helper.UndoAction.Custom, freeTextAnnotHistory));
  1458. freeTextPoint = new Point(0, 0);
  1459. }
  1460. else
  1461. {
  1462. updateFreeText.RemoveAnnot();
  1463. CreateFreetextCanceled?.Invoke(this, annotParam);
  1464. }
  1465. }
  1466. RemoveTextBox();
  1467. };
  1468. BaseLayer createAnnotTool = this;
  1469. if (createAnnotTool != null)
  1470. {
  1471. createAnnotTool.Children.Add(textBorder);
  1472. createAnnotTool.Arrange();
  1473. }
  1474. textui.LayoutUpdated += (object sender, EventArgs e) =>
  1475. {
  1476. createAnnotTool.Arrange();
  1477. };
  1478. }
  1479. }
  1480. catch
  1481. {
  1482. }
  1483. }
  1484. public void RemoveTextBox()
  1485. {
  1486. if (lastTextBorder == null)
  1487. {
  1488. return;
  1489. }
  1490. BaseLayer removeLayer = this;
  1491. removeLayer.Children.Remove(lastTextBorder);
  1492. }
  1493. private void DrawText()
  1494. {
  1495. if (isProportionalScaling)
  1496. {
  1497. Point mouseOffset = (Point)(mouseStartPoint - mouseEndPoint);
  1498. if (mouseOffset.X < 0)
  1499. {
  1500. if (mouseOffset.Y > 0)
  1501. {
  1502. mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseStartPoint.X - mouseEndPoint.X);
  1503. }
  1504. else
  1505. {
  1506. mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseEndPoint.X - mouseStartPoint.X);
  1507. }
  1508. }
  1509. else
  1510. {
  1511. if (mouseOffset.Y > 0)
  1512. {
  1513. mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseEndPoint.X - mouseStartPoint.X);
  1514. }
  1515. else
  1516. {
  1517. mouseEndPoint = new Point(mouseEndPoint.X, mouseStartPoint.Y + mouseStartPoint.X - mouseEndPoint.X);
  1518. }
  1519. }
  1520. }
  1521. Rect rect = new Rect(mouseStartPoint, mouseEndPoint);
  1522. double mLeft = rect.Left;
  1523. double mRight = rect.Right;
  1524. double mUp = rect.Top;
  1525. double mDown = rect.Bottom;
  1526. if (rect.Left < maxRect.Left)
  1527. {
  1528. mLeft = maxRect.Left;
  1529. }
  1530. if (rect.Right > maxRect.Right)
  1531. {
  1532. mRight = maxRect.Right;
  1533. }
  1534. if (rect.Top < maxRect.Top)
  1535. {
  1536. mUp = maxRect.Top;
  1537. }
  1538. if (rect.Bottom > maxRect.Bottom)
  1539. {
  1540. mDown = maxRect.Bottom;
  1541. }
  1542. Rect drawRect = new Rect(mLeft, mUp, mRight - mLeft, mDown - mUp);
  1543. DPIRect = drawRect;
  1544. try
  1545. {
  1546. if (lastTextui != null && lastTextBorder != null && cPDFAnnotation != null && cPDFAnnotation.Type == C_ANNOTATION_TYPE.C_ANNOTATION_FREETEXT)
  1547. {
  1548. CPDFFreeTextAnnotation annotFreeText = (cPDFAnnotation as CPDFFreeTextAnnotation);
  1549. CTextAttribute textAttribute = annotFreeText.FreeTextDa;
  1550. byte transparency = annotFreeText.GetTransparency();
  1551. lastTextui.FontSize = DpiHelper.PDFNumToStandardNum(textAttribute.FontSize * zoomFactor);
  1552. Color textColor = Color.FromArgb(
  1553. transparency,
  1554. textAttribute.FontColor[0],
  1555. textAttribute.FontColor[1],
  1556. textAttribute.FontColor[2]);
  1557. Color borderColor = Colors.Transparent;
  1558. Color backgroundColor = Colors.Transparent;
  1559. byte[] colorArray = new byte[3];
  1560. if (annotFreeText.Transparency > 0)
  1561. {
  1562. borderColor = Color.FromArgb(annotFreeText.Transparency, annotFreeText.LineColor[0], annotFreeText.LineColor[1], annotFreeText.LineColor[2]);
  1563. }
  1564. if (annotFreeText.HasBgColor)
  1565. {
  1566. backgroundColor = Color.FromArgb(annotFreeText.Transparency, annotFreeText.BgColor[0], annotFreeText.BgColor[1], annotFreeText.BgColor[2]);
  1567. }
  1568. Border parentUI = lastTextui.Parent as Border;
  1569. if (parentUI != null)
  1570. {
  1571. parentUI.SetValue(Canvas.LeftProperty, drawRect.Left);
  1572. parentUI.SetValue(Canvas.TopProperty, drawRect.Top);
  1573. // The width is incorrect
  1574. if (mouseEndPoint.X >= mouseStartPoint.X)
  1575. {
  1576. parentUI.MaxWidth = (pageBound.Right - drawRect.X - cropPoint.X);
  1577. }
  1578. else
  1579. {
  1580. parentUI.MaxWidth = (drawRect.Right - pageBound.X - cropPoint.X);
  1581. }
  1582. if (mouseEndPoint.Y >= mouseStartPoint.Y)
  1583. {
  1584. parentUI.MaxHeight = (pageBound.Bottom - drawRect.Y - cropPoint.Y);
  1585. }
  1586. else
  1587. {
  1588. parentUI.MaxHeight = (drawRect.Bottom - pageBound.Y - cropPoint.Y);
  1589. }
  1590. }
  1591. lastTextui.MinWidth = drawRect.Width;
  1592. lastTextui.MinHeight = drawRect.Height;
  1593. lastTextui.Foreground = new SolidColorBrush(textColor);
  1594. lastTextui.Background = new SolidColorBrush(backgroundColor);
  1595. lastTextBorder.Padding = new Thickness(0);
  1596. lastTextBorder.BorderBrush = new SolidColorBrush(borderColor);
  1597. double rawWidth = annotFreeText.GetBorderWidth();
  1598. double drawWidth = DpiHelper.PDFNumToStandardNum(rawWidth * zoomFactor);
  1599. lastTextBorder.BorderThickness = new Thickness(drawWidth);
  1600. lastTextui.BorderThickness = new Thickness(0);
  1601. lastTextui.Text = annotFreeText.Content;
  1602. lastTextui.Opacity = annotFreeText.Transparency;
  1603. if (annotFreeText.BorderStyle != C_BORDER_STYLE.BS_SOLID && annotFreeText.Dash != null && annotFreeText.Dash.Length > 0)
  1604. {
  1605. //补充保存虚线样式
  1606. DashedBorder dashBorder = (DashedBorder)lastTextBorder;
  1607. DoubleCollection dashCollection = new DoubleCollection();
  1608. foreach (float num in annotFreeText.Dash)
  1609. {
  1610. dashCollection.Add(num);
  1611. }
  1612. dashBorder.DrawDashBorder(true, drawWidth, rawWidth, dashCollection);
  1613. }
  1614. string fontName = string.Empty;
  1615. string fontFamily = string.Empty;
  1616. CPDFFont.GetFamilyStyleName(annotFreeText.FreeTextDa.FontName, ref fontFamily, ref fontName);
  1617. lastTextui.FontFamily = new FontFamily(fontFamily);
  1618. lastTextui.FontWeight = IsBold(textAttribute.FontName) ? FontWeights.Bold : FontWeights.Normal;
  1619. lastTextui.FontStyle = IsItalic(textAttribute.FontName) ? FontStyles.Italic : FontStyles.Normal;
  1620. lastTextui.AcceptsReturn = true;
  1621. lastTextui.TextWrapping = TextWrapping.Wrap;
  1622. lastTextui.TextAlignment = TextAlignment.Left;
  1623. switch (annotFreeText.Alignment)
  1624. {
  1625. case C_TEXT_ALIGNMENT.ALIGNMENT_LEFT:
  1626. lastTextui.TextAlignment = TextAlignment.Left;
  1627. break;
  1628. case C_TEXT_ALIGNMENT.ALIGNMENT_RIGHT:
  1629. lastTextui.TextAlignment = TextAlignment.Right;
  1630. break;
  1631. case C_TEXT_ALIGNMENT.ALIGNMENT_CENTER:
  1632. lastTextui.TextAlignment = TextAlignment.Center;
  1633. break;
  1634. default:
  1635. break;
  1636. }
  1637. }
  1638. }
  1639. catch
  1640. {
  1641. }
  1642. }
  1643. /// <summary>
  1644. /// Use to calculate the point drawn at a fixed angle
  1645. /// </summary>
  1646. /// <param name="currentPoint">
  1647. /// Current point
  1648. /// </param>
  1649. /// <param name="startPoint">
  1650. /// Start point
  1651. /// </param>
  1652. /// <param name="pageBound">
  1653. /// Maximum drawing area
  1654. /// </param>
  1655. /// <returns>
  1656. /// Return the calculated point
  1657. /// </returns>
  1658. internal Point CalcAnglePoint(Point currentPoint, Point startPoint, Rect pageBound)
  1659. {
  1660. Vector angleVector = currentPoint - startPoint;
  1661. Point originPoint = new Point(startPoint.X, startPoint.Y - angleVector.Length);
  1662. Vector orignVector = originPoint - startPoint;
  1663. Rect checkRect = pageBound;
  1664. int angle = (int)Vector.AngleBetween(orignVector, angleVector);
  1665. if (angle < 0)
  1666. {
  1667. angle += 360;
  1668. }
  1669. int mod = angle % 45;
  1670. int quot = angle / 45;
  1671. Point anglePoint = currentPoint;
  1672. int rotateAngle = 0;
  1673. if (mod < 22)
  1674. {
  1675. Matrix rotateMatrix = new Matrix();
  1676. rotateAngle = quot * 45;
  1677. rotateMatrix.RotateAt(rotateAngle, startPoint.X, startPoint.Y);
  1678. anglePoint = rotateMatrix.Transform(originPoint);
  1679. anglePoint = new Point((int)anglePoint.X, (int)anglePoint.Y);
  1680. }
  1681. else
  1682. {
  1683. Matrix rotateMatrix = new Matrix();
  1684. rotateAngle = (quot + 1) * 45;
  1685. rotateMatrix.RotateAt(rotateAngle, startPoint.X, startPoint.Y);
  1686. anglePoint = rotateMatrix.Transform(originPoint);
  1687. anglePoint = new Point((int)anglePoint.X, (int)anglePoint.Y);
  1688. }
  1689. if (checkRect.Contains(anglePoint) == false)
  1690. {
  1691. switch (rotateAngle)
  1692. {
  1693. case 0:
  1694. {
  1695. anglePoint.X = startPoint.X;
  1696. anglePoint.Y = Math.Max(checkRect.Top, Math.Min(anglePoint.Y, startPoint.Y));
  1697. }
  1698. break;
  1699. case 45:
  1700. {
  1701. double addValue = Math.Min(anglePoint.X - startPoint.X, checkRect.Right - startPoint.X);
  1702. addValue = Math.Min(addValue, startPoint.Y - checkRect.Top);
  1703. anglePoint.X = startPoint.X + addValue;
  1704. anglePoint.Y = startPoint.Y - addValue;
  1705. }
  1706. break;
  1707. case 90:
  1708. {
  1709. anglePoint.X = startPoint.X + Math.Min(anglePoint.X - startPoint.X, checkRect.Right - startPoint.X);
  1710. anglePoint.Y = startPoint.Y;
  1711. }
  1712. break;
  1713. case 135:
  1714. {
  1715. double addValue = Math.Min(anglePoint.X - startPoint.X, checkRect.Right - startPoint.X);
  1716. addValue = Math.Min(addValue, checkRect.Bottom - startPoint.Y);
  1717. anglePoint.X = startPoint.X + addValue;
  1718. anglePoint.Y = startPoint.Y + addValue;
  1719. }
  1720. break;
  1721. case 180:
  1722. {
  1723. anglePoint.X = startPoint.X;
  1724. anglePoint.Y = Math.Min(anglePoint.Y, checkRect.Bottom);
  1725. }
  1726. break;
  1727. case 225:
  1728. {
  1729. double addValue = Math.Min(startPoint.X - anglePoint.X, startPoint.X - checkRect.Left);
  1730. addValue = Math.Min(addValue, checkRect.Bottom - startPoint.Y);
  1731. anglePoint.X = startPoint.X - addValue;
  1732. anglePoint.Y = startPoint.Y + addValue;
  1733. }
  1734. break;
  1735. case 270:
  1736. {
  1737. anglePoint.X = startPoint.X - Math.Min(startPoint.X - anglePoint.X, startPoint.X - checkRect.Left);
  1738. anglePoint.Y = startPoint.Y;
  1739. }
  1740. break;
  1741. case 315:
  1742. {
  1743. double addValue = Math.Min(startPoint.X - anglePoint.X, startPoint.X - checkRect.Left);
  1744. addValue = Math.Min(addValue, startPoint.Y - checkRect.Top);
  1745. anglePoint.X = startPoint.X - addValue;
  1746. anglePoint.Y = startPoint.Y - addValue;
  1747. }
  1748. break;
  1749. case 360:
  1750. {
  1751. anglePoint.X = startPoint.X;
  1752. anglePoint.Y = Math.Max(checkRect.Top, Math.Min(anglePoint.Y, startPoint.Y));
  1753. }
  1754. break;
  1755. default:
  1756. break;
  1757. }
  1758. }
  1759. return anglePoint;
  1760. }
  1761. public bool IsCanSave()
  1762. {
  1763. if (cPDFAnnotation == null)
  1764. return false;
  1765. if (cPDFAnnotation is CPDFPolygonAnnotation)
  1766. {
  1767. if (drawPoints.Count <= 2)
  1768. return false;
  1769. }
  1770. return true;
  1771. }
  1772. public bool IsCreating()
  1773. {
  1774. return cPDFAnnotation != null;
  1775. }
  1776. }
  1777. }