Fix for SkMatrixConvolutionImageFilter with large borders.

Intersect the requested processing rect with the destination
bounds.

R=junov@chromium.org

Review URL: https://codereview.chromium.org/267863004

git-svn-id: http://skia.googlecode.com/svn/trunk@14543 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/effects/SkMatrixConvolutionImageFilter.cpp b/src/effects/SkMatrixConvolutionImageFilter.cpp
index be1dcb4..f6bc6a1 100644
--- a/src/effects/SkMatrixConvolutionImageFilter.cpp
+++ b/src/effects/SkMatrixConvolutionImageFilter.cpp
@@ -151,9 +151,10 @@
 template<class PixelFetcher, bool convolveAlpha>
 void SkMatrixConvolutionImageFilter::filterPixels(const SkBitmap& src,
                                                   SkBitmap* result,
-                                                  const SkIRect& rect,
+                                                  const SkIRect& r,
                                                   const SkIRect& bounds) const {
-    if (rect.isEmpty()) {
+    SkIRect rect(r);
+    if (!rect.intersect(bounds)) {
         return;
     }
     for (int y = rect.fTop; y < rect.fBottom; ++y) {
diff --git a/tests/ImageFilterTest.cpp b/tests/ImageFilterTest.cpp
index ffefb2c..08277a1 100644
--- a/tests/ImageFilterTest.cpp
+++ b/tests/ImageFilterTest.cpp
@@ -398,6 +398,38 @@
     canvas.drawRect(rect, paint);
 }
 
+DEF_TEST(ImageFilterMatrixConvolutionBorder, reporter) {
+    // Check that a filter with borders outside the target bounds
+    // does not crash.
+    SkScalar kernel[3] = {
+        0, 0, 0,
+    };
+    SkISize kernelSize = SkISize::Make(3, 1);
+    SkScalar gain = SK_Scalar1, bias = 0;
+    SkIPoint kernelOffset = SkIPoint::Make(2, 0);
+
+    SkAutoTUnref<SkImageFilter> filter(
+        SkMatrixConvolutionImageFilter::Create(
+            kernelSize, kernel, gain, bias, kernelOffset,
+            SkMatrixConvolutionImageFilter::kClamp_TileMode, true));
+
+    SkBitmap result;
+
+    int width = 10, height = 10;
+    result.allocN32Pixels(width, height);
+    SkCanvas canvas(result);
+    canvas.clear(0);
+
+    SkPaint filterPaint;
+    filterPaint.setImageFilter(filter);
+    SkRect bounds = SkRect::MakeWH(1, 10);
+    SkRect rect = SkRect::Make(SkIRect::MakeWH(width, height));
+    SkPaint rectPaint;
+    canvas.saveLayer(&bounds, &filterPaint);
+    canvas.drawRect(rect, rectPaint);
+    canvas.restore();
+}
+
 DEF_TEST(ImageFilterCropRect, reporter) {
     SkBitmap temp;
     temp.allocN32Pixels(100, 100);