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