• 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 "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