Document.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include "mupdf/fitz.h"
  2. #include "mupdf/pdf.h"
  3. #include "MuPDF.h"
  4. #ifndef __DOCUMENT
  5. #define __DOCUMENT
  6. #pragma once
  7. using namespace System;
  8. namespace MuPDF {
  9. ref class WriterOptions;
  10. public ref class Document sealed : IDisposable, IEquatable<Document^> {
  11. public:
  12. property int PageCount {
  13. int get() { return _pageCount; }
  14. }
  15. property int ObjectCount {
  16. int get() { return pdf_count_objects(Context::Ptr, _pdf); }
  17. }
  18. property int AssociatedFileCount {
  19. int get() { return pdf_count_document_associated_files(Context::Ptr, _pdf); }
  20. }
  21. property bool NeedsPassword {
  22. bool get() { return fz_needs_password(Context::Ptr, _document); }
  23. }
  24. property bool WasRepaired {
  25. bool get() { return pdf_was_repaired(Context::Ptr, _pdf); }
  26. }
  27. property bool HasUnsavedChanges {
  28. bool get() { return pdf_has_unsaved_changes(Context::Ptr, _pdf); }
  29. }
  30. property String^ FilePath {
  31. String^ get() { return _path; }
  32. internal: void set(String^ value) { _path = value; }
  33. }
  34. property PdfDictionary^ Trailer {
  35. PdfDictionary^ get() {
  36. return gcnew PdfDictionary(_trailer);
  37. }
  38. }
  39. property PdfDictionary^ Root {
  40. PdfDictionary^ get() {
  41. return gcnew PdfDictionary(pdf_dict_get(Context::Ptr, _trailer, PDF_NAME(Root)));
  42. }
  43. }
  44. property PdfDocumentInfo^ Info {
  45. PdfDocumentInfo^ get() {
  46. return gcnew PdfDocumentInfo(pdf_dict_get(Context::Ptr, _trailer, PDF_NAME(Info)));
  47. }
  48. }
  49. property bool CanUndo {
  50. bool get() { return pdf_can_undo(Context::Ptr, _pdf); }
  51. }
  52. property bool CanRedo {
  53. bool get() { return pdf_can_redo(Context::Ptr, _pdf); }
  54. }
  55. property bool CanBeSavedIncrementally {
  56. bool get() { return pdf_can_be_saved_incrementally(Context::Ptr, _pdf); }
  57. }
  58. property bool IsDisposed {
  59. bool get() { return _document == NULL; }
  60. }
  61. /// <summary>
  62. /// Loads specific page from document.
  63. /// </summary>
  64. /// <param name="pageNumber">The page number (starts from 0).</param>
  65. /// <returns>The loaded page.</returns>
  66. Page^ LoadPage(int pageNumber);
  67. int GetPageNumber(Page^ page) {
  68. return pdf_lookup_page_number(Context::Ptr, _pdf, page->PagePtr);
  69. }
  70. /// <summary>
  71. /// Insert a page previously created by NewPage into the pages tree of the document.
  72. /// </summary>
  73. /// <param name="page">The page to be inserted.</param>
  74. /// <param name="beforePageNumber">The page number to insert at (pages numbered from 0). 0 <= n <= page_count inserts before page n. Negative numbers or INT_MAX are treated as page count, and insert at the end. 0 inserts at the start. All existing pages are after the insertion point are shuffled up.</param>
  75. void InsertPage(Page^ page, int beforePageNumber) {
  76. pdf_insert_page(Context::Ptr, _pdf, beforePageNumber, page->PagePtr);
  77. }
  78. void AppendPage(Page^ page) {
  79. pdf_insert_page(Context::Ptr, _pdf, INT_MAX, page->PagePtr);
  80. }
  81. /// <summary>
  82. /// Removes specific page from document.
  83. /// </summary>
  84. /// <param name="pageNumber">The page number (starts from 0).</param>
  85. void DeletePage(int pageNumber) {
  86. pdf_delete_page(Context::Ptr, _pdf, pageNumber);
  87. }
  88. /// <summary>
  89. /// Removes specific pages [start, end) from document. This does not remove the page contents or resources from the file.
  90. /// </summary>
  91. /// <param name="start">The first page number to be removed (starts from 0).</param>
  92. /// <param name="end">The last page number remained (starts from 0). If end is negative or greater than the number of pages in the document, it will be taken to be the end of the document.</param>
  93. void DeletePage(int start, int end) {
  94. pdf_delete_page_range(Context::Ptr, _pdf, start, end);
  95. }
  96. void RearrangePages(array<int>^ pageNumbers) {
  97. pin_ptr<int> n = &pageNumbers[0];
  98. pdf_rearrange_pages(Context::Ptr, _pdf, pageNumbers->Length, n, PDF_CLEAN_STRUCTURE_DROP);
  99. }
  100. void SyncOpenPages() {
  101. pdf_sync_open_pages(Context::Ptr, _pdf);
  102. }
  103. void Save(String^ filePath, WriterOptions^ options);
  104. void SaveSnapshot(String^ filePath);
  105. bool CheckPassword(String^ password);
  106. void CloseFile() {
  107. ReleaseHandle();
  108. }
  109. void Reopen();
  110. #pragma region Object creation
  111. PdfDictionary^ NewPage(Box mediaBox, int rotate, PdfDictionary^ resources, array<Byte>^ contents);
  112. PdfDictionary^ NewDictionary(int capacity) {
  113. return gcnew PdfDictionary(pdf_new_dict(Context::Ptr, _pdf, capacity));
  114. }
  115. PdfArray^ NewArray(int capacity) {
  116. return gcnew PdfArray(pdf_new_array(Context::Ptr, _pdf, capacity));
  117. }
  118. PdfArray^ NewBox(Box box) {
  119. return gcnew PdfArray(pdf_new_rect(Context::Ptr, _pdf, box));
  120. }
  121. PdfArray^ NewMatrix(Matrix matrix) {
  122. return gcnew PdfArray(pdf_new_matrix(Context::Ptr, _pdf, matrix));
  123. }
  124. #pragma endregion
  125. #pragma region Undo-redo
  126. void EnableJournal() {
  127. pdf_enable_journal(Context::Ptr, _pdf);
  128. }
  129. void BeginOperation() {
  130. pdf_begin_implicit_operation(Context::Ptr, _pdf);
  131. }
  132. void CancelOperation() {
  133. pdf_abandon_operation(Context::Ptr, _pdf);
  134. }
  135. void EndOperation() {
  136. pdf_end_operation(Context::Ptr, _pdf);
  137. }
  138. void Undo() {
  139. pdf_undo(Context::Ptr, _pdf);
  140. }
  141. void Redo() {
  142. pdf_redo(Context::Ptr, _pdf);
  143. }
  144. #pragma endregion
  145. Equatable(Document, _document)
  146. internal:
  147. Document() {
  148. auto d = pdf_create_document(Context::Ptr);
  149. _document = (fz_document*)d;
  150. InitTrailer();
  151. }
  152. Document(fz_document* document) : _document(document) {
  153. InitTrailer();
  154. };
  155. Document(fz_stream* stream);
  156. ~Document() {
  157. ReleaseHandle();
  158. }
  159. property pdf_document* Ptr {
  160. pdf_document* get() { return _pdf; }
  161. }
  162. private:
  163. fz_document* _document;
  164. fz_stream* _stream;
  165. pdf_document* _pdf;
  166. pdf_obj* _trailer;
  167. String^ _path;
  168. int _pageCount;
  169. void InitTrailer();
  170. void ReleaseHandle() {
  171. fz_context* ctx = Context::Ptr;
  172. fz_drop_document(ctx, _document);
  173. fz_drop_stream(ctx, _stream);
  174. _document = NULL;
  175. _pdf = NULL;
  176. _trailer = NULL;
  177. _stream = NULL;
  178. }
  179. void OpenStream(fz_stream* stream);
  180. };
  181. public ref class WriterOptions sealed {
  182. public:
  183. bool Incremental;
  184. bool Pretty;
  185. bool Ascii;
  186. bool Compress;
  187. bool CompressImages;
  188. bool CompressFonts;
  189. bool Decompress;
  190. bool Garbage;
  191. bool Linear;
  192. bool Clean;
  193. bool Sanitize;
  194. bool Appearance;
  195. bool Decrypt;
  196. bool DoNotRegenerateId;
  197. bool Permissions;
  198. array<Byte>^ OwnerPassword;
  199. array<Byte>^ UserPassword;
  200. bool Snapshot;
  201. bool PreserveMetadata;
  202. bool UseObjectStreams;
  203. int CompressionEffort;
  204. internal:
  205. pdf_write_options ToNative();
  206. };
  207. }
  208. #endif // !__DOCUMENT