Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(482)

Side by Side Diff: printing/emf_win.cc

Issue 6611032: Unifying NativeMetafile class interface (as much as possible) for Linux, Mac, Win (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixes for CHROMEOS Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "printing/emf_win.h" 5 #include "printing/emf_win.h"
6 6
7 #include "base/file_path.h" 7 #include "base/file_path.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "base/scoped_ptr.h" 10 #include "base/scoped_ptr.h"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 ExtEscape(dc, escape, size, reinterpret_cast<LPCSTR>(bits), 43 ExtEscape(dc, escape, size, reinterpret_cast<LPCSTR>(bits),
44 sizeof(supported), reinterpret_cast<LPSTR>(&supported)); 44 sizeof(supported), reinterpret_cast<LPSTR>(&supported));
45 } 45 }
46 return !!supported; 46 return !!supported;
47 } 47 }
48 48
49 Emf::Emf() : emf_(NULL), hdc_(NULL) { 49 Emf::Emf() : emf_(NULL), hdc_(NULL) {
50 } 50 }
51 51
52 Emf::~Emf() { 52 Emf::~Emf() {
53 CloseEmf(); 53 Close();
54 DCHECK(!emf_ && !hdc_); 54 DCHECK(!emf_ && !hdc_);
55 } 55 }
56 56
57 bool Emf::Init(const void* src_buffer, uint32 src_buffer_size) { 57 bool Emf::Init(const void* src_buffer, uint32 src_buffer_size) {
58 DCHECK(!emf_ && !hdc_); 58 DCHECK(!emf_ && !hdc_);
59 emf_ = SetEnhMetaFileBits(src_buffer_size, 59 emf_ = SetEnhMetaFileBits(src_buffer_size,
60 reinterpret_cast<const BYTE*>(src_buffer)); 60 reinterpret_cast<const BYTE*>(src_buffer));
61 return emf_ != NULL; 61 return emf_ != NULL;
62 } 62 }
vandebo (ex-Chrome) 2011/03/12 01:21:06 I don't remember if I specifically said to reorder
dpapad 2011/03/14 18:02:38 Done.
63 63
64 uint32 Emf::GetDataSize() const {
65 DCHECK(emf_ && !hdc_);
66 return GetEnhMetaFileBits(emf_, 0, NULL);
67 }
68
69 bool Emf::GetData(void* buffer, uint32 size) const {
70 DCHECK(emf_ && !hdc_);
71 DCHECK(buffer && size);
72 uint32 size2 =
73 GetEnhMetaFileBits(emf_, size, reinterpret_cast<BYTE*>(buffer));
74 DCHECK(size2 == size);
75 return size2 == size && size2 != 0;
76 }
77
78 bool Emf::FinishPage() {
79 DCHECK(hdc_);
80 if (!hdc_)
81 return false;
82 PageBreakRecord record(PageBreakRecord::END_PAGE);
83 return !!GdiComment(hdc_, sizeof(record),
84 reinterpret_cast<const BYTE *>(&record));
85 }
86
87 void Emf::Close() {
88 DCHECK(!hdc_);
89 if (emf_) {
90 DeleteEnhMetaFile(emf_);
91 emf_ = NULL;
92 }
93 }
94
95 bool Emf::SaveTo(const FilePath& file_path) const {
96 HANDLE file = CreateFile(file_path.value().c_str(), GENERIC_WRITE,
97 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
98 CREATE_ALWAYS, 0, NULL);
99 if (file == INVALID_HANDLE_VALUE)
100 return false;
101
102 bool success = false;
103 std::vector<uint8> buffer;
104 if (GetData(&buffer)) {
105 DWORD written = 0;
106 if (WriteFile(file, &*buffer.begin(), static_cast<DWORD>(buffer.size()),
107 &written, NULL) &&
108 written == buffer.size()) {
109 success = true;
110 }
111 }
112 CloseHandle(file);
113 return success;
114 }
115
116 gfx::Rect Emf::GetPageBounds(unsigned int page_number) const {
117 DCHECK(emf_ && !hdc_);
118 ENHMETAHEADER header;
119 if (GetEnhMetaFileHeader(emf_, sizeof(header), &header) != sizeof(header)) {
120 NOTREACHED();
121 return gfx::Rect();
122 }
123 if (header.rclBounds.left == 0 &&
124 header.rclBounds.top == 0 &&
125 header.rclBounds.right == -1 &&
126 header.rclBounds.bottom == -1) {
127 // A freshly created EMF buffer that has no drawing operation has invalid
128 // bounds. Instead of having an (0,0) size, it has a (-1,-1) size. Detect
129 // this special case and returns an empty Rect instead of an invalid one.
130 return gfx::Rect();
131 }
132 return gfx::Rect(header.rclBounds.left,
133 header.rclBounds.top,
134 header.rclBounds.right - header.rclBounds.left,
135 header.rclBounds.bottom - header.rclBounds.top);
136 }
137
138 bool Emf::StartPage() {
139 DCHECK(hdc_);
140 if (!hdc_)
141 return false;
142 PageBreakRecord record(PageBreakRecord::START_PAGE);
143 return !!GdiComment(hdc_, sizeof(record),
144 reinterpret_cast<const BYTE *>(&record));
145 }
146
64 bool Emf::CreateDc(HDC sibling, const RECT* rect) { 147 bool Emf::CreateDc(HDC sibling, const RECT* rect) {
65 DCHECK(!emf_ && !hdc_); 148 DCHECK(!emf_ && !hdc_);
66 hdc_ = CreateEnhMetaFile(sibling, NULL, rect, NULL); 149 hdc_ = CreateEnhMetaFile(sibling, NULL, rect, NULL);
67 DCHECK(hdc_); 150 DCHECK(hdc_);
68 return hdc_ != NULL; 151 return hdc_ != NULL;
69 } 152 }
70 153
71 bool Emf::CreateFileBackedDc(HDC sibling, const RECT* rect, 154 bool Emf::CreateFileBackedDc(HDC sibling,
155 const RECT* rect,
72 const FilePath& path) { 156 const FilePath& path) {
73 DCHECK(!emf_ && !hdc_); 157 DCHECK(!emf_ && !hdc_);
74 DCHECK(!path.empty()); 158 DCHECK(!path.empty());
75 hdc_ = CreateEnhMetaFile(sibling, path.value().c_str(), rect, NULL); 159 hdc_ = CreateEnhMetaFile(sibling, path.value().c_str(), rect, NULL);
76 DCHECK(hdc_); 160 DCHECK(hdc_);
77 return hdc_ != NULL; 161 return hdc_ != NULL;
78 } 162 }
79 163
80 bool Emf::CreateFromFile(const FilePath& metafile_path) { 164 bool Emf::CreateFromFile(const FilePath& metafile_path) {
81 DCHECK(!emf_ && !hdc_); 165 DCHECK(!emf_ && !hdc_);
82 emf_ = GetEnhMetaFile(metafile_path.value().c_str()); 166 emf_ = GetEnhMetaFile(metafile_path.value().c_str());
83 DCHECK(emf_); 167 DCHECK(emf_);
84 return emf_ != NULL; 168 return emf_ != NULL;
85 } 169 }
86 170
87 171
88 bool Emf::CloseDc() { 172 bool Emf::CloseDc() {
vandebo (ex-Chrome) 2011/03/12 01:21:06 CloseDC should be Close(), not CloseEmf -- CloseEm
dpapad 2011/03/14 18:02:38 Done.
89 DCHECK(!emf_ && hdc_); 173 DCHECK(!emf_ && hdc_);
90 emf_ = CloseEnhMetaFile(hdc_); 174 emf_ = CloseEnhMetaFile(hdc_);
91 DCHECK(emf_); 175 DCHECK(emf_);
92 hdc_ = NULL; 176 hdc_ = NULL;
93 return emf_ != NULL; 177 return emf_ != NULL;
94 } 178 }
95 179
96 void Emf::CloseEmf() {
97 DCHECK(!hdc_);
98 if (emf_) {
99 DeleteEnhMetaFile(emf_);
100 emf_ = NULL;
101 }
102 }
103
104 bool Emf::Playback(HDC hdc, const RECT* rect) const { 180 bool Emf::Playback(HDC hdc, const RECT* rect) const {
105 DCHECK(emf_ && !hdc_); 181 DCHECK(emf_ && !hdc_);
106 RECT bounds; 182 RECT bounds;
107 if (!rect) { 183 if (!rect) {
108 // Get the natural bounds of the EMF buffer. 184 // Get the natural bounds of the EMF buffer.
109 bounds = GetBounds().ToRECT(); 185 bounds = GetPageBounds(1).ToRECT();
110 rect = &bounds; 186 rect = &bounds;
111 } 187 }
112 return PlayEnhMetaFile(hdc, emf_, rect) != 0; 188 return PlayEnhMetaFile(hdc, emf_, rect) != 0;
113 } 189 }
114 190
115 bool Emf::SafePlayback(HDC context) const { 191 bool Emf::SafePlayback(HDC context) const {
116 DCHECK(emf_ && !hdc_); 192 DCHECK(emf_ && !hdc_);
117 XFORM base_matrix; 193 XFORM base_matrix;
118 if (!GetWorldTransform(context, &base_matrix)) { 194 if (!GetWorldTransform(context, &base_matrix)) {
119 NOTREACHED(); 195 NOTREACHED();
120 return false; 196 return false;
121 } 197 }
122 return EnumEnhMetaFile(context, 198 return EnumEnhMetaFile(context,
123 emf_, 199 emf_,
124 &Emf::SafePlaybackProc, 200 &Emf::SafePlaybackProc,
125 reinterpret_cast<void*>(&base_matrix), 201 reinterpret_cast<void*>(&base_matrix),
126 &GetBounds().ToRECT()) != 0; 202 &GetPageBounds(1).ToRECT()) != 0;
127 }
128
129 gfx::Rect Emf::GetBounds() const {
130 DCHECK(emf_ && !hdc_);
131 ENHMETAHEADER header;
132 if (GetEnhMetaFileHeader(emf_, sizeof(header), &header) != sizeof(header)) {
133 NOTREACHED();
134 return gfx::Rect();
135 }
136 if (header.rclBounds.left == 0 &&
137 header.rclBounds.top == 0 &&
138 header.rclBounds.right == -1 &&
139 header.rclBounds.bottom == -1) {
140 // A freshly created EMF buffer that has no drawing operation has invalid
141 // bounds. Instead of having an (0,0) size, it has a (-1,-1) size. Detect
142 // this special case and returns an empty Rect instead of an invalid one.
143 return gfx::Rect();
144 }
145 return gfx::Rect(header.rclBounds.left,
146 header.rclBounds.top,
147 header.rclBounds.right - header.rclBounds.left,
148 header.rclBounds.bottom - header.rclBounds.top);
149 }
150
151 uint32 Emf::GetDataSize() const {
152 DCHECK(emf_ && !hdc_);
153 return GetEnhMetaFileBits(emf_, 0, NULL);
154 }
155
156 bool Emf::GetData(void* buffer, uint32 size) const {
157 DCHECK(emf_ && !hdc_);
158 DCHECK(buffer && size);
159 uint32 size2 =
160 GetEnhMetaFileBits(emf_, size, reinterpret_cast<BYTE*>(buffer));
161 DCHECK(size2 == size);
162 return size2 == size && size2 != 0;
163 } 203 }
164 204
165 bool Emf::GetData(std::vector<uint8>* buffer) const { 205 bool Emf::GetData(std::vector<uint8>* buffer) const {
166 uint32 size = GetDataSize(); 206 uint32 size = GetDataSize();
167 if (!size) 207 if (!size)
168 return false; 208 return false;
169 209
170 buffer->resize(size); 210 buffer->resize(size);
171 if (!GetData(&buffer->front(), size)) 211 if (!GetData(&buffer->front(), size))
172 return false; 212 return false;
173 return true; 213 return true;
174 } 214 }
175 215
176 bool Emf::SaveTo(const std::wstring& filename) const {
177 HANDLE file = CreateFile(filename.c_str(), GENERIC_WRITE,
178 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
179 CREATE_ALWAYS, 0, NULL);
180 if (file == INVALID_HANDLE_VALUE)
181 return false;
182
183 bool success = false;
184 std::vector<uint8> buffer;
185 if (GetData(&buffer)) {
186 DWORD written = 0;
187 if (WriteFile(file, &*buffer.begin(), static_cast<DWORD>(buffer.size()),
188 &written, NULL) &&
189 written == buffer.size()) {
190 success = true;
191 }
192 }
193 CloseHandle(file);
194 return success;
195 }
196
197 int CALLBACK Emf::SafePlaybackProc(HDC hdc, 216 int CALLBACK Emf::SafePlaybackProc(HDC hdc,
198 HANDLETABLE* handle_table, 217 HANDLETABLE* handle_table,
199 const ENHMETARECORD* record, 218 const ENHMETARECORD* record,
200 int objects_count, 219 int objects_count,
201 LPARAM param) { 220 LPARAM param) {
202 const XFORM* base_matrix = reinterpret_cast<const XFORM*>(param); 221 const XFORM* base_matrix = reinterpret_cast<const XFORM*>(param);
203 EnumerationContext context; 222 EnumerationContext context;
204 context.handle_table = handle_table; 223 context.handle_table = handle_table;
205 context.objects_count = objects_count; 224 context.objects_count = objects_count;
206 context.hdc = hdc; 225 context.hdc = hdc;
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 break; 421 break;
403 } 422 }
404 default: { 423 default: {
405 res = Play(); 424 res = Play();
406 break; 425 break;
407 } 426 }
408 } 427 }
409 return res; 428 return res;
410 } 429 }
411 430
412 bool Emf::StartPage() {
413 DCHECK(hdc_);
414 if (!hdc_)
415 return false;
416 PageBreakRecord record(PageBreakRecord::START_PAGE);
417 return !!GdiComment(hdc_, sizeof(record),
418 reinterpret_cast<const BYTE *>(&record));
419 }
420
421 bool Emf::EndPage() {
422 DCHECK(hdc_);
423 if (!hdc_)
424 return false;
425 PageBreakRecord record(PageBreakRecord::END_PAGE);
426 return !!GdiComment(hdc_, sizeof(record),
427 reinterpret_cast<const BYTE *>(&record));
428 }
429
430
431 Emf::Enumerator::Enumerator(const Emf& emf, HDC context, const RECT* rect) { 431 Emf::Enumerator::Enumerator(const Emf& emf, HDC context, const RECT* rect) {
432 context_.handle_table = NULL; 432 context_.handle_table = NULL;
433 context_.objects_count = 0; 433 context_.objects_count = 0;
434 context_.hdc = NULL; 434 context_.hdc = NULL;
435 items_.clear(); 435 items_.clear();
436 if (!EnumEnhMetaFile(context, 436 if (!EnumEnhMetaFile(context,
437 emf.emf(), 437 emf.emf(),
438 &Emf::Enumerator::EnhMetaFileProc, 438 &Emf::Enumerator::EnhMetaFileProc,
439 reinterpret_cast<void*>(this), 439 reinterpret_cast<void*>(this),
440 rect)) { 440 rect)) {
(...skipping 26 matching lines...) Expand all
467 } else { 467 } else {
468 DCHECK_EQ(emf.context_.handle_table, handle_table); 468 DCHECK_EQ(emf.context_.handle_table, handle_table);
469 DCHECK_EQ(emf.context_.objects_count, objects_count); 469 DCHECK_EQ(emf.context_.objects_count, objects_count);
470 DCHECK_EQ(emf.context_.hdc, hdc); 470 DCHECK_EQ(emf.context_.hdc, hdc);
471 } 471 }
472 emf.items_.push_back(Record(&emf.context_, record)); 472 emf.items_.push_back(Record(&emf.context_, record));
473 return 1; 473 return 1;
474 } 474 }
475 475
476 } // namespace printing 476 } // namespace printing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698