From d8b57717793f069db2ccd7c8174d0822bd7de6e1 Mon Sep 17 00:00:00 2001 From: fs Date: Wed, 20 May 2015 00:52:17 -0700 Subject: [PATCH] Don't fail SkMergeImageFilter if one of the inputs are empty If one of the inputs to a SkMergeImageFilter was clipped away or otherwise caused the filterImage(...) invocation for it to return false, the entire effect would be "failed" and return false -- regardless of if it had produced a result or not. Instead of returning false directly if filterImage(...) for a source returned false, consider all the inputs, and then only return false if all of them do. BUG=chromium:489046 Review URL: https://codereview.chromium.org/1133523006 --- src/effects/SkMergeImageFilter.cpp | 7 ++++++- tests/ImageFilterTest.cpp | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/effects/SkMergeImageFilter.cpp b/src/effects/SkMergeImageFilter.cpp index f68d913378..4c5404d5fb 100755 --- a/src/effects/SkMergeImageFilter.cpp +++ b/src/effects/SkMergeImageFilter.cpp @@ -77,6 +77,7 @@ bool SkMergeImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src, SkCanvas canvas(dst); SkPaint paint; + bool didProduceResult = false; int inputCount = countInputs(); for (int i = 0; i < inputCount; ++i) { SkBitmap tmp; @@ -85,7 +86,7 @@ bool SkMergeImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src, SkImageFilter* filter = getInput(i); if (filter) { if (!filter->filterImage(proxy, src, ctx, &tmp, &pos)) { - return false; + continue; } srcPtr = &tmp; } else { @@ -98,8 +99,12 @@ bool SkMergeImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src, paint.setXfermode(NULL); } canvas.drawSprite(*srcPtr, pos.x() - x0, pos.y() - y0, &paint); + didProduceResult = true; } + if (!didProduceResult) + return false; + offset->fX = bounds.left(); offset->fY = bounds.top(); *result = dst->accessBitmap(false); diff --git a/tests/ImageFilterTest.cpp b/tests/ImageFilterTest.cpp index 6c596156fe..0076ac56fb 100644 --- a/tests/ImageFilterTest.cpp +++ b/tests/ImageFilterTest.cpp @@ -442,6 +442,12 @@ DEF_TEST(ImageFilterDrawTiled, reporter) { SkAutoTUnref rectShaderFilter(SkRectShaderImageFilter::Create(shader.get())); + SkAutoTUnref greenColorShader(SkShader::CreateColorShader(SK_ColorGREEN)); + SkImageFilter::CropRect leftSideCropRect(SkRect::MakeXYWH(0, 0, 32, 64)); + SkAutoTUnref rectShaderFilterLeft(SkRectShaderImageFilter::Create(greenColorShader.get(), &leftSideCropRect)); + SkImageFilter::CropRect rightSideCropRect(SkRect::MakeXYWH(32, 0, 32, 64)); + SkAutoTUnref rectShaderFilterRight(SkRectShaderImageFilter::Create(greenColorShader.get(), &rightSideCropRect)); + struct { const char* fName; SkImageFilter* fFilter; @@ -464,6 +470,8 @@ DEF_TEST(ImageFilterDrawTiled, reporter) { kernelSize, kernel, gain, bias, SkIPoint::Make(1, 1), SkMatrixConvolutionImageFilter::kRepeat_TileMode, false) }, { "merge", SkMergeImageFilter::Create(NULL, NULL, SkXfermode::kSrcOver_Mode) }, + { "merge with disjoint inputs", SkMergeImageFilter::Create( + rectShaderFilterLeft, rectShaderFilterRight, SkXfermode::kSrcOver_Mode) }, { "offset", SkOffsetImageFilter::Create(SK_Scalar1, SK_Scalar1) }, { "dilate", SkDilateImageFilter::Create(3, 2) }, { "erode", SkErodeImageFilter::Create(2, 3) },