Index: src/effects/SkBlurImageFilter.cpp |
diff --git a/src/effects/SkBlurImageFilter.cpp b/src/effects/SkBlurImageFilter.cpp |
index 157a0c333573cc44253343f2ec3ceabd1955b8ea..25383cda0688fec5e823a8e5172c1816d99bf02b 100644 |
--- a/src/effects/SkBlurImageFilter.cpp |
+++ b/src/effects/SkBlurImageFilter.cpp |
@@ -21,8 +21,11 @@ SkBlurImageFilter::SkBlurImageFilter(SkFlattenableReadBuffer& buffer) |
fSigma.fHeight = buffer.readScalar(); |
} |
-SkBlurImageFilter::SkBlurImageFilter(SkScalar sigmaX, SkScalar sigmaY, SkImageFilter* input) |
- : INHERITED(input), fSigma(SkSize::Make(sigmaX, sigmaY)) { |
+SkBlurImageFilter::SkBlurImageFilter(SkScalar sigmaX, |
+ SkScalar sigmaY, |
+ SkImageFilter* input, |
+ const SkIRect* cropRect) |
+ : INHERITED(input, cropRect), fSigma(SkSize::Make(sigmaX, sigmaY)) { |
SkASSERT(sigmaX >= 0 && sigmaY >= 0); |
} |
@@ -33,13 +36,13 @@ void SkBlurImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const { |
} |
static void boxBlurX(const SkBitmap& src, SkBitmap* dst, int kernelSize, |
- int leftOffset, int rightOffset) |
+ int leftOffset, int rightOffset, const SkIRect& bounds) |
{ |
- int width = src.width(), height = src.height(); |
+ int width = bounds.width(), height = bounds.height(); |
int rightBorder = SkMin32(rightOffset + 1, width); |
for (int y = 0; y < height; ++y) { |
int sumA = 0, sumR = 0, sumG = 0, sumB = 0; |
- SkPMColor* p = src.getAddr32(0, y); |
+ SkPMColor* p = src.getAddr32(bounds.fLeft, y + bounds.fTop); |
for (int i = 0; i < rightBorder; ++i) { |
sumA += SkGetPackedA32(*p); |
sumR += SkGetPackedR32(*p); |
@@ -48,7 +51,7 @@ static void boxBlurX(const SkBitmap& src, SkBitmap* dst, int kernelSize, |
p++; |
} |
- const SkColor* sptr = src.getAddr32(0, y); |
+ const SkColor* sptr = src.getAddr32(bounds.fLeft, bounds.fTop + y); |
SkColor* dptr = dst->getAddr32(0, y); |
for (int x = 0; x < width; ++x) { |
*dptr = SkPackARGB32(sumA / kernelSize, |
@@ -76,15 +79,15 @@ static void boxBlurX(const SkBitmap& src, SkBitmap* dst, int kernelSize, |
} |
static void boxBlurY(const SkBitmap& src, SkBitmap* dst, int kernelSize, |
- int topOffset, int bottomOffset) |
+ int topOffset, int bottomOffset, const SkIRect& bounds) |
{ |
- int width = src.width(), height = src.height(); |
+ int width = bounds.width(), height = bounds.height(); |
int bottomBorder = SkMin32(bottomOffset + 1, height); |
int srcStride = src.rowBytesAsPixels(); |
int dstStride = dst->rowBytesAsPixels(); |
for (int x = 0; x < width; ++x) { |
int sumA = 0, sumR = 0, sumG = 0, sumB = 0; |
- SkColor* p = src.getAddr32(x, 0); |
+ SkColor* p = src.getAddr32(bounds.fLeft + x, bounds.fTop); |
for (int i = 0; i < bottomBorder; ++i) { |
sumA += SkGetPackedA32(*p); |
sumR += SkGetPackedR32(*p); |
@@ -93,7 +96,7 @@ static void boxBlurY(const SkBitmap& src, SkBitmap* dst, int kernelSize, |
p += srcStride; |
} |
- const SkColor* sptr = src.getAddr32(x, 0); |
+ const SkColor* sptr = src.getAddr32(bounds.fLeft + x, bounds.fTop); |
SkColor* dptr = dst->getAddr32(x, 0); |
for (int y = 0; y < height; ++y) { |
*dptr = SkPackARGB32(sumA / kernelSize, |
@@ -153,7 +156,14 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy, |
return false; |
} |
- dst->setConfig(src.config(), src.width(), src.height()); |
+ SkIRect srcBounds, dstBounds; |
+ src.getBounds(&srcBounds); |
+ if (!this->applyCropRect(&srcBounds)) { |
+ return false; |
+ } |
+ |
+ dst->setConfig(src.config(), srcBounds.width(), srcBounds.height()); |
+ dst->getBounds(&dstBounds); |
dst->allocPixels(); |
int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX; |
int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY; |
@@ -176,21 +186,23 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy, |
} |
if (kernelSizeX > 0 && kernelSizeY > 0) { |
- boxBlurX(src, &temp, kernelSizeX, lowOffsetX, highOffsetX); |
- boxBlurY(temp, dst, kernelSizeY, lowOffsetY, highOffsetY); |
- boxBlurX(*dst, &temp, kernelSizeX, highOffsetX, lowOffsetX); |
- boxBlurY(temp, dst, kernelSizeY, highOffsetY, lowOffsetY); |
- boxBlurX(*dst, &temp, kernelSizeX3, highOffsetX, highOffsetX); |
- boxBlurY(temp, dst, kernelSizeY3, highOffsetY, highOffsetY); |
+ boxBlurX(src, &temp, kernelSizeX, lowOffsetX, highOffsetX, srcBounds); |
+ boxBlurY(temp, dst, kernelSizeY, lowOffsetY, highOffsetY, dstBounds); |
+ boxBlurX(*dst, &temp, kernelSizeX, highOffsetX, lowOffsetX, dstBounds); |
+ boxBlurY(temp, dst, kernelSizeY, highOffsetY, lowOffsetY, dstBounds); |
+ boxBlurX(*dst, &temp, kernelSizeX3, highOffsetX, highOffsetX, dstBounds); |
+ boxBlurY(temp, dst, kernelSizeY3, highOffsetY, highOffsetY, dstBounds); |
} else if (kernelSizeX > 0) { |
- boxBlurX(src, dst, kernelSizeX, lowOffsetX, highOffsetX); |
- boxBlurX(*dst, &temp, kernelSizeX, highOffsetX, lowOffsetX); |
- boxBlurX(temp, dst, kernelSizeX3, highOffsetX, highOffsetX); |
+ boxBlurX(src, dst, kernelSizeX, lowOffsetX, highOffsetX, srcBounds); |
+ boxBlurX(*dst, &temp, kernelSizeX, highOffsetX, lowOffsetX, dstBounds); |
+ boxBlurX(temp, dst, kernelSizeX3, highOffsetX, highOffsetX, dstBounds); |
} else if (kernelSizeY > 0) { |
- boxBlurY(src, dst, kernelSizeY, lowOffsetY, highOffsetY); |
- boxBlurY(*dst, &temp, kernelSizeY, highOffsetY, lowOffsetY); |
- boxBlurY(temp, dst, kernelSizeY3, highOffsetY, highOffsetY); |
+ boxBlurY(src, dst, kernelSizeY, lowOffsetY, highOffsetY, srcBounds); |
+ boxBlurY(*dst, &temp, kernelSizeY, highOffsetY, lowOffsetY, dstBounds); |
+ boxBlurY(temp, dst, kernelSizeY3, highOffsetY, highOffsetY, dstBounds); |
} |
+ offset->fX += srcBounds.fLeft; |
+ offset->fY += srcBounds.fTop; |
return true; |
} |
@@ -202,12 +214,21 @@ bool SkBlurImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, SkBitm |
return false; |
} |
GrTexture* source = input.getTexture(); |
- SkRect rect; |
+ SkIRect rect; |
src.getBounds(&rect); |
+ if (!this->applyCropRect(&rect)) { |
+ return false; |
+ } |
SkAutoTUnref<GrTexture> tex(SkGpuBlurUtils::GaussianBlur(source->getContext(), |
- source, false, rect, |
- fSigma.width(), fSigma.height())); |
- return SkImageFilterUtils::WrapTexture(tex, src.width(), src.height(), result); |
+ source, |
+ false, |
+ SkRect::Make(rect), |
+ true, |
+ fSigma.width(), |
+ fSigma.height())); |
+ offset->fX += rect.fLeft; |
+ offset->fY += rect.fTop; |
+ return SkImageFilterUtils::WrapTexture(tex, rect.width(), rect.height(), result); |
#else |
SkDEBUGFAIL("Should not call in GPU-less build"); |
return false; |