1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef PRINTING_EMF_WIN_H_
6 #define PRINTING_EMF_WIN_H_
15 #include "base/compiler_specific.h"
16 #include "base/component_export.h"
17 #include "base/gtest_prod_util.h"
18 #include "base/memory/raw_ptr.h"
19 #include "printing/metafile.h"
32 // Simple wrapper class that manage an EMF data stream and its virtual HDC.
33 class COMPONENT_EXPORT(PRINTING_METAFILE) Emf : public Metafile {
37 struct EnumerationContext;
39 // Generates a virtual HDC that will record every GDI commands and compile
40 // it in a EMF data stream.
42 Emf(const Emf&) = delete;
43 Emf& operator=(const Emf&) = delete;
49 // Generates a new metafile that will record every GDI command, and will
50 // be saved to `metafile_path`.
51 bool InitToFile(const base::FilePath& metafile_path);
53 // Initializes the Emf with the data in `metafile_path`.
54 bool InitFromFile(const base::FilePath& metafile_path);
58 bool InitFromData(base::span<const uint8_t> data) override;
60 // Inserts a custom GDICOMMENT records indicating StartPage/EndPage calls
61 // (since StartPage and EndPage do not work in a metafile DC). Only valid
62 // when hdc_ is non-NULL. `page_size`, `content_area`, and `scale_factor` are
64 void StartPage(const gfx::Size& page_size,
65 const gfx::Rect& content_area,
67 mojom::PageOrientation page_orientation) override;
68 bool FinishPage() override;
69 bool FinishDocument() override;
71 uint32_t GetDataSize() const override;
72 bool GetData(void* buffer, uint32_t size) const override;
73 bool ShouldCopySharedMemoryRegionData() const override;
74 mojom::MetafileDataType GetDataType() const override;
76 // Should be passed to Playback to keep the exact same size.
77 gfx::Rect GetPageBounds(unsigned int page_number) const override;
79 unsigned int GetPageCount() const override;
80 HDC context() const override;
81 bool Playback(HDC hdc, const RECT* rect) const override;
82 bool SafePlayback(HDC hdc) const override;
84 HENHMETAFILE emf() const { return emf_; }
87 FRIEND_TEST_ALL_PREFIXES(EmfTest, DC);
88 FRIEND_TEST_ALL_PREFIXES(EmfPrintingTest, PageBreak);
89 FRIEND_TEST_ALL_PREFIXES(EmfTest, FileBackedEmf);
91 // Playbacks safely one EMF record.
92 static int CALLBACK SafePlaybackProc(HDC hdc,
93 HANDLETABLE* handle_table,
94 const ENHMETARECORD* record,
98 // Compiled EMF data handle.
101 // Valid when generating EMF data through a virtual HDC.
105 struct Emf::EnumerationContext {
106 EnumerationContext();
108 raw_ptr<HANDLETABLE> handle_table;
111 raw_ptr<const XFORM> base_matrix;
112 int dc_on_page_start;
115 // One EMF record. It keeps pointers to the EMF buffer held by Emf::emf_.
116 // The entries become invalid once Emf::CloseEmf() is called.
117 class COMPONENT_EXPORT(PRINTING_METAFILE) Emf::Record {
120 bool Play(EnumerationContext* context) const;
122 // Plays the record working around quirks with SetLayout,
123 // SetWorldTransform and ModifyWorldTransform. See implementation for details.
124 bool SafePlayback(EnumerationContext* context) const;
126 // Access the underlying EMF record.
127 const ENHMETARECORD* record() const { return record_; }
130 explicit Record(const ENHMETARECORD* record);
134 friend class Enumerator;
135 raw_ptr<const ENHMETARECORD> record_;
138 // Retrieves individual records out of a Emf buffer. The main use is to skip
139 // over records that are unsupported on a specific printer or to play back
140 // only a part of an EMF buffer.
141 class COMPONENT_EXPORT(PRINTING_METAFILE) Emf::Enumerator {
143 // Iterator type used for iterating the records.
144 typedef std::vector<Record>::const_iterator const_iterator;
146 // Enumerates the records at construction time. `hdc` and `rect` are
147 // both optional at the same time or must both be valid.
148 // Warning: `emf` must be kept valid for the time this object is alive.
149 Enumerator(const Emf& emf, HDC hdc, const RECT* rect);
150 Enumerator(const Enumerator&) = delete;
151 Enumerator& operator=(const Enumerator&) = delete;
154 // Retrieves the first Record.
155 const_iterator begin() const;
157 // Retrieves the end of the array.
158 const_iterator end() const;
161 FRIEND_TEST_ALL_PREFIXES(EmfPrintingTest, Enumerate);
163 // Processes one EMF record and saves it in the items_ array.
164 static int CALLBACK EnhMetaFileProc(HDC hdc,
165 HANDLETABLE* handle_table,
166 const ENHMETARECORD* record,
170 // The collection of every EMF records in the currently loaded EMF buffer.
171 // Initialized by Enumerate(). It keeps pointers to the EMF buffer held by
172 // Emf::emf_. The entries become invalid once Emf::CloseEmf() is called.
173 std::vector<Record> items_;
175 EnumerationContext context_;
178 } // namespace printing
180 #endif // PRINTING_EMF_WIN_H_