diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkImageFilter.cpp | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp index 3b4ad31456..11a2f74c70 100644 --- a/src/core/SkImageFilter.cpp +++ b/src/core/SkImageFilter.cpp @@ -69,25 +69,38 @@ void SkImageFilter::CropRect::toString(SkString* str) const { void SkImageFilter::CropRect::applyTo(const SkIRect& imageBounds, const SkMatrix& ctm, + bool embiggen, SkIRect* cropped) const { *cropped = imageBounds; if (fFlags) { SkRect devCropR; ctm.mapRect(&devCropR, fRect); - const SkIRect devICropR = devCropR.roundOut(); + SkIRect devICropR = devCropR.roundOut(); - // Compute the left/top first, in case we have to read them to compute right/bottom + // Compute the left/top first, in case we need to modify the right/bottom for a missing edge if (fFlags & kHasLeft_CropEdge) { - cropped->fLeft = devICropR.fLeft; + if (embiggen || devICropR.fLeft > cropped->fLeft) { + cropped->fLeft = devICropR.fLeft; + } + } else { + devICropR.fRight = cropped->fLeft + devICropR.width(); } if (fFlags & kHasTop_CropEdge) { - cropped->fTop = devICropR.fTop; + if (embiggen || devICropR.fTop > cropped->fTop) { + cropped->fTop = devICropR.fTop; + } + } else { + devICropR.fBottom = cropped->fTop + devICropR.height(); } if (fFlags & kHasWidth_CropEdge) { - cropped->fRight = cropped->fLeft + devICropR.width(); + if (embiggen || devICropR.fRight < cropped->fRight) { + cropped->fRight = devICropR.fRight; + } } if (fFlags & kHasHeight_CropEdge) { - cropped->fBottom = cropped->fTop + devICropR.height(); + if (embiggen || devICropR.fBottom < cropped->fBottom) { + cropped->fBottom = devICropR.fBottom; + } } } } @@ -306,7 +319,7 @@ SkIRect SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect bounds = this->onFilterBounds(src, ctm, direction); bounds = this->onFilterNodeBounds(bounds, ctm, direction); SkIRect dst; - this->getCropRect().applyTo(bounds, ctm, &dst); + this->getCropRect().applyTo(bounds, ctm, this->affectsTransparentBlack(), &dst); return dst; } } @@ -328,6 +341,9 @@ SkRect SkImageFilter::computeFastBounds(const SkRect& src) const { } bool SkImageFilter::canComputeFastBounds() const { + if (this->affectsTransparentBlack()) { + return false; + } for (int i = 0; i < fInputCount; i++) { SkImageFilter* input = this->getInput(i); if (input && !input->canComputeFastBounds()) { @@ -437,7 +453,7 @@ bool SkImageFilter::asAColorFilter(SkColorFilter** filterPtr) const { bool SkImageFilter::applyCropRect(const Context& ctx, const SkIRect& srcBounds, SkIRect* dstBounds) const { SkIRect temp = this->onFilterNodeBounds(srcBounds, ctx.ctm(), kForward_MapDirection); - fCropRect.applyTo(temp, ctx.ctm(), dstBounds); + fCropRect.applyTo(temp, ctx.ctm(), this->affectsTransparentBlack(), dstBounds); // Intersect against the clip bounds, in case the crop rect has // grown the bounds beyond the original clip. This can happen for // example in tiling, where the clip is much smaller than the filtered @@ -453,7 +469,7 @@ bool SkImageFilter::applyCropRectDeprecated(const Context& ctx, Proxy* proxy, co src.getBounds(&srcBounds); srcBounds.offset(*srcOffset); SkIRect dstBounds = this->onFilterNodeBounds(srcBounds, ctx.ctm(), kForward_MapDirection); - fCropRect.applyTo(dstBounds, ctx.ctm(), bounds); + fCropRect.applyTo(dstBounds, ctx.ctm(), this->affectsTransparentBlack(), bounds); if (!bounds->intersect(ctx.clipBounds())) { return false; } @@ -504,7 +520,7 @@ sk_sp<SkSpecialImage> SkImageFilter::applyCropRect(const Context& ctx, srcBounds = SkIRect::MakeXYWH(srcOffset->fX, srcOffset->fY, src->width(), src->height()); SkIRect dstBounds = this->onFilterNodeBounds(srcBounds, ctx.ctm(), kForward_MapDirection); - fCropRect.applyTo(dstBounds, ctx.ctm(), bounds); + fCropRect.applyTo(dstBounds, ctx.ctm(), this->affectsTransparentBlack(), bounds); if (!bounds->intersect(ctx.clipBounds())) { return nullptr; } |