OLD | NEW |
| (Empty) |
1 // Copyright (c) 2006-2008 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 | |
5 #ifndef CHROME_COMMON_GFX_EMF_H__ | |
6 #define CHROME_COMMON_GFX_EMF_H__ | |
7 | |
8 #include <windows.h> | |
9 #include <vector> | |
10 | |
11 #include "base/basictypes.h" | |
12 | |
13 namespace gfx { | |
14 | |
15 class Rect; | |
16 | |
17 // Simple wrapper class that manage an EMF data stream and its virtual HDC. | |
18 class Emf { | |
19 public: | |
20 class Record; | |
21 class Enumerator; | |
22 struct EnumerationContext; | |
23 | |
24 Emf(); | |
25 ~Emf(); | |
26 | |
27 // Generates a virtual HDC that will record every GDI commands and compile it | |
28 // in a EMF data stream. | |
29 // hdc is used to setup the default DPI and color settings. hdc is optional. | |
30 // rect specifies the dimensions (in .01-millimeter units) of the EMF. rect is | |
31 // optional. | |
32 bool CreateDc(HDC sibling, const RECT* rect); | |
33 | |
34 // Load a EMF data stream. buffer contains EMF data. | |
35 bool CreateFromData(const void* buffer, size_t size); | |
36 | |
37 // TODO(maruel): CreateFromFile(). If ever used. Maybe users would like to | |
38 // have the ability to save web pages to an EMF file? Afterward, it is easy to | |
39 // convert to PDF or PS. | |
40 | |
41 // Closes the HDC created by CreateDc() and generates the compiled EMF | |
42 // data. | |
43 bool CloseDc(); | |
44 | |
45 // Closes the EMF data handle when it is not needed anymore. | |
46 void CloseEmf(); | |
47 | |
48 // "Plays" the EMF buffer in a HDC. It is the same effect as calling the | |
49 // original GDI function that were called when recording the EMF. |rect| is in | |
50 // "logical units" and is optional. If |rect| is NULL, the natural EMF bounds | |
51 // are used. | |
52 // Note: Windows has been known to have stack buffer overflow in its GDI | |
53 // functions, whether used directly or indirectly through precompiled EMF | |
54 // data. We have to accept the risk here. Since it is used only for printing, | |
55 // it requires user intervention. | |
56 bool Playback(HDC hdc, const RECT* rect) const; | |
57 | |
58 // The slow version of Playback(). It enumerates all the records and play them | |
59 // back in the HDC. The trick is that it skip over the records known to have | |
60 // issue with some printers. See Emf::Record::SafePlayback implementation for | |
61 // details. | |
62 bool SafePlayback(HDC hdc) const; | |
63 | |
64 // Retrieves the bounds of the painted area by this EMF buffer. This value | |
65 // should be passed to Playback to keep the exact same size. | |
66 gfx::Rect GetBounds() const; | |
67 | |
68 // Retrieves the EMF stream size. | |
69 unsigned GetDataSize() const; | |
70 | |
71 // Retrieves the EMF stream. | |
72 bool GetData(void* buffer, size_t size) const; | |
73 | |
74 // Retrieves the EMF stream. It is an helper function. | |
75 bool GetData(std::vector<uint8>* buffer) const; | |
76 | |
77 HENHMETAFILE emf() const { | |
78 return emf_; | |
79 } | |
80 | |
81 HDC hdc() const { | |
82 return hdc_; | |
83 } | |
84 | |
85 // Saves the EMF data to a file as-is. It is recommended to use the .emf file | |
86 // extension but it is not enforced. This function synchronously writes to the | |
87 // file. For testing only. | |
88 bool SaveTo(const std::wstring& filename) const; | |
89 | |
90 private: | |
91 // Playbacks safely one EMF record. | |
92 static int CALLBACK SafePlaybackProc(HDC hdc, | |
93 HANDLETABLE* handle_table, | |
94 const ENHMETARECORD* record, | |
95 int objects_count, | |
96 LPARAM param); | |
97 | |
98 // Compiled EMF data handle. | |
99 HENHMETAFILE emf_; | |
100 | |
101 // Valid when generating EMF data through a virtual HDC. | |
102 HDC hdc_; | |
103 | |
104 DISALLOW_EVIL_CONSTRUCTORS(Emf); | |
105 }; | |
106 | |
107 struct Emf::EnumerationContext { | |
108 HANDLETABLE* handle_table; | |
109 int objects_count; | |
110 HDC hdc; | |
111 }; | |
112 | |
113 // One EMF record. It keeps pointers to the EMF buffer held by Emf::emf_. | |
114 // The entries become invalid once Emf::CloseEmf() is called. | |
115 class Emf::Record { | |
116 public: | |
117 Record(); | |
118 | |
119 // Plays the record. | |
120 bool Play() const; | |
121 | |
122 // Plays the record working around quirks with SetLayout, | |
123 // SetWorldTransform and ModifyWorldTransform. See implementation for details. | |
124 bool SafePlayback(const XFORM* base_matrix) const; | |
125 | |
126 // Access the underlying EMF record. | |
127 const ENHMETARECORD* record() const { return record_; } | |
128 | |
129 protected: | |
130 Record(const EnumerationContext* context, | |
131 const ENHMETARECORD* record); | |
132 | |
133 private: | |
134 friend class Emf; | |
135 friend class Enumerator; | |
136 const ENHMETARECORD* record_; | |
137 const EnumerationContext* context_; | |
138 }; | |
139 | |
140 // Retrieves individual records out of a Emf buffer. The main use is to skip | |
141 // over records that are unsupported on a specific printer or to play back | |
142 // only a part of an EMF buffer. | |
143 class Emf::Enumerator { | |
144 public: | |
145 // Iterator type used for iterating the records. | |
146 typedef std::vector<Record>::const_iterator const_iterator; | |
147 | |
148 // Enumerates the records at construction time. |hdc| and |rect| are | |
149 // both optional at the same time or must both be valid. | |
150 // Warning: |emf| must be kept valid for the time this object is alive. | |
151 Enumerator(const Emf& emf, HDC hdc, const RECT* rect); | |
152 | |
153 // Retrieves the first Record. | |
154 const_iterator begin() const; | |
155 | |
156 // Retrieves the end of the array. | |
157 const_iterator end() const; | |
158 | |
159 private: | |
160 // Processes one EMF record and saves it in the items_ array. | |
161 static int CALLBACK EnhMetaFileProc(HDC hdc, | |
162 HANDLETABLE* handle_table, | |
163 const ENHMETARECORD* record, | |
164 int objects_count, | |
165 LPARAM param); | |
166 | |
167 // The collection of every EMF records in the currently loaded EMF buffer. | |
168 // Initialized by Enumerate(). It keeps pointers to the EMF buffer held by | |
169 // Emf::emf_. The entries become invalid once Emf::CloseEmf() is called. | |
170 std::vector<Record> items_; | |
171 | |
172 EnumerationContext context_; | |
173 | |
174 DISALLOW_EVIL_CONSTRUCTORS(Enumerator); | |
175 }; | |
176 | |
177 } // namespace gfx | |
178 | |
179 #endif // CHROME_COMMON_GFX_EMF_H__ | |
OLD | NEW |