summaryrefslogtreecommitdiffstats
path: root/printing
diff options
context:
space:
mode:
authorvitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-20 01:57:38 +0000
committervitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-20 01:57:38 +0000
commit0064b398edd44fb98f9a5964a1bfbbd1bb41c869 (patch)
tree39801508dd7ce1802cddb8456f17f752d7f8927a /printing
parent45070024ddc42410274943d0e2a55a72e29837da (diff)
downloadchromium_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.cc67
-rw-r--r--printing/emf_win.h16
-rw-r--r--printing/emf_win_unittest.cc4
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();