OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
| 9 #include <algorithm> |
9 #include <memory> | 10 #include <memory> |
10 | 11 |
11 #include "base/files/file.h" | 12 #include "base/files/file.h" |
12 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
13 #include "base/logging.h" | 14 #include "base/logging.h" |
14 #include "base/macros.h" | 15 #include "base/macros.h" |
| 16 #include "base/memory/ptr_util.h" |
15 #include "base/win/scoped_gdi_object.h" | 17 #include "base/win/scoped_gdi_object.h" |
16 #include "base/win/scoped_hdc.h" | 18 #include "base/win/scoped_hdc.h" |
17 #include "base/win/scoped_select_object.h" | 19 #include "base/win/scoped_select_object.h" |
18 #include "skia/ext/skia_utils_win.h" | 20 #include "skia/ext/skia_utils_win.h" |
19 #include "third_party/skia/include/core/SkBitmap.h" | 21 #include "third_party/skia/include/core/SkBitmap.h" |
20 #include "ui/gfx/codec/jpeg_codec.h" | 22 #include "ui/gfx/codec/jpeg_codec.h" |
21 #include "ui/gfx/codec/png_codec.h" | 23 #include "ui/gfx/codec/png_codec.h" |
22 #include "ui/gfx/geometry/rect.h" | 24 #include "ui/gfx/geometry/rect.h" |
23 #include "ui/gfx/geometry/size.h" | 25 #include "ui/gfx/geometry/size.h" |
24 | 26 |
| 27 namespace printing { |
| 28 |
25 namespace { | 29 namespace { |
26 | 30 |
27 int CALLBACK IsAlphaBlendUsedEnumProc(HDC, | 31 int CALLBACK IsAlphaBlendUsedEnumProc(HDC, |
28 HANDLETABLE*, | 32 HANDLETABLE*, |
29 const ENHMETARECORD *record, | 33 const ENHMETARECORD *record, |
30 int, | 34 int, |
31 LPARAM data) { | 35 LPARAM data) { |
32 bool* result = reinterpret_cast<bool*>(data); | 36 bool* result = reinterpret_cast<bool*>(data); |
33 if (!result) | 37 if (!result) |
34 return 0; | 38 return 0; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 // Play this command to the metafile DC. | 92 // Play this command to the metafile DC. |
89 ::PlayEnhMetaFileRecord(metafile_dc, handle_table, record, num_objects); | 93 ::PlayEnhMetaFileRecord(metafile_dc, handle_table, record, num_objects); |
90 break; | 94 break; |
91 } | 95 } |
92 return 1; // Continue enumeration | 96 return 1; // Continue enumeration |
93 } | 97 } |
94 | 98 |
95 // Bitmapt for rasterization. | 99 // Bitmapt for rasterization. |
96 class RasterBitmap { | 100 class RasterBitmap { |
97 public: | 101 public: |
98 explicit RasterBitmap(const gfx::Size& raster_size) | 102 explicit RasterBitmap(const gfx::Size& raster_size) : saved_object_(nullptr) { |
99 : saved_object_(NULL) { | 103 context_.Set(::CreateCompatibleDC(nullptr)); |
100 context_.Set(::CreateCompatibleDC(NULL)); | |
101 if (!context_.IsValid()) { | 104 if (!context_.IsValid()) { |
102 NOTREACHED() << "Bitmap DC creation failed"; | 105 NOTREACHED() << "Bitmap DC creation failed"; |
103 return; | 106 return; |
104 } | 107 } |
105 ::SetGraphicsMode(context_.Get(), GM_ADVANCED); | 108 ::SetGraphicsMode(context_.Get(), GM_ADVANCED); |
106 void* bits = NULL; | 109 void* bits = nullptr; |
107 gfx::Rect bitmap_rect(raster_size); | 110 gfx::Rect bitmap_rect(raster_size); |
108 skia::CreateBitmapHeader(raster_size.width(), raster_size.height(), | 111 skia::CreateBitmapHeader(raster_size.width(), raster_size.height(), |
109 &header_.bmiHeader); | 112 &header_.bmiHeader); |
110 bitmap_.reset(CreateDIBSection(context_.Get(), &header_, DIB_RGB_COLORS, | 113 bitmap_.reset(CreateDIBSection(context_.Get(), &header_, DIB_RGB_COLORS, |
111 &bits, NULL, 0)); | 114 &bits, nullptr, 0)); |
112 if (!bitmap_.is_valid()) | 115 if (!bitmap_.is_valid()) |
113 NOTREACHED() << "Raster bitmap creation for printing failed"; | 116 NOTREACHED() << "Raster bitmap creation for printing failed"; |
114 | 117 |
115 saved_object_ = ::SelectObject(context_.Get(), bitmap_.get()); | 118 saved_object_ = ::SelectObject(context_.Get(), bitmap_.get()); |
116 RECT rect = bitmap_rect.ToRECT(); | 119 RECT rect = bitmap_rect.ToRECT(); |
117 ::FillRect(context_.Get(), &rect, | 120 ::FillRect(context_.Get(), &rect, |
118 static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH))); | 121 static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH))); |
119 } | 122 } |
120 | 123 |
121 ~RasterBitmap() { | 124 ~RasterBitmap() { |
122 ::SelectObject(context_.Get(), saved_object_); | 125 ::SelectObject(context_.Get(), saved_object_); |
123 } | 126 } |
124 | 127 |
125 HDC context() const { | 128 HDC context() const { |
126 return context_.Get(); | 129 return context_.Get(); |
127 } | 130 } |
128 | 131 |
129 base::win::ScopedCreateDC context_; | 132 base::win::ScopedCreateDC context_; |
130 BITMAPINFO header_; | 133 BITMAPINFO header_; |
131 base::win::ScopedBitmap bitmap_; | 134 base::win::ScopedBitmap bitmap_; |
132 HGDIOBJ saved_object_; | 135 HGDIOBJ saved_object_; |
133 | 136 |
134 private: | 137 private: |
135 DISALLOW_COPY_AND_ASSIGN(RasterBitmap); | 138 DISALLOW_COPY_AND_ASSIGN(RasterBitmap); |
136 }; | 139 }; |
137 | 140 |
138 | |
139 | |
140 } // namespace | |
141 | |
142 namespace printing { | |
143 | |
144 bool DIBFormatNativelySupported(HDC dc, uint32_t escape, const BYTE* bits, | 141 bool DIBFormatNativelySupported(HDC dc, uint32_t escape, const BYTE* bits, |
145 int size) { | 142 int size) { |
146 BOOL supported = FALSE; | 143 BOOL supported = FALSE; |
147 if (ExtEscape(dc, QUERYESCSUPPORT, sizeof(escape), | 144 if (ExtEscape(dc, QUERYESCSUPPORT, sizeof(escape), |
148 reinterpret_cast<LPCSTR>(&escape), 0, 0) > 0) { | 145 reinterpret_cast<LPCSTR>(&escape), 0, 0) > 0) { |
149 ExtEscape(dc, escape, size, reinterpret_cast<LPCSTR>(bits), | 146 ExtEscape(dc, escape, size, reinterpret_cast<LPCSTR>(bits), |
150 sizeof(supported), reinterpret_cast<LPSTR>(&supported)); | 147 sizeof(supported), reinterpret_cast<LPSTR>(&supported)); |
151 } | 148 } |
152 return !!supported; | 149 return !!supported; |
153 } | 150 } |
154 | 151 |
155 Emf::Emf() : emf_(NULL), hdc_(NULL) { | 152 } // namespace |
156 } | 153 |
| 154 Emf::Emf() : emf_(nullptr), hdc_(nullptr) {} |
157 | 155 |
158 Emf::~Emf() { | 156 Emf::~Emf() { |
159 Close(); | 157 Close(); |
160 } | 158 } |
161 | 159 |
162 void Emf::Close() { | 160 void Emf::Close() { |
163 DCHECK(!hdc_); | 161 DCHECK(!hdc_); |
164 if (emf_) | 162 if (emf_) |
165 DeleteEnhMetaFile(emf_); | 163 DeleteEnhMetaFile(emf_); |
166 emf_ = NULL; | 164 emf_ = nullptr; |
167 } | 165 } |
168 | 166 |
169 bool Emf::InitToFile(const base::FilePath& metafile_path) { | 167 bool Emf::InitToFile(const base::FilePath& metafile_path) { |
170 DCHECK(!emf_ && !hdc_); | 168 DCHECK(!emf_ && !hdc_); |
171 hdc_ = CreateEnhMetaFile(NULL, metafile_path.value().c_str(), NULL, NULL); | 169 hdc_ = CreateEnhMetaFile(nullptr, metafile_path.value().c_str(), nullptr, |
| 170 nullptr); |
172 DCHECK(hdc_); | 171 DCHECK(hdc_); |
173 return hdc_ != NULL; | 172 return !!hdc_; |
174 } | 173 } |
175 | 174 |
176 bool Emf::InitFromFile(const base::FilePath& metafile_path) { | 175 bool Emf::InitFromFile(const base::FilePath& metafile_path) { |
177 DCHECK(!emf_ && !hdc_); | 176 DCHECK(!emf_ && !hdc_); |
178 emf_ = GetEnhMetaFile(metafile_path.value().c_str()); | 177 emf_ = GetEnhMetaFile(metafile_path.value().c_str()); |
179 DCHECK(emf_); | 178 DCHECK(emf_); |
180 return emf_ != NULL; | 179 return !!emf_; |
181 } | 180 } |
182 | 181 |
183 bool Emf::Init() { | 182 bool Emf::Init() { |
184 DCHECK(!emf_ && !hdc_); | 183 DCHECK(!emf_ && !hdc_); |
185 hdc_ = CreateEnhMetaFile(NULL, NULL, NULL, NULL); | 184 hdc_ = CreateEnhMetaFile(nullptr, nullptr, nullptr, nullptr); |
186 DCHECK(hdc_); | 185 DCHECK(hdc_); |
187 return hdc_ != NULL; | 186 return !!hdc_; |
188 } | 187 } |
189 | 188 |
190 bool Emf::InitFromData(const void* src_buffer, uint32_t src_buffer_size) { | 189 bool Emf::InitFromData(const void* src_buffer, uint32_t src_buffer_size) { |
191 DCHECK(!emf_ && !hdc_); | 190 DCHECK(!emf_ && !hdc_); |
192 emf_ = SetEnhMetaFileBits(src_buffer_size, | 191 emf_ = SetEnhMetaFileBits(src_buffer_size, |
193 reinterpret_cast<const BYTE*>(src_buffer)); | 192 reinterpret_cast<const BYTE*>(src_buffer)); |
194 return emf_ != NULL; | 193 return !!emf_; |
195 } | 194 } |
196 | 195 |
197 bool Emf::FinishDocument() { | 196 bool Emf::FinishDocument() { |
198 DCHECK(!emf_ && hdc_); | 197 DCHECK(!emf_ && hdc_); |
199 emf_ = CloseEnhMetaFile(hdc_); | 198 emf_ = CloseEnhMetaFile(hdc_); |
200 DCHECK(emf_); | 199 DCHECK(emf_); |
201 hdc_ = NULL; | 200 hdc_ = nullptr; |
202 return emf_ != NULL; | 201 return !!emf_; |
203 } | 202 } |
204 | 203 |
205 bool Emf::Playback(HDC hdc, const RECT* rect) const { | 204 bool Emf::Playback(HDC hdc, const RECT* rect) const { |
206 DCHECK(emf_ && !hdc_); | 205 DCHECK(emf_ && !hdc_); |
207 RECT bounds; | 206 RECT bounds; |
208 if (!rect) { | 207 if (!rect) { |
209 // Get the natural bounds of the EMF buffer. | 208 // Get the natural bounds of the EMF buffer. |
210 bounds = GetPageBounds(1).ToRECT(); | 209 bounds = GetPageBounds(1).ToRECT(); |
211 rect = &bounds; | 210 rect = &bounds; |
212 } | 211 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 unsigned int Emf::GetPageCount() const { | 250 unsigned int Emf::GetPageCount() const { |
252 return 1; | 251 return 1; |
253 } | 252 } |
254 | 253 |
255 HDC Emf::context() const { | 254 HDC Emf::context() const { |
256 return hdc_; | 255 return hdc_; |
257 } | 256 } |
258 | 257 |
259 uint32_t Emf::GetDataSize() const { | 258 uint32_t Emf::GetDataSize() const { |
260 DCHECK(emf_ && !hdc_); | 259 DCHECK(emf_ && !hdc_); |
261 return GetEnhMetaFileBits(emf_, 0, NULL); | 260 return GetEnhMetaFileBits(emf_, 0, nullptr); |
262 } | 261 } |
263 | 262 |
264 bool Emf::GetData(void* buffer, uint32_t size) const { | 263 bool Emf::GetData(void* buffer, uint32_t size) const { |
265 DCHECK(emf_ && !hdc_); | 264 DCHECK(emf_ && !hdc_); |
266 DCHECK(buffer && size); | 265 DCHECK(buffer && size); |
267 uint32_t size2 = | 266 uint32_t size2 = |
268 GetEnhMetaFileBits(emf_, size, reinterpret_cast<BYTE*>(buffer)); | 267 GetEnhMetaFileBits(emf_, size, reinterpret_cast<BYTE*>(buffer)); |
269 DCHECK(size2 == size); | 268 DCHECK(size2 == size); |
270 return size2 == size && size2 != 0; | 269 return size2 == size && size2 != 0; |
271 } | 270 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 // device. | 342 // device. |
344 // TODO(sanjeevr): We should also add JPEG/PNG support for SetSIBitsToDevice | 343 // TODO(sanjeevr): We should also add JPEG/PNG support for SetSIBitsToDevice |
345 // | 344 // |
346 // We also process any custom EMR_GDICOMMENT records which are our | 345 // We also process any custom EMR_GDICOMMENT records which are our |
347 // placeholders for StartPage and EndPage. | 346 // placeholders for StartPage and EndPage. |
348 // Note: I should probably care about view ports and clipping, eventually. | 347 // Note: I should probably care about view ports and clipping, eventually. |
349 bool res = false; | 348 bool res = false; |
350 const XFORM* base_matrix = context->base_matrix; | 349 const XFORM* base_matrix = context->base_matrix; |
351 switch (record()->iType) { | 350 switch (record()->iType) { |
352 case EMR_STRETCHDIBITS: { | 351 case EMR_STRETCHDIBITS: { |
353 const EMRSTRETCHDIBITS * sdib_record = | 352 const EMRSTRETCHDIBITS* sdib_record = |
354 reinterpret_cast<const EMRSTRETCHDIBITS*>(record()); | 353 reinterpret_cast<const EMRSTRETCHDIBITS*>(record()); |
355 const BYTE* record_start = reinterpret_cast<const BYTE *>(record()); | 354 const BYTE* record_start = reinterpret_cast<const BYTE *>(record()); |
356 const BITMAPINFOHEADER *bmih = | 355 const BITMAPINFOHEADER* bmih = reinterpret_cast<const BITMAPINFOHEADER*>( |
357 reinterpret_cast<const BITMAPINFOHEADER *>(record_start + | 356 record_start + sdib_record->offBmiSrc); |
358 sdib_record->offBmiSrc); | |
359 const BYTE* bits = record_start + sdib_record->offBitsSrc; | 357 const BYTE* bits = record_start + sdib_record->offBitsSrc; |
360 bool play_normally = true; | 358 bool play_normally = true; |
361 res = false; | 359 res = false; |
362 HDC hdc = context->hdc; | 360 HDC hdc = context->hdc; |
363 std::unique_ptr<SkBitmap> bitmap; | 361 std::unique_ptr<SkBitmap> bitmap; |
364 if (bmih->biCompression == BI_JPEG) { | 362 if (bmih->biCompression == BI_JPEG) { |
365 if (!DIBFormatNativelySupported(hdc, CHECKJPEGFORMAT, bits, | 363 if (!DIBFormatNativelySupported(hdc, CHECKJPEGFORMAT, bits, |
366 bmih->biSizeImage)) { | 364 bmih->biSizeImage)) { |
367 play_normally = false; | 365 play_normally = false; |
368 bitmap = gfx::JPEGCodec::Decode(bits, bmih->biSizeImage); | 366 bitmap = gfx::JPEGCodec::Decode(bits, bmih->biSizeImage); |
369 } | 367 } |
370 } else if (bmih->biCompression == BI_PNG) { | 368 } else if (bmih->biCompression == BI_PNG) { |
371 if (!DIBFormatNativelySupported(hdc, CHECKPNGFORMAT, bits, | 369 if (!DIBFormatNativelySupported(hdc, CHECKPNGFORMAT, bits, |
372 bmih->biSizeImage)) { | 370 bmih->biSizeImage)) { |
373 play_normally = false; | 371 play_normally = false; |
374 bitmap.reset(new SkBitmap()); | 372 bitmap = base::MakeUnique<SkBitmap>(); |
375 gfx::PNGCodec::Decode(bits, bmih->biSizeImage, bitmap.get()); | 373 gfx::PNGCodec::Decode(bits, bmih->biSizeImage, bitmap.get()); |
376 } | 374 } |
377 } | 375 } |
378 if (!play_normally) { | 376 if (play_normally) { |
| 377 res = Play(context); |
| 378 } else { |
379 DCHECK(bitmap.get()); | 379 DCHECK(bitmap.get()); |
380 if (bitmap.get()) { | 380 if (bitmap.get()) { |
381 SkAutoLockPixels lock(*bitmap.get()); | 381 SkAutoLockPixels lock(*bitmap.get()); |
382 DCHECK_EQ(bitmap->colorType(), kN32_SkColorType); | 382 DCHECK_EQ(bitmap->colorType(), kN32_SkColorType); |
383 const uint32_t* pixels = | 383 const uint32_t* pixels = |
384 static_cast<const uint32_t*>(bitmap->getPixels()); | 384 static_cast<const uint32_t*>(bitmap->getPixels()); |
385 if (pixels == NULL) { | 385 if (!pixels) { |
386 NOTREACHED(); | 386 NOTREACHED(); |
387 return false; | 387 return false; |
388 } | 388 } |
389 BITMAPINFOHEADER bmi = {0}; | 389 BITMAPINFOHEADER bmi = {0}; |
390 skia::CreateBitmapHeader(bitmap->width(), bitmap->height(), &bmi); | 390 skia::CreateBitmapHeader(bitmap->width(), bitmap->height(), &bmi); |
391 res = (0 != StretchDIBits(hdc, sdib_record->xDest, sdib_record->yDest, | 391 res = (0 != StretchDIBits(hdc, sdib_record->xDest, sdib_record->yDest, |
392 sdib_record->cxDest, | 392 sdib_record->cxDest, |
393 sdib_record->cyDest, sdib_record->xSrc, | 393 sdib_record->cyDest, sdib_record->xSrc, |
394 sdib_record->ySrc, | 394 sdib_record->ySrc, |
395 sdib_record->cxSrc, sdib_record->cySrc, | 395 sdib_record->cxSrc, sdib_record->cySrc, |
396 pixels, | 396 pixels, |
397 reinterpret_cast<const BITMAPINFO *>(&bmi), | 397 reinterpret_cast<const BITMAPINFO *>(&bmi), |
398 sdib_record->iUsageSrc, | 398 sdib_record->iUsageSrc, |
399 sdib_record->dwRop)); | 399 sdib_record->dwRop)); |
400 } | 400 } |
401 } else { | |
402 res = Play(context); | |
403 } | 401 } |
404 break; | 402 break; |
405 } | 403 } |
406 case EMR_SETWORLDTRANSFORM: { | 404 case EMR_SETWORLDTRANSFORM: { |
407 DCHECK_EQ(record()->nSize, sizeof(DWORD) * 2 + sizeof(XFORM)); | 405 DCHECK_EQ(record()->nSize, sizeof(DWORD) * 2 + sizeof(XFORM)); |
408 const XFORM* xform = reinterpret_cast<const XFORM*>(record()->dParm); | 406 const XFORM* xform = reinterpret_cast<const XFORM*>(record()->dParm); |
409 HDC hdc = context->hdc; | 407 HDC hdc = context->hdc; |
410 if (base_matrix) { | 408 if (base_matrix) { |
411 res = 0 != SetWorldTransform(hdc, base_matrix) && | 409 res = 0 != SetWorldTransform(hdc, base_matrix) && |
412 ModifyWorldTransform(hdc, xform, MWT_LEFTMULTIPLY); | 410 ModifyWorldTransform(hdc, xform, MWT_LEFTMULTIPLY); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 DCHECK_EQ(emf.context_.handle_table, handle_table); | 506 DCHECK_EQ(emf.context_.handle_table, handle_table); |
509 DCHECK_EQ(emf.context_.objects_count, objects_count); | 507 DCHECK_EQ(emf.context_.objects_count, objects_count); |
510 DCHECK_EQ(emf.context_.hdc, hdc); | 508 DCHECK_EQ(emf.context_.hdc, hdc); |
511 } | 509 } |
512 emf.items_.push_back(Record(record)); | 510 emf.items_.push_back(Record(record)); |
513 return 1; | 511 return 1; |
514 } | 512 } |
515 | 513 |
516 bool Emf::IsAlphaBlendUsed() const { | 514 bool Emf::IsAlphaBlendUsed() const { |
517 bool result = false; | 515 bool result = false; |
518 ::EnumEnhMetaFile(NULL, | 516 ::EnumEnhMetaFile(nullptr, emf(), &IsAlphaBlendUsedEnumProc, &result, |
519 emf(), | 517 nullptr); |
520 &IsAlphaBlendUsedEnumProc, | |
521 &result, | |
522 NULL); | |
523 return result; | 518 return result; |
524 } | 519 } |
525 | 520 |
526 std::unique_ptr<Emf> Emf::RasterizeMetafile(int raster_area_in_pixels) const { | 521 std::unique_ptr<Emf> Emf::RasterizeMetafile(int raster_area_in_pixels) const { |
527 gfx::Rect page_bounds = GetPageBounds(1); | 522 gfx::Rect page_bounds = GetPageBounds(1); |
528 gfx::Size page_size(page_bounds.size()); | 523 gfx::Size page_size(page_bounds.size()); |
529 if (page_size.GetArea() <= 0) { | 524 if (page_size.GetArea() <= 0) { |
530 NOTREACHED() << "Metafile is empty"; | 525 NOTREACHED() << "Metafile is empty"; |
531 page_bounds = gfx::Rect(1, 1); | 526 page_bounds = gfx::Rect(1, 1); |
532 } | 527 } |
533 | 528 |
534 float scale = sqrt( | 529 float scale = sqrt( |
535 static_cast<float>(raster_area_in_pixels) / page_size.GetArea()); | 530 static_cast<float>(raster_area_in_pixels) / page_size.GetArea()); |
536 page_size.set_width(std::max<int>(1, page_size.width() * scale)); | 531 page_size.set_width(std::max<int>(1, page_size.width() * scale)); |
537 page_size.set_height(std::max<int>(1, page_size.height() * scale)); | 532 page_size.set_height(std::max<int>(1, page_size.height() * scale)); |
538 | 533 |
539 | 534 |
540 RasterBitmap bitmap(page_size); | 535 RasterBitmap bitmap(page_size); |
541 | 536 |
542 gfx::Rect bitmap_rect(page_size); | 537 gfx::Rect bitmap_rect(page_size); |
543 RECT rect = bitmap_rect.ToRECT(); | 538 RECT rect = bitmap_rect.ToRECT(); |
544 Playback(bitmap.context(), &rect); | 539 Playback(bitmap.context(), &rect); |
545 | 540 |
546 std::unique_ptr<Emf> result(new Emf); | 541 std::unique_ptr<Emf> result = base::MakeUnique<Emf>(); |
547 result->Init(); | 542 result->Init(); |
548 HDC hdc = result->context(); | 543 HDC hdc = result->context(); |
549 DCHECK(hdc); | 544 DCHECK(hdc); |
550 skia::InitializeDC(hdc); | 545 skia::InitializeDC(hdc); |
551 | 546 |
552 // Params are ignored. | 547 // Params are ignored. |
553 result->StartPage(page_bounds.size(), page_bounds, 1); | 548 result->StartPage(page_bounds.size(), page_bounds, 1); |
554 | 549 |
555 ::ModifyWorldTransform(hdc, NULL, MWT_IDENTITY); | 550 ::ModifyWorldTransform(hdc, nullptr, MWT_IDENTITY); |
556 XFORM xform = { | 551 XFORM xform = { |
557 static_cast<float>(page_bounds.width()) / bitmap_rect.width(), | 552 static_cast<float>(page_bounds.width()) / bitmap_rect.width(), |
558 0, | 553 0, |
559 0, | 554 0, |
560 static_cast<float>(page_bounds.height()) / bitmap_rect.height(), | 555 static_cast<float>(page_bounds.height()) / bitmap_rect.height(), |
561 static_cast<float>(page_bounds.x()), | 556 static_cast<float>(page_bounds.x()), |
562 static_cast<float>(page_bounds.y()), | 557 static_cast<float>(page_bounds.y()), |
563 }; | 558 }; |
564 ::SetWorldTransform(hdc, &xform); | 559 ::SetWorldTransform(hdc, &xform); |
565 ::BitBlt(hdc, 0, 0, bitmap_rect.width(), bitmap_rect.height(), | 560 ::BitBlt(hdc, 0, 0, bitmap_rect.width(), bitmap_rect.height(), |
566 bitmap.context(), bitmap_rect.x(), bitmap_rect.y(), SRCCOPY); | 561 bitmap.context(), bitmap_rect.x(), bitmap_rect.y(), SRCCOPY); |
567 | 562 |
568 result->FinishPage(); | 563 result->FinishPage(); |
569 result->FinishDocument(); | 564 result->FinishDocument(); |
570 | |
571 return result; | 565 return result; |
572 } | 566 } |
573 | 567 |
574 std::unique_ptr<Emf> Emf::RasterizeAlphaBlend() const { | 568 std::unique_ptr<Emf> Emf::RasterizeAlphaBlend() const { |
575 gfx::Rect page_bounds = GetPageBounds(1); | 569 gfx::Rect page_bounds = GetPageBounds(1); |
576 if (page_bounds.size().GetArea() <= 0) { | 570 if (page_bounds.size().GetArea() <= 0) { |
577 NOTREACHED() << "Metafile is empty"; | 571 NOTREACHED() << "Metafile is empty"; |
578 page_bounds = gfx::Rect(1, 1); | 572 page_bounds = gfx::Rect(1, 1); |
579 } | 573 } |
580 | 574 |
581 RasterBitmap bitmap(page_bounds.size()); | 575 RasterBitmap bitmap(page_bounds.size()); |
582 | 576 |
583 // Map metafile page_bounds.x(), page_bounds.y() to bitmap 0, 0. | 577 // Map metafile page_bounds.x(), page_bounds.y() to bitmap 0, 0. |
584 XFORM xform = {1, | 578 XFORM xform = {1, |
585 0, | 579 0, |
586 0, | 580 0, |
587 1, | 581 1, |
588 static_cast<float>(-page_bounds.x()), | 582 static_cast<float>(-page_bounds.x()), |
589 static_cast<float>(-page_bounds.y())}; | 583 static_cast<float>(-page_bounds.y())}; |
590 ::SetWorldTransform(bitmap.context(), &xform); | 584 ::SetWorldTransform(bitmap.context(), &xform); |
591 | 585 |
592 std::unique_ptr<Emf> result(new Emf); | 586 std::unique_ptr<Emf> result = base::MakeUnique<Emf>(); |
593 result->Init(); | 587 result->Init(); |
594 HDC hdc = result->context(); | 588 HDC hdc = result->context(); |
595 DCHECK(hdc); | 589 DCHECK(hdc); |
596 skia::InitializeDC(hdc); | 590 skia::InitializeDC(hdc); |
597 | 591 |
598 HDC bitmap_dc = bitmap.context(); | 592 HDC bitmap_dc = bitmap.context(); |
599 RECT rect = page_bounds.ToRECT(); | 593 RECT rect = page_bounds.ToRECT(); |
600 ::EnumEnhMetaFile(hdc, emf(), &RasterizeAlphaBlendProc, &bitmap_dc, &rect); | 594 ::EnumEnhMetaFile(hdc, emf(), &RasterizeAlphaBlendProc, &bitmap_dc, &rect); |
601 | 595 |
602 result->FinishDocument(); | 596 result->FinishDocument(); |
603 | |
604 return result; | 597 return result; |
605 } | 598 } |
606 | 599 |
607 | |
608 } // namespace printing | 600 } // namespace printing |
OLD | NEW |