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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « printing/emf_win.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: printing/emf_win.cc
diff --git a/printing/emf_win.cc b/printing/emf_win.cc
index a5d4c024070042c7e8ebd02f0cd88467ca345a6a..a6005dc7f8ae0687de9ae3228990834e06fbbb73 100644
--- a/printing/emf_win.cc
+++ b/printing/emf_win.cc
@@ -54,6 +54,101 @@ int CALLBACK IsAlphaBlendUsedEnumProc(HDC,
return 1;
}
+int CALLBACK RasterizeAlphaBlendProc(HDC metafile_dc,
+ HANDLETABLE* handle_table,
+ const ENHMETARECORD *record,
+ int num_objects,
+ LPARAM data) {
+ HDC bitmap_dc = *reinterpret_cast<HDC*>(data);
+ // Play this command to the bitmap DC.
+ ::PlayEnhMetaFileRecord(bitmap_dc, handle_table, record, num_objects);
+ switch (record->iType) {
+ case EMR_ALPHABLEND: {
+ const EMRALPHABLEND* alpha_blend =
+ reinterpret_cast<const EMRALPHABLEND*>(record);
+ // Don't modify transformation here.
+ // Old implementation did reset transformations for DC to identity matrix.
+ // That was not correct and cause some bugs, like unexpected cropping.
+ // EMRALPHABLEND is rendered into bitmap and metafile contexts with
+ // current transformation. If we don't touch them here BitBlt will copy
+ // same areas.
+ ::BitBlt(metafile_dc,
+ alpha_blend->xDest,
+ alpha_blend->yDest,
+ alpha_blend->cxDest,
+ alpha_blend->cyDest,
+ bitmap_dc,
+ alpha_blend->xDest,
+ alpha_blend->yDest,
+ SRCCOPY);
+ break;
+ }
+ case EMR_CREATEBRUSHINDIRECT:
+ case EMR_CREATECOLORSPACE:
+ case EMR_CREATECOLORSPACEW:
+ case EMR_CREATEDIBPATTERNBRUSHPT:
+ case EMR_CREATEMONOBRUSH:
+ case EMR_CREATEPALETTE:
+ case EMR_CREATEPEN:
+ case EMR_DELETECOLORSPACE:
+ case EMR_DELETEOBJECT:
+ case EMR_EXTCREATEFONTINDIRECTW:
+ // Play object creation command only once.
+ break;
+
+ default:
+ // Play this command to the metafile DC.
+ ::PlayEnhMetaFileRecord(metafile_dc, handle_table, record, num_objects);
+ break;
+ }
+ return 1; // Continue enumeration
+}
+
+// Bitmapt for rasterization.
+class RasterBitmap {
+ public:
+ explicit RasterBitmap(const gfx::Size& raster_size)
+ : saved_object_(NULL) {
+ context_.Set(::CreateCompatibleDC(NULL));
+ if (!context_) {
+ NOTREACHED() << "Bitmap DC creation failed";
+ return;
+ }
+ ::SetGraphicsMode(context_, GM_ADVANCED);
+ void* bits = NULL;
+ gfx::Rect bitmap_rect(raster_size);
+ gfx::CreateBitmapHeader(raster_size.width(), raster_size.height(),
+ &header_.bmiHeader);
+ bitmap_.Set(::CreateDIBSection(context_, &header_, DIB_RGB_COLORS, &bits,
+ NULL, 0));
+ if (!bitmap_)
+ NOTREACHED() << "Raster bitmap creation for printing failed";
+
+ saved_object_ = ::SelectObject(context_, bitmap_);
+ ::FillRect(context_, &bitmap_rect.ToRECT(),
Timur Iskhodzhanov 2013/03/28 03:49:39 FYI taking an address of a temporary object is not
+ static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH)));
+
+ }
+
+ ~RasterBitmap() {
+ ::SelectObject(context_, saved_object_);
+ }
+
+ HDC context() const {
+ return context_;
+ }
+
+ base::win::ScopedCreateDC context_;
+ BITMAPINFO header_;
+ base::win::ScopedBitmap bitmap_;
+ HGDIOBJ saved_object_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(RasterBitmap);
+};
+
+
+
} // namespace
namespace printing {
@@ -516,28 +611,11 @@ Emf* Emf::RasterizeMetafile(int raster_area_in_pixels) const {
page_size.set_width(std::max<int>(1, page_size.width() * scale));
page_size.set_height(std::max<int>(1, page_size.height() * scale));
- base::win::ScopedCreateDC bitmap_dc(::CreateCompatibleDC(NULL));
- if (!bitmap_dc) {
- NOTREACHED() << "Bitmap DC creation failed";
- return NULL;
- }
- ::SetGraphicsMode(bitmap_dc, GM_ADVANCED);
- void* bits = NULL;
- BITMAPINFO hdr;
- gfx::CreateBitmapHeader(page_size.width(), page_size.height(),
- &hdr.bmiHeader);
- base::win::ScopedBitmap hbitmap(CreateDIBSection(
- bitmap_dc, &hdr, DIB_RGB_COLORS, &bits, NULL, 0));
- if (!hbitmap)
- NOTREACHED() << "Raster bitmap creation for printing failed";
-
- base::win::ScopedSelectObject selectBitmap(bitmap_dc, hbitmap);
- RECT rect = { 0, 0, page_size.width(), page_size.height() };
- HBRUSH white_brush = static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH));
- FillRect(bitmap_dc, &rect, white_brush);
+
+ RasterBitmap bitmap(page_size);
gfx::Rect bitmap_rect(page_size);
- Playback(bitmap_dc, &bitmap_rect.ToRECT());
+ Playback(bitmap.context(), &bitmap_rect.ToRECT());
scoped_ptr<Emf> result(new Emf);
result->Init();
@@ -557,7 +635,7 @@ Emf* Emf::RasterizeMetafile(int raster_area_in_pixels) const {
};
::SetWorldTransform(hdc, &xform);
::BitBlt(hdc, 0, 0, bitmap_rect.width(), bitmap_rect.height(),
- bitmap_dc, bitmap_rect.x(), bitmap_rect.y(), SRCCOPY);
+ bitmap.context(), bitmap_rect.x(), bitmap_rect.y(), SRCCOPY);
result->FinishPage();
result->FinishDocument();
@@ -565,4 +643,33 @@ Emf* Emf::RasterizeMetafile(int raster_area_in_pixels) const {
return result.release();
}
+Emf* Emf::RasterizeAlphaBlend() const {
+ gfx::Rect page_bounds = GetPageBounds(1);
+ if (page_bounds.size().GetArea() <= 0) {
+ NOTREACHED() << "Metafile is empty";
+ page_bounds = gfx::Rect(1, 1);
+ }
+
+ RasterBitmap bitmap(page_bounds.size());
+
+ // Map metafile page_bounds.x(), page_bounds.y() to bitmap 0, 0.
+ XFORM xform = { 1, 0, 0, 1, -page_bounds.x(), -page_bounds.y()};
+ ::SetWorldTransform(bitmap.context(), &xform);
+
+ scoped_ptr<Emf> result(new Emf);
+ result->Init();
+ HDC hdc = result->context();
+ DCHECK(hdc);
+ skia::InitializeDC(hdc);
+
+ HDC bitmap_dc = bitmap.context();
+ ::EnumEnhMetaFile(hdc, emf(), &RasterizeAlphaBlendProc, &bitmap_dc,
+ &page_bounds.ToRECT());
+
+ result->FinishDocument();
+
+ return result.release();
+}
+
+
} // namespace printing
« 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