SelectText.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. using ComPDFKit.Tool.Help;
  2. using ComPDFKit.Viewer.Layer;
  3. using ComPDFKitViewer;
  4. using ComPDFKitViewer.Helper;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Windows;
  8. using System.Windows.Media;
  9. namespace ComPDFKit.Tool.DrawTool
  10. {
  11. public class TextDrawRect
  12. {
  13. public string Text { get; set; }
  14. /// <summary>
  15. /// Current text rectangle (PDF DPI)
  16. /// </summary>
  17. public Rect DrawRect { get; set; }
  18. public SolidColorBrush PaintBrush { get; set; } = new SolidColorBrush(Color.FromArgb(0x46, 0x46, 0x82, 0xB4));
  19. #region Properties Used for Searching
  20. internal bool DrawActiveSearch { get; set; } = false;
  21. internal TextSearchItem SearchInfo { get; set; }
  22. #endregion
  23. }
  24. public class TextSelectInfo
  25. {
  26. public int StartPage = -1;
  27. public int EndPage = -1;
  28. /// <summary>
  29. /// Original page coordinates
  30. /// </summary>
  31. public Point StartPoint = new Point();
  32. /// <summary>
  33. /// Original page coordinates
  34. /// </summary>
  35. public Point EndPoint = new Point();
  36. public int PageRotate;
  37. public bool RotateRecord;
  38. public Dictionary<int, string> PageSelectText = new Dictionary<int, string>();
  39. public Dictionary<int, List<TextDrawRect>> PageSelectTextRectList = new Dictionary<int, List<TextDrawRect>>();
  40. public Dictionary<int, KeyValuePair<Point, Point>> PageSelectPointList = new Dictionary<int, KeyValuePair<Point, Point>>();
  41. internal Dictionary<int, List<Rect>> ConvertToSelectRectDict()
  42. {
  43. Dictionary<int, List<Rect>> TextRectDict = new Dictionary<int, List<Rect>>();
  44. if (PageSelectTextRectList != null)
  45. {
  46. foreach (int key in PageSelectTextRectList.Keys)
  47. {
  48. List<TextDrawRect> textDrawRects = PageSelectTextRectList[key];
  49. List<Rect> rectList = new List<Rect>();
  50. foreach (TextDrawRect drawItem in textDrawRects)
  51. {
  52. rectList.Add(drawItem.DrawRect);
  53. }
  54. TextRectDict[key] = rectList;
  55. }
  56. }
  57. return TextRectDict;
  58. }
  59. }
  60. internal class SelectText : CustomizeLayer
  61. {
  62. protected DrawingContext drawDC { get; set; }
  63. private TextSelectInfo textInfo { get; set; } = new TextSelectInfo();
  64. private TextSelectInfo searchInfo { get; set; } = new TextSelectInfo();
  65. /// <summary>
  66. ///Identify whether the text selection effect is being drawn
  67. /// </summary>
  68. protected bool isDrawSelectText { get; set; }
  69. private TextSelectInfo SortTextSelectInfo(TextSelectInfo textInfo)
  70. {
  71. if (textInfo == null || textInfo.StartPage <= textInfo.EndPage)
  72. {
  73. return textInfo;
  74. }
  75. TextSelectInfo SortItem = new TextSelectInfo();
  76. SortItem.StartPage = textInfo.EndPage;
  77. SortItem.StartPoint = textInfo.EndPoint;
  78. SortItem.EndPage = textInfo.StartPage;
  79. SortItem.EndPoint = textInfo.StartPoint;
  80. SortItem.PageSelectPointList = textInfo.PageSelectPointList;
  81. SortItem.PageSelectTextRectList = textInfo.PageSelectTextRectList;
  82. SortItem.PageSelectText = textInfo.PageSelectText;
  83. SortItem.PageRotate = textInfo.PageRotate;
  84. SortItem.RotateRecord = textInfo.RotateRecord;
  85. return SortItem;
  86. }
  87. private void SetTextSelectRange(TextSelectInfo SelectTextItem, CPDFViewer cPDFViewer, Point tolerance, bool DoubleClick = false)
  88. {
  89. if (SelectTextItem == null)
  90. {
  91. return;
  92. }
  93. // Remove data that does not need to be displayed
  94. for (int i = 0; i < SelectTextItem.PageSelectText.Count; i++)
  95. {
  96. var item = SelectTextItem.PageSelectText.ElementAt(i);
  97. if (item.Key < SelectTextItem.StartPage || item.Key > SelectTextItem.EndPage)
  98. {
  99. SelectTextItem.PageSelectText.Remove(item.Key);
  100. }
  101. }
  102. for (int i = 0; i < SelectTextItem.PageSelectPointList.Count; i++)
  103. {
  104. var item = SelectTextItem.PageSelectPointList.ElementAt(i);
  105. if (item.Key < SelectTextItem.StartPage || item.Key > SelectTextItem.EndPage)
  106. {
  107. SelectTextItem.PageSelectPointList.Remove(item.Key);
  108. }
  109. }
  110. for (int i = 0; i < SelectTextItem.PageSelectTextRectList.Count; i++)
  111. {
  112. var item = SelectTextItem.PageSelectTextRectList.ElementAt(i);
  113. if (item.Key < SelectTextItem.StartPage || item.Key > SelectTextItem.EndPage)
  114. {
  115. SelectTextItem.PageSelectTextRectList.Remove(item.Key);
  116. }
  117. }
  118. // Add or update data
  119. for (int i = SelectTextItem.StartPage; i <= SelectTextItem.EndPage; i++)
  120. {
  121. PageViewData RenderPage = cPDFViewer.GetPageNodeByPageIndex(i);
  122. if (RenderPage == null)
  123. {
  124. continue;
  125. }
  126. Point StartPoint = new Point(0, 0);
  127. Point EndPoint = new Point(RenderPage.RawSize.Width, RenderPage.RawSize.Height);
  128. if (i == SelectTextItem.StartPage)
  129. {
  130. StartPoint = SelectTextItem.StartPoint;
  131. }
  132. if (i == SelectTextItem.EndPage)
  133. {
  134. EndPoint = SelectTextItem.EndPoint;
  135. }
  136. bool ReSelect = true;
  137. if (SelectTextItem.PageSelectPointList.ContainsKey(i))
  138. {
  139. KeyValuePair<Point, Point> PrevPointRange = SelectTextItem.PageSelectPointList[i];
  140. if (PrevPointRange.Key == StartPoint && PrevPointRange.Value == EndPoint)
  141. {
  142. ReSelect = false;
  143. }
  144. }
  145. if (ReSelect)
  146. {
  147. if (DoubleClick == true)
  148. {
  149. Rect uiRect = Rect.Empty;
  150. SelectTextItem.PageSelectText[i] = PDFHelp.GetDoubleClickText(cPDFViewer.GetDocument(), i, StartPoint, ref uiRect);
  151. SelectTextItem.PageSelectPointList[i] = new KeyValuePair<Point, Point>(StartPoint, EndPoint);
  152. SelectTextItem.PageSelectTextRectList[i] = new List<TextDrawRect>() { new TextDrawRect() { DrawRect = uiRect, Text = SelectTextItem.PageSelectText[i] } };
  153. }
  154. else
  155. {
  156. SelectTextItem.PageSelectText[i] = PDFHelp.GetSelectText(cPDFViewer.GetDocument(), i, StartPoint, EndPoint, tolerance);
  157. SelectTextItem.PageSelectPointList[i] = new KeyValuePair<Point, Point>(StartPoint, EndPoint);
  158. SelectTextItem.PageSelectTextRectList[i] = PDFHelp.GetSelectTextRect(cPDFViewer.GetDocument(), i, StartPoint, EndPoint, tolerance);
  159. }
  160. }
  161. }
  162. }
  163. public SelectText()
  164. {
  165. }
  166. public void StartDraw(Point pagePoint, int pageIndex)
  167. {
  168. isDrawSelectText = true;
  169. textInfo = new TextSelectInfo()
  170. {
  171. StartPage = pageIndex,
  172. EndPage = pageIndex,
  173. StartPoint = pagePoint,
  174. EndPoint = pagePoint
  175. };
  176. }
  177. public void MoveDraw(Point downPoint, int pageIndex, CPDFViewer cPDFViewer, Point tolerance, bool DoubleClick)
  178. {
  179. if (isDrawSelectText)
  180. {
  181. textInfo.EndPage = pageIndex;
  182. textInfo.EndPoint = downPoint;
  183. SetTextSelectRange(SortTextSelectInfo(textInfo), cPDFViewer, tolerance, DoubleClick);
  184. Draw(cPDFViewer);
  185. }
  186. }
  187. public TextSelectInfo GetTextSelectInfo()
  188. {
  189. return textInfo;
  190. }
  191. public TextSelectInfo GetSearchInfo()
  192. {
  193. return searchInfo;
  194. }
  195. public void SetSearchInfo(TextSelectInfo searchInfo)
  196. {
  197. this.searchInfo = searchInfo;
  198. }
  199. public void CleanSearchInfo()
  200. {
  201. searchInfo = new TextSelectInfo();
  202. }
  203. public void RemoveSelectDataInfo()
  204. {
  205. textInfo = new TextSelectInfo();
  206. }
  207. public bool HasSelectTextInfo()
  208. {
  209. if (textInfo?.PageSelectTextRectList.Count > 0)
  210. {
  211. return true;
  212. }
  213. return false;
  214. }
  215. public bool HasSearchInfo()
  216. {
  217. if (searchInfo?.PageSelectTextRectList.Count > 0)
  218. {
  219. return true;
  220. }
  221. return false;
  222. }
  223. public void EndDraw()
  224. {
  225. isDrawSelectText = false;
  226. }
  227. public void Draw(CPDFViewer cPDFViewer)
  228. {
  229. Dispatcher.Invoke(() =>
  230. {
  231. drawDC = Open();
  232. DrawSelectRange(drawDC, textInfo, cPDFViewer);
  233. DrawSelectRange(drawDC, searchInfo, cPDFViewer);
  234. Present();
  235. });
  236. }
  237. public void CleanDraw(CPDFViewer cPDFViewer)
  238. {
  239. Dispatcher.Invoke(() =>
  240. {
  241. drawDC = Open();
  242. DrawSelectRange(drawDC, searchInfo, cPDFViewer);
  243. Present();
  244. });
  245. }
  246. public override void Draw()
  247. {
  248. }
  249. private void DrawSelectRange(DrawingContext dc, TextSelectInfo SelectTextItem, CPDFViewer cPDFViewer)
  250. {
  251. List<RenderData> renderDatas=new List<RenderData>();
  252. if (cPDFViewer.CurrentRenderFrame!=null)
  253. {
  254. renderDatas = cPDFViewer.CurrentRenderFrame.GetRenderDatas();
  255. }
  256. foreach (RenderData PaintRange in renderDatas)
  257. {
  258. if (SelectTextItem.PageSelectTextRectList.ContainsKey(PaintRange.PageIndex))
  259. {
  260. List<TextDrawRect> PaintRectList = SelectTextItem.PageSelectTextRectList[PaintRange.PageIndex];
  261. foreach (TextDrawRect SelectRect in PaintRectList)
  262. {
  263. Rect drawRect = SelectRect.DrawRect;
  264. Rect textRect = drawRect;
  265. if (cPDFViewer.GetDocument() != null && SelectTextItem.RotateRecord)
  266. {
  267. var rawPage = cPDFViewer.GetDocument().PageAtIndex(PaintRange.PageIndex);
  268. if (rawPage != null)
  269. {
  270. int rotation = rawPage.Rotation - SelectTextItem.PageRotate;
  271. if (rotation != 0)
  272. {
  273. Size rawSize = new Size(PaintRange.PageBound.Width, PaintRange.PageBound.Height);
  274. Matrix matrix = new Matrix();
  275. matrix.RotateAt(-rotation * 90, rawSize.Width / 2, rawSize.Height / 2);
  276. Rect checkRect = new Rect(0, 0, rawSize.Width, rawSize.Height);
  277. checkRect.Transform(matrix);
  278. matrix = new Matrix();
  279. matrix.RotateAt(rotation * 90, checkRect.Width / 96D * 72D / 2, checkRect.Height / 96D * 72D / 2);
  280. checkRect = new Rect(0, 0, checkRect.Width / 96D * 72D, checkRect.Height / 96D * 72D);
  281. textRect.Transform(matrix);
  282. checkRect.Transform(matrix);
  283. drawRect = new Rect(textRect.Left - checkRect.Left,
  284. textRect.Top - checkRect.Top,
  285. textRect.Width, textRect.Height);
  286. }
  287. }
  288. }
  289. Rect BorderRect = PaintRange.PageBound;
  290. Rect RawPaintRect =DpiHelper.PDFRectToStandardRect(
  291. new Rect(
  292. drawRect.Left * cPDFViewer.CurrentRenderFrame.ZoomFactor - DpiHelper.StandardNumToPDFNum(PaintRange.CropLeft) * cPDFViewer.CurrentRenderFrame.ZoomFactor,
  293. drawRect.Top * cPDFViewer.CurrentRenderFrame.ZoomFactor - DpiHelper.StandardNumToPDFNum(PaintRange.CropTop) * cPDFViewer.CurrentRenderFrame.ZoomFactor,
  294. drawRect.Width * cPDFViewer.CurrentRenderFrame.ZoomFactor,
  295. drawRect.Height * cPDFViewer.CurrentRenderFrame.ZoomFactor));
  296. RawPaintRect.X += BorderRect.X;
  297. RawPaintRect.Y += BorderRect.Y;
  298. RectangleGeometry clipGeometry = new RectangleGeometry();
  299. clipGeometry.Rect = BorderRect;
  300. dc.PushClip(clipGeometry);
  301. Rect paintRect = RawPaintRect;
  302. dc.DrawRectangle(SelectRect.PaintBrush, null, paintRect);
  303. TextSearchItem searchInfo = SelectRect.SearchInfo;
  304. if (SelectRect.DrawActiveSearch && searchInfo.BorderThickness > 0 && searchInfo.BorderBrush != Brushes.Transparent)
  305. {
  306. Rect outRect = new Rect(paintRect.Left - searchInfo.BorderThickness / 2 - searchInfo.Padding.Left,
  307. paintRect.Top - searchInfo.BorderThickness / 2 - searchInfo.Padding.Top,
  308. paintRect.Width + searchInfo.BorderThickness + searchInfo.Padding.Left + searchInfo.Padding.Right,
  309. paintRect.Height + searchInfo.BorderThickness + searchInfo.Padding.Top + searchInfo.Padding.Bottom);
  310. Pen borderPen = new Pen(searchInfo.BorderBrush, searchInfo.BorderThickness);
  311. dc.DrawRectangle(null, borderPen, outRect);
  312. }
  313. dc.Pop();
  314. }
  315. }
  316. }
  317. }
  318. }
  319. }