| 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 |