1/* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "SkBlurImageFilter.h" 9#include "SkColor.h" 10#include "SkDisplacementMapEffect.h" 11#include "SkDropShadowImageFilter.h" 12#include "SkGradientShader.h" 13#include "SkImage.h" 14#include "SkImageSource.h" 15#include "SkMorphologyImageFilter.h" 16#include "SkScalar.h" 17#include "SkSurface.h" 18#include "gm.h" 19#include "sk_tool_utils.h" 20 21namespace skiagm { 22 23// This GM draws image filters with a CTM containing shearing / rotation. 24// It checks that the scale portion of the CTM is correctly extracted 25// and applied to the image inputs separately from the non-scale portion. 26 27static sk_sp<SkImage> make_gradient_circle(int width, int height) { 28 SkScalar x = SkIntToScalar(width / 2); 29 SkScalar y = SkIntToScalar(height / 2); 30 SkScalar radius = SkMinScalar(x, y) * 0.8f; 31 32 auto surface(SkSurface::MakeRasterN32Premul(width, height)); 33 SkCanvas* canvas = surface->getCanvas(); 34 35 canvas->clear(0x00000000); 36 SkColor colors[2]; 37 colors[0] = SK_ColorWHITE; 38 colors[1] = SK_ColorBLACK; 39 SkPaint paint; 40 paint.setShader(SkGradientShader::MakeRadial(SkPoint::Make(x, y), radius, colors, nullptr, 2, 41 SkShader::kClamp_TileMode)); 42 canvas->drawCircle(x, y, radius, paint); 43 44 return surface->makeImageSnapshot(); 45} 46 47class ImageFiltersTransformedGM : public GM { 48public: 49 ImageFiltersTransformedGM() { 50 this->setBGColor(SK_ColorBLACK); 51 } 52 53protected: 54 55 SkString onShortName() override { return SkString("imagefilterstransformed"); } 56 57 SkISize onISize() override { return SkISize::Make(420, 240); } 58 59 void onOnceBeforeDraw() override { 60 fCheckerboard = SkImage::MakeFromBitmap( 61 sk_tool_utils::create_checkerboard_bitmap(64, 64, 0xFFA0A0A0, 0xFF404040, 8)); 62 fGradientCircle = make_gradient_circle(64, 64); 63 } 64 65 void onDraw(SkCanvas* canvas) override { 66 sk_sp<SkImageFilter> gradient(SkImageSource::Make(fGradientCircle)); 67 sk_sp<SkImageFilter> checkerboard(SkImageSource::Make(fCheckerboard)); 68 sk_sp<SkImageFilter> filters[] = { 69 SkBlurImageFilter::Make(12, 0, nullptr), 70 SkDropShadowImageFilter::Make(0, 15, 8, 0, SK_ColorGREEN, 71 SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, nullptr), 72 SkDisplacementMapEffect::Make(SkDisplacementMapEffect::kR_ChannelSelectorType, 73 SkDisplacementMapEffect::kR_ChannelSelectorType, 74 12, 75 std::move(gradient), 76 checkerboard), 77 SkDilateImageFilter::Make(2, 2, checkerboard), 78 SkErodeImageFilter::Make(2, 2, checkerboard), 79 }; 80 81 const SkScalar margin = SkIntToScalar(20); 82 const SkScalar size = SkIntToScalar(60); 83 84 for (size_t j = 0; j < 3; j++) { 85 canvas->save(); 86 canvas->translate(margin, 0); 87 for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) { 88 SkPaint paint; 89 paint.setColor(SK_ColorWHITE); 90 paint.setImageFilter(filters[i]); 91 paint.setAntiAlias(true); 92 canvas->save(); 93 canvas->translate(size * SK_ScalarHalf, size * SK_ScalarHalf); 94 canvas->scale(SkDoubleToScalar(0.8), SkDoubleToScalar(0.8)); 95 if (j == 1) { 96 canvas->rotate(SkIntToScalar(45)); 97 } else if (j == 2) { 98 canvas->skew(SkDoubleToScalar(0.5), SkDoubleToScalar(0.2)); 99 } 100 canvas->translate(-size * SK_ScalarHalf, -size * SK_ScalarHalf); 101 canvas->drawOval(SkRect::MakeXYWH(0, size * SkDoubleToScalar(0.1), 102 size, size * SkDoubleToScalar(0.6)), paint); 103 canvas->restore(); 104 canvas->translate(size + margin, 0); 105 } 106 canvas->restore(); 107 canvas->translate(0, size + margin); 108 } 109 } 110 111private: 112 sk_sp<SkImage> fCheckerboard; 113 sk_sp<SkImage> fGradientCircle; 114 typedef GM INHERITED; 115}; 116DEF_GM( return new ImageFiltersTransformedGM; ) 117} 118 119////////////////////////////////////////////////////////////////////////////// 120#include "SkXfermodeImageFilter.h" 121 122DEF_SIMPLE_GM(rotate_imagefilter, canvas, 500, 500) { 123 SkPaint paint; 124 125 const SkRect r = SkRect::MakeXYWH(50, 50, 100, 100); 126 127 sk_sp<SkImageFilter> filters[] = { 128 nullptr, 129 SkBlurImageFilter::Make(6, 0, nullptr), 130 SkXfermodeImageFilter::Make(SkBlendMode::kSrcOver, nullptr), 131 }; 132 133 for (auto& filter : filters) { 134 paint.setAntiAlias(false); 135 paint.setImageFilter(filter); 136 137 canvas->save(); 138 139 canvas->drawRect(r, paint); 140 141 canvas->translate(150, 0); 142 canvas->save(); 143 canvas->rotate(30, 100, 100); 144 canvas->drawRect(r, paint); 145 canvas->restore(); 146 147 paint.setAntiAlias(true); 148 canvas->translate(150, 0); 149 canvas->save(); 150 canvas->rotate(30, 100, 100); 151 canvas->drawRect(r, paint); 152 canvas->restore(); 153 154 canvas->restore(); 155 canvas->translate(0, 150); 156 } 157} 158