aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--expectations/gm/ignored-tests.txt3
-rw-r--r--gm/xfermodes.cpp13
-rw-r--r--src/pdf/SkPDFDevice.cpp38
3 files changed, 33 insertions, 21 deletions
diff --git a/expectations/gm/ignored-tests.txt b/expectations/gm/ignored-tests.txt
index d6e5b8e276..d4f3e5766f 100644
--- a/expectations/gm/ignored-tests.txt
+++ b/expectations/gm/ignored-tests.txt
@@ -72,3 +72,6 @@ xfermodeimagefilter
# Added by sugoi in https://codereview.chromium.org/101623007
displacement
+
+# Added by vandebo while fixing Chromium bug 328009. Expanding xfermodes gm.
+xfermodes
diff --git a/gm/xfermodes.cpp b/gm/xfermodes.cpp
index 6e1de3eb67..7ee1e80086 100644
--- a/gm/xfermodes.cpp
+++ b/gm/xfermodes.cpp
@@ -66,8 +66,10 @@ class XfermodesGM : public GM {
kQuarterClearInLayer_SrcType = 0x20,
//! A W/2xH/2 transparent image.
kSmallTransparentImage_SrcType = 0x40,
+ //! kRectangleImage_SrcType drawn directly with a mask.
+ kRectangleWithMask_SrcType = 0x80,
- kAll_SrcType = 0x7F, //!< All the source types.
+ kAll_SrcType = 0xFF, //!< All the source types.
kBasic_SrcType = 0x03, //!< Just basic source types.
};
@@ -112,6 +114,15 @@ class XfermodesGM : public GM {
canvas->drawRect(r, p);
break;
}
+ case kRectangleWithMask_SrcType: {
+ canvas->save(SkCanvas::kClip_SaveFlag);
+ restoreNeeded = true;
+ SkScalar w = SkIntToScalar(W);
+ SkScalar h = SkIntToScalar(H);
+ SkRect r = SkRect::MakeXYWH(x, y + h / 4, w, h * 23 / 60);
+ canvas->clipRect(r);
+ // Fall through.
+ }
case kRectangle_SrcType: {
SkScalar w = SkIntToScalar(W);
SkScalar h = SkIntToScalar(H);
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index cdfec330f0..6625a8e701 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -1912,8 +1912,10 @@ void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode,
ContentEntry* contentEntries = getContentEntries()->get();
SkASSERT(dst);
SkASSERT(!contentEntries->fNext.get());
- // We have to make a copy of these here because changing the current
- // content into a form-xobject will destroy them.
+ // Changing the current content into a form-xobject will destroy the clip
+ // objects which is fine since the xobject will already be clipped. However
+ // if source has shape, we need to clip it too, so a copy of the clip is
+ // saved.
SkClipStack clipStack = contentEntries->fState.fClipStack;
SkRegion clipRegion = contentEntries->fState.fClipRegion;
@@ -1930,7 +1932,8 @@ void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode,
// reduces to Dst.
if (shape == NULL || xfermode == SkXfermode::kDstOut_Mode ||
xfermode == SkXfermode::kSrcATop_Mode) {
- ScopedContentEntry content(this, &clipStack, clipRegion, identity,
+ ScopedContentEntry content(this, &fExistingClipStack,
+ fExistingClipRegion, identity,
stockPaint);
SkPDFUtils::DrawFormXObject(this->addXObjectResource(dst),
&content.entry()->fContent);
@@ -1951,7 +1954,7 @@ void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode,
// the non-transparent parts of the device and the outlines (shape) of
// all images and devices drawn.
drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), dst,
- &clipStack, clipRegion,
+ &fExistingClipStack, fExistingClipRegion,
SkXfermode::kSrcOver_Mode, true);
} else {
SkAutoTUnref<SkPDFFormXObject> dstMaskStorage;
@@ -1970,16 +1973,17 @@ void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode,
dstMaskStorage.reset(createFormXObjectFromDevice());
dstMask = dstMaskStorage.get();
}
- drawFormXObjectWithMask(addXObjectResource(dst), dstMask, &clipStack,
- clipRegion, SkXfermode::kSrcOver_Mode, true);
+ drawFormXObjectWithMask(addXObjectResource(dst), dstMask,
+ &fExistingClipStack, fExistingClipRegion,
+ SkXfermode::kSrcOver_Mode, true);
}
if (xfermode == SkXfermode::kClear_Mode) {
return;
} else if (xfermode == SkXfermode::kSrc_Mode ||
xfermode == SkXfermode::kDstATop_Mode) {
- ScopedContentEntry content(this, &clipStack, clipRegion, identity,
- stockPaint);
+ ScopedContentEntry content(this, &fExistingClipStack,
+ fExistingClipRegion, identity, stockPaint);
if (content.entry()) {
SkPDFUtils::DrawFormXObject(
this->addXObjectResource(srcFormXObject.get()),
@@ -1989,8 +1993,8 @@ void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode,
return;
}
} else if (xfermode == SkXfermode::kSrcATop_Mode) {
- ScopedContentEntry content(this, &clipStack, clipRegion, identity,
- stockPaint);
+ ScopedContentEntry content(this, &fExistingClipStack,
+ fExistingClipRegion, identity, stockPaint);
if (content.entry()) {
SkPDFUtils::DrawFormXObject(this->addXObjectResource(dst),
&content.entry()->fContent);
@@ -2005,30 +2009,24 @@ void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode,
xfermode == SkXfermode::kDstATop_Mode ||
xfermode == SkXfermode::kModulate_Mode);
- ScopedContentEntry inShapeContentEntry(this, &fExistingClipStack,
- fExistingClipRegion, identity,
- stockPaint);
- if (!inShapeContentEntry.entry()) {
- return;
- }
-
if (xfermode == SkXfermode::kSrcIn_Mode ||
xfermode == SkXfermode::kSrcOut_Mode ||
xfermode == SkXfermode::kSrcATop_Mode) {
drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), dst,
- &clipStack, clipRegion,
+ &fExistingClipStack, fExistingClipRegion,
SkXfermode::kSrcOver_Mode,
xfermode == SkXfermode::kSrcOut_Mode);
} else {
SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode;
if (xfermode == SkXfermode::kModulate_Mode) {
drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()),
- dst, &clipStack, clipRegion,
+ dst, &fExistingClipStack,
+ fExistingClipRegion,
SkXfermode::kSrcOver_Mode, false);
mode = SkXfermode::kMultiply_Mode;
}
drawFormXObjectWithMask(addXObjectResource(dst), srcFormXObject.get(),
- &clipStack, clipRegion, mode,
+ &fExistingClipStack, fExistingClipRegion, mode,
xfermode == SkXfermode::kDstOut_Mode);
}
}