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

Side by Side Diff: printing/emf_win.cc

Issue 11078018: Restored partial rasterization for AlphaBlend. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 2 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
« no previous file with comments | « printing/emf_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/file_path.h" 7 #include "base/file_path.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/win/scoped_gdi_object.h" 10 #include "base/win/scoped_gdi_object.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 switch (record->iType) { 47 switch (record->iType) {
48 case EMR_ALPHABLEND: { 48 case EMR_ALPHABLEND: {
49 *result = true; 49 *result = true;
50 return 0; 50 return 0;
51 break; 51 break;
52 } 52 }
53 } 53 }
54 return 1; 54 return 1;
55 } 55 }
56 56
57 int CALLBACK RasterizeAlphaBlendProc(HDC metafile_dc,
58 HANDLETABLE* handle_table,
59 const ENHMETARECORD *record,
60 int num_objects,
61 LPARAM data) {
62 HDC bitmap_dc = *reinterpret_cast<HDC*>(data);
63 // Play this command to the bitmap DC.
64 ::PlayEnhMetaFileRecord(bitmap_dc, handle_table, record, num_objects);
65 switch (record->iType) {
66 case EMR_ALPHABLEND: {
67 const EMRALPHABLEND* alpha_blend =
68 reinterpret_cast<const EMRALPHABLEND*>(record);
69 // Don't modify transformation here.
70 // Old implementation did reset transformations for DC to identity matrix.
71 // That was not correct and cause some bugs, like unexpected cropping.
72 // EMRALPHABLEND is rendered into bitmap and metafile contexts with
73 // current transformation. If we don't touch them here BitBlt will copy
74 // same areas.
75 ::BitBlt(metafile_dc,
76 alpha_blend->xDest,
77 alpha_blend->yDest,
78 alpha_blend->cxDest,
79 alpha_blend->cyDest,
80 bitmap_dc,
81 alpha_blend->xDest,
82 alpha_blend->yDest,
83 SRCCOPY);
84 break;
85 }
86 case EMR_CREATEBRUSHINDIRECT:
87 case EMR_CREATECOLORSPACE:
88 case EMR_CREATECOLORSPACEW:
89 case EMR_CREATEDIBPATTERNBRUSHPT:
90 case EMR_CREATEMONOBRUSH:
91 case EMR_CREATEPALETTE:
92 case EMR_CREATEPEN:
93 case EMR_DELETECOLORSPACE:
94 case EMR_DELETEOBJECT:
95 case EMR_EXTCREATEFONTINDIRECTW:
96 // Play object creation command only once.
97 break;
98
99 default:
100 // Play this command to the metafile DC.
101 ::PlayEnhMetaFileRecord(metafile_dc, handle_table, record, num_objects);
102 break;
103 }
104 return 1; // Continue enumeration
105 }
106
107 // Bitmapt for rasterization.
108 class RasterBitmap {
109 public:
110 explicit RasterBitmap(const gfx::Size& raster_size)
111 : saved_object_(NULL) {
112 context_.Set(::CreateCompatibleDC(NULL));
113 if (!context_) {
114 NOTREACHED() << "Bitmap DC creation failed";
115 return;
116 }
117 ::SetGraphicsMode(context_, GM_ADVANCED);
118 void* bits = NULL;
119 gfx::Rect bitmap_rect(raster_size);
120 gfx::CreateBitmapHeader(raster_size.width(), raster_size.height(),
121 &header_.bmiHeader);
122 bitmap_.Set(::CreateDIBSection(context_, &header_, DIB_RGB_COLORS, &bits,
123 NULL, 0));
124 if (!bitmap_)
125 NOTREACHED() << "Raster bitmap creation for printing failed";
126
127 saved_object_ = ::SelectObject(context_, bitmap_);
128 ::FillRect(context_, &bitmap_rect.ToRECT(),
Timur Iskhodzhanov 2013/03/28 03:49:39 FYI taking an address of a temporary object is not
129 static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH)));
130
131 }
132
133 ~RasterBitmap() {
134 ::SelectObject(context_, saved_object_);
135 }
136
137 HDC context() const {
138 return context_;
139 }
140
141 base::win::ScopedCreateDC context_;
142 BITMAPINFO header_;
143 base::win::ScopedBitmap bitmap_;
144 HGDIOBJ saved_object_;
145
146 private:
147 DISALLOW_COPY_AND_ASSIGN(RasterBitmap);
148 };
149
150
151
57 } // namespace 152 } // namespace
58 153
59 namespace printing { 154 namespace printing {
60 155
61 bool DIBFormatNativelySupported(HDC dc, uint32 escape, const BYTE* bits, 156 bool DIBFormatNativelySupported(HDC dc, uint32 escape, const BYTE* bits,
62 int size) { 157 int size) {
63 BOOL supported = FALSE; 158 BOOL supported = FALSE;
64 if (ExtEscape(dc, QUERYESCSUPPORT, sizeof(escape), 159 if (ExtEscape(dc, QUERYESCSUPPORT, sizeof(escape),
65 reinterpret_cast<LPCSTR>(&escape), 0, 0) > 0) { 160 reinterpret_cast<LPCSTR>(&escape), 0, 0) > 0) {
66 ExtEscape(dc, escape, size, reinterpret_cast<LPCSTR>(bits), 161 ExtEscape(dc, escape, size, reinterpret_cast<LPCSTR>(bits),
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 gfx::Size page_size(page_bounds.size()); 604 gfx::Size page_size(page_bounds.size());
510 if (page_size.GetArea() <= 0) { 605 if (page_size.GetArea() <= 0) {
511 NOTREACHED() << "Metafile is empty"; 606 NOTREACHED() << "Metafile is empty";
512 page_bounds = gfx::Rect(1, 1); 607 page_bounds = gfx::Rect(1, 1);
513 } 608 }
514 609
515 float scale = sqrt(float(raster_area_in_pixels) / page_size.GetArea()); 610 float scale = sqrt(float(raster_area_in_pixels) / page_size.GetArea());
516 page_size.set_width(std::max<int>(1, page_size.width() * scale)); 611 page_size.set_width(std::max<int>(1, page_size.width() * scale));
517 page_size.set_height(std::max<int>(1, page_size.height() * scale)); 612 page_size.set_height(std::max<int>(1, page_size.height() * scale));
518 613
519 base::win::ScopedCreateDC bitmap_dc(::CreateCompatibleDC(NULL));
520 if (!bitmap_dc) {
521 NOTREACHED() << "Bitmap DC creation failed";
522 return NULL;
523 }
524 ::SetGraphicsMode(bitmap_dc, GM_ADVANCED);
525 void* bits = NULL;
526 BITMAPINFO hdr;
527 gfx::CreateBitmapHeader(page_size.width(), page_size.height(),
528 &hdr.bmiHeader);
529 base::win::ScopedBitmap hbitmap(CreateDIBSection(
530 bitmap_dc, &hdr, DIB_RGB_COLORS, &bits, NULL, 0));
531 if (!hbitmap)
532 NOTREACHED() << "Raster bitmap creation for printing failed";
533 614
534 base::win::ScopedSelectObject selectBitmap(bitmap_dc, hbitmap); 615 RasterBitmap bitmap(page_size);
535 RECT rect = { 0, 0, page_size.width(), page_size.height() };
536 HBRUSH white_brush = static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH));
537 FillRect(bitmap_dc, &rect, white_brush);
538 616
539 gfx::Rect bitmap_rect(page_size); 617 gfx::Rect bitmap_rect(page_size);
540 Playback(bitmap_dc, &bitmap_rect.ToRECT()); 618 Playback(bitmap.context(), &bitmap_rect.ToRECT());
541 619
542 scoped_ptr<Emf> result(new Emf); 620 scoped_ptr<Emf> result(new Emf);
543 result->Init(); 621 result->Init();
544 HDC hdc = result->context(); 622 HDC hdc = result->context();
545 DCHECK(hdc); 623 DCHECK(hdc);
546 skia::InitializeDC(hdc); 624 skia::InitializeDC(hdc);
547 625
548 // Params are ignored. 626 // Params are ignored.
549 result->StartPage(page_bounds.size(), page_bounds, 1); 627 result->StartPage(page_bounds.size(), page_bounds, 1);
550 628
551 ::ModifyWorldTransform(hdc, NULL, MWT_IDENTITY); 629 ::ModifyWorldTransform(hdc, NULL, MWT_IDENTITY);
552 XFORM xform = { 630 XFORM xform = {
553 float(page_bounds.width()) / bitmap_rect.width(), 0, 631 float(page_bounds.width()) / bitmap_rect.width(), 0,
554 0, float(page_bounds.height()) / bitmap_rect.height(), 632 0, float(page_bounds.height()) / bitmap_rect.height(),
555 page_bounds.x(), 633 page_bounds.x(),
556 page_bounds.y(), 634 page_bounds.y(),
557 }; 635 };
558 ::SetWorldTransform(hdc, &xform); 636 ::SetWorldTransform(hdc, &xform);
559 ::BitBlt(hdc, 0, 0, bitmap_rect.width(), bitmap_rect.height(), 637 ::BitBlt(hdc, 0, 0, bitmap_rect.width(), bitmap_rect.height(),
560 bitmap_dc, bitmap_rect.x(), bitmap_rect.y(), SRCCOPY); 638 bitmap.context(), bitmap_rect.x(), bitmap_rect.y(), SRCCOPY);
561 639
562 result->FinishPage(); 640 result->FinishPage();
563 result->FinishDocument(); 641 result->FinishDocument();
564 642
565 return result.release(); 643 return result.release();
566 } 644 }
567 645
646 Emf* Emf::RasterizeAlphaBlend() const {
647 gfx::Rect page_bounds = GetPageBounds(1);
648 if (page_bounds.size().GetArea() <= 0) {
649 NOTREACHED() << "Metafile is empty";
650 page_bounds = gfx::Rect(1, 1);
651 }
652
653 RasterBitmap bitmap(page_bounds.size());
654
655 // Map metafile page_bounds.x(), page_bounds.y() to bitmap 0, 0.
656 XFORM xform = { 1, 0, 0, 1, -page_bounds.x(), -page_bounds.y()};
657 ::SetWorldTransform(bitmap.context(), &xform);
658
659 scoped_ptr<Emf> result(new Emf);
660 result->Init();
661 HDC hdc = result->context();
662 DCHECK(hdc);
663 skia::InitializeDC(hdc);
664
665 HDC bitmap_dc = bitmap.context();
666 ::EnumEnhMetaFile(hdc, emf(), &RasterizeAlphaBlendProc, &bitmap_dc,
667 &page_bounds.ToRECT());
668
669 result->FinishDocument();
670
671 return result.release();
672 }
673
674
568 } // namespace printing 675 } // namespace printing
OLDNEW
« no previous file with comments | « printing/emf_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698