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