emf_win.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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_EMF_WIN_H_
  5. #define PRINTING_EMF_WIN_H_
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <windows.h>
  9. #include <memory>
  10. #include <vector>
  11. #include "base/compiler_specific.h"
  12. #include "base/component_export.h"
  13. #include "base/gtest_prod_util.h"
  14. #include "base/memory/raw_ptr.h"
  15. #include "printing/metafile.h"
  16. namespace base {
  17. class FilePath;
  18. }
  19. namespace gfx {
  20. class Rect;
  21. class Size;
  22. } // namespace gfx
  23. namespace printing {
  24. // Simple wrapper class that manage an EMF data stream and its virtual HDC.
  25. class COMPONENT_EXPORT(PRINTING_METAFILE) Emf : public Metafile {
  26. public:
  27. class Record;
  28. class Enumerator;
  29. struct EnumerationContext;
  30. // Generates a virtual HDC that will record every GDI commands and compile
  31. // it in a EMF data stream.
  32. Emf();
  33. Emf(const Emf&) = delete;
  34. Emf& operator=(const Emf&) = delete;
  35. ~Emf() override;
  36. // Closes metafile.
  37. void Close();
  38. // Generates a new metafile that will record every GDI command, and will
  39. // be saved to `metafile_path`.
  40. bool InitToFile(const base::FilePath& metafile_path);
  41. // Initializes the Emf with the data in `metafile_path`.
  42. bool InitFromFile(const base::FilePath& metafile_path);
  43. // Metafile methods.
  44. bool Init() override;
  45. bool InitFromData(base::span<const uint8_t> data) override;
  46. // Inserts a custom GDICOMMENT records indicating StartPage/EndPage calls
  47. // (since StartPage and EndPage do not work in a metafile DC). Only valid
  48. // when hdc_ is non-NULL. `page_size`, `content_area`, and `scale_factor` are
  49. // ignored.
  50. void StartPage(const gfx::Size& page_size,
  51. const gfx::Rect& content_area,
  52. float scale_factor,
  53. mojom::PageOrientation page_orientation) override;
  54. bool FinishPage() override;
  55. bool FinishDocument() override;
  56. uint32_t GetDataSize() const override;
  57. bool GetData(void* buffer, uint32_t size) const override;
  58. bool ShouldCopySharedMemoryRegionData() const override;
  59. mojom::MetafileDataType GetDataType() const override;
  60. // Should be passed to Playback to keep the exact same size.
  61. gfx::Rect GetPageBounds(unsigned int page_number) const override;
  62. unsigned int GetPageCount() const override;
  63. HDC context() const override;
  64. bool Playback(HDC hdc, const RECT* rect) const override;
  65. bool SafePlayback(HDC hdc) const override;
  66. HENHMETAFILE emf() const { return emf_; }
  67. private:
  68. FRIEND_TEST_ALL_PREFIXES(EmfTest, DC);
  69. FRIEND_TEST_ALL_PREFIXES(EmfPrintingTest, PageBreak);
  70. FRIEND_TEST_ALL_PREFIXES(EmfTest, FileBackedEmf);
  71. // Playbacks safely one EMF record.
  72. static int CALLBACK SafePlaybackProc(HDC hdc,
  73. HANDLETABLE* handle_table,
  74. const ENHMETARECORD* record,
  75. int objects_count,
  76. LPARAM param);
  77. // Compiled EMF data handle.
  78. HENHMETAFILE emf_;
  79. // Valid when generating EMF data through a virtual HDC.
  80. HDC hdc_;
  81. };
  82. struct Emf::EnumerationContext {
  83. EnumerationContext();
  84. raw_ptr<HANDLETABLE> handle_table;
  85. int objects_count;
  86. HDC hdc;
  87. raw_ptr<const XFORM> base_matrix;
  88. int dc_on_page_start;
  89. };
  90. // One EMF record. It keeps pointers to the EMF buffer held by Emf::emf_.
  91. // The entries become invalid once Emf::CloseEmf() is called.
  92. class COMPONENT_EXPORT(PRINTING_METAFILE) Emf::Record {
  93. public:
  94. // Plays the record.
  95. bool Play(EnumerationContext* context) const;
  96. // Plays the record working around quirks with SetLayout,
  97. // SetWorldTransform and ModifyWorldTransform. See implementation for details.
  98. bool SafePlayback(EnumerationContext* context) const;
  99. // Access the underlying EMF record.
  100. const ENHMETARECORD* record() const { return record_; }
  101. protected:
  102. explicit Record(const ENHMETARECORD* record);
  103. private:
  104. friend class Emf;
  105. friend class Enumerator;
  106. const ENHMETARECORD* record_;
  107. };
  108. // Retrieves individual records out of a Emf buffer. The main use is to skip
  109. // over records that are unsupported on a specific printer or to play back
  110. // only a part of an EMF buffer.
  111. class COMPONENT_EXPORT(PRINTING_METAFILE) Emf::Enumerator {
  112. public:
  113. // Iterator type used for iterating the records.
  114. typedef std::vector<Record>::const_iterator const_iterator;
  115. // Enumerates the records at construction time. `hdc` and `rect` are
  116. // both optional at the same time or must both be valid.
  117. // Warning: `emf` must be kept valid for the time this object is alive.
  118. Enumerator(const Emf& emf, HDC hdc, const RECT* rect);
  119. Enumerator(const Enumerator&) = delete;
  120. Enumerator& operator=(const Enumerator&) = delete;
  121. ~Enumerator();
  122. // Retrieves the first Record.
  123. const_iterator begin() const;
  124. // Retrieves the end of the array.
  125. const_iterator end() const;
  126. private:
  127. FRIEND_TEST_ALL_PREFIXES(EmfPrintingTest, Enumerate);
  128. // Processes one EMF record and saves it in the items_ array.
  129. static int CALLBACK EnhMetaFileProc(HDC hdc,
  130. HANDLETABLE* handle_table,
  131. const ENHMETARECORD* record,
  132. int objects_count,
  133. LPARAM param);
  134. // The collection of every EMF records in the currently loaded EMF buffer.
  135. // Initialized by Enumerate(). It keeps pointers to the EMF buffer held by
  136. // Emf::emf_. The entries become invalid once Emf::CloseEmf() is called.
  137. std::vector<Record> items_;
  138. EnumerationContext context_;
  139. };
  140. } // namespace printing
  141. #endif // PRINTING_EMF_WIN_H_