1 
2 /*
3  * Copyright 2011 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 #include "SampleCode.h"
9 #include "SkView.h"
10 #include "SkCanvas.h"
11 #include "SkBlurMaskFilter.h"
12 #include "SkCamera.h"
13 #include "SkColorFilter.h"
14 #include "SkColorPriv.h"
15 #include "SkDevice.h"
16 #include "SkGradientShader.h"
17 #include "SkImageDecoder.h"
18 #include "SkInterpolator.h"
19 #include "SkMaskFilter.h"
20 #include "SkPath.h"
21 #include "SkRegion.h"
22 #include "SkShader.h"
23 #include "SkTime.h"
24 #include "SkTypeface.h"
25 #include "SkUtils.h"
26 #include "SkKey.h"
27 #include "SkXfermode.h"
28 #include "SkDrawFilter.h"
29 
make_paint(SkPaint * paint,const SkMatrix & localMatrix)30 static void make_paint(SkPaint* paint, const SkMatrix& localMatrix) {
31     SkColor colors[] = { 0, SK_ColorWHITE };
32     SkPoint pts[] = { { 0, 0 }, { 0, SK_Scalar1*20 } };
33     SkShader* s = SkGradientShader::CreateLinear(pts, colors, nullptr, 2, SkShader::kClamp_TileMode,
34                                                  0, &localMatrix);
35 
36     paint->setShader(s)->unref();
37     paint->setXfermodeMode(SkXfermode::kDstIn_Mode);
38 }
39 
dump_layers(const char label[],SkCanvas * canvas)40 static void dump_layers(const char label[], SkCanvas* canvas) {
41     SkDebugf("Dump Layers(%s)\n", label);
42 
43     SkCanvas::LayerIter iter(canvas, true);
44     int index = 0;
45     while (!iter.done()) {
46         SkImageInfo info = iter.device()->imageInfo();
47         const SkIRect& clip = iter.clip().getBounds();
48         SkDebugf("Layer[%d] bitmap [%d %d] X=%d Y=%d clip=[%d %d %d %d] alpha=%d\n", index++,
49                  info.width(), info.height(), iter.x(), iter.y(),
50                  clip.fLeft, clip.fTop, clip.fRight, clip.fBottom,
51                  iter.paint().getAlpha());
52         iter.next();
53     }
54 }
55 
56 // test drawing with strips of fading gradient above and below
test_fade(SkCanvas * canvas)57 static void test_fade(SkCanvas* canvas) {
58     SkAutoCanvasRestore ar(canvas, true);
59 
60     SkRect r;
61 
62     SkPaint p;
63     p.setAlpha(0x88);
64 
65     SkAutoCanvasRestore ar2(canvas, false);
66 
67     // create the layers
68 
69     r.set(0, 0, SkIntToScalar(100), SkIntToScalar(100));
70     canvas->clipRect(r);
71 
72     r.fBottom = SkIntToScalar(20);
73     canvas->saveLayer(&r, nullptr);
74 
75     r.fTop = SkIntToScalar(80);
76     r.fBottom = SkIntToScalar(100);
77     canvas->saveLayer(&r, nullptr);
78 
79     // now draw the "content"
80 
81     if (true) {
82         r.set(0, 0, SkIntToScalar(100), SkIntToScalar(100));
83 
84         canvas->saveLayerAlpha(&r, 0x80);
85 
86         SkPaint p;
87         p.setColor(SK_ColorRED);
88         p.setAntiAlias(true);
89         canvas->drawOval(r, p);
90 
91         dump_layers("inside layer alpha", canvas);
92 
93         canvas->restore();
94     } else {
95         r.set(0, 0, SkIntToScalar(100), SkIntToScalar(100));
96 
97         SkPaint p;
98         p.setColor(SK_ColorRED);
99         p.setAntiAlias(true);
100         canvas->drawOval(r, p);
101     }
102 
103 //    return;
104 
105     dump_layers("outside layer alpha", canvas);
106 
107     // now apply an effect
108     SkMatrix m;
109     m.setScale(SK_Scalar1, -SK_Scalar1);
110     m.postTranslate(0, SkIntToScalar(100));
111 
112     SkPaint paint;
113     make_paint(&paint, m);
114     r.set(0, 0, SkIntToScalar(100), SkIntToScalar(20));
115 //    SkDebugf("--------- draw top grad\n");
116     canvas->drawRect(r, paint);
117 
118     r.fTop = SkIntToScalar(80);
119     r.fBottom = SkIntToScalar(100);
120 //    SkDebugf("--------- draw bot grad\n");
121     canvas->drawRect(r, paint);
122 }
123 
124 class RedFilter : public SkDrawFilter {
125 public:
filter(SkPaint * p,SkDrawFilter::Type)126     bool filter(SkPaint* p, SkDrawFilter::Type) override {
127         fColor = p->getColor();
128         if (fColor == SK_ColorRED) {
129             p->setColor(SK_ColorGREEN);
130         }
131         return true;
132     }
133 
134 private:
135     SkColor fColor;
136 };
137 
138 class LayersView : public SkView {
139 public:
LayersView()140     LayersView() {}
141 
142 protected:
143     // overrides from SkEventSink
onQuery(SkEvent * evt)144     bool onQuery(SkEvent* evt) override {
145         if (SampleCode::TitleQ(*evt)) {
146             SampleCode::TitleR(evt, "Layers");
147             return true;
148         }
149         return this->INHERITED::onQuery(evt);
150     }
151 
drawBG(SkCanvas * canvas)152     void drawBG(SkCanvas* canvas) {
153         canvas->drawColor(SK_ColorGRAY);
154     }
155 
onDraw(SkCanvas * canvas)156     void onDraw(SkCanvas* canvas) override {
157         this->drawBG(canvas);
158 
159         if (true) {
160             SkRect r;
161             r.set(SkIntToScalar(0), SkIntToScalar(0),
162                   SkIntToScalar(220), SkIntToScalar(120));
163             SkPaint p;
164             canvas->saveLayer(&r, &p);
165             canvas->drawColor(0xFFFF0000);
166             p.setAlpha(0);  // or 0
167             p.setXfermodeMode(SkXfermode::kSrc_Mode);
168             canvas->drawOval(r, p);
169             canvas->restore();
170             return;
171         }
172 
173         if (false) {
174             SkRect r;
175             r.set(SkIntToScalar(0), SkIntToScalar(0),
176                   SkIntToScalar(220), SkIntToScalar(120));
177             SkPaint p;
178             p.setAlpha(0x88);
179             p.setAntiAlias(true);
180 
181             if (true) {
182                 canvas->saveLayer(&r, &p);
183                 p.setColor(0xFFFF0000);
184                 canvas->drawOval(r, p);
185                 canvas->restore();
186             }
187 
188             p.setColor(0xFF0000FF);
189             r.offset(SkIntToScalar(20), SkIntToScalar(50));
190             canvas->drawOval(r, p);
191         }
192 
193         if (false) {
194             SkPaint p;
195             p.setAlpha(0x88);
196             p.setAntiAlias(true);
197 
198             canvas->translate(SkIntToScalar(300), 0);
199 
200             SkRect r;
201             r.set(SkIntToScalar(0), SkIntToScalar(0),
202                   SkIntToScalar(220), SkIntToScalar(60));
203 
204             canvas->saveLayer(&r, &p);
205 
206             r.set(SkIntToScalar(0), SkIntToScalar(0),
207                   SkIntToScalar(220), SkIntToScalar(120));
208             p.setColor(SK_ColorBLUE);
209             canvas->drawOval(r, p);
210             canvas->restore();
211             return;
212         }
213 
214         test_fade(canvas);
215     }
216 
onFindClickHandler(SkScalar x,SkScalar y,unsigned modi)217     SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
218         this->inval(nullptr);
219 
220         return this->INHERITED::onFindClickHandler(x, y, modi);
221     }
222 
onClick(Click * click)223     bool onClick(Click* click) override {
224         return this->INHERITED::onClick(click);
225     }
226 
handleKey(SkKey)227     virtual bool handleKey(SkKey) {
228         this->inval(nullptr);
229         return true;
230     }
231 
232 private:
233     typedef SkView INHERITED;
234 };
235 DEF_SAMPLE( return new LayersView; )
236 
237 //////////////////////////////////////////////////////////////////////////////
238 
239 #include "SkBlurImageFilter.h"
240 #include "SkMatrixConvolutionImageFilter.h"
241 #include "SkMorphologyImageFilter.h"
242 
243 #include "Resources.h"
244 #include "SkAnimTimer.h"
245 
246 class BackdropView : public SampleView {
247     SkPoint fCenter;
248     SkScalar fAngle;
249     SkAutoTUnref<SkImage> fImage;
250     SkAutoTUnref<SkImageFilter> fFilter;
251 public:
BackdropView()252     BackdropView() {
253         fCenter.set(200, 150);
254         fAngle = 0;
255         fImage.reset(GetResourceAsImage("mandrill_512.png"));
256         fFilter.reset(SkDilateImageFilter::Create(8, 8));
257     }
258 
259 protected:
260     // overrides from SkEventSink
onQuery(SkEvent * evt)261     bool onQuery(SkEvent* evt) override {
262         if (SampleCode::TitleQ(*evt)) {
263             SampleCode::TitleR(evt, "Backdrop");
264             return true;
265         }
266         return this->INHERITED::onQuery(evt);
267     }
268 
onDrawContent(SkCanvas * canvas)269     void onDrawContent(SkCanvas* canvas) override {
270         canvas->drawImage(fImage, 0, 0, nullptr);
271 
272         const SkScalar w = 250;
273         const SkScalar h = 150;
274         SkPath path;
275         path.addOval(SkRect::MakeXYWH(-w/2, -h/2, w, h));
276         SkMatrix m;
277         m.setRotate(fAngle);
278         m.postTranslate(fCenter.x(), fCenter.y());
279         path.transform(m);
280 
281         canvas->clipPath(path, SkRegion::kIntersect_Op, true);
282         const SkRect bounds = path.getBounds();
283 
284         SkPaint paint;
285         paint.setAlpha(0xCC);
286         canvas->saveLayer({ &bounds, &paint, fFilter, 0 });
287 
288         canvas->restore();
289     }
290 
onAnimate(const SkAnimTimer & timer)291     bool onAnimate(const SkAnimTimer& timer) override {
292         fAngle = SkDoubleToScalar(fmod(timer.secs() * 360 / 5, 360));
293         return true;
294     }
295 
onFindClickHandler(SkScalar x,SkScalar y,unsigned modi)296     SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
297         this->inval(nullptr);
298         return new Click(this);
299     }
300 
onClick(Click * click)301     bool onClick(Click* click) override {
302         this->inval(nullptr);
303         fCenter = click->fCurr;
304         return this->INHERITED::onClick(click);
305     }
306 
307 private:
308     typedef SampleView INHERITED;
309 };
310 DEF_SAMPLE( return new BackdropView; )
311 
312