PDFDocument.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  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 Paroxe.PdfRenderer.WebGL;
  10. using System;
  11. using System.Collections;
  12. using System.IO;
  13. using System.Runtime.InteropServices;
  14. using UnityEngine;
  15. namespace Paroxe.PdfRenderer
  16. {
  17. /// <summary>
  18. /// Represents a PDF document. This class is the entry point of all functionalities.
  19. /// </summary>
  20. public class PDFDocument : IDisposable
  21. {
  22. private bool m_Disposed;
  23. private IntPtr m_NativePointer;
  24. private byte[] m_DocumentBuffer;
  25. private bool m_ValidDocument;
  26. private PDFRenderer m_ConvenienceRenderer;
  27. public static PDFJS_Promise<PDFDocument> LoadDocumentFromUrlAsync(string url)
  28. {
  29. PDFJS_Promise<PDFDocument> documentPromise = new PDFJS_Promise<PDFDocument>();
  30. #if !UNITY_WEBGL || UNITY_EDITOR
  31. PDFJS_Library.Instance.PreparePromiseCoroutine(LoadDocumentFromWWWCoroutine, documentPromise, url).Start();
  32. #else
  33. LoadDocumentParameters parameters = new LoadDocumentParameters();
  34. parameters.url = url;
  35. PDFJS_Library.Instance.PreparePromiseCoroutine(LoadDocumentCoroutine, documentPromise, parameters).Start();
  36. #endif
  37. return documentPromise;
  38. }
  39. #if !UNITY_WEBGL || UNITY_EDITOR
  40. private static IEnumerator LoadDocumentFromWWWCoroutine(PDFJS_PromiseCoroutine promiseCoroutine, IPDFJS_Promise promise, object urlString)
  41. {
  42. PDFJS_Promise<PDFDocument> documentPromise = promise as PDFJS_Promise<PDFDocument>;
  43. PDFLibrary.Instance.EnsureInitialized();
  44. while (!PDFLibrary.Instance.IsInitialized)
  45. yield return null;
  46. string url = urlString as string;
  47. WWW www = new WWW(url);
  48. yield return www;
  49. if (www.error == null)
  50. {
  51. documentPromise.HasFinished = true;
  52. documentPromise.HasSucceeded = true;
  53. documentPromise.HasReceivedJSResponse = true;
  54. documentPromise.Result = new PDFDocument(www.bytes);
  55. promiseCoroutine.ExecuteThenAction(true, documentPromise.Result);
  56. }
  57. else
  58. {
  59. documentPromise.HasFinished = true;
  60. documentPromise.HasSucceeded = false;
  61. promiseCoroutine.ExecuteThenAction(false, null);
  62. }
  63. }
  64. #endif
  65. public static PDFJS_Promise<PDFDocument> LoadDocumentFromBytesAsync(byte[] bytes)
  66. {
  67. PDFJS_Promise<PDFDocument> documentPromise = new PDFJS_Promise<PDFDocument>();
  68. #if !UNITY_WEBGL || UNITY_EDITOR
  69. documentPromise.HasFinished = true;
  70. documentPromise.HasSucceeded = true;
  71. documentPromise.HasReceivedJSResponse = true;
  72. documentPromise.Result = new PDFDocument(bytes);
  73. #else
  74. LoadDocumentParameters parameters = new LoadDocumentParameters();
  75. parameters.bytes = bytes;
  76. PDFJS_Library.Instance.PreparePromiseCoroutine(LoadDocumentCoroutine, documentPromise, parameters).Start();
  77. #endif
  78. return documentPromise;
  79. }
  80. public PDFDocument(IntPtr nativePointer)
  81. {
  82. PDFLibrary.AddRef("PDFDocument");
  83. m_NativePointer = nativePointer;
  84. m_ValidDocument = true;
  85. }
  86. #if !UNITY_WEBGL || UNITY_EDITOR
  87. /// <summary>
  88. /// Open PDF Document with the specified byte array.
  89. /// </summary>
  90. /// <param name="buffer"></param>
  91. public PDFDocument(byte[] buffer)
  92. : this(buffer, "")
  93. { }
  94. /// <summary>
  95. /// Open PDF Document with the specified byte array.
  96. /// </summary>
  97. /// <param name="buffer"></param>
  98. /// <param name="password">Can be null or empty</param>
  99. public PDFDocument(byte[] buffer, string password)
  100. {
  101. PDFLibrary.AddRef("PDFDocument");
  102. CommonInit(buffer, password);
  103. }
  104. /// <summary>
  105. /// Open PDF Document located at the specified path
  106. /// </summary>
  107. /// <param name="filePath"></param>
  108. public PDFDocument(string filePath)
  109. : this(filePath, "")
  110. { }
  111. /// <summary>
  112. ///
  113. /// </summary>
  114. /// <param name="filePath"></param>
  115. /// <param name="password">Can be null or empty</param>
  116. public PDFDocument(string filePath, string password)
  117. {
  118. PDFLibrary.AddRef("PDFDocument");
  119. #if !UNITY_WEBPLAYER && !UNITY_WINRT
  120. CommonInit(File.ReadAllBytes(filePath), password);
  121. #else
  122. m_ValidDocument = false;
  123. #endif
  124. }
  125. #endif
  126. ~PDFDocument()
  127. {
  128. Dispose(false);
  129. }
  130. protected virtual void Dispose(bool disposing)
  131. {
  132. if (!m_Disposed)
  133. {
  134. lock (PDFLibrary.nativeLock)
  135. {
  136. if (m_NativePointer != IntPtr.Zero)
  137. {
  138. #if UNITY_WEBGL && !UNITY_EDITOR
  139. PDFJS_CloseDocument(m_NativePointer.ToInt32());
  140. #else
  141. FPDF_CloseDocument(m_NativePointer);
  142. #endif
  143. m_NativePointer = IntPtr.Zero;
  144. }
  145. }
  146. PDFLibrary.RemoveRef("PDFDocument");
  147. m_Disposed = true;
  148. }
  149. }
  150. public void Dispose()
  151. {
  152. Dispose(true);
  153. GC.SuppressFinalize(this);
  154. }
  155. /// <summary>
  156. /// Return a convenience PDFRenderer instance.
  157. /// </summary>
  158. public PDFRenderer Renderer
  159. {
  160. get
  161. {
  162. if (m_ConvenienceRenderer == null)
  163. m_ConvenienceRenderer = new PDFRenderer();
  164. return m_ConvenienceRenderer;
  165. }
  166. }
  167. /// <summary>
  168. /// The byte array of the document.
  169. /// </summary>
  170. public byte[] DocumentBuffer
  171. {
  172. get { return m_DocumentBuffer; }
  173. }
  174. /// <summary>
  175. /// Return if the document is valid. The document can be invalid if the password is invalid or if the
  176. /// document itseft is corrupted. See PDFLibrary.GetLastError.
  177. /// </summary>
  178. public bool IsValid
  179. {
  180. get { return m_ValidDocument; }
  181. }
  182. public IntPtr NativePointer
  183. {
  184. get { return m_NativePointer; }
  185. }
  186. public int GetPageCount()
  187. {
  188. #if UNITY_WEBGL && !UNITY_EDITOR
  189. return PDFJS_GetPageCount(m_NativePointer.ToInt32());
  190. #else
  191. return FPDF_GetPageCount(m_NativePointer);
  192. #endif
  193. }
  194. #if !UNITY_WEBGL || UNITY_EDITOR
  195. public Vector2 GetPageSize(int pageIndex)
  196. {
  197. double width;
  198. double height;
  199. FPDF_GetPageSizeByIndex(m_NativePointer, pageIndex, out width, out height);
  200. return new Vector2((float) width, (float) height);
  201. }
  202. #endif
  203. #if !UNITY_WEBGL || UNITY_EDITOR
  204. public int GetPageWidth(int pageIndex)
  205. {
  206. double width;
  207. double height;
  208. FPDF_GetPageSizeByIndex(m_NativePointer, pageIndex, out width, out height);
  209. return (int) width;
  210. }
  211. #endif
  212. #if !UNITY_WEBGL || UNITY_EDITOR
  213. public int GetPageHeight(int pageIndex)
  214. {
  215. double width;
  216. double height;
  217. FPDF_GetPageSizeByIndex(m_NativePointer, pageIndex, out width, out height);
  218. return (int) height;
  219. }
  220. #endif
  221. #if !UNITY_WEBGL
  222. /// <summary>
  223. /// Return the root bookmark of the document.
  224. /// </summary>
  225. /// <returns></returns>
  226. public PDFBookmark GetRootBookmark()
  227. {
  228. return GetRootBookmark(null);
  229. }
  230. #endif
  231. #if !UNITY_WEBGL
  232. /// <summary>
  233. /// Return the root bookmark of the document.
  234. /// </summary>
  235. /// <param name="device">Pass the device that will receive bookmarks action</param>
  236. /// <returns></returns>
  237. public PDFBookmark GetRootBookmark(IPDFDevice device)
  238. {
  239. return new PDFBookmark(this, null, IntPtr.Zero, device);
  240. }
  241. #endif
  242. #if !UNITY_WEBGL || UNITY_EDITOR
  243. public PDFPage GetPage(int index)
  244. {
  245. return new PDFPage(this, index);
  246. }
  247. #endif
  248. public PDFJS_Promise<PDFPage> GetPageAsync(int index)
  249. {
  250. return PDFPage.LoadPageAsync(this, index);
  251. }
  252. private void CommonInit(byte[] buffer, string password)
  253. {
  254. m_DocumentBuffer = buffer;
  255. if (m_DocumentBuffer != null)
  256. {
  257. #if !UNITY_WEBGL || UNITY_EDITOR
  258. m_NativePointer = FPDF_LoadMemDocument(m_DocumentBuffer, m_DocumentBuffer.Length, password);
  259. #endif
  260. m_ValidDocument = (m_NativePointer != IntPtr.Zero);
  261. }
  262. else
  263. {
  264. m_ValidDocument = false;
  265. }
  266. }
  267. #if UNITY_WEBGL && !UNITY_EDITOR
  268. class LoadDocumentParameters
  269. {
  270. public string url;
  271. public byte[] bytes;
  272. }
  273. private static IEnumerator LoadDocumentCoroutine(PDFJS_PromiseCoroutine promiseCoroutine, IPDFJS_Promise promise, object pars)
  274. {
  275. PDFJS_Promise<PDFDocument> documentPromise = promise as PDFJS_Promise<PDFDocument>;
  276. PDFLibrary.Instance.EnsureInitialized();
  277. while (!PDFLibrary.Instance.IsInitialized)
  278. yield return null;
  279. LoadDocumentParameters parameters = pars as LoadDocumentParameters;
  280. if (!string.IsNullOrEmpty(parameters.url))
  281. PDFJS_LoadDocumentFromURL(promise.PromiseHandle, parameters.url);
  282. else
  283. PDFJS_LoadDocumentFromBytes(promise.PromiseHandle, Convert.ToBase64String(parameters.bytes));
  284. while (!promiseCoroutine.Promise.HasReceivedJSResponse)
  285. yield return null;
  286. if (documentPromise.HasSucceeded)
  287. {
  288. int documentHandle = int.Parse(promiseCoroutine.Promise.JSObjectHandle);
  289. PDFDocument document = new PDFDocument(new IntPtr(documentHandle));
  290. documentPromise.Result = document;
  291. documentPromise.HasFinished = true;
  292. promiseCoroutine.ExecuteThenAction(true, documentHandle);
  293. }
  294. else
  295. {
  296. documentPromise.Result = null;
  297. documentPromise.HasFinished = true;
  298. promiseCoroutine.ExecuteThenAction(false, null);
  299. }
  300. }
  301. #endif
  302. #region NATIVE
  303. #if !UNITY_WEBGL || UNITY_EDITOR
  304. [DllImport(PDFLibrary.PLUGIN_ASSEMBLY)]
  305. private static extern void FPDF_CloseDocument(IntPtr document);
  306. [DllImport(PDFLibrary.PLUGIN_ASSEMBLY)]
  307. private static extern uint FPDF_GetDocPermissions(IntPtr document);
  308. [DllImport(PDFLibrary.PLUGIN_ASSEMBLY)]
  309. private static extern int FPDF_GetPageCount(IntPtr document);
  310. [DllImport(PDFLibrary.PLUGIN_ASSEMBLY, CharSet = CharSet.Ansi)]
  311. private static extern IntPtr FPDF_LoadMemDocument(byte[] data_buf, int size, string password);
  312. [DllImport(PDFLibrary.PLUGIN_ASSEMBLY)]
  313. private static extern int FPDF_GetPageSizeByIndex(IntPtr document, int page_index, out double width, out double height);
  314. #else
  315. [DllImport(PDFLibrary.PLUGIN_ASSEMBLY)]
  316. private static extern void PDFJS_LoadDocumentFromURL(string promiseHandle, string documentUrl);
  317. [DllImport(PDFLibrary.PLUGIN_ASSEMBLY)]
  318. private static extern void PDFJS_LoadDocumentFromBytes(string promiseHandle, string base64);
  319. [DllImport(PDFLibrary.PLUGIN_ASSEMBLY)]
  320. private static extern void PDFJS_CloseDocument(int document);
  321. [DllImport(PDFLibrary.PLUGIN_ASSEMBLY)]
  322. private static extern int PDFJS_GetPageCount(int documentHandle);
  323. #endif
  324. #endregion
  325. }
  326. }