blob: 0101a9c2a042816f2237874ccf1a15da4ea7f2b4 [file] [log] [blame]
reed@google.com8926b162012-03-23 15:36:36 +00001/*
2 * Copyright 2011 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 "SkColorFilter.h"
11#include "SkColorPriv.h"
12#include "SkShader.h"
13
14#include "SkBlurImageFilter.h"
senorblanco@chromium.org44888c62012-08-20 19:23:24 +000015#include "SkColorFilterImageFilter.h"
junov@chromium.orgf44fcdc2013-08-07 20:00:55 +000016#include "SkDropShadowImageFilter.h"
reed@google.com8926b162012-03-23 15:36:36 +000017#include "SkTestImageFilters.h"
18
19class FailImageFilter : public SkImageFilter {
20public:
reed7daaaa42014-08-21 10:53:34 -070021 class Registrar {
22 public:
23 Registrar() {
24 SkFlattenable::Register("FailImageFilter",
reed7daaaa42014-08-21 10:53:34 -070025 FailImageFilter::CreateProc,
reed7daaaa42014-08-21 10:53:34 -070026 FailImageFilter::GetFlattenableType());
27 }
28 };
halcanary385fe4d2015-08-26 13:07:48 -070029 static FailImageFilter* Create() { return new FailImageFilter; }
djsollen@google.comba28d032012-03-26 17:57:35 +000030
robertphillipsf3f5bad2014-12-19 13:49:15 -080031 SK_TO_STRING_OVERRIDE()
djsollen@google.comba28d032012-03-26 17:57:35 +000032 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(FailImageFilter)
reed9fa60da2014-08-21 07:59:51 -070033
reed@google.com8926b162012-03-23 15:36:36 +000034protected:
halcanary96fcdcc2015-08-27 07:41:13 -070035 FailImageFilter() : INHERITED(0, nullptr) {}
reed9fa60da2014-08-21 07:59:51 -070036
reed8dc0ccb2015-03-20 06:32:52 -070037 bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
mtklein36352bf2015-03-25 18:17:31 -070038 SkBitmap* result, SkIPoint* offset) const override {
reed@google.com8926b162012-03-23 15:36:36 +000039 return false;
40 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000041
reed@google.com8926b162012-03-23 15:36:36 +000042private:
reed@google.com8926b162012-03-23 15:36:36 +000043 typedef SkImageFilter INHERITED;
44};
45
reed7daaaa42014-08-21 10:53:34 -070046static FailImageFilter::Registrar gReg0;
47
reed9fa60da2014-08-21 07:59:51 -070048SkFlattenable* FailImageFilter::CreateProc(SkReadBuffer& buffer) {
49 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 0);
50 return FailImageFilter::Create();
51}
djsollen@google.comba28d032012-03-26 17:57:35 +000052
robertphillipsf3f5bad2014-12-19 13:49:15 -080053#ifndef SK_IGNORE_TO_STRING
54void FailImageFilter::toString(SkString* str) const {
55 str->appendf("FailImageFilter: (");
56 str->append(")");
57}
58#endif
59
reed@google.com8926b162012-03-23 15:36:36 +000060class IdentityImageFilter : public SkImageFilter {
61public:
reed7daaaa42014-08-21 10:53:34 -070062 class Registrar {
63 public:
64 Registrar() {
65 SkFlattenable::Register("IdentityImageFilter",
reed7daaaa42014-08-21 10:53:34 -070066 IdentityImageFilter::CreateProc,
reed7daaaa42014-08-21 10:53:34 -070067 IdentityImageFilter::GetFlattenableType());
68 }
69 };
halcanary96fcdcc2015-08-27 07:41:13 -070070 static IdentityImageFilter* Create(SkImageFilter* input = nullptr) {
halcanary385fe4d2015-08-26 13:07:48 -070071 return new IdentityImageFilter(input);
commit-bot@chromium.orgcac5fd52014-03-10 10:51:58 +000072 }
reed@google.com8926b162012-03-23 15:36:36 +000073
robertphillipsf3f5bad2014-12-19 13:49:15 -080074 SK_TO_STRING_OVERRIDE()
djsollen@google.comba28d032012-03-26 17:57:35 +000075 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(IdentityImageFilter)
reed@google.com8926b162012-03-23 15:36:36 +000076protected:
reed7daaaa42014-08-21 10:53:34 -070077 IdentityImageFilter(SkImageFilter* input) : INHERITED(1, &input) {}
reed9fa60da2014-08-21 07:59:51 -070078
reed8dc0ccb2015-03-20 06:32:52 -070079 bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
mtklein36352bf2015-03-25 18:17:31 -070080 SkBitmap* result, SkIPoint* offset) const override {
reed@google.com8926b162012-03-23 15:36:36 +000081 *result = src;
commit-bot@chromium.orgf7efa502014-04-11 18:57:00 +000082 offset->set(0, 0);
reed@google.com8926b162012-03-23 15:36:36 +000083 return true;
84 }
85
reed@google.com8926b162012-03-23 15:36:36 +000086private:
reed@google.com8926b162012-03-23 15:36:36 +000087 typedef SkImageFilter INHERITED;
88};
89
reed7daaaa42014-08-21 10:53:34 -070090static IdentityImageFilter::Registrar gReg1;
91
reed9fa60da2014-08-21 07:59:51 -070092SkFlattenable* IdentityImageFilter::CreateProc(SkReadBuffer& buffer) {
93 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
94 return IdentityImageFilter::Create(common.getInput(0));
95}
djsollen@google.comba28d032012-03-26 17:57:35 +000096
robertphillipsf3f5bad2014-12-19 13:49:15 -080097#ifndef SK_IGNORE_TO_STRING
98void IdentityImageFilter::toString(SkString* str) const {
99 str->appendf("IdentityImageFilter: (");
100 str->append(")");
101}
102#endif
103
reed@google.com8926b162012-03-23 15:36:36 +0000104///////////////////////////////////////////////////////////////////////////////
105
106static void draw_paint(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
107 SkPaint paint;
108 paint.setImageFilter(imf);
109 paint.setColor(SK_ColorGREEN);
110 canvas->save();
111 canvas->clipRect(r);
112 canvas->drawPaint(paint);
113 canvas->restore();
114}
115
116static void draw_line(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
117 SkPaint paint;
118 paint.setColor(SK_ColorBLUE);
119 paint.setImageFilter(imf);
120 paint.setStrokeWidth(r.width()/10);
121 canvas->drawLine(r.fLeft, r.fTop, r.fRight, r.fBottom, paint);
122}
123
124static void draw_rect(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
125 SkPaint paint;
126 paint.setColor(SK_ColorYELLOW);
127 paint.setImageFilter(imf);
128 SkRect rr(r);
129 rr.inset(r.width()/10, r.height()/10);
130 canvas->drawRect(rr, paint);
131}
132
133static void draw_path(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
134 SkPaint paint;
135 paint.setColor(SK_ColorMAGENTA);
136 paint.setImageFilter(imf);
137 paint.setAntiAlias(true);
138 canvas->drawCircle(r.centerX(), r.centerY(), r.width()*2/5, paint);
139}
140
141static void draw_text(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
142 SkPaint paint;
143 paint.setImageFilter(imf);
144 paint.setColor(SK_ColorCYAN);
145 paint.setAntiAlias(true);
caryclark1818acb2015-07-24 12:09:25 -0700146 sk_tool_utils::set_portable_typeface(&paint);
reed@google.com8926b162012-03-23 15:36:36 +0000147 paint.setTextSize(r.height()/2);
148 paint.setTextAlign(SkPaint::kCenter_Align);
149 canvas->drawText("Text", 4, r.centerX(), r.centerY(), paint);
150}
151
152static void draw_bitmap(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
153 SkPaint paint;
154 paint.setImageFilter(imf);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000155
reed@google.com8926b162012-03-23 15:36:36 +0000156 SkIRect bounds;
157 r.roundOut(&bounds);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000158
reed@google.com8926b162012-03-23 15:36:36 +0000159 SkBitmap bm;
reed@google.comeb9a46c2014-01-25 16:46:20 +0000160 bm.allocN32Pixels(bounds.width(), bounds.height());
junov@google.comdbfac8a2012-12-06 21:47:40 +0000161 bm.eraseColor(SK_ColorTRANSPARENT);
reed@google.com8926b162012-03-23 15:36:36 +0000162 SkCanvas c(bm);
halcanary96fcdcc2015-08-27 07:41:13 -0700163 draw_path(&c, r, nullptr);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000164
reed@google.com8926b162012-03-23 15:36:36 +0000165 canvas->drawBitmap(bm, 0, 0, &paint);
166}
167
168static void draw_sprite(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
169 SkPaint paint;
170 paint.setImageFilter(imf);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000171
reed@google.com8926b162012-03-23 15:36:36 +0000172 SkIRect bounds;
173 r.roundOut(&bounds);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000174
reed@google.com8926b162012-03-23 15:36:36 +0000175 SkBitmap bm;
reed@google.comeb9a46c2014-01-25 16:46:20 +0000176 bm.allocN32Pixels(bounds.width(), bounds.height());
junov@google.comdbfac8a2012-12-06 21:47:40 +0000177 bm.eraseColor(SK_ColorTRANSPARENT);
reed@google.com8926b162012-03-23 15:36:36 +0000178 SkCanvas c(bm);
halcanary96fcdcc2015-08-27 07:41:13 -0700179 draw_path(&c, r, nullptr);
reed@google.com8926b162012-03-23 15:36:36 +0000180
181 SkPoint loc = { r.fLeft, r.fTop };
182 canvas->getTotalMatrix().mapPoints(&loc, 1);
183 canvas->drawSprite(bm,
184 SkScalarRoundToInt(loc.fX), SkScalarRoundToInt(loc.fY),
185 &paint);
186}
187
188///////////////////////////////////////////////////////////////////////////////
189
190class ImageFiltersBaseGM : public skiagm::GM {
191public:
192 ImageFiltersBaseGM () {}
193
194protected:
mtklein36352bf2015-03-25 18:17:31 -0700195 SkString onShortName() override {
reed@google.com8926b162012-03-23 15:36:36 +0000196 return SkString("imagefiltersbase");
197 }
198
mtklein36352bf2015-03-25 18:17:31 -0700199 SkISize onISize() override { return SkISize::Make(700, 500); }
reed@google.com8926b162012-03-23 15:36:36 +0000200
201 void draw_frame(SkCanvas* canvas, const SkRect& r) {
202 SkPaint paint;
203 paint.setStyle(SkPaint::kStroke_Style);
204 paint.setColor(SK_ColorRED);
205 canvas->drawRect(r, paint);
206 }
207
mtklein36352bf2015-03-25 18:17:31 -0700208 void onDraw(SkCanvas* canvas) override {
reed@google.com8926b162012-03-23 15:36:36 +0000209 void (*drawProc[])(SkCanvas*, const SkRect&, SkImageFilter*) = {
210 draw_paint,
211 draw_line, draw_rect, draw_path, draw_text,
212 draw_bitmap,
213 draw_sprite
214 };
rmistry@google.comd6176b02012-08-23 18:14:13 +0000215
reed@google.com8926b162012-03-23 15:36:36 +0000216 SkColorFilter* cf = SkColorFilter::CreateModeFilter(SK_ColorRED,
217 SkXfermode::kSrcIn_Mode);
218 SkImageFilter* filters[] = {
halcanary96fcdcc2015-08-27 07:41:13 -0700219 nullptr,
commit-bot@chromium.orgcac5fd52014-03-10 10:51:58 +0000220 IdentityImageFilter::Create(),
221 FailImageFilter::Create(),
senorblanco@chromium.orgcd9f5592012-10-26 19:37:00 +0000222 SkColorFilterImageFilter::Create(cf),
commit-bot@chromium.orgcac5fd52014-03-10 10:51:58 +0000223 SkBlurImageFilter::Create(12.0f, 0.0f),
sugoi234f0362014-10-23 13:59:52 -0700224 SkDropShadowImageFilter::Create(10.0f, 5.0f, 3.0f, 3.0f, SK_ColorBLUE,
225 SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode),
reed@google.com8926b162012-03-23 15:36:36 +0000226 };
227 cf->unref();
228
229 SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));
230 SkScalar MARGIN = SkIntToScalar(16);
231 SkScalar DX = r.width() + MARGIN;
232 SkScalar DY = r.height() + MARGIN;
233
234 canvas->translate(MARGIN, MARGIN);
235 for (size_t i = 0; i < SK_ARRAY_COUNT(drawProc); ++i) {
236 canvas->save();
237 for (size_t j = 0; j < SK_ARRAY_COUNT(filters); ++j) {
238 drawProc[i](canvas, r, filters[j]);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000239
reed@google.com8926b162012-03-23 15:36:36 +0000240 draw_frame(canvas, r);
241 canvas->translate(0, DY);
242 }
243 canvas->restore();
244 canvas->translate(DX, 0);
245 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000246
reed@google.com4bca84d2012-06-27 14:00:06 +0000247 for(size_t j = 0; j < SK_ARRAY_COUNT(filters); ++j) {
248 SkSafeUnref(filters[j]);
249 }
reed@google.com8926b162012-03-23 15:36:36 +0000250 }
251
252private:
253 typedef GM INHERITED;
254};
reed8dc0ccb2015-03-20 06:32:52 -0700255DEF_GM( return new ImageFiltersBaseGM; )
reed@google.com8926b162012-03-23 15:36:36 +0000256
257///////////////////////////////////////////////////////////////////////////////
258
reed8dc0ccb2015-03-20 06:32:52 -0700259/*
260 * Want to test combos of filter and LCD text, to be sure we disable LCD in the presence of
261 * a filter.
262 */
263class ImageFiltersTextBaseGM : public skiagm::GM {
264 SkString fSuffix;
265public:
266 ImageFiltersTextBaseGM(const char suffix[]) : fSuffix(suffix) {}
267
268protected:
mtklein36352bf2015-03-25 18:17:31 -0700269 SkString onShortName() override {
reed8dc0ccb2015-03-20 06:32:52 -0700270 SkString name;
271 name.printf("%s_%s", "textfilter", fSuffix.c_str());
272 return name;
273 }
274
mtklein36352bf2015-03-25 18:17:31 -0700275 SkISize onISize() override { return SkISize::Make(512, 342); }
reed8dc0ccb2015-03-20 06:32:52 -0700276
277 void drawWaterfall(SkCanvas* canvas, const SkPaint& origPaint) {
278 const uint32_t flags[] = {
279 0,
280 SkPaint::kAntiAlias_Flag,
281 SkPaint::kAntiAlias_Flag | SkPaint::kLCDRenderText_Flag,
282 };
283 SkPaint paint(origPaint);
caryclark1818acb2015-07-24 12:09:25 -0700284 sk_tool_utils::set_portable_typeface(&paint);
reed8dc0ccb2015-03-20 06:32:52 -0700285 paint.setTextSize(30);
286
287 SkAutoCanvasRestore acr(canvas, true);
288 for (size_t i = 0; i < SK_ARRAY_COUNT(flags); ++i) {
289 paint.setFlags(flags[i]);
290 canvas->drawText("Hamburgefons", 11, 0, 0, paint);
291 canvas->translate(0, 40);
292 }
293 }
294
295 virtual void installFilter(SkPaint* paint) = 0;
296
mtklein36352bf2015-03-25 18:17:31 -0700297 void onDraw(SkCanvas* canvas) override {
reed8dc0ccb2015-03-20 06:32:52 -0700298 SkPaint paint;
299
300 canvas->translate(20, 40);
301
302 for (int doSaveLayer = 0; doSaveLayer <= 1; ++doSaveLayer) {
303 SkAutoCanvasRestore acr(canvas, true);
304 for (int useFilter = 0; useFilter <= 1; ++useFilter) {
305 SkAutoCanvasRestore acr2(canvas, true);
306
307 SkPaint paint;
308 if (useFilter) {
309 this->installFilter(&paint);
310 }
311 if (doSaveLayer) {
halcanary96fcdcc2015-08-27 07:41:13 -0700312 canvas->saveLayer(nullptr, &paint);
313 paint.setImageFilter(nullptr);
reed8dc0ccb2015-03-20 06:32:52 -0700314 }
315 this->drawWaterfall(canvas, paint);
316
317 acr2.restore();
318 canvas->translate(250, 0);
319 }
320 acr.restore();
321 canvas->translate(0, 200);
322 }
323 }
324
325private:
326 typedef GM INHERITED;
327};
328
329class ImageFiltersText_IF : public ImageFiltersTextBaseGM {
330public:
331 ImageFiltersText_IF() : ImageFiltersTextBaseGM("image") {}
332
mtklein36352bf2015-03-25 18:17:31 -0700333 void installFilter(SkPaint* paint) override {
reed8dc0ccb2015-03-20 06:32:52 -0700334 paint->setImageFilter(SkBlurImageFilter::Create(1.5f, 1.5f))->unref();
335 }
336};
337DEF_GM( return new ImageFiltersText_IF; )
338
339class ImageFiltersText_CF : public ImageFiltersTextBaseGM {
340public:
341 ImageFiltersText_CF() : ImageFiltersTextBaseGM("color") {}
342
mtklein36352bf2015-03-25 18:17:31 -0700343 void installFilter(SkPaint* paint) override {
reed8dc0ccb2015-03-20 06:32:52 -0700344 paint->setColorFilter(SkColorFilter::CreateModeFilter(SK_ColorBLUE, SkXfermode::kSrcIn_Mode))->unref();
345 }
346};
347DEF_GM( return new ImageFiltersText_CF; )
348