Index: src/core/SkImageFilter.cpp |
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp |
index 821edc0e1abbd6af85e2b9f41a6e28a5a27ef4de..9fca5cf6c9d65ddc7580fffa13252b8328fe3fc3 100644 |
--- a/src/core/SkImageFilter.cpp |
+++ b/src/core/SkImageFilter.cpp |
@@ -66,12 +66,13 @@ void SkImageFilter::CropRect::toString(SkString* str) const { |
} |
#endif |
-bool SkImageFilter::CropRect::applyTo(const SkIRect& imageBounds, const Context& ctx, |
+void SkImageFilter::CropRect::applyTo(const SkIRect& imageBounds, |
+ const SkMatrix& ctm, |
SkIRect* cropped) const { |
*cropped = imageBounds; |
if (fFlags) { |
SkRect devCropR; |
- ctx.ctm().mapRect(&devCropR, fRect); |
+ ctm.mapRect(&devCropR, fRect); |
const SkIRect devICropR = devCropR.roundOut(); |
// Compute the left/top first, in case we have to read them to compute right/bottom |
@@ -88,12 +89,6 @@ bool SkImageFilter::CropRect::applyTo(const SkIRect& imageBounds, const Context& |
cropped->fBottom = cropped->fTop + devICropR.height(); |
} |
} |
- // 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 |
- // primitive. If we didn't do this, we would be processing the filter |
- // at the full crop rect size in every tile. |
- return cropped->intersect(ctx.clipBounds()); |
} |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
@@ -274,9 +269,22 @@ bool SkImageFilter::filterInput(int index, Proxy* proxy, const SkBitmap& src, |
return input->filterImage(proxy, src, this->mapContext(ctx), result, offset); |
} |
-bool SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst) const { |
+bool SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst, |
+ MapDirection direction) const { |
SkASSERT(dst); |
- return this->onFilterBounds(src, ctm, dst); |
+ SkIRect bounds; |
+ if (kReverse_MapDirection == direction) { |
+ this->onFilterNodeBounds(src, ctm, &bounds, direction); |
+ return this->onFilterBounds(bounds, ctm, dst, direction); |
+ } else { |
+ SkIRect temp; |
+ if (!this->onFilterBounds(src, ctm, &bounds, direction)) { |
+ return false; |
+ } |
+ this->onFilterNodeBounds(bounds, ctm, &temp, direction); |
+ this->getCropRect().applyTo(temp, ctm, dst); |
+ return true; |
+ } |
} |
void SkImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const { |
@@ -396,7 +404,13 @@ bool SkImageFilter::applyCropRect(const Context& ctx, const SkBitmap& src, |
src.getBounds(srcBounds); |
srcBounds->offset(srcOffset); |
this->onFilterNodeBounds(*srcBounds, ctx.ctm(), dstBounds, kForward_MapDirection); |
- return fCropRect.applyTo(*dstBounds, ctx, dstBounds); |
+ fCropRect.applyTo(*dstBounds, ctx.ctm(), 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 |
+ // primitive. If we didn't do this, we would be processing the filter |
+ // at the full crop rect size in every tile. |
+ return dstBounds->intersect(ctx.clipBounds()); |
} |
bool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitmap& src, |
@@ -406,7 +420,8 @@ bool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitm |
srcBounds.offset(*srcOffset); |
SkIRect dstBounds; |
this->onFilterNodeBounds(srcBounds, ctx.ctm(), &dstBounds, kForward_MapDirection); |
- if (!fCropRect.applyTo(dstBounds, ctx, bounds)) { |
+ fCropRect.applyTo(dstBounds, ctx.ctm(), bounds); |
+ if (!bounds->intersect(ctx.clipBounds())) { |
return false; |
} |
@@ -428,18 +443,17 @@ bool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitm |
} |
bool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, |
- SkIRect* dst) const { |
+ SkIRect* dst, MapDirection direction) const { |
if (fInputCount < 1) { |
*dst = src; |
return true; |
} |
- SkIRect bounds, totalBounds; |
- this->onFilterNodeBounds(src, ctm, &bounds, kReverse_MapDirection); |
+ SkIRect totalBounds; |
for (int i = 0; i < fInputCount; ++i) { |
SkImageFilter* filter = this->getInput(i); |
- SkIRect rect = bounds; |
- if (filter && !filter->filterBounds(bounds, ctm, &rect)) { |
+ SkIRect rect = src; |
+ if (filter && !filter->filterBounds(src, ctm, &rect, direction)) { |
return false; |
} |
if (0 == i) { |