blob: 70f95ef5bdcc4ac1594aeb8db29562fe56fdd4be [file] [log] [blame]
senorblanco@chromium.org8d21f6c2012-10-12 19:14:06 +00001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "gm/gm.h"
9#include "include/core/SkCanvas.h"
10#include "include/core/SkColorPriv.h"
11#include "include/core/SkShader.h"
12#include "include/effects/SkColorMatrixFilter.h"
senorblanco@chromium.org8d21f6c2012-10-12 19:14:06 +000013
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "include/effects/SkBlurImageFilter.h"
15#include "include/effects/SkColorFilterImageFilter.h"
16#include "include/private/SkTDArray.h"
senorblanco@chromium.org8d21f6c2012-10-12 19:14:06 +000017
18#define FILTER_WIDTH SkIntToScalar(30)
19#define FILTER_HEIGHT SkIntToScalar(30)
20#define MARGIN SkIntToScalar(10)
21
reedd053ce92016-03-22 10:17:23 -070022static sk_sp<SkColorFilter> cf_make_brightness(float brightness) {
Mike Reede869a1e2019-04-30 12:18:54 -040023 float matrix[20] = {
24 1, 0, 0, 0, brightness,
25 0, 1, 0, 0, brightness,
26 0, 0, 1, 0, brightness,
reed3061af42016-01-07 15:47:29 -080027 0, 0, 0, 1, 0 };
Mike Reede869a1e2019-04-30 12:18:54 -040028 return SkColorFilters::Matrix(matrix);
senorblanco@chromium.org8d21f6c2012-10-12 19:14:06 +000029}
30
reedd053ce92016-03-22 10:17:23 -070031static sk_sp<SkColorFilter> cf_make_grayscale() {
Mike Reede869a1e2019-04-30 12:18:54 -040032 float matrix[20];
33 memset(matrix, 0, 20 * sizeof(float));
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +000034 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;
Mike Reede869a1e2019-04-30 12:18:54 -040038 return SkColorFilters::Matrix(matrix);
reed3061af42016-01-07 15:47:29 -080039}
40
reedd053ce92016-03-22 10:17:23 -070041static sk_sp<SkColorFilter> cf_make_colorize(SkColor color) {
Mike Reedb286bc22019-04-08 16:23:20 -040042 return SkColorFilters::Blend(color, SkBlendMode::kSrc);
reed3061af42016-01-07 15:47:29 -080043}
44
reedd053ce92016-03-22 10:17:23 -070045static void sk_gm_get_colorfilters(SkTArray<sk_sp<SkColorFilter>>* array) {
46 array->push_back(cf_make_brightness(0.5f));
47 array->push_back(cf_make_grayscale());
48 array->push_back(cf_make_colorize(SK_ColorBLUE));
reed3061af42016-01-07 15:47:29 -080049}
50
51///////////////////////////////////////////////////////////////////////////////////////////////////
Hal Canary8a001442018-09-19 11:31:27 -040052
Mike Kleinc0bd9f92019-04-23 12:05:21 -050053#include "include/core/SkImage.h"
54#include "include/effects/SkGradientShader.h"
55#include "tools/Resources.h"
reed3061af42016-01-07 15:47:29 -080056
reed2ad1aa62016-03-09 09:50:50 -080057static sk_sp<SkShader> sh_make_lineargradient0() {
reed3061af42016-01-07 15:47:29 -080058 const SkPoint pts[] = { { 0, 0 }, { 100, 100 } };
59 const SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
Mike Reedfae8fce2019-04-03 10:27:45 -040060 return SkGradientShader::MakeLinear(pts, colors, nullptr, 3, SkTileMode::kRepeat);
reed3061af42016-01-07 15:47:29 -080061}
62
reed2ad1aa62016-03-09 09:50:50 -080063static sk_sp<SkShader> sh_make_lineargradient1() {
reed3061af42016-01-07 15:47:29 -080064 const SkPoint pts[] = { { 0, 0 }, { 100, 100 } };
65 const SkColor colors[] = { SK_ColorRED, 0x0000FF00, SK_ColorBLUE };
Mike Reedfae8fce2019-04-03 10:27:45 -040066 return SkGradientShader::MakeLinear(pts, colors, nullptr, 3, SkTileMode::kRepeat);
reed3061af42016-01-07 15:47:29 -080067}
68
reed2ad1aa62016-03-09 09:50:50 -080069static sk_sp<SkShader> sh_make_image() {
Hal Canaryc465d132017-12-08 10:21:31 -050070 sk_sp<SkImage> image(GetResourceAsImage("images/mandrill_128.png"));
bsalomondfe3e502016-01-21 06:44:08 -080071 if (!image) {
72 return nullptr;
73 }
Mike Reedfae8fce2019-04-03 10:27:45 -040074 return image->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat);
reed3061af42016-01-07 15:47:29 -080075}
76
reed57fa2412016-01-07 17:56:33 -080077static void sk_gm_get_shaders(SkTDArray<SkShader*>* array) {
reed2ad1aa62016-03-09 09:50:50 -080078 if (auto shader = sh_make_lineargradient0()) {
79 *array->append() = shader.release();
bsalomondfe3e502016-01-21 06:44:08 -080080 }
reed2ad1aa62016-03-09 09:50:50 -080081 if (auto shader = sh_make_lineargradient1()) {
82 *array->append() = shader.release();
bsalomondfe3e502016-01-21 06:44:08 -080083 }
reed2ad1aa62016-03-09 09:50:50 -080084 if (auto shader = sh_make_image()) {
85 *array->append() = shader.release();
bsalomondfe3e502016-01-21 06:44:08 -080086 }
reed3061af42016-01-07 15:47:29 -080087}
88
89///////////////////////////////////////////////////////////////////////////////////////////////////
90
robertphillips6e7025a2016-04-04 04:31:25 -070091static sk_sp<SkImageFilter> make_blur(float amount, sk_sp<SkImageFilter> input) {
92 return SkBlurImageFilter::Make(amount, amount, std::move(input));
reed3061af42016-01-07 15:47:29 -080093}
94
robertphillips6e7025a2016-04-04 04:31:25 -070095static sk_sp<SkImageFilter> make_brightness(float amount, sk_sp<SkImageFilter> input) {
robertphillips5605b562016-04-05 11:50:42 -070096 return SkColorFilterImageFilter::Make(cf_make_brightness(amount), std::move(input));
reed3061af42016-01-07 15:47:29 -080097}
98
robertphillips6e7025a2016-04-04 04:31:25 -070099static sk_sp<SkImageFilter> make_grayscale(sk_sp<SkImageFilter> input) {
robertphillips5605b562016-04-05 11:50:42 -0700100 return SkColorFilterImageFilter::Make(cf_make_grayscale(), std::move(input));
senorblanco@chromium.org8d21f6c2012-10-12 19:14:06 +0000101}
102
robertphillips6e7025a2016-04-04 04:31:25 -0700103static sk_sp<SkImageFilter> make_mode_blue(sk_sp<SkImageFilter> input) {
robertphillips5605b562016-04-05 11:50:42 -0700104 return SkColorFilterImageFilter::Make(cf_make_colorize(SK_ColorBLUE), std::move(input));
senorblanco@chromium.org8d21f6c2012-10-12 19:14:06 +0000105}
106
robertphillips6e7025a2016-04-04 04:31:25 -0700107static void draw_clipped_rect(SkCanvas* canvas,
108 const SkRect& r,
109 const SkPaint& paint,
110 float outset = 0.0f) {
robertphillips5605b562016-04-05 11:50:42 -0700111 canvas->save();
112 SkRect clip(r);
113 clip.outset(outset, outset);
114 canvas->clipRect(clip);
115 canvas->drawRect(r, paint);
116 canvas->restore();
halcanary2a243382015-09-09 08:16:41 -0700117}
senorblanco@chromium.org8d21f6c2012-10-12 19:14:06 +0000118
halcanary2a243382015-09-09 08:16:41 -0700119DEF_SIMPLE_GM(colorfilterimagefilter, canvas, 400, 100){
senorblanco@chromium.org8d21f6c2012-10-12 19:14:06 +0000120 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) {
robertphillips6e7025a2016-04-04 04:31:25 -0700125 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);
senorblanco@chromium.org8d21f6c2012-10-12 19:14:06 +0000129 canvas->translate(FILTER_WIDTH + MARGIN, 0);
130 }
131 canvas->restore();
132 canvas->translate(0, FILTER_HEIGHT + MARGIN);
133 {
robertphillips6e7025a2016-04-04 04:31:25 -0700134 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);
senorblanco@chromium.org8d21f6c2012-10-12 19:14:06 +0000138 canvas->translate(FILTER_WIDTH + MARGIN, 0);
139 }
140 {
robertphillips6e7025a2016-04-04 04:31:25 -0700141 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);
senorblanco@chromium.org8d21f6c2012-10-12 19:14:06 +0000145 canvas->translate(FILTER_WIDTH + MARGIN, 0);
146 }
147 {
robertphillips6e7025a2016-04-04 04:31:25 -0700148 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);
senorblanco@chromium.org8d21f6c2012-10-12 19:14:06 +0000152 canvas->translate(FILTER_WIDTH + MARGIN, 0);
153 }
154 {
robertphillips6e7025a2016-04-04 04:31:25 -0700155 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);
senorblanco@chromium.org8d21f6c2012-10-12 19:14:06 +0000159 canvas->translate(FILTER_WIDTH + MARGIN, 0);
160 }
161 {
robertphillips6e7025a2016-04-04 04:31:25 -0700162 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);
senorblanco@chromium.org8d21f6c2012-10-12 19:14:06 +0000166 canvas->translate(FILTER_WIDTH + MARGIN, 0);
167 }
senorblanco0abdf762015-08-20 11:10:41 -0700168 {
robertphillips6e7025a2016-04-04 04:31:25 -0700169 sk_sp<SkImageFilter> blue(make_mode_blue(nullptr));
170 paint.setImageFilter(std::move(blue));
171 draw_clipped_rect(canvas, r, paint, 5);
senorblanco0abdf762015-08-20 11:10:41 -0700172 canvas->translate(FILTER_WIDTH + MARGIN, 0);
173 }
halcanary2a243382015-09-09 08:16:41 -0700174}
halcanary287d22d2015-09-24 10:20:05 -0700175
176DEF_SIMPLE_GM(colorfilterimagefilter_layer, canvas, 32, 32) {
177 SkAutoCanvasRestore autoCanvasRestore(canvas, false);
178 SkColorMatrix cm;
179 cm.setSaturation(0.0f);
Mike Reed50d79af2019-04-21 22:17:03 -0400180 sk_sp<SkColorFilter> cf(SkColorFilters::Matrix(cm));
halcanary287d22d2015-09-24 10:20:05 -0700181 SkPaint p;
robertphillips5605b562016-04-05 11:50:42 -0700182 p.setImageFilter(SkColorFilterImageFilter::Make(std::move(cf), nullptr));
Ben Wagnera93a14a2017-08-28 10:34:05 -0400183 canvas->saveLayer(nullptr, &p);
halcanary287d22d2015-09-24 10:20:05 -0700184 canvas->clear(SK_ColorRED);
185}
reed3061af42016-01-07 15:47:29 -0800186
187///////////////////////////////////////////////////////////////////////////////////////////////////
188
Mike Kleinc0bd9f92019-04-23 12:05:21 -0500189#include "include/effects/SkGradientShader.h"
Hal Canary8a001442018-09-19 11:31:27 -0400190
reed57fa2412016-01-07 17:56:33 -0800191template <typename T> class SkTRefArray : public SkTDArray<T> {
192public:
193 ~SkTRefArray() { this->unrefAll(); }
194};
195
Mike Reeda03d4072017-06-01 09:37:57 -0400196DEF_SIMPLE_GM(colorfiltershader, canvas, 610, 610) {
reedd053ce92016-03-22 10:17:23 -0700197 SkTArray<sk_sp<SkColorFilter>> filters;
reed57fa2412016-01-07 17:56:33 -0800198 sk_gm_get_colorfilters(&filters);
199
200 SkTRefArray<SkShader*> shaders;
201 sk_gm_get_shaders(&shaders);
reed3061af42016-01-07 15:47:29 -0800202
Mike Reeda03d4072017-06-01 09:37:57 -0400203 const SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
204 *shaders.append() = SkGradientShader::MakeTwoPointConical({0, 0}, 50, {0, 0}, 150,
205 colors, nullptr, 2,
Mike Reedfae8fce2019-04-03 10:27:45 -0400206 SkTileMode::kClamp).release();
Mike Reeda03d4072017-06-01 09:37:57 -0400207
reed3061af42016-01-07 15:47:29 -0800208 SkPaint paint;
209 SkRect r = SkRect::MakeWH(120, 120);
210
211 canvas->translate(20, 20);
212 for (int y = 0; y < shaders.count(); ++y) {
213 SkShader* shader = shaders[y];
bsalomondfe3e502016-01-21 06:44:08 -0800214
reed3061af42016-01-07 15:47:29 -0800215 canvas->save();
216 for (int x = -1; x < filters.count(); ++x) {
reedd053ce92016-03-22 10:17:23 -0700217 sk_sp<SkColorFilter> filter = x >= 0 ? filters[x] : nullptr;
reed3061af42016-01-07 15:47:29 -0800218
reed150835e2016-03-10 06:36:49 -0800219 paint.setShader(shader->makeWithColorFilter(filter));
reed3061af42016-01-07 15:47:29 -0800220 canvas->drawRect(r, paint);
221 canvas->translate(150, 0);
222 }
223 canvas->restore();
224 canvas->translate(0, 150);
225 }
226}
Mike Reed01b2b832017-06-09 10:51:52 -0400227
Mike Reedc723b702019-03-12 11:49:00 -0400228template <typename Maker> void do_mixershader(SkCanvas* canvas, Maker&& maker) {
Mike Reedfae8fce2019-04-03 10:27:45 -0400229 auto shaderA = GetResourceAsImage("images/mandrill_128.png")->makeShader(SkTileMode::kClamp,
230 SkTileMode::kClamp);
Mike Reed01b2b832017-06-09 10:51:52 -0400231 const SkColor colors[] = { SK_ColorGREEN, 0 };
232 auto shaderB = SkGradientShader::MakeRadial({60, 60}, 55, colors, nullptr, 2,
Mike Reedfae8fce2019-04-03 10:27:45 -0400233 SkTileMode::kClamp,
Mike Reed01b2b832017-06-09 10:51:52 -0400234 SkGradientShader::kInterpolateColorsInPremul_Flag,
235 nullptr);
236 const SkBlendMode modes[] = {
237 SkBlendMode::kSrc, SkBlendMode::kModulate, SkBlendMode::kColorBurn, SkBlendMode::kPlus,
238 SkBlendMode::kDstATop,
239 };
240 SkPaint paint;
241 SkRect r = SkRect::MakeWH(120, 120);
242
243 canvas->translate(10, 10);
244 for (auto mode : modes) {
245 canvas->save();
246 const int count = 6;
247 for (int x = 0; x < count; ++x) {
248 const float t = x * 1.0f / (count - 1);
Mike Reedc723b702019-03-12 11:49:00 -0400249 paint.setShader(maker(shaderA, shaderB, mode, t));
Mike Reed01b2b832017-06-09 10:51:52 -0400250 canvas->drawRect(r, paint);
251 canvas->translate(r.width() + 10, 0);
252 }
253 canvas->restore();
254 canvas->translate(0, r.height() + 20);
255 }
256}
Mike Reedc723b702019-03-12 11:49:00 -0400257
258DEF_SIMPLE_GM(mixershader, canvas, 800, 700) {
259 do_mixershader(canvas, [](sk_sp<SkShader> a, sk_sp<SkShader> b, SkBlendMode mode, float t) {
Mike Reedc8bea7d2019-04-09 13:55:36 -0400260 auto sh = SkShaders::Blend(mode, a, b);
261 return SkShaders::Lerp(t, a, sh);
Mike Reedc723b702019-03-12 11:49:00 -0400262 });
263}
264
Mike Reed376d8122019-03-14 11:39:02 -0400265DEF_SIMPLE_GM(mixershader2, canvas, 800, 700) {
Mike Reedc723b702019-03-12 11:49:00 -0400266 do_mixershader(canvas, [](sk_sp<SkShader> a, sk_sp<SkShader> b, SkBlendMode mode, float t) {
Mike Reedc8bea7d2019-04-09 13:55:36 -0400267 return SkShaders::Lerp(t, a, SkShaders::Blend(mode, a, b));
Mike Reedc723b702019-03-12 11:49:00 -0400268 });
269}