|  | /* | 
|  | * Copyright 2015 Google Inc. | 
|  | * | 
|  | * Use of this source code is governed by a BSD-style license that can be | 
|  | * found in the LICENSE file. | 
|  | */ | 
|  |  | 
|  | #include "gm.h" | 
|  | #include "SkCanvas.h" | 
|  | #include "SkBlurImageFilter.h" | 
|  | #include "SkColorFilterImageFilter.h" | 
|  | #include "SkModeColorFilter.h" | 
|  | #include "SkMorphologyImageFilter.h" | 
|  | #include "SkOffsetImageFilter.h" | 
|  | #include "SkSurface.h" | 
|  | #include "sk_tool_utils.h" | 
|  |  | 
|  | static sk_sp<SkImage> make_image(SkCanvas* rootCanvas) { | 
|  | SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100); | 
|  | auto surface(sk_tool_utils::makeSurface(rootCanvas, info)); | 
|  |  | 
|  | SkPaint paint; | 
|  | paint.setAntiAlias(true); | 
|  | paint.setColor(SK_ColorRED); | 
|  | surface->getCanvas()->drawCircle(50, 50, 50, paint); | 
|  | return surface->makeImageSnapshot(); | 
|  | } | 
|  |  | 
|  | static void show_image(SkCanvas* canvas, SkImage* image, sk_sp<SkImageFilter> filter) { | 
|  | SkPaint paint; | 
|  | paint.setStyle(SkPaint::kStroke_Style); | 
|  | SkRect r = SkRect::MakeIWH(image->width(), image->height()).makeOutset(SK_ScalarHalf, | 
|  | SK_ScalarHalf); | 
|  | canvas->drawRect(r, paint); | 
|  |  | 
|  | paint.setStyle(SkPaint::kFill_Style); | 
|  | paint.setImageFilter(filter); | 
|  | canvas->drawImage(image, 0, 0, &paint); | 
|  | } | 
|  |  | 
|  | typedef sk_sp<SkImageFilter> (*ImageFilterFactory)(); | 
|  |  | 
|  | // +[]{...} did not work on windows (VS) | 
|  | // (ImageFilterFactory)[]{...} did not work on linux (gcc) | 
|  | // hence this cast function | 
|  | template <typename T> ImageFilterFactory IFCCast(T arg) { return arg; } | 
|  |  | 
|  | // Show the effect of localmatriximagefilter with various matrices, on various filters | 
|  | DEF_SIMPLE_GM(localmatriximagefilter, canvas, 640, 640) { | 
|  | sk_sp<SkImage> image0(make_image(canvas)); | 
|  |  | 
|  | const ImageFilterFactory factories[] = { | 
|  | IFCCast([]{ return SkBlurImageFilter::Make(8, 8, nullptr); }), | 
|  | IFCCast([]{ return SkDilateImageFilter::Make(8, 8, nullptr); }), | 
|  | IFCCast([]{ return SkErodeImageFilter::Make(8, 8, nullptr); }), | 
|  | IFCCast([]{ return SkOffsetImageFilter::Make(8, 8, nullptr); }), | 
|  | }; | 
|  |  | 
|  | const SkMatrix matrices[] = { | 
|  | SkMatrix::MakeScale(SK_ScalarHalf, SK_ScalarHalf), | 
|  | SkMatrix::MakeScale(2, 2), | 
|  | SkMatrix::MakeTrans(10, 10) | 
|  | }; | 
|  |  | 
|  | const SkScalar spacer = image0->width() * 3.0f / 2; | 
|  |  | 
|  | canvas->translate(40, 40); | 
|  | for (auto&& factory : factories) { | 
|  | sk_sp<SkImageFilter> filter(factory()); | 
|  |  | 
|  | canvas->save(); | 
|  | show_image(canvas, image0.get(), filter); | 
|  | for (const auto& matrix : matrices) { | 
|  | sk_sp<SkImageFilter> localFilter(filter->makeWithLocalMatrix(matrix)); | 
|  | canvas->translate(spacer, 0); | 
|  | show_image(canvas, image0.get(), std::move(localFilter)); | 
|  | } | 
|  | canvas->restore(); | 
|  | canvas->translate(0, spacer); | 
|  | } | 
|  | } |