PDFTextPage.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. /*
  2. http://www.cgsoso.com/forum-211-1.html
  3. CG搜搜 Unity3d 每日Unity3d插件免费更新 更有VIP资源!
  4. CGSOSO 主打游戏开发,影视设计等CG资源素材。
  5. 插件如若商用,请务必官网购买!
  6. daily assets update for try.
  7. U should buy the asset from home store if u use it in your project!
  8. */
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Runtime.InteropServices;
  12. using UnityEngine;
  13. #if NETFX_CORE && !UNITY_WSA_10_0
  14. using WinRTLegacy.Text;
  15. #else
  16. using System.Text;
  17. #endif
  18. namespace Paroxe.PdfRenderer
  19. {
  20. #if !UNITY_WEBGL
  21. /// <summary>
  22. /// This class allow to access the text of a page.
  23. /// </summary>
  24. public class PDFTextPage : IDisposable, IEquatable<PDFTextPage>
  25. {
  26. private bool m_Disposed;
  27. private IntPtr m_NativePointer;
  28. private PDFPage m_Page;
  29. private static Dictionary<IntPtr, int> s_InstanceMap = new Dictionary<IntPtr, int>();
  30. public PDFTextPage(PDFPage page)
  31. {
  32. if (page == null)
  33. throw new NullReferenceException();
  34. PDFLibrary.AddRef("PDFTextPage");
  35. m_Page = page;
  36. m_NativePointer = FPDFText_LoadPage(m_Page.NativePointer);
  37. if (m_NativePointer != IntPtr.Zero)
  38. {
  39. if (s_InstanceMap.ContainsKey(m_NativePointer))
  40. {
  41. s_InstanceMap[m_NativePointer] = s_InstanceMap[m_NativePointer] + 1;
  42. }
  43. else
  44. s_InstanceMap[m_NativePointer] = 1;
  45. }
  46. }
  47. ~PDFTextPage()
  48. {
  49. Dispose(false);
  50. }
  51. public void Dispose()
  52. {
  53. Dispose(true);
  54. GC.SuppressFinalize(this);
  55. }
  56. protected virtual void Dispose(bool disposing)
  57. {
  58. if (!m_Disposed)
  59. {
  60. lock (PDFLibrary.nativeLock)
  61. {
  62. if (m_NativePointer != IntPtr.Zero)
  63. {
  64. s_InstanceMap[m_NativePointer] = s_InstanceMap[m_NativePointer] - 1;
  65. if (s_InstanceMap[m_NativePointer] == 0)
  66. {
  67. if (m_Page.NativePointer != IntPtr.Zero && m_Page.Document.NativePointer != IntPtr.Zero)
  68. FPDFText_ClosePage(m_NativePointer);
  69. s_InstanceMap.Remove(m_NativePointer);
  70. m_NativePointer = IntPtr.Zero;
  71. }
  72. }
  73. }
  74. PDFLibrary.RemoveRef("PDFTextPage");
  75. m_Disposed = true;
  76. }
  77. }
  78. public IntPtr NativePointer
  79. {
  80. get { return m_NativePointer; }
  81. }
  82. /// <summary>
  83. /// Return a refence to the page.
  84. /// </summary>
  85. public PDFPage Page
  86. {
  87. get { return m_Page; }
  88. }
  89. /// <summary>
  90. /// Return the page index of the text.
  91. /// </summary>
  92. public int PageIndex
  93. {
  94. get { return m_Page.PageIndex; }
  95. }
  96. /// <summary>
  97. /// Return the number of character in the page.
  98. /// </summary>
  99. /// <returns></returns>
  100. public int CountChars()
  101. {
  102. return FPDFText_CountChars(m_NativePointer);
  103. }
  104. /// <summary>
  105. /// Count number of rectangular areas occupied by a segment of texts.
  106. /// </summary>
  107. /// <param name="startIndex"></param>
  108. /// <param name="count"></param>
  109. /// <returns></returns>
  110. public int CountRects(int startIndex, int count)
  111. {
  112. return FPDFText_CountRects(m_NativePointer, startIndex, count);
  113. }
  114. /// <summary>
  115. /// Extract text within a rectangular boundary on the page.
  116. /// </summary>
  117. /// <param name="left"></param>
  118. /// <param name="top"></param>
  119. /// <param name="right"></param>
  120. /// <param name="bottom"></param>
  121. /// <param name="charCount"></param>
  122. /// <returns></returns>
  123. public string GetBoundedText(float left, float top, float right, float bottom, int charCount)
  124. {
  125. byte[] textBuffer = new byte[(charCount + 1) * 2];
  126. FPDFText_GetBoundedText(m_NativePointer, left, top, right, bottom, textBuffer, textBuffer.Length);
  127. return Encoding.Unicode.GetString(textBuffer);
  128. }
  129. /// <summary>
  130. /// Get bounding box of a particular character.
  131. /// </summary>
  132. /// <param name="charIndex"></param>
  133. /// <returns></returns>
  134. public Rect GetCharBox(int charIndex)
  135. {
  136. double left;
  137. double right;
  138. double bottom;
  139. double top;
  140. FPDFText_GetCharBox(m_NativePointer, charIndex, out left, out right, out bottom, out top);
  141. return new Rect((float) left, (float) top, Mathf.Abs((float) right - (float) left),
  142. Mathf.Abs((float) bottom - (float) top));
  143. }
  144. /// <summary>
  145. /// Get the index of a character at or nearby a certain position on the page.
  146. /// </summary>
  147. /// <param name="pos"></param>
  148. /// <param name="tolerance"></param>
  149. /// <returns></returns>
  150. public int GetCharIndexAtPos(Vector2 pos, Vector2 tolerance)
  151. {
  152. /*Vector2 pagePos = m_Page.ConvertUnityUIDevicePositionToPagePosition(pos,
  153. m_Page.Document.GetPageSize(m_Page.PageIndex));*/
  154. return FPDFText_GetCharIndexAtPos(m_NativePointer, pos.x, pos.y, tolerance.x, tolerance.y);
  155. }
  156. /// <summary>
  157. /// Get the font size of a particular character.
  158. /// </summary>
  159. /// <param name="charIndex"></param>
  160. /// <returns></returns>
  161. public double GetFontSize(int charIndex)
  162. {
  163. return FPDFText_GetFontSize(m_NativePointer, charIndex);
  164. }
  165. /// <summary>
  166. /// Get a rectangular area from the result generated by CountRects
  167. /// </summary>
  168. /// <param name="rectIndex"></param>
  169. /// <returns></returns>
  170. public Rect GetRect(int rectIndex)
  171. {
  172. double left;
  173. double right;
  174. double bottom;
  175. double top;
  176. FPDFText_GetRect(m_NativePointer, rectIndex, out left, out top, out right, out bottom);
  177. return new Rect((float) left, (float) top, Mathf.Abs((float) right - (float) left),
  178. Mathf.Abs((float) bottom - (float) top));
  179. }
  180. /// <summary>
  181. /// Extract text string from the page.
  182. /// </summary>
  183. /// <param name="startIndex"></param>
  184. /// <param name="count"></param>
  185. /// <returns></returns>
  186. public string GetText(int startIndex, int count)
  187. {
  188. byte[] textBuffer = new byte[(count + 1)*2];
  189. FPDFText_GetText(m_NativePointer, startIndex, count, textBuffer);
  190. return Encoding.Unicode.GetString(textBuffer);
  191. }
  192. /// <summary>
  193. /// Get a character in the page.
  194. /// </summary>
  195. /// <param name="charIndex"></param>
  196. /// <returns></returns>
  197. public string GetChar(int charIndex)
  198. {
  199. return char.ConvertFromUtf32((int) FPDFText_GetUnicode(m_NativePointer, charIndex));
  200. }
  201. public IList<PDFSearchResult> Search(string findWhat,
  202. PDFSearchHandle.MatchOption flags = PDFSearchHandle.MatchOption.NONE, int startIndex = 0)
  203. {
  204. if (string.IsNullOrEmpty(findWhat.Trim()))
  205. return new List<PDFSearchResult>();
  206. return Search(Encoding.Unicode.GetBytes(findWhat.Trim() + "\0"), flags, startIndex);
  207. }
  208. public IList<PDFSearchResult> Search(byte[] findWhatUnicode,
  209. PDFSearchHandle.MatchOption flags = PDFSearchHandle.MatchOption.NONE, int startIndex = 0)
  210. {
  211. List<PDFSearchResult> searchResults = new List<PDFSearchResult>();
  212. if (findWhatUnicode == null)
  213. return searchResults;
  214. using (PDFSearchHandle searchHandle = new PDFSearchHandle(this, findWhatUnicode, startIndex, flags))
  215. {
  216. foreach (PDFSearchResult result in searchHandle.EnumerateSearchResults())
  217. {
  218. searchResults.Add(result);
  219. }
  220. }
  221. return searchResults;
  222. }
  223. public bool Equals(PDFTextPage other)
  224. {
  225. return (m_NativePointer != IntPtr.Zero && m_NativePointer == other.m_NativePointer);
  226. }
  227. #region NATIVE
  228. [DllImport(PDFLibrary.PLUGIN_ASSEMBLY)]
  229. private static extern IntPtr FPDFText_LoadPage(IntPtr page);
  230. [DllImport(PDFLibrary.PLUGIN_ASSEMBLY)]
  231. private static extern void FPDFText_ClosePage(IntPtr text_page);
  232. [DllImport(PDFLibrary.PLUGIN_ASSEMBLY)]
  233. private static extern int FPDFText_CountChars(IntPtr text_page);
  234. [DllImport(PDFLibrary.PLUGIN_ASSEMBLY)]
  235. private static extern int FPDFText_CountRects(IntPtr text_page, int start_index, int count);
  236. [DllImport(PDFLibrary.PLUGIN_ASSEMBLY)]
  237. private static extern int FPDFText_GetBoundedText(IntPtr text_page, double left, double top, double right,
  238. double bottom, [In, Out] byte[] buffer, int buflen);
  239. [DllImport(PDFLibrary.PLUGIN_ASSEMBLY)]
  240. private static extern void FPDFText_GetCharBox(IntPtr text_page, int index, out double left, out double right,
  241. out double bottom, out double top);
  242. [DllImport(PDFLibrary.PLUGIN_ASSEMBLY)]
  243. private static extern int FPDFText_GetCharIndexAtPos(IntPtr text_page, double x, double y, double xTolerance,
  244. double yTolerance);
  245. [DllImport(PDFLibrary.PLUGIN_ASSEMBLY)]
  246. private static extern double FPDFText_GetFontSize(IntPtr text_page, int index);
  247. [DllImport(PDFLibrary.PLUGIN_ASSEMBLY)]
  248. private static extern void FPDFText_GetRect(IntPtr text_page, int rect_index, out double left, out double top,
  249. out double right, out double bottom);
  250. [DllImport(PDFLibrary.PLUGIN_ASSEMBLY)]
  251. private static extern int FPDFText_GetText(IntPtr text_page, int start_index, int count, [In, Out] byte[] buffer);
  252. [DllImport(PDFLibrary.PLUGIN_ASSEMBLY)]
  253. private static extern uint FPDFText_GetUnicode(IntPtr text_page, int index);
  254. #endregion
  255. }
  256. #endif
  257. }