Document.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #include "Document.h"
  2. #include "MuException.h"
  3. #include "Vcclr.h"
  4. #pragma unmanaged
  5. static fz_document* OpenDocumentWithStream(fz_context* ctx, fz_stream* stream) {
  6. fz_document* s;
  7. MuTryReturn(ctx, fz_open_document_with_stream(ctx, ".pdf", stream), s);
  8. }
  9. static fz_page* LoadPage(fz_context* ctx, fz_document* doc, int pn) {
  10. fz_page* p;
  11. MuTryReturn(ctx, fz_load_page(ctx, doc, pn), p);
  12. }
  13. DLLEXP int PdfSaveDocument(fz_context* ctx, pdf_document* doc, const wchar_t* filePath, const pdf_write_options* options) {
  14. char* utf8path = NULL;
  15. fz_try(ctx) {
  16. utf8path = fz_utf8_from_wchar(ctx, filePath);
  17. pdf_save_document(ctx, doc, utf8path, options);
  18. }
  19. fz_always(ctx) {
  20. fz_free(ctx, utf8path);
  21. }
  22. fz_catch(ctx) {
  23. return 0;
  24. }
  25. return 1;
  26. }
  27. DLLEXP int PdfSaveSnapshot(fz_context* ctx, pdf_document* doc, const wchar_t* filePath) {
  28. char* utf8path = NULL;
  29. fz_try(ctx) {
  30. utf8path = fz_utf8_from_wchar(ctx, filePath);
  31. pdf_save_snapshot(ctx, doc, utf8path);
  32. }
  33. fz_always(ctx) {
  34. fz_free(ctx, utf8path);
  35. }
  36. fz_catch(ctx) {
  37. return 0;
  38. }
  39. return 1;
  40. }
  41. #pragma managed
  42. MuPDF::Document::Document(fz_stream* stream) {
  43. OpenStream(stream);
  44. }
  45. void MuPDF::Document::OpenStream(fz_stream* stream) {
  46. fz_context* ctx = Context::Ptr;
  47. fz_document* doc = OpenDocumentWithStream(ctx, stream);
  48. if (doc) {
  49. _document = doc;
  50. _stream = stream;
  51. InitTrailer();
  52. return;
  53. }
  54. else {
  55. fz_drop_stream(ctx, stream);
  56. }
  57. throw MuException::FromContext();
  58. }
  59. void MuPDF::Document::InitTrailer() {
  60. fz_context* ctx = Context::Ptr;
  61. _pdf = pdf_document_from_fz_document(ctx, _document);
  62. if (!_pdf) {
  63. throw gcnew MuException("Document is not PDF.");
  64. }
  65. _trailer = pdf_trailer(ctx, _pdf);
  66. if (!_trailer) {
  67. throw gcnew MuException("Missing document trailer.");
  68. }
  69. _pageCount = fz_count_pages(ctx, _document);
  70. }
  71. MuPDF::Page^ MuPDF::Document::LoadPage(int pageNumber) {
  72. fz_page* p = ::LoadPage(Context::Ptr, _document, pageNumber);
  73. if (p) {
  74. return gcnew Page(p, pageNumber);
  75. }
  76. throw MuException::FromContext();
  77. }
  78. MuPDF::PdfDictionary^ MuPDF::Document::NewPage(Box mediaBox, int rotate, PdfDictionary^ resources, array<Byte>^ contents) {
  79. pin_ptr<Byte> c = &contents[0];
  80. auto b = fz_new_buffer_from_copied_data(Context::Ptr, c, contents->Length);
  81. return gcnew PdfDictionary(pdf_add_page(Context::Ptr, _pdf, mediaBox, rotate, resources ? resources->Ptr : NULL, b));
  82. }
  83. void MuPDF::Document::Save(String^ filePath, WriterOptions^ options) {
  84. pin_ptr<const wchar_t> p = PtrToStringChars(filePath);
  85. pdf_write_options w = options->ToNative();
  86. auto r = PdfSaveDocument(Context::Ptr, _pdf, (const wchar_t*)p, (const pdf_write_options*)&w);
  87. if (!r) {
  88. throw MuException::FromContext();
  89. }
  90. }
  91. void MuPDF::Document::SaveSnapshot(String^ filePath) {
  92. pin_ptr<const wchar_t> p = PtrToStringChars(filePath);
  93. auto r = PdfSaveSnapshot(Context::Ptr, _pdf, (const wchar_t*)p);
  94. if (!r) {
  95. throw MuException::FromContext();
  96. }
  97. }
  98. bool MuPDF::Document::CheckPassword(String^ password) {
  99. const char* c = (char*)(void*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(password);
  100. int r = fz_authenticate_password(Context::Ptr, _document, c);
  101. delete c;
  102. return r;
  103. }
  104. void MuPDF::Document::Reopen() {
  105. if (!_path) {
  106. throw gcnew System::InvalidOperationException("Could not reopen a document without path");
  107. }
  108. Stream^ s = gcnew Stream(_path);
  109. try {
  110. OpenStream(s->Ptr);
  111. }
  112. catch (Exception^) {
  113. delete s;
  114. throw;
  115. }
  116. }
  117. pdf_write_options MuPDF::WriterOptions::ToNative() {
  118. pdf_write_options r{};
  119. r.do_incremental = Incremental;
  120. r.do_pretty = Pretty;
  121. r.do_ascii = Ascii;
  122. r.do_compress = Compress;
  123. r.do_compress_images = CompressImages;
  124. r.do_compress_fonts = CompressFonts;
  125. r.do_decompress = Decompress;
  126. r.do_garbage = Garbage;
  127. r.do_linear = Linear;
  128. r.do_clean = Clean;
  129. r.do_sanitize = Sanitize;
  130. r.do_appearance = Appearance;
  131. r.do_encrypt = Decrypt;
  132. r.dont_regenerate_id = DoNotRegenerateId;
  133. r.do_snapshot = Snapshot;
  134. r.do_preserve_metadata = PreserveMetadata;
  135. r.do_use_objstms = UseObjectStreams;
  136. r.compression_effort = CompressionEffort;
  137. if (OwnerPassword) {
  138. System::Runtime::InteropServices::Marshal::Copy(OwnerPassword, 0, (IntPtr)(void*)&r.opwd_utf8, OwnerPassword->Length);
  139. }
  140. if (UserPassword) {
  141. System::Runtime::InteropServices::Marshal::Copy(UserPassword, 0, (IntPtr)(void*)&r.upwd_utf8, UserPassword->Length);
  142. }
  143. return r;
  144. }