blob: d1bd5a72df80c1cafdae882ba79f44c9815c91b9 [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",
25#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
26 FailImageFilter::DeepCreateProc,
27#else
28 FailImageFilter::CreateProc,
29#endif
30 FailImageFilter::GetFlattenableType());
31 }
32 };
commit-bot@chromium.orgcac5fd52014-03-10 10:51:58 +000033 static FailImageFilter* Create() {
34 return SkNEW(FailImageFilter);
35 }
djsollen@google.comba28d032012-03-26 17:57:35 +000036
37 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(FailImageFilter)
reed9fa60da2014-08-21 07:59:51 -070038
reed@google.com8926b162012-03-23 15:36:36 +000039protected:
reed7daaaa42014-08-21 10:53:34 -070040 FailImageFilter() : INHERITED(0, NULL) {}
reed9fa60da2014-08-21 07:59:51 -070041
senorblanco@chromium.org4cb543d2014-03-14 15:44:01 +000042 virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
commit-bot@chromium.orgf7efa502014-04-11 18:57:00 +000043 SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE {
reed@google.com8926b162012-03-23 15:36:36 +000044 return false;
45 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000046
reed9fa60da2014-08-21 07:59:51 -070047#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
48 FailImageFilter(SkReadBuffer& buffer) : INHERITED(0, buffer) {}
49#endif
reed@google.com8926b162012-03-23 15:36:36 +000050
51private:
reed@google.com8926b162012-03-23 15:36:36 +000052 typedef SkImageFilter INHERITED;
53};
54
reed7daaaa42014-08-21 10:53:34 -070055static FailImageFilter::Registrar gReg0;
56
reed9fa60da2014-08-21 07:59:51 -070057SkFlattenable* FailImageFilter::CreateProc(SkReadBuffer& buffer) {
58 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 0);
59 return FailImageFilter::Create();
60}
djsollen@google.comba28d032012-03-26 17:57:35 +000061
reed@google.com8926b162012-03-23 15:36:36 +000062class IdentityImageFilter : public SkImageFilter {
63public:
reed7daaaa42014-08-21 10:53:34 -070064 class Registrar {
65 public:
66 Registrar() {
67 SkFlattenable::Register("IdentityImageFilter",
68#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
69 IdentityImageFilter::DeepCreateProc,
70#else
71 IdentityImageFilter::CreateProc,
72#endif
73 IdentityImageFilter::GetFlattenableType());
74 }
75 };
senorblanco9ea3d572014-07-08 09:16:22 -070076 static IdentityImageFilter* Create(SkImageFilter* input = NULL) {
77 return SkNEW_ARGS(IdentityImageFilter, (input));
commit-bot@chromium.orgcac5fd52014-03-10 10:51:58 +000078 }
reed@google.com8926b162012-03-23 15:36:36 +000079
djsollen@google.comba28d032012-03-26 17:57:35 +000080 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(IdentityImageFilter)
reed@google.com8926b162012-03-23 15:36:36 +000081protected:
reed7daaaa42014-08-21 10:53:34 -070082 IdentityImageFilter(SkImageFilter* input) : INHERITED(1, &input) {}
reed9fa60da2014-08-21 07:59:51 -070083
senorblanco@chromium.org4cb543d2014-03-14 15:44:01 +000084 virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
commit-bot@chromium.orgf7efa502014-04-11 18:57:00 +000085 SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE {
reed@google.com8926b162012-03-23 15:36:36 +000086 *result = src;
commit-bot@chromium.orgf7efa502014-04-11 18:57:00 +000087 offset->set(0, 0);
reed@google.com8926b162012-03-23 15:36:36 +000088 return true;
89 }
90
reed9fa60da2014-08-21 07:59:51 -070091#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
92 IdentityImageFilter(SkReadBuffer& buffer) : INHERITED(1, buffer) {}
93#endif
reed@google.com8926b162012-03-23 15:36:36 +000094
95private:
reed@google.com8926b162012-03-23 15:36:36 +000096 typedef SkImageFilter INHERITED;
97};
98
reed7daaaa42014-08-21 10:53:34 -070099static IdentityImageFilter::Registrar gReg1;
100
reed9fa60da2014-08-21 07:59:51 -0700101SkFlattenable* IdentityImageFilter::CreateProc(SkReadBuffer& buffer) {
102 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
103 return IdentityImageFilter::Create(common.getInput(0));
104}
djsollen@google.comba28d032012-03-26 17:57:35 +0000105
reed@google.com8926b162012-03-23 15:36:36 +0000106///////////////////////////////////////////////////////////////////////////////
107
108static void draw_paint(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
109 SkPaint paint;
110 paint.setImageFilter(imf);
111 paint.setColor(SK_ColorGREEN);
112 canvas->save();
113 canvas->clipRect(r);
114 canvas->drawPaint(paint);
115 canvas->restore();
116}
117
118static void draw_line(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
119 SkPaint paint;
120 paint.setColor(SK_ColorBLUE);
121 paint.setImageFilter(imf);
122 paint.setStrokeWidth(r.width()/10);
123 canvas->drawLine(r.fLeft, r.fTop, r.fRight, r.fBottom, paint);
124}
125
126static void draw_rect(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
127 SkPaint paint;
128 paint.setColor(SK_ColorYELLOW);
129 paint.setImageFilter(imf);
130 SkRect rr(r);
131 rr.inset(r.width()/10, r.height()/10);
132 canvas->drawRect(rr, paint);
133}
134
135static void draw_path(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
136 SkPaint paint;
137 paint.setColor(SK_ColorMAGENTA);
138 paint.setImageFilter(imf);
139 paint.setAntiAlias(true);
140 canvas->drawCircle(r.centerX(), r.centerY(), r.width()*2/5, paint);
141}
142
143static void draw_text(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
144 SkPaint paint;
145 paint.setImageFilter(imf);
146 paint.setColor(SK_ColorCYAN);
147 paint.setAntiAlias(true);
Cary Clark992c7b02014-07-31 08:58:44 -0400148 sk_tool_utils::set_portable_typeface(&paint);
reed@google.com8926b162012-03-23 15:36:36 +0000149 paint.setTextSize(r.height()/2);
150 paint.setTextAlign(SkPaint::kCenter_Align);
151 canvas->drawText("Text", 4, r.centerX(), r.centerY(), paint);
152}
153
154static void draw_bitmap(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
155 SkPaint paint;
156 paint.setImageFilter(imf);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000157
reed@google.com8926b162012-03-23 15:36:36 +0000158 SkIRect bounds;
159 r.roundOut(&bounds);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000160
reed@google.com8926b162012-03-23 15:36:36 +0000161 SkBitmap bm;
reed@google.comeb9a46c2014-01-25 16:46:20 +0000162 bm.allocN32Pixels(bounds.width(), bounds.height());
junov@google.comdbfac8a2012-12-06 21:47:40 +0000163 bm.eraseColor(SK_ColorTRANSPARENT);
reed@google.com8926b162012-03-23 15:36:36 +0000164 SkCanvas c(bm);
165 draw_path(&c, r, NULL);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000166
reed@google.com8926b162012-03-23 15:36:36 +0000167 canvas->drawBitmap(bm, 0, 0, &paint);
168}
169
170static void draw_sprite(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
171 SkPaint paint;
172 paint.setImageFilter(imf);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000173
reed@google.com8926b162012-03-23 15:36:36 +0000174 SkIRect bounds;
175 r.roundOut(&bounds);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000176
reed@google.com8926b162012-03-23 15:36:36 +0000177 SkBitmap bm;
reed@google.comeb9a46c2014-01-25 16:46:20 +0000178 bm.allocN32Pixels(bounds.width(), bounds.height());
junov@google.comdbfac8a2012-12-06 21:47:40 +0000179 bm.eraseColor(SK_ColorTRANSPARENT);
reed@google.com8926b162012-03-23 15:36:36 +0000180 SkCanvas c(bm);
181 draw_path(&c, r, NULL);
182
183 SkPoint loc = { r.fLeft, r.fTop };
184 canvas->getTotalMatrix().mapPoints(&loc, 1);
185 canvas->drawSprite(bm,
186 SkScalarRoundToInt(loc.fX), SkScalarRoundToInt(loc.fY),
187 &paint);
188}
189
190///////////////////////////////////////////////////////////////////////////////
191
192class ImageFiltersBaseGM : public skiagm::GM {
193public:
194 ImageFiltersBaseGM () {}
195
196protected:
reed@google.com8926b162012-03-23 15:36:36 +0000197 virtual SkString onShortName() {
198 return SkString("imagefiltersbase");
199 }
200
junov@chromium.orgf44fcdc2013-08-07 20:00:55 +0000201 virtual SkISize onISize() { return SkISize::Make(700, 500); }
reed@google.com8926b162012-03-23 15:36:36 +0000202
203 void draw_frame(SkCanvas* canvas, const SkRect& r) {
204 SkPaint paint;
205 paint.setStyle(SkPaint::kStroke_Style);
206 paint.setColor(SK_ColorRED);
207 canvas->drawRect(r, paint);
208 }
209
junov@chromium.orgff06af22013-01-14 16:27:50 +0000210 virtual uint32_t onGetFlags() const {
211 // Because of the use of drawSprite, this test is excluded
212 // from scaled replay tests because drawSprite ignores the
213 // reciprocal scale that is applied at record time, which is
214 // the intended behavior of drawSprite.
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +0000215 return kSkipScaledReplay_Flag | kSkipTiled_Flag;
junov@chromium.orgff06af22013-01-14 16:27:50 +0000216 }
217
reed@google.com8926b162012-03-23 15:36:36 +0000218 virtual void onDraw(SkCanvas* canvas) {
219 void (*drawProc[])(SkCanvas*, const SkRect&, SkImageFilter*) = {
220 draw_paint,
221 draw_line, draw_rect, draw_path, draw_text,
222 draw_bitmap,
223 draw_sprite
224 };
rmistry@google.comd6176b02012-08-23 18:14:13 +0000225
reed@google.com8926b162012-03-23 15:36:36 +0000226 SkColorFilter* cf = SkColorFilter::CreateModeFilter(SK_ColorRED,
227 SkXfermode::kSrcIn_Mode);
228 SkImageFilter* filters[] = {
reed@google.com8926b162012-03-23 15:36:36 +0000229 NULL,
commit-bot@chromium.orgcac5fd52014-03-10 10:51:58 +0000230 IdentityImageFilter::Create(),
231 FailImageFilter::Create(),
senorblanco@chromium.orgcd9f5592012-10-26 19:37:00 +0000232 SkColorFilterImageFilter::Create(cf),
commit-bot@chromium.orgcac5fd52014-03-10 10:51:58 +0000233 SkBlurImageFilter::Create(12.0f, 0.0f),
senorblancobc9845b2014-07-22 12:49:25 -0700234 SkDropShadowImageFilter::Create(10.0f, 5.0f, 3.0f, 3.0f, SK_ColorBLUE),
reed@google.com8926b162012-03-23 15:36:36 +0000235 };
236 cf->unref();
237
238 SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));
239 SkScalar MARGIN = SkIntToScalar(16);
240 SkScalar DX = r.width() + MARGIN;
241 SkScalar DY = r.height() + MARGIN;
242
243 canvas->translate(MARGIN, MARGIN);
244 for (size_t i = 0; i < SK_ARRAY_COUNT(drawProc); ++i) {
245 canvas->save();
246 for (size_t j = 0; j < SK_ARRAY_COUNT(filters); ++j) {
247 drawProc[i](canvas, r, filters[j]);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000248
reed@google.com8926b162012-03-23 15:36:36 +0000249 draw_frame(canvas, r);
250 canvas->translate(0, DY);
251 }
252 canvas->restore();
253 canvas->translate(DX, 0);
254 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000255
reed@google.com4bca84d2012-06-27 14:00:06 +0000256 for(size_t j = 0; j < SK_ARRAY_COUNT(filters); ++j) {
257 SkSafeUnref(filters[j]);
258 }
reed@google.com8926b162012-03-23 15:36:36 +0000259 }
260
261private:
262 typedef GM INHERITED;
263};
264
265///////////////////////////////////////////////////////////////////////////////
266
267static skiagm::GM* MyFactory(void*) { return new ImageFiltersBaseGM; }
268static skiagm::GMRegistry reg(MyFactory);