diff options
-rw-r--r-- | expectations/gm/ignored-tests.txt | 3 | ||||
-rw-r--r-- | gm/xfermodes.cpp | 13 | ||||
-rw-r--r-- | src/pdf/SkPDFDevice.cpp | 38 |
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); } } |