| 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,
|
| 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;
|
| }
|
|
|