From 22c57abe439f200472a14b2341b68ed7c0ce785e Mon Sep 17 00:00:00 2001 From: Robert Phillips Date: Mon, 19 Dec 2016 16:51:53 -0500 Subject: Fix mapping from src to dst image space in SkAlphaThresholdFilter This CL does 3 things: It updates the imagealphathreshold GMs so they would've caught this bug It updates SkAlphaImageThresholdFilter to fix the bug It updates the imagealphathreshold_surface GM to match the imagealphathreshold_crop GM (which it was, presumably, originally written to do) The bug in question is that the prior mapping from src to dst space was correct as long as the imageOffset was (0, 0). BUG=675332 Change-Id: I3aa1f463a2234576fb2277797caa2fc4aba2650d Reviewed-on: https://skia-review.googlesource.com/6291 Reviewed-by: Brian Osman Reviewed-by: Stephan White Commit-Queue: Robert Phillips --- gm/imagealphathreshold.cpp | 69 ++++++++++++++++++++++------------ src/effects/SkAlphaThresholdFilter.cpp | 3 +- 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/gm/imagealphathreshold.cpp b/gm/imagealphathreshold.cpp index 1e90f76bf0..302cdeea52 100644 --- a/gm/imagealphathreshold.cpp +++ b/gm/imagealphathreshold.cpp @@ -7,27 +7,25 @@ #include "gm.h" #include "SkAlphaThresholdFilter.h" -#include "SkRandom.h" +#include "SkOffsetImageFilter.h" #include "SkSurface.h" #define WIDTH 500 #define HEIGHT 500 -namespace { - -void draw_rects(SkCanvas* canvas) { +static void draw_rects(SkCanvas* canvas) { SkPaint rectPaint; - rectPaint.setColor(0xFF0000FF); + rectPaint.setColor(SK_ColorBLUE); canvas->drawRect(SkRect::MakeXYWH(0, 0, WIDTH / 2, HEIGHT / 2), rectPaint); rectPaint.setColor(0xBFFF0000); canvas->drawRect(SkRect::MakeXYWH(WIDTH / 2, 0, WIDTH / 2, HEIGHT / 2), rectPaint); rectPaint.setColor(0x3F00FF00); canvas->drawRect(SkRect::MakeXYWH(0, HEIGHT / 2, WIDTH / 2, HEIGHT / 2), rectPaint); - rectPaint.setColor(0x00000000); + rectPaint.setColor(SK_ColorTRANSPARENT); canvas->drawRect(SkRect::MakeXYWH(WIDTH / 2, HEIGHT / 2, WIDTH / 2, HEIGHT / 2), rectPaint); } -SkPaint create_filter_paint(SkImageFilter::CropRect* cropRect = nullptr) { +static SkPaint create_filter_paint(SkImageFilter::CropRect* cropRect = nullptr) { SkIRect rects[2]; rects[0] = SkIRect::MakeXYWH(0, 150, WIDTH, HEIGHT - 300); rects[1] = SkIRect::MakeXYWH(150, 0, WIDTH - 300, HEIGHT); @@ -35,18 +33,15 @@ SkPaint create_filter_paint(SkImageFilter::CropRect* cropRect = nullptr) { region.setRects(rects, 2); SkPaint paint; - paint.setImageFilter(SkAlphaThresholdFilter::Make(region, 0.2f, 0.7f, nullptr, cropRect)); + sk_sp offset(SkOffsetImageFilter::Make(25, 25, nullptr)); + paint.setImageFilter(SkAlphaThresholdFilter::Make(region, 0.2f, 0.7f, std::move(offset), cropRect)); return paint; } -}; - -namespace skiagm { - -class ImageAlphaThresholdGM : public GM { +class ImageAlphaThresholdGM : public skiagm::GM { public: ImageAlphaThresholdGM(bool useCropRect) : fUseCropRect(useCropRect) { - this->setBGColor(0xFFFFFFFF); + this->setBGColor(SK_ColorWHITE); } protected: @@ -87,8 +82,31 @@ private: typedef GM INHERITED; }; +// Create a 'width' x 'height' SkSurface that matches the colorType of 'canvas' as +// best we can +static sk_sp make_color_matching_surface(SkCanvas* canvas, int width, int height, + SkAlphaType alphaType) { + + SkColorType ct = canvas->imageInfo().colorType(); + sk_sp cs(sk_ref_sp(canvas->imageInfo().colorSpace())); + + if (kUnknown_SkColorType == ct) { + // For backends that aren't yet color-space aware we just fallback to N32. + ct = kN32_SkColorType; + cs = nullptr; + } + + SkImageInfo info = SkImageInfo::Make(width, height, ct, alphaType, std::move(cs)); + + sk_sp result = canvas->makeSurface(info); + if (!result) { + result = SkSurface::MakeRaster(info); + } + + return result; +} -class ImageAlphaThresholdSurfaceGM : public GM { +class ImageAlphaThresholdSurfaceGM : public skiagm::GM { public: ImageAlphaThresholdSurfaceGM() { this->setBGColor(0xFFFFFFFF); @@ -104,12 +122,17 @@ protected: } void onDraw(SkCanvas* canvas) override { - SkImageInfo info = SkImageInfo::MakeS32(WIDTH, HEIGHT, kOpaque_SkAlphaType); - auto surface(canvas->makeSurface(info)); - if (nullptr == surface) { - surface = SkSurface::MakeRaster(info); - } - surface->getCanvas()->clear(SK_ColorWHITE); + SkMatrix matrix; + matrix.reset(); + matrix.setTranslate(WIDTH * .1f, HEIGHT * .1f); + matrix.postScale(.8f, .8f); + + canvas->concat(matrix); + + sk_sp surface(make_color_matching_surface(canvas, WIDTH, HEIGHT, + kPremul_SkAlphaType)); + + surface->getCanvas()->clear(SK_ColorTRANSPARENT); draw_rects(surface->getCanvas()); SkPaint paint = create_filter_paint(); @@ -118,7 +141,7 @@ protected: } private: - typedef GM INHERITED; + typedef skiagm::GM INHERITED; }; ////////////////////////////////////////////////////////////////////////////// @@ -126,5 +149,3 @@ private: DEF_GM(return new ImageAlphaThresholdGM(true);) DEF_GM(return new ImageAlphaThresholdGM(false);) DEF_GM(return new ImageAlphaThresholdSurfaceGM();) - -} diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp index 6cf1ce61e4..81416e2817 100644 --- a/src/effects/SkAlphaThresholdFilter.cpp +++ b/src/effects/SkAlphaThresholdFilter.cpp @@ -225,8 +225,9 @@ sk_sp SkAlphaThresholdFilterImpl::onFilterImage(SkSpecialImage* U8CPU outerThreshold = (U8CPU)(fOuterThreshold * 0xFF); SkColor* dptr = dst.getAddr32(0, 0); int dstWidth = dst.width(), dstHeight = dst.height(); + SkIPoint srcOffset = { bounds.fLeft - inputOffset.fX, bounds.fTop - inputOffset.fY }; for (int y = 0; y < dstHeight; ++y) { - const SkColor* sptr = inputBM.getAddr32(bounds.fLeft, bounds.fTop+y); + const SkColor* sptr = inputBM.getAddr32(srcOffset.fX, srcOffset.fY+y); for (int x = 0; x < dstWidth; ++x) { const SkColor& source = sptr[x]; -- cgit v1.2.3