| 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 "base/files/file.h" | 7 #include "base/files/file.h" |
| 8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/win/scoped_gdi_object.h" | 11 #include "base/win/scoped_gdi_object.h" |
| 12 #include "base/win/scoped_hdc.h" | 12 #include "base/win/scoped_hdc.h" |
| 13 #include "base/win/scoped_select_object.h" | 13 #include "base/win/scoped_select_object.h" |
| 14 #include "skia/ext/vector_platform_device_emf_win.h" | 14 #include "skia/ext/vector_platform_device_emf_win.h" |
| 15 #include "third_party/skia/include/core/SkBitmap.h" | 15 #include "third_party/skia/include/core/SkBitmap.h" |
| 16 #include "ui/gfx/codec/jpeg_codec.h" | 16 #include "ui/gfx/codec/jpeg_codec.h" |
| 17 #include "ui/gfx/codec/png_codec.h" | 17 #include "ui/gfx/codec/png_codec.h" |
| 18 #include "ui/gfx/gdi_util.h" | 18 #include "ui/gfx/gdi_util.h" |
| 19 #include "ui/gfx/rect.h" | 19 #include "ui/gfx/rect.h" |
| 20 #include "ui/gfx/size.h" | 20 #include "ui/gfx/size.h" |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| 23 | 23 |
| 24 const int kCustomGdiCommentSignature = 0xdeadbabe; | |
| 25 struct PageBreakRecord { | |
| 26 int signature; | |
| 27 enum PageBreakType { | |
| 28 START_PAGE, | |
| 29 END_PAGE, | |
| 30 } type; | |
| 31 explicit PageBreakRecord(PageBreakType type_in) | |
| 32 : signature(kCustomGdiCommentSignature), type(type_in) { | |
| 33 } | |
| 34 bool IsValid() const { | |
| 35 return (signature == kCustomGdiCommentSignature) && | |
| 36 (type >= START_PAGE) && (type <= END_PAGE); | |
| 37 } | |
| 38 }; | |
| 39 | |
| 40 int CALLBACK IsAlphaBlendUsedEnumProc(HDC, | 24 int CALLBACK IsAlphaBlendUsedEnumProc(HDC, |
| 41 HANDLETABLE*, | 25 HANDLETABLE*, |
| 42 const ENHMETARECORD *record, | 26 const ENHMETARECORD *record, |
| 43 int, | 27 int, |
| 44 LPARAM data) { | 28 LPARAM data) { |
| 45 bool* result = reinterpret_cast<bool*>(data); | 29 bool* result = reinterpret_cast<bool*>(data); |
| 46 if (!result) | 30 if (!result) |
| 47 return 0; | 31 return 0; |
| 48 switch (record->iType) { | 32 switch (record->iType) { |
| 49 case EMR_ALPHABLEND: { | 33 case EMR_ALPHABLEND: { |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 int size) { | 143 int size) { |
| 160 BOOL supported = FALSE; | 144 BOOL supported = FALSE; |
| 161 if (ExtEscape(dc, QUERYESCSUPPORT, sizeof(escape), | 145 if (ExtEscape(dc, QUERYESCSUPPORT, sizeof(escape), |
| 162 reinterpret_cast<LPCSTR>(&escape), 0, 0) > 0) { | 146 reinterpret_cast<LPCSTR>(&escape), 0, 0) > 0) { |
| 163 ExtEscape(dc, escape, size, reinterpret_cast<LPCSTR>(bits), | 147 ExtEscape(dc, escape, size, reinterpret_cast<LPCSTR>(bits), |
| 164 sizeof(supported), reinterpret_cast<LPSTR>(&supported)); | 148 sizeof(supported), reinterpret_cast<LPSTR>(&supported)); |
| 165 } | 149 } |
| 166 return !!supported; | 150 return !!supported; |
| 167 } | 151 } |
| 168 | 152 |
| 169 Emf::Emf() : emf_(NULL), hdc_(NULL), page_count_(0) { | 153 Emf::Emf() : emf_(NULL), hdc_(NULL) { |
| 170 } | 154 } |
| 171 | 155 |
| 172 Emf::~Emf() { | 156 Emf::~Emf() { |
| 173 Close(); | 157 Close(); |
| 174 } | 158 } |
| 175 | 159 |
| 176 void Emf::Close() { | 160 void Emf::Close() { |
| 177 DCHECK(!hdc_); | 161 DCHECK(!hdc_); |
| 178 if (emf_) | 162 if (emf_) |
| 179 DeleteEnhMetaFile(emf_); | 163 DeleteEnhMetaFile(emf_); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 | 213 |
| 230 bool Emf::SafePlayback(HDC context) const { | 214 bool Emf::SafePlayback(HDC context) const { |
| 231 DCHECK(emf_ && !hdc_); | 215 DCHECK(emf_ && !hdc_); |
| 232 XFORM base_matrix; | 216 XFORM base_matrix; |
| 233 if (!GetWorldTransform(context, &base_matrix)) { | 217 if (!GetWorldTransform(context, &base_matrix)) { |
| 234 NOTREACHED(); | 218 NOTREACHED(); |
| 235 return false; | 219 return false; |
| 236 } | 220 } |
| 237 Emf::EnumerationContext playback_context; | 221 Emf::EnumerationContext playback_context; |
| 238 playback_context.base_matrix = &base_matrix; | 222 playback_context.base_matrix = &base_matrix; |
| 239 RECT rect = GetPageBounds(1).ToRECT(); | 223 gfx::Rect bound = GetPageBounds(1); |
| 240 return EnumEnhMetaFile(context, | 224 RECT rect = bound.ToRECT(); |
| 225 return bound.IsEmpty() || |
| 226 EnumEnhMetaFile(context, |
| 241 emf_, | 227 emf_, |
| 242 &Emf::SafePlaybackProc, | 228 &Emf::SafePlaybackProc, |
| 243 reinterpret_cast<void*>(&playback_context), | 229 reinterpret_cast<void*>(&playback_context), |
| 244 &rect) != 0; | 230 &rect) != 0; |
| 245 } | 231 } |
| 246 | 232 |
| 247 gfx::Rect Emf::GetPageBounds(unsigned int page_number) const { | 233 gfx::Rect Emf::GetPageBounds(unsigned int page_number) const { |
| 248 DCHECK(emf_ && !hdc_); | 234 DCHECK(emf_ && !hdc_); |
| 249 DCHECK_EQ(1U, page_number); | 235 DCHECK_EQ(1U, page_number); |
| 250 ENHMETAHEADER header; | 236 ENHMETAHEADER header; |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 default: | 434 default: |
| 449 res = false; | 435 res = false; |
| 450 break; | 436 break; |
| 451 } | 437 } |
| 452 break; | 438 break; |
| 453 } | 439 } |
| 454 case EMR_SETLAYOUT: | 440 case EMR_SETLAYOUT: |
| 455 // Ignore it. | 441 // Ignore it. |
| 456 res = true; | 442 res = true; |
| 457 break; | 443 break; |
| 458 case EMR_GDICOMMENT: { | |
| 459 const EMRGDICOMMENT* comment_record = | |
| 460 reinterpret_cast<const EMRGDICOMMENT*>(record()); | |
| 461 if (comment_record->cbData == sizeof(PageBreakRecord)) { | |
| 462 const PageBreakRecord* page_break_record = | |
| 463 reinterpret_cast<const PageBreakRecord*>(comment_record->Data); | |
| 464 if (page_break_record && page_break_record->IsValid()) { | |
| 465 if (page_break_record->type == PageBreakRecord::START_PAGE) { | |
| 466 res = !!::StartPage(context->hdc); | |
| 467 DCHECK_EQ(0, context->dc_on_page_start); | |
| 468 context->dc_on_page_start = ::SaveDC(context->hdc); | |
| 469 } else if (page_break_record->type == PageBreakRecord::END_PAGE) { | |
| 470 DCHECK_NE(0, context->dc_on_page_start); | |
| 471 ::RestoreDC(context->hdc, context->dc_on_page_start); | |
| 472 context->dc_on_page_start = 0; | |
| 473 res = !!::EndPage(context->hdc); | |
| 474 } else { | |
| 475 res = false; | |
| 476 NOTREACHED(); | |
| 477 } | |
| 478 } else { | |
| 479 res = Play(context); | |
| 480 } | |
| 481 } else { | |
| 482 res = true; | |
| 483 } | |
| 484 break; | |
| 485 } | |
| 486 default: { | 444 default: { |
| 487 res = Play(context); | 445 res = Play(context); |
| 488 break; | 446 break; |
| 489 } | 447 } |
| 490 } | 448 } |
| 491 return res; | 449 return res; |
| 492 } | 450 } |
| 493 | 451 |
| 494 SkBaseDevice* Emf::StartPageForVectorCanvas( | 452 SkBaseDevice* Emf::StartPageForVectorCanvas( |
| 495 const gfx::Size& page_size, const gfx::Rect& content_area, | 453 const gfx::Size& page_size, const gfx::Rect& content_area, |
| 496 const float& scale_factor) { | 454 const float& scale_factor) { |
| 497 if (!StartPage(page_size, content_area, scale_factor)) | 455 if (!StartPage(page_size, content_area, scale_factor)) |
| 498 return NULL; | 456 return NULL; |
| 499 | 457 |
| 500 return skia::VectorPlatformDeviceEmf::CreateDevice(page_size.width(), | 458 return skia::VectorPlatformDeviceEmf::CreateDevice(page_size.width(), |
| 501 page_size.height(), | 459 page_size.height(), |
| 502 true, hdc_); | 460 true, hdc_); |
| 503 } | 461 } |
| 504 | 462 |
| 505 bool Emf::StartPage(const gfx::Size& /*page_size*/, | 463 bool Emf::StartPage(const gfx::Size& /*page_size*/, |
| 506 const gfx::Rect& /*content_area*/, | 464 const gfx::Rect& /*content_area*/, |
| 507 const float& /*scale_factor*/) { | 465 const float& /*scale_factor*/) { |
| 508 DCHECK(hdc_); | 466 return true; |
| 509 if (!hdc_) | |
| 510 return false; | |
| 511 page_count_++; | |
| 512 PageBreakRecord record(PageBreakRecord::START_PAGE); | |
| 513 return !!GdiComment(hdc_, sizeof(record), | |
| 514 reinterpret_cast<const BYTE *>(&record)); | |
| 515 } | 467 } |
| 516 | 468 |
| 517 bool Emf::FinishPage() { | 469 bool Emf::FinishPage() { |
| 518 DCHECK(hdc_); | 470 return true; |
| 519 if (!hdc_) | |
| 520 return false; | |
| 521 PageBreakRecord record(PageBreakRecord::END_PAGE); | |
| 522 return !!GdiComment(hdc_, sizeof(record), | |
| 523 reinterpret_cast<const BYTE *>(&record)); | |
| 524 } | 471 } |
| 525 | 472 |
| 526 Emf::Enumerator::Enumerator(const Emf& emf, HDC context, const RECT* rect) { | 473 Emf::Enumerator::Enumerator(const Emf& emf, HDC context, const RECT* rect) { |
| 527 items_.clear(); | 474 items_.clear(); |
| 528 if (!EnumEnhMetaFile(context, | 475 if (!EnumEnhMetaFile(context, |
| 529 emf.emf(), | 476 emf.emf(), |
| 530 &Emf::Enumerator::EnhMetaFileProc, | 477 &Emf::Enumerator::EnhMetaFileProc, |
| 531 reinterpret_cast<void*>(this), | 478 reinterpret_cast<void*>(this), |
| 532 rect)) { | 479 rect)) { |
| 533 NOTREACHED(); | 480 NOTREACHED(); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 RECT rect = page_bounds.ToRECT(); | 590 RECT rect = page_bounds.ToRECT(); |
| 644 ::EnumEnhMetaFile(hdc, emf(), &RasterizeAlphaBlendProc, &bitmap_dc, &rect); | 591 ::EnumEnhMetaFile(hdc, emf(), &RasterizeAlphaBlendProc, &bitmap_dc, &rect); |
| 645 | 592 |
| 646 result->FinishDocument(); | 593 result->FinishDocument(); |
| 647 | 594 |
| 648 return result.Pass(); | 595 return result.Pass(); |
| 649 } | 596 } |
| 650 | 597 |
| 651 | 598 |
| 652 } // namespace printing | 599 } // namespace printing |
| OLD | NEW |