1 /*
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"
15 #include "SkColorFilterImageFilter.h"
16 #include "SkDropShadowImageFilter.h"
17 #include "SkTestImageFilters.h"
18
19 class FailImageFilter : public SkImageFilter {
20 public:
21 class Registrar {
22 public:
Registrar()23 Registrar() {
24 SkFlattenable::Register("FailImageFilter",
25 FailImageFilter::CreateProc,
26 FailImageFilter::GetFlattenableType());
27 }
28 };
Create()29 static FailImageFilter* Create() { return new FailImageFilter; }
30
31 SK_TO_STRING_OVERRIDE()
32 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(FailImageFilter)
33
34 protected:
FailImageFilter()35 FailImageFilter() : INHERITED(0, nullptr) {}
36
onFilterImageDeprecated(Proxy *,const SkBitmap & src,const Context &,SkBitmap * result,SkIPoint * offset) const37 bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&,
38 SkBitmap* result, SkIPoint* offset) const override {
39 return false;
40 }
41
42 private:
43 typedef SkImageFilter INHERITED;
44 };
45
46 static FailImageFilter::Registrar gReg0;
47
CreateProc(SkReadBuffer & buffer)48 SkFlattenable* FailImageFilter::CreateProc(SkReadBuffer& buffer) {
49 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 0);
50 return FailImageFilter::Create();
51 }
52
53 #ifndef SK_IGNORE_TO_STRING
toString(SkString * str) const54 void FailImageFilter::toString(SkString* str) const {
55 str->appendf("FailImageFilter: (");
56 str->append(")");
57 }
58 #endif
59
60 class IdentityImageFilter : public SkImageFilter {
61 public:
62 class Registrar {
63 public:
Registrar()64 Registrar() {
65 SkFlattenable::Register("IdentityImageFilter",
66 IdentityImageFilter::CreateProc,
67 IdentityImageFilter::GetFlattenableType());
68 }
69 };
Create(SkImageFilter * input=nullptr)70 static IdentityImageFilter* Create(SkImageFilter* input = nullptr) {
71 return new IdentityImageFilter(input);
72 }
73
74 SK_TO_STRING_OVERRIDE()
75 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(IdentityImageFilter)
76 protected:
IdentityImageFilter(SkImageFilter * input)77 IdentityImageFilter(SkImageFilter* input) : INHERITED(1, &input) {}
78
onFilterImageDeprecated(Proxy *,const SkBitmap & src,const Context &,SkBitmap * result,SkIPoint * offset) const79 bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&,
80 SkBitmap* result, SkIPoint* offset) const override {
81 *result = src;
82 offset->set(0, 0);
83 return true;
84 }
85
86 private:
87 typedef SkImageFilter INHERITED;
88 };
89
90 static IdentityImageFilter::Registrar gReg1;
91
CreateProc(SkReadBuffer & buffer)92 SkFlattenable* IdentityImageFilter::CreateProc(SkReadBuffer& buffer) {
93 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
94 return IdentityImageFilter::Create(common.getInput(0));
95 }
96
97 #ifndef SK_IGNORE_TO_STRING
toString(SkString * str) const98 void IdentityImageFilter::toString(SkString* str) const {
99 str->appendf("IdentityImageFilter: (");
100 str->append(")");
101 }
102 #endif
103
104 ///////////////////////////////////////////////////////////////////////////////
105
draw_paint(SkCanvas * canvas,const SkRect & r,SkImageFilter * imf)106 static 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
draw_line(SkCanvas * canvas,const SkRect & r,SkImageFilter * imf)116 static 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
draw_rect(SkCanvas * canvas,const SkRect & r,SkImageFilter * imf)124 static 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
draw_path(SkCanvas * canvas,const SkRect & r,SkImageFilter * imf)133 static 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
draw_text(SkCanvas * canvas,const SkRect & r,SkImageFilter * imf)141 static 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);
146 sk_tool_utils::set_portable_typeface(&paint);
147 paint.setTextSize(r.height()/2);
148 paint.setTextAlign(SkPaint::kCenter_Align);
149 canvas->drawText("Text", 4, r.centerX(), r.centerY(), paint);
150 }
151
draw_bitmap(SkCanvas * canvas,const SkRect & r,SkImageFilter * imf)152 static void draw_bitmap(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
153 SkPaint paint;
154 paint.setImageFilter(imf);
155
156 SkIRect bounds;
157 r.roundOut(&bounds);
158
159 SkBitmap bm;
160 bm.allocN32Pixels(bounds.width(), bounds.height());
161 bm.eraseColor(SK_ColorTRANSPARENT);
162 SkCanvas c(bm);
163 draw_path(&c, r, nullptr);
164
165 canvas->drawBitmap(bm, 0, 0, &paint);
166 }
167
168 ///////////////////////////////////////////////////////////////////////////////
169
170 class ImageFiltersBaseGM : public skiagm::GM {
171 public:
ImageFiltersBaseGM()172 ImageFiltersBaseGM () {}
173
174 protected:
onShortName()175 SkString onShortName() override {
176 return SkString("imagefiltersbase");
177 }
178
onISize()179 SkISize onISize() override { return SkISize::Make(700, 500); }
180
draw_frame(SkCanvas * canvas,const SkRect & r)181 void draw_frame(SkCanvas* canvas, const SkRect& r) {
182 SkPaint paint;
183 paint.setStyle(SkPaint::kStroke_Style);
184 paint.setColor(SK_ColorRED);
185 canvas->drawRect(r, paint);
186 }
187
onDraw(SkCanvas * canvas)188 void onDraw(SkCanvas* canvas) override {
189 void (*drawProc[])(SkCanvas*, const SkRect&, SkImageFilter*) = {
190 draw_paint,
191 draw_line, draw_rect, draw_path, draw_text,
192 draw_bitmap,
193 };
194
195 SkColorFilter* cf = SkColorFilter::CreateModeFilter(SK_ColorRED,
196 SkXfermode::kSrcIn_Mode);
197 SkImageFilter* filters[] = {
198 nullptr,
199 IdentityImageFilter::Create(),
200 FailImageFilter::Create(),
201 SkColorFilterImageFilter::Create(cf),
202 SkBlurImageFilter::Create(12.0f, 0.0f),
203 SkDropShadowImageFilter::Create(10.0f, 5.0f, 3.0f, 3.0f, SK_ColorBLUE,
204 SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode),
205 };
206 cf->unref();
207
208 SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));
209 SkScalar MARGIN = SkIntToScalar(16);
210 SkScalar DX = r.width() + MARGIN;
211 SkScalar DY = r.height() + MARGIN;
212
213 canvas->translate(MARGIN, MARGIN);
214 for (size_t i = 0; i < SK_ARRAY_COUNT(drawProc); ++i) {
215 canvas->save();
216 for (size_t j = 0; j < SK_ARRAY_COUNT(filters); ++j) {
217 drawProc[i](canvas, r, filters[j]);
218
219 draw_frame(canvas, r);
220 canvas->translate(0, DY);
221 }
222 canvas->restore();
223 canvas->translate(DX, 0);
224 }
225
226 for(size_t j = 0; j < SK_ARRAY_COUNT(filters); ++j) {
227 SkSafeUnref(filters[j]);
228 }
229 }
230
231 private:
232 typedef GM INHERITED;
233 };
234 DEF_GM( return new ImageFiltersBaseGM; )
235
236 ///////////////////////////////////////////////////////////////////////////////
237
238 /*
239 * Want to test combos of filter and LCD text, to be sure we disable LCD in the presence of
240 * a filter.
241 */
242 class ImageFiltersTextBaseGM : public skiagm::GM {
243 SkString fSuffix;
244 public:
ImageFiltersTextBaseGM(const char suffix[])245 ImageFiltersTextBaseGM(const char suffix[]) : fSuffix(suffix) {}
246
247 protected:
onShortName()248 SkString onShortName() override {
249 SkString name;
250 name.printf("%s_%s", "textfilter", fSuffix.c_str());
251 return name;
252 }
253
onISize()254 SkISize onISize() override { return SkISize::Make(512, 342); }
255
drawWaterfall(SkCanvas * canvas,const SkPaint & origPaint)256 void drawWaterfall(SkCanvas* canvas, const SkPaint& origPaint) {
257 const uint32_t flags[] = {
258 0,
259 SkPaint::kAntiAlias_Flag,
260 SkPaint::kAntiAlias_Flag | SkPaint::kLCDRenderText_Flag,
261 };
262 SkPaint paint(origPaint);
263 sk_tool_utils::set_portable_typeface(&paint);
264 paint.setTextSize(30);
265
266 SkAutoCanvasRestore acr(canvas, true);
267 for (size_t i = 0; i < SK_ARRAY_COUNT(flags); ++i) {
268 paint.setFlags(flags[i]);
269 canvas->drawText("Hamburgefons", 11, 0, 0, paint);
270 canvas->translate(0, 40);
271 }
272 }
273
274 virtual void installFilter(SkPaint* paint) = 0;
275
onDraw(SkCanvas * canvas)276 void onDraw(SkCanvas* canvas) override {
277 SkPaint paint;
278
279 canvas->translate(20, 40);
280
281 for (int doSaveLayer = 0; doSaveLayer <= 1; ++doSaveLayer) {
282 SkAutoCanvasRestore acr(canvas, true);
283 for (int useFilter = 0; useFilter <= 1; ++useFilter) {
284 SkAutoCanvasRestore acr2(canvas, true);
285
286 SkPaint paint;
287 if (useFilter) {
288 this->installFilter(&paint);
289 }
290 if (doSaveLayer) {
291 canvas->saveLayer(nullptr, &paint);
292 paint.setImageFilter(nullptr);
293 }
294 this->drawWaterfall(canvas, paint);
295
296 acr2.restore();
297 canvas->translate(250, 0);
298 }
299 acr.restore();
300 canvas->translate(0, 200);
301 }
302 }
303
304 private:
305 typedef GM INHERITED;
306 };
307
308 class ImageFiltersText_IF : public ImageFiltersTextBaseGM {
309 public:
ImageFiltersText_IF()310 ImageFiltersText_IF() : ImageFiltersTextBaseGM("image") {}
311
installFilter(SkPaint * paint)312 void installFilter(SkPaint* paint) override {
313 paint->setImageFilter(SkBlurImageFilter::Create(1.5f, 1.5f))->unref();
314 }
315 };
316 DEF_GM( return new ImageFiltersText_IF; )
317
318 class ImageFiltersText_CF : public ImageFiltersTextBaseGM {
319 public:
ImageFiltersText_CF()320 ImageFiltersText_CF() : ImageFiltersTextBaseGM("color") {}
321
installFilter(SkPaint * paint)322 void installFilter(SkPaint* paint) override {
323 paint->setColorFilter(SkColorFilter::CreateModeFilter(SK_ColorBLUE, SkXfermode::kSrcIn_Mode))->unref();
324 }
325 };
326 DEF_GM( return new ImageFiltersText_CF; )
327
328