Chromium Code Reviews| Index: src/core/SkImageFilter.cpp |
| diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp |
| index 3b4ad314563217ded15baa1756d36f63ce7aa960..11a2f74c70910e06901e6c8f6b873b9a91dbaf8f 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, |
|
robertphillips
2016/04/01 19:58:08
cropped -> dst - as in header ?
Stephen White
2016/04/01 21:26:35
Changed the header back to cropped instead.
|
| 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; |
| } |