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