1/* 2 * Copyright 2012 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 "gm.h" 9#include "SkCanvas.h" 10#include "SkColorMatrixFilter.h" 11#include "SkColorPriv.h" 12#include "SkShader.h" 13 14#include "SkBlurImageFilter.h" 15#include "SkColorFilterImageFilter.h" 16#include "SkTDArray.h" 17 18#define FILTER_WIDTH SkIntToScalar(30) 19#define FILTER_HEIGHT SkIntToScalar(30) 20#define MARGIN SkIntToScalar(10) 21 22static sk_sp<SkColorFilter> cf_make_brightness(float brightness) { 23 SkScalar amount255 = brightness * 255; 24 SkScalar matrix[20] = { 25 1, 0, 0, 0, amount255, 26 0, 1, 0, 0, amount255, 27 0, 0, 1, 0, amount255, 28 0, 0, 0, 1, 0 }; 29 return SkColorFilter::MakeMatrixFilterRowMajor255(matrix); 30} 31 32static sk_sp<SkColorFilter> cf_make_grayscale() { 33 SkScalar matrix[20]; 34 memset(matrix, 0, 20 * sizeof(SkScalar)); 35 matrix[0] = matrix[5] = matrix[10] = 0.2126f; 36 matrix[1] = matrix[6] = matrix[11] = 0.7152f; 37 matrix[2] = matrix[7] = matrix[12] = 0.0722f; 38 matrix[18] = 1.0f; 39 return SkColorFilter::MakeMatrixFilterRowMajor255(matrix); 40} 41 42static sk_sp<SkColorFilter> cf_make_colorize(SkColor color) { 43 return SkColorFilter::MakeModeFilter(color, SkBlendMode::kSrc); 44} 45 46static void sk_gm_get_colorfilters(SkTArray<sk_sp<SkColorFilter>>* array) { 47 array->push_back(cf_make_brightness(0.5f)); 48 array->push_back(cf_make_grayscale()); 49 array->push_back(cf_make_colorize(SK_ColorBLUE)); 50} 51 52/////////////////////////////////////////////////////////////////////////////////////////////////// 53#include "SkGradientShader.h" 54#include "SkImage.h" 55#include "Resources.h" 56 57static sk_sp<SkShader> sh_make_lineargradient0() { 58 const SkPoint pts[] = { { 0, 0 }, { 100, 100 } }; 59 const SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE }; 60 return SkGradientShader::MakeLinear(pts, colors, nullptr, 3, SkShader::kRepeat_TileMode); 61} 62 63static sk_sp<SkShader> sh_make_lineargradient1() { 64 const SkPoint pts[] = { { 0, 0 }, { 100, 100 } }; 65 const SkColor colors[] = { SK_ColorRED, 0x0000FF00, SK_ColorBLUE }; 66 return SkGradientShader::MakeLinear(pts, colors, nullptr, 3, SkShader::kRepeat_TileMode); 67} 68 69static sk_sp<SkShader> sh_make_image() { 70 sk_sp<SkImage> image(GetResourceAsImage("images/mandrill_128.png")); 71 if (!image) { 72 return nullptr; 73 } 74 return image->makeShader(SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); 75} 76 77static void sk_gm_get_shaders(SkTDArray<SkShader*>* array) { 78 if (auto shader = sh_make_lineargradient0()) { 79 *array->append() = shader.release(); 80 } 81 if (auto shader = sh_make_lineargradient1()) { 82 *array->append() = shader.release(); 83 } 84 if (auto shader = sh_make_image()) { 85 *array->append() = shader.release(); 86 } 87} 88 89/////////////////////////////////////////////////////////////////////////////////////////////////// 90 91static sk_sp<SkImageFilter> make_blur(float amount, sk_sp<SkImageFilter> input) { 92 return SkBlurImageFilter::Make(amount, amount, std::move(input)); 93} 94 95static sk_sp<SkImageFilter> make_brightness(float amount, sk_sp<SkImageFilter> input) { 96 return SkColorFilterImageFilter::Make(cf_make_brightness(amount), std::move(input)); 97} 98 99static sk_sp<SkImageFilter> make_grayscale(sk_sp<SkImageFilter> input) { 100 return SkColorFilterImageFilter::Make(cf_make_grayscale(), std::move(input)); 101} 102 103static sk_sp<SkImageFilter> make_mode_blue(sk_sp<SkImageFilter> input) { 104 return SkColorFilterImageFilter::Make(cf_make_colorize(SK_ColorBLUE), std::move(input)); 105} 106 107static void draw_clipped_rect(SkCanvas* canvas, 108 const SkRect& r, 109 const SkPaint& paint, 110 float outset = 0.0f) { 111 canvas->save(); 112 SkRect clip(r); 113 clip.outset(outset, outset); 114 canvas->clipRect(clip); 115 canvas->drawRect(r, paint); 116 canvas->restore(); 117} 118 119DEF_SIMPLE_GM(colorfilterimagefilter, canvas, 400, 100){ 120 SkRect r = SkRect::MakeWH(FILTER_WIDTH, FILTER_HEIGHT); 121 SkPaint paint; 122 paint.setColor(SK_ColorRED); 123 canvas->save(); 124 for (float brightness = -1.0f; brightness <= 1.0f; brightness += 0.2f) { 125 sk_sp<SkImageFilter> dim(make_brightness(-brightness, nullptr)); 126 sk_sp<SkImageFilter> bright(make_brightness(brightness, std::move(dim))); 127 paint.setImageFilter(std::move(bright)); 128 draw_clipped_rect(canvas, r, paint); 129 canvas->translate(FILTER_WIDTH + MARGIN, 0); 130 } 131 canvas->restore(); 132 canvas->translate(0, FILTER_HEIGHT + MARGIN); 133 { 134 sk_sp<SkImageFilter> brightness(make_brightness(0.9f, nullptr)); 135 sk_sp<SkImageFilter> grayscale(make_grayscale(std::move(brightness))); 136 paint.setImageFilter(std::move(grayscale)); 137 draw_clipped_rect(canvas, r, paint); 138 canvas->translate(FILTER_WIDTH + MARGIN, 0); 139 } 140 { 141 sk_sp<SkImageFilter> grayscale(make_grayscale(nullptr)); 142 sk_sp<SkImageFilter> brightness(make_brightness(0.9f, std::move(grayscale))); 143 paint.setImageFilter(std::move(brightness)); 144 draw_clipped_rect(canvas, r, paint); 145 canvas->translate(FILTER_WIDTH + MARGIN, 0); 146 } 147 { 148 sk_sp<SkImageFilter> blue(make_mode_blue(nullptr)); 149 sk_sp<SkImageFilter> brightness(make_brightness(1.0f, std::move(blue))); 150 paint.setImageFilter(std::move(brightness)); 151 draw_clipped_rect(canvas, r, paint); 152 canvas->translate(FILTER_WIDTH + MARGIN, 0); 153 } 154 { 155 sk_sp<SkImageFilter> brightness(make_brightness(1.0f, nullptr)); 156 sk_sp<SkImageFilter> blue(make_mode_blue(std::move(brightness))); 157 paint.setImageFilter(std::move(blue)); 158 draw_clipped_rect(canvas, r, paint); 159 canvas->translate(FILTER_WIDTH + MARGIN, 0); 160 } 161 { 162 sk_sp<SkImageFilter> blur(make_blur(3.0f, nullptr)); 163 sk_sp<SkImageFilter> brightness(make_brightness(0.5f, std::move(blur))); 164 paint.setImageFilter(std::move(brightness)); 165 draw_clipped_rect(canvas, r, paint, 3); 166 canvas->translate(FILTER_WIDTH + MARGIN, 0); 167 } 168 { 169 sk_sp<SkImageFilter> blue(make_mode_blue(nullptr)); 170 paint.setImageFilter(std::move(blue)); 171 draw_clipped_rect(canvas, r, paint, 5); 172 canvas->translate(FILTER_WIDTH + MARGIN, 0); 173 } 174} 175 176DEF_SIMPLE_GM(colorfilterimagefilter_layer, canvas, 32, 32) { 177 SkAutoCanvasRestore autoCanvasRestore(canvas, false); 178 SkColorMatrix cm; 179 cm.setSaturation(0.0f); 180 sk_sp<SkColorFilter> cf(SkColorFilter::MakeMatrixFilterRowMajor255(cm.fMat)); 181 SkPaint p; 182 p.setImageFilter(SkColorFilterImageFilter::Make(std::move(cf), nullptr)); 183 canvas->saveLayer(nullptr, &p); 184 canvas->clear(SK_ColorRED); 185} 186 187/////////////////////////////////////////////////////////////////////////////////////////////////// 188 189#include "SkGradientShader.h" 190template <typename T> class SkTRefArray : public SkTDArray<T> { 191public: 192 ~SkTRefArray() { this->unrefAll(); } 193}; 194 195DEF_SIMPLE_GM(colorfiltershader, canvas, 610, 610) { 196 SkTArray<sk_sp<SkColorFilter>> filters; 197 sk_gm_get_colorfilters(&filters); 198 199 SkTRefArray<SkShader*> shaders; 200 sk_gm_get_shaders(&shaders); 201 202 const SkColor colors[] = { SK_ColorRED, SK_ColorBLUE }; 203 *shaders.append() = SkGradientShader::MakeTwoPointConical({0, 0}, 50, {0, 0}, 150, 204 colors, nullptr, 2, 205 SkShader::kClamp_TileMode).release(); 206 207 SkPaint paint; 208 SkRect r = SkRect::MakeWH(120, 120); 209 210 canvas->translate(20, 20); 211 for (int y = 0; y < shaders.count(); ++y) { 212 SkShader* shader = shaders[y]; 213 214 canvas->save(); 215 for (int x = -1; x < filters.count(); ++x) { 216 sk_sp<SkColorFilter> filter = x >= 0 ? filters[x] : nullptr; 217 218 paint.setShader(shader->makeWithColorFilter(filter)); 219 canvas->drawRect(r, paint); 220 canvas->translate(150, 0); 221 } 222 canvas->restore(); 223 canvas->translate(0, 150); 224 } 225} 226 227DEF_SIMPLE_GM(mixershader, canvas, 800, 700) { 228 auto shaderA = GetResourceAsImage("images/mandrill_128.png")->makeShader(SkShader::kClamp_TileMode, 229 SkShader::kClamp_TileMode); 230 const SkColor colors[] = { SK_ColorGREEN, 0 }; 231 auto shaderB = SkGradientShader::MakeRadial({60, 60}, 55, colors, nullptr, 2, 232 SkShader::kClamp_TileMode, 233 SkGradientShader::kInterpolateColorsInPremul_Flag, 234 nullptr); 235 const SkBlendMode modes[] = { 236 SkBlendMode::kSrc, SkBlendMode::kModulate, SkBlendMode::kColorBurn, SkBlendMode::kPlus, 237 SkBlendMode::kDstATop, 238 }; 239 SkPaint paint; 240 SkRect r = SkRect::MakeWH(120, 120); 241 242 canvas->translate(10, 10); 243 for (auto mode : modes) { 244 canvas->save(); 245 const int count = 6; 246 for (int x = 0; x < count; ++x) { 247 const float t = x * 1.0f / (count - 1); 248 paint.setShader(SkShader::MakeCompose(shaderA, shaderB, mode, t)); 249 canvas->drawRect(r, paint); 250 canvas->translate(r.width() + 10, 0); 251 } 252 canvas->restore(); 253 canvas->translate(0, r.height() + 20); 254 } 255} 256