diff options
author | vitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-20 01:57:38 +0000 |
---|---|---|
committer | vitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-20 01:57:38 +0000 |
commit | 0064b398edd44fb98f9a5964a1bfbbd1bb41c869 (patch) | |
tree | 39801508dd7ce1802cddb8456f17f752d7f8927a /printing | |
parent | 45070024ddc42410274943d0e2a55a72e29837da (diff) | |
download | chromium_src-0064b398edd44fb98f9a5964a1bfbbd1bb41c869.zip chromium_src-0064b398edd44fb98f9a5964a1bfbbd1bb41c869.tar.gz chromium_src-0064b398edd44fb98f9a5964a1bfbbd1bb41c869.tar.bz2 |
Restore DC before EndPage call to state if was just after StartPage. We need this because EndPage clips page with current clipping region.
BUG=71509
TEST=unittest
Review URL: https://chromiumcodereview.appspot.com/10557019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@143119 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'printing')
-rw-r--r-- | printing/emf_win.cc | 67 | ||||
-rw-r--r-- | printing/emf_win.h | 16 | ||||
-rw-r--r-- | printing/emf_win_unittest.cc | 4 |
3 files changed, 49 insertions, 38 deletions
diff --git a/printing/emf_win.cc b/printing/emf_win.cc index 984c8b3..3634cbd 100644 --- a/printing/emf_win.cc +++ b/printing/emf_win.cc @@ -109,10 +109,12 @@ bool Emf::SafePlayback(HDC context) const { NOTREACHED(); return false; } + Emf::EnumerationContext playback_context; + playback_context.base_matrix = &base_matrix; return EnumEnhMetaFile(context, emf_, &Emf::SafePlaybackProc, - reinterpret_cast<void*>(&base_matrix), + reinterpret_cast<void*>(&playback_context), &GetPageBounds(1).ToRECT()) != 0; } @@ -190,32 +192,34 @@ int CALLBACK Emf::SafePlaybackProc(HDC hdc, const ENHMETARECORD* record, int objects_count, LPARAM param) { - const XFORM* base_matrix = reinterpret_cast<const XFORM*>(param); - EnumerationContext context; - context.handle_table = handle_table; - context.objects_count = objects_count; - context.hdc = hdc; - Record record_instance(&context, record); - bool success = record_instance.SafePlayback(base_matrix); + Emf::EnumerationContext* context = + reinterpret_cast<Emf::EnumerationContext*>(param); + context->handle_table = handle_table; + context->objects_count = objects_count; + context->hdc = hdc; + Record record_instance(record); + bool success = record_instance.SafePlayback(context); DCHECK(success); return 1; } -Emf::Record::Record(const EnumerationContext* context, - const ENHMETARECORD* record) - : record_(record), - context_(context) { +Emf::EnumerationContext::EnumerationContext() { + memset(this, 0, sizeof(*this)); +} + +Emf::Record::Record(const ENHMETARECORD* record) + : record_(record) { DCHECK(record_); } -bool Emf::Record::Play() const { - return 0 != PlayEnhMetaFileRecord(context_->hdc, - context_->handle_table, +bool Emf::Record::Play(Emf::EnumerationContext* context) const { + return 0 != PlayEnhMetaFileRecord(context->hdc, + context->handle_table, record_, - context_->objects_count); + context->objects_count); } -bool Emf::Record::SafePlayback(const XFORM* base_matrix) const { +bool Emf::Record::SafePlayback(Emf::EnumerationContext* context) const { // For EMF field description, see [MS-EMF] Enhanced Metafile Format // Specification. // @@ -259,7 +263,8 @@ bool Emf::Record::SafePlayback(const XFORM* base_matrix) const { // We also process any custom EMR_GDICOMMENT records which are our // placeholders for StartPage and EndPage. // Note: I should probably care about view ports and clipping, eventually. - bool res; + bool res = false; + const XFORM* base_matrix = context->base_matrix; switch (record()->iType) { case EMR_STRETCHDIBITS: { const EMRSTRETCHDIBITS * sdib_record = @@ -271,7 +276,7 @@ bool Emf::Record::SafePlayback(const XFORM* base_matrix) const { const BYTE* bits = record_start + sdib_record->offBitsSrc; bool play_normally = true; res = false; - HDC hdc = context_->hdc; + HDC hdc = context->hdc; scoped_ptr<SkBitmap> bitmap; if (bmih->biCompression == BI_JPEG) { if (!DIBFormatNativelySupported(hdc, CHECKJPEGFORMAT, bits, @@ -311,14 +316,14 @@ bool Emf::Record::SafePlayback(const XFORM* base_matrix) const { sdib_record->dwRop)); } } else { - res = Play(); + res = Play(context); } break; } case EMR_SETWORLDTRANSFORM: { DCHECK_EQ(record()->nSize, sizeof(DWORD) * 2 + sizeof(XFORM)); const XFORM* xform = reinterpret_cast<const XFORM*>(record()->dParm); - HDC hdc = context_->hdc; + HDC hdc = context->hdc; if (base_matrix) { res = 0 != SetWorldTransform(hdc, base_matrix) && ModifyWorldTransform(hdc, xform, MWT_LEFTMULTIPLY); @@ -332,7 +337,7 @@ bool Emf::Record::SafePlayback(const XFORM* base_matrix) const { sizeof(DWORD) * 2 + sizeof(XFORM) + sizeof(DWORD)); const XFORM* xform = reinterpret_cast<const XFORM*>(record()->dParm); const DWORD* option = reinterpret_cast<const DWORD*>(xform + 1); - HDC hdc = context_->hdc; + HDC hdc = context->hdc; switch (*option) { case MWT_IDENTITY: if (base_matrix) { @@ -371,15 +376,20 @@ bool Emf::Record::SafePlayback(const XFORM* base_matrix) const { reinterpret_cast<const PageBreakRecord*>(comment_record->Data); if (page_break_record && page_break_record->IsValid()) { if (page_break_record->type == PageBreakRecord::START_PAGE) { - res = !!::StartPage(context_->hdc); + res = !!::StartPage(context->hdc); + DCHECK_EQ(0, context->dc_on_page_start); + context->dc_on_page_start = ::SaveDC(context->hdc); } else if (page_break_record->type == PageBreakRecord::END_PAGE) { - res = !!::EndPage(context_->hdc); + DCHECK_NE(0, context->dc_on_page_start); + ::RestoreDC(context->hdc, context->dc_on_page_start); + context->dc_on_page_start = 0; + res = !!::EndPage(context->hdc); } else { res = false; NOTREACHED(); } } else { - res = Play(); + res = Play(context); } } else { res = true; @@ -387,7 +397,7 @@ bool Emf::Record::SafePlayback(const XFORM* base_matrix) const { break; } default: { - res = Play(); + res = Play(context); break; } } @@ -427,9 +437,6 @@ bool Emf::FinishPage() { } Emf::Enumerator::Enumerator(const Emf& emf, HDC context, const RECT* rect) { - context_.handle_table = NULL; - context_.objects_count = 0; - context_.hdc = NULL; items_.clear(); if (!EnumEnhMetaFile(context, emf.emf(), @@ -467,7 +474,7 @@ int CALLBACK Emf::Enumerator::EnhMetaFileProc(HDC hdc, DCHECK_EQ(emf.context_.objects_count, objects_count); DCHECK_EQ(emf.context_.hdc, hdc); } - emf.items_.push_back(Record(&emf.context_, record)); + emf.items_.push_back(Record(record)); return 1; } diff --git a/printing/emf_win.h b/printing/emf_win.h index 8317627..b593e24 100644 --- a/printing/emf_win.h +++ b/printing/emf_win.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -113,9 +113,13 @@ class PRINTING_EXPORT Emf : public Metafile { }; struct Emf::EnumerationContext { + EnumerationContext(); + HANDLETABLE* handle_table; int objects_count; HDC hdc; + const XFORM* base_matrix; + int dc_on_page_start; }; // One EMF record. It keeps pointers to the EMF buffer held by Emf::emf_. @@ -123,24 +127,22 @@ struct Emf::EnumerationContext { class PRINTING_EXPORT Emf::Record { public: // Plays the record. - bool Play() const; + bool Play(EnumerationContext* context) const; // Plays the record working around quirks with SetLayout, // SetWorldTransform and ModifyWorldTransform. See implementation for details. - bool SafePlayback(const XFORM* base_matrix) const; + bool SafePlayback(EnumerationContext* context) const; // Access the underlying EMF record. const ENHMETARECORD* record() const { return record_; } protected: - Record(const EnumerationContext* context, - const ENHMETARECORD* record); + explicit Record(const ENHMETARECORD* record); private: friend class Emf; friend class Enumerator; const ENHMETARECORD* record_; - const EnumerationContext* context_; }; // Retrieves individual records out of a Emf buffer. The main use is to skip @@ -163,6 +165,8 @@ class PRINTING_EXPORT Emf::Enumerator { const_iterator end() const; private: + FRIEND_TEST_ALL_PREFIXES(EmfPrintingTest, Enumerate); + // Processes one EMF record and saves it in the items_ array. static int CALLBACK EnhMetaFileProc(HDC hdc, HANDLETABLE* handle_table, diff --git a/printing/emf_win_unittest.cc b/printing/emf_win_unittest.cc index add23f9..8d07213 100644 --- a/printing/emf_win_unittest.cc +++ b/printing/emf_win_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -116,7 +116,7 @@ TEST_F(EmfPrintingTest, Enumerate) { // If you get this assert, you need to lookup iType in wingdi.h. It starts // with EMR_HEADER. EMR_HEADER; - EXPECT_TRUE(itr->SafePlayback(NULL)) << + EXPECT_TRUE(itr->SafePlayback(&emf_enum.context_)) << " index: " << index << " type: " << itr->record()->iType; } context->PageDone(); |