printed_document.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef PRINTING_PRINTED_DOCUMENT_H_
  5. #define PRINTING_PRINTED_DOCUMENT_H_
  6. #include <map>
  7. #include <memory>
  8. #include <string>
  9. #include "base/files/file_path.h"
  10. #include "base/memory/ref_counted.h"
  11. #include "base/synchronization/lock.h"
  12. #include "build/build_config.h"
  13. #include "printing/mojom/print.mojom.h"
  14. #include "printing/print_settings.h"
  15. namespace base {
  16. class RefCountedMemory;
  17. }
  18. namespace printing {
  19. class MetafilePlayer;
  20. class PrintedPage;
  21. class PrintingContext;
  22. // A collection of rendered pages. The settings are immutable. If the print
  23. // settings are changed, a new PrintedDocument must be created.
  24. // Warning: May be accessed from many threads at the same time. Only one thread
  25. // will have write access. Sensible functions are protected by a lock.
  26. // Warning: Once a page is loaded, it cannot be replaced. Pages may be discarded
  27. // under low memory conditions.
  28. class COMPONENT_EXPORT(PRINTING) PrintedDocument
  29. : public base::RefCountedThreadSafe<PrintedDocument> {
  30. public:
  31. // The cookie shall be unique and has a specific relationship with its
  32. // originating source and settings.
  33. PrintedDocument(std::unique_ptr<PrintSettings> settings,
  34. const std::u16string& name,
  35. int cookie);
  36. PrintedDocument(const PrintedDocument&) = delete;
  37. PrintedDocument& operator=(const PrintedDocument&) = delete;
  38. #if BUILDFLAG(IS_WIN)
  39. // Indicates that the PDF has been generated and the document is waiting for
  40. // conversion for printing. This is needed on Windows so that the print job
  41. // is not cancelled if the web contents dies before PDF conversion finishes.
  42. // This is applicable when using the GDI print API.
  43. void SetConvertingPdf();
  44. // Sets a page's data. 0-based. Note: locks for a short amount of time.
  45. void SetPage(uint32_t page_number,
  46. std::unique_ptr<MetafilePlayer> metafile,
  47. float shrink,
  48. const gfx::Size& page_size,
  49. const gfx::Rect& page_content_rect);
  50. // Retrieves a page. If the page is not available right now, it
  51. // requests to have this page be rendered and returns NULL.
  52. // Note: locks for a short amount of time.
  53. scoped_refptr<PrintedPage> GetPage(uint32_t page_number);
  54. // Removes reference to a particular `page` based on its page number.
  55. // Note: locks for a short amount of time.
  56. void RemovePage(const PrintedPage* page);
  57. #endif // BUILDFLAG(IS_WIN)
  58. // Sets the document data. Note: locks for a short amount of time.
  59. void SetDocument(std::unique_ptr<MetafilePlayer> metafile);
  60. // Retrieves the metafile with the data to print. Lock must be held when
  61. // calling this function
  62. const MetafilePlayer* GetMetafile();
  63. // Draws the page in the context.
  64. // Note: locks for a short amount of time in debug only.
  65. #if BUILDFLAG(IS_WIN)
  66. // This is applicable when using the Windows GDI print API.
  67. mojom::ResultCode RenderPrintedPage(const PrintedPage& page,
  68. PrintingContext* context) const;
  69. #if !defined(NDEBUG)
  70. // Verifies that the page is intended to be printed for the document.
  71. // Note: locks for a short amount of time.
  72. bool IsPageInList(const PrintedPage& page) const;
  73. #endif // !defined(NDEBUG)
  74. #endif // BUILDFLAG(IS_WIN)
  75. // Draws the document in the context. Fails if context->NewPage() or
  76. // context->PageDone() fails.
  77. mojom::ResultCode RenderPrintedDocument(PrintingContext* context);
  78. // Returns true if all the necessary pages for the settings are already
  79. // rendered.
  80. // Note: This function always locks and may parse the whole tree.
  81. bool IsComplete() const;
  82. // Sets the number of pages in the document to be rendered. Can only be set
  83. // once.
  84. // Note: locks for a short amount of time.
  85. void set_page_count(uint32_t max_page);
  86. // Number of pages in the document.
  87. // Note: locks for a short amount of time.
  88. uint32_t page_count() const;
  89. // Returns the number of expected pages to be rendered. It is a non-linear
  90. // series if settings().ranges is not empty. It is the same value as
  91. // document_page_count() otherwise.
  92. // Note: locks for a short amount of time.
  93. uint32_t expected_page_count() const;
  94. // Getters. All these items are immutable hence thread-safe.
  95. const PrintSettings& settings() const { return *immutable_.settings_; }
  96. const std::u16string& name() const { return immutable_.name_; }
  97. int cookie() const { return immutable_.cookie_; }
  98. // Sets a path where to dump printing output files for debugging. If never
  99. // set, no files are generated. `debug_dump_path` must not be empty.
  100. static void SetDebugDumpPath(const base::FilePath& debug_dump_path);
  101. // Returns true if SetDebugDumpPath() has been called.
  102. static bool HasDebugDumpPath();
  103. // Creates debug file name from given `document_name` and `extension`.
  104. // `extension` should include the leading dot. e.g. ".pdf"
  105. // Should only be called when debug dumps are enabled.
  106. static base::FilePath CreateDebugDumpPath(
  107. const std::u16string& document_name,
  108. const base::FilePath::StringType& extension);
  109. // Dump data on blocking task runner.
  110. // Should only be called when debug dumps are enabled.
  111. void DebugDumpData(const base::RefCountedMemory* data,
  112. const base::FilePath::StringType& extension);
  113. private:
  114. friend class base::RefCountedThreadSafe<PrintedDocument>;
  115. ~PrintedDocument();
  116. // Array of data for each print previewed page.
  117. using PrintedPages = std::map<uint32_t, scoped_refptr<PrintedPage>>;
  118. // Contains all the mutable stuff. All this stuff MUST be accessed with the
  119. // lock held.
  120. struct Mutable {
  121. Mutable();
  122. ~Mutable();
  123. // Number of expected pages to be rendered.
  124. // Warning: Lock must be held when accessing this member.
  125. uint32_t expected_page_count_ = 0;
  126. // The total number of pages in the document.
  127. uint32_t page_count_ = 0;
  128. std::unique_ptr<MetafilePlayer> metafile_;
  129. #if BUILDFLAG(IS_WIN)
  130. // Contains the pages' representation. This is a collection of PrintedPage.
  131. // Warning: Lock must be held when accessing this member.
  132. // This is applicable when using the Windows GDI print API which has the
  133. // extra conversion step from PDF to EMF prior to sending to device.
  134. // The metafile_ field is not used in this scenario.
  135. PrintedPages pages_;
  136. // Whether the PDF is being converted for printing.
  137. bool converting_pdf_ = false;
  138. #endif
  139. };
  140. // Contains all the immutable stuff. All this stuff can be accessed without
  141. // any lock held. This is because it can't be changed after the object's
  142. // construction.
  143. struct Immutable {
  144. Immutable(std::unique_ptr<PrintSettings> settings,
  145. const std::u16string& name,
  146. int cookie);
  147. ~Immutable();
  148. // Print settings used to generate this document. Immutable.
  149. std::unique_ptr<PrintSettings> settings_;
  150. // Document name. Immutable.
  151. std::u16string name_;
  152. // Cookie to uniquely identify this document. It is used to make sure that a
  153. // PrintedPage is correctly belonging to the PrintedDocument. Since
  154. // PrintedPage generation is completely asynchronous, it could be easy to
  155. // mess up and send the page to the wrong document. It can be viewed as a
  156. // simpler hash of PrintSettings since a new document is made each time the
  157. // print settings change.
  158. int cookie_;
  159. };
  160. // All writable data member access must be guarded by this lock. Needs to be
  161. // mutable since it can be acquired from const member functions.
  162. mutable base::Lock lock_;
  163. // All the mutable members.
  164. Mutable mutable_;
  165. // All the immutable members.
  166. const Immutable immutable_;
  167. };
  168. } // namespace printing
  169. #endif // PRINTING_PRINTED_DOCUMENT_H_