| Index: src/core/SkImageFilter.cpp
|
| diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp
|
| index 6613f09b93b7fd0ba2f06aa3ebe7db4ed04f89fd..2be66e787c5c6efba9148de9884c3e26a85b012f 100644
|
| --- a/src/core/SkImageFilter.cpp
|
| +++ b/src/core/SkImageFilter.cpp
|
| @@ -8,6 +8,7 @@
|
| #include "SkImageFilter.h"
|
|
|
| #include "SkBitmap.h"
|
| +#include "SkDevice.h"
|
| #include "SkReadBuffer.h"
|
| #include "SkWriteBuffer.h"
|
| #include "SkRect.h"
|
| @@ -155,9 +156,7 @@ bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Cont
|
| }
|
| GrTexture* srcTexture = input.getTexture();
|
| SkIRect bounds;
|
| - src.getBounds(&bounds);
|
| - bounds.offset(srcOffset);
|
| - if (!this->applyCropRect(&bounds, ctx.ctm())) {
|
| + if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &bounds, &input)) {
|
| return false;
|
| }
|
| SkRect srcRect = SkRect::Make(bounds);
|
| @@ -196,18 +195,60 @@ bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Cont
|
| #endif
|
| }
|
|
|
| -bool SkImageFilter::applyCropRect(SkIRect* rect, const SkMatrix& matrix) const {
|
| +bool SkImageFilter::applyCropRect(const Context& ctx, const SkBitmap& src,
|
| + const SkIPoint& srcOffset, SkIRect* bounds) const {
|
| + SkIRect srcBounds;
|
| + src.getBounds(&srcBounds);
|
| + srcBounds.offset(srcOffset);
|
| SkRect cropRect;
|
| - matrix.mapRect(&cropRect, fCropRect.rect());
|
| + ctx.ctm().mapRect(&cropRect, fCropRect.rect());
|
| SkIRect cropRectI;
|
| cropRect.roundOut(&cropRectI);
|
| uint32_t flags = fCropRect.flags();
|
| - // If the original crop rect edges were unset, max out the new crop edges
|
| - if (!(flags & CropRect::kHasLeft_CropEdge)) cropRectI.fLeft = SK_MinS32;
|
| - if (!(flags & CropRect::kHasTop_CropEdge)) cropRectI.fTop = SK_MinS32;
|
| - if (!(flags & CropRect::kHasRight_CropEdge)) cropRectI.fRight = SK_MaxS32;
|
| - if (!(flags & CropRect::kHasBottom_CropEdge)) cropRectI.fBottom = SK_MaxS32;
|
| - return rect->intersect(cropRectI);
|
| + if (flags & CropRect::kHasLeft_CropEdge) srcBounds.fLeft = cropRectI.fLeft;
|
| + if (flags & CropRect::kHasTop_CropEdge) srcBounds.fTop = cropRectI.fTop;
|
| + if (flags & CropRect::kHasRight_CropEdge) srcBounds.fRight = cropRectI.fRight;
|
| + if (flags & CropRect::kHasBottom_CropEdge) srcBounds.fBottom = cropRectI.fBottom;
|
| + if (!srcBounds.intersect(ctx.clipBounds())) {
|
| + return false;
|
| + }
|
| + *bounds = srcBounds;
|
| + return true;
|
| +}
|
| +
|
| +bool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitmap& src,
|
| + SkIPoint* srcOffset, SkIRect* bounds, SkBitmap* dst) const {
|
| + SkIRect srcBounds;
|
| + src.getBounds(&srcBounds);
|
| + srcBounds.offset(*srcOffset);
|
| + SkRect cropRect;
|
| + ctx.ctm().mapRect(&cropRect, fCropRect.rect());
|
| + SkIRect cropRectI;
|
| + cropRect.roundOut(&cropRectI);
|
| + uint32_t flags = fCropRect.flags();
|
| + *bounds = srcBounds;
|
| + if (flags & CropRect::kHasLeft_CropEdge) bounds->fLeft = cropRectI.fLeft;
|
| + if (flags & CropRect::kHasTop_CropEdge) bounds->fTop = cropRectI.fTop;
|
| + if (flags & CropRect::kHasRight_CropEdge) bounds->fRight = cropRectI.fRight;
|
| + if (flags & CropRect::kHasBottom_CropEdge) bounds->fBottom = cropRectI.fBottom;
|
| + if (!bounds->intersect(ctx.clipBounds())) {
|
| + return false;
|
| + }
|
| + if (srcBounds.contains(*bounds)) {
|
| + *dst = src;
|
| + return true;
|
| + } else {
|
| + SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds->width(), bounds->height()));
|
| + if (!device) {
|
| + return false;
|
| + }
|
| + SkCanvas canvas(device);
|
| + canvas.clear(0x00000000);
|
| + canvas.drawBitmap(src, srcOffset->x() - bounds->x(), srcOffset->y() - bounds->y());
|
| + *srcOffset = SkIPoint::Make(bounds->x(), bounds->y());
|
| + *dst = device->accessBitmap(false);
|
| + return true;
|
| + }
|
| }
|
|
|
| bool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
|
|
|