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 "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 "SkGradientShader.h"
16 #include "SkImage.h"
17 #include "SkInterpolator.h"
18 #include "SkMaskFilter.h"
19 #include "SkPath.h"
20 #include "SkRegion.h"
21 #include "SkShader.h"
22 #include "SkTime.h"
23 #include "SkTypeface.h"
24 #include "SkUtils.h"
25 #include "SkKey.h"
26 #include "SkDrawFilter.h"
27 #include "SkClipOpPriv.h"
28
make_paint(SkPaint * paint,const SkMatrix & localMatrix)29 static void make_paint(SkPaint* paint, const SkMatrix& localMatrix) {
30 SkColor colors[] = { 0, SK_ColorWHITE };
31 SkPoint pts[] = { { 0, 0 }, { 0, SK_Scalar1*20 } };
32 paint->setShader(SkGradientShader::MakeLinear(pts, colors, nullptr, 2,
33 SkShader::kClamp_TileMode, 0, &localMatrix));
34 paint->setBlendMode(SkBlendMode::kDstIn);
35 }
36
37 // test drawing with strips of fading gradient above and below
test_fade(SkCanvas * canvas)38 static void test_fade(SkCanvas* canvas) {
39 SkAutoCanvasRestore ar(canvas, true);
40
41 SkRect r;
42
43 SkPaint p;
44 p.setAlpha(0x88);
45
46 SkAutoCanvasRestore ar2(canvas, false);
47
48 // create the layers
49
50 r.set(0, 0, SkIntToScalar(100), SkIntToScalar(100));
51 canvas->clipRect(r);
52
53 r.fBottom = SkIntToScalar(20);
54 canvas->saveLayer(&r, nullptr);
55
56 r.fTop = SkIntToScalar(80);
57 r.fBottom = SkIntToScalar(100);
58 canvas->saveLayer(&r, nullptr);
59
60 // now draw the "content"
61
62 if (true) {
63 r.set(0, 0, SkIntToScalar(100), SkIntToScalar(100));
64
65 canvas->saveLayerAlpha(&r, 0x80);
66
67 SkPaint p;
68 p.setColor(SK_ColorRED);
69 p.setAntiAlias(true);
70 canvas->drawOval(r, p);
71
72 canvas->restore();
73 } else {
74 r.set(0, 0, SkIntToScalar(100), SkIntToScalar(100));
75
76 SkPaint p;
77 p.setColor(SK_ColorRED);
78 p.setAntiAlias(true);
79 canvas->drawOval(r, p);
80 }
81
82 // return;
83
84 // now apply an effect
85 SkMatrix m;
86 m.setScale(SK_Scalar1, -SK_Scalar1);
87 m.postTranslate(0, SkIntToScalar(100));
88
89 SkPaint paint;
90 make_paint(&paint, m);
91 r.set(0, 0, SkIntToScalar(100), SkIntToScalar(20));
92 // SkDebugf("--------- draw top grad\n");
93 canvas->drawRect(r, paint);
94
95 r.fTop = SkIntToScalar(80);
96 r.fBottom = SkIntToScalar(100);
97 // SkDebugf("--------- draw bot grad\n");
98 canvas->drawRect(r, paint);
99 }
100
101 class RedFilter : public SkDrawFilter {
102 public:
filter(SkPaint * p,SkDrawFilter::Type)103 bool filter(SkPaint* p, SkDrawFilter::Type) override {
104 fColor = p->getColor();
105 if (fColor == SK_ColorRED) {
106 p->setColor(SK_ColorGREEN);
107 }
108 return true;
109 }
110
111 private:
112 SkColor fColor;
113 };
114
115 class LayersView : public SkView {
116 public:
LayersView()117 LayersView() {}
118
119 protected:
120 // overrides from SkEventSink
onQuery(SkEvent * evt)121 bool onQuery(SkEvent* evt) override {
122 if (SampleCode::TitleQ(*evt)) {
123 SampleCode::TitleR(evt, "Layers");
124 return true;
125 }
126 return this->INHERITED::onQuery(evt);
127 }
128
drawBG(SkCanvas * canvas)129 void drawBG(SkCanvas* canvas) {
130 canvas->drawColor(SK_ColorGRAY);
131 }
132
onDraw(SkCanvas * canvas)133 void onDraw(SkCanvas* canvas) override {
134 this->drawBG(canvas);
135
136 if (true) {
137 SkRect r;
138 r.set(SkIntToScalar(0), SkIntToScalar(0),
139 SkIntToScalar(220), SkIntToScalar(120));
140 SkPaint p;
141 canvas->saveLayer(&r, &p);
142 canvas->drawColor(0xFFFF0000);
143 p.setAlpha(0); // or 0
144 p.setBlendMode(SkBlendMode::kSrc);
145 canvas->drawOval(r, p);
146 canvas->restore();
147 return;
148 }
149
150 if (false) {
151 SkRect r;
152 r.set(SkIntToScalar(0), SkIntToScalar(0),
153 SkIntToScalar(220), SkIntToScalar(120));
154 SkPaint p;
155 p.setAlpha(0x88);
156 p.setAntiAlias(true);
157
158 if (true) {
159 canvas->saveLayer(&r, &p);
160 p.setColor(0xFFFF0000);
161 canvas->drawOval(r, p);
162 canvas->restore();
163 }
164
165 p.setColor(0xFF0000FF);
166 r.offset(SkIntToScalar(20), SkIntToScalar(50));
167 canvas->drawOval(r, p);
168 }
169
170 if (false) {
171 SkPaint p;
172 p.setAlpha(0x88);
173 p.setAntiAlias(true);
174
175 canvas->translate(SkIntToScalar(300), 0);
176
177 SkRect r;
178 r.set(SkIntToScalar(0), SkIntToScalar(0),
179 SkIntToScalar(220), SkIntToScalar(60));
180
181 canvas->saveLayer(&r, &p);
182
183 r.set(SkIntToScalar(0), SkIntToScalar(0),
184 SkIntToScalar(220), SkIntToScalar(120));
185 p.setColor(SK_ColorBLUE);
186 canvas->drawOval(r, p);
187 canvas->restore();
188 return;
189 }
190
191 test_fade(canvas);
192 }
193
onFindClickHandler(SkScalar x,SkScalar y,unsigned modi)194 SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
195 this->inval(nullptr);
196
197 return this->INHERITED::onFindClickHandler(x, y, modi);
198 }
199
onClick(Click * click)200 bool onClick(Click* click) override {
201 return this->INHERITED::onClick(click);
202 }
203
handleKey(SkKey)204 virtual bool handleKey(SkKey) {
205 this->inval(nullptr);
206 return true;
207 }
208
209 private:
210 typedef SkView INHERITED;
211 };
212 DEF_SAMPLE( return new LayersView; )
213
214 //////////////////////////////////////////////////////////////////////////////
215
216 #include "SkBlurImageFilter.h"
217 #include "SkMatrixConvolutionImageFilter.h"
218 #include "SkMorphologyImageFilter.h"
219
220 #include "Resources.h"
221 #include "SkAnimTimer.h"
222
223 class BackdropView : public SampleView {
224 SkPoint fCenter;
225 SkScalar fAngle;
226 sk_sp<SkImage> fImage;
227 sk_sp<SkImageFilter> fFilter;
228 public:
BackdropView()229 BackdropView() {
230 fCenter.set(200, 150);
231 fAngle = 0;
232 fImage = GetResourceAsImage("mandrill_512.png");
233 fFilter = SkDilateImageFilter::Make(8, 8, nullptr);
234 }
235
236 protected:
237 // overrides from SkEventSink
onQuery(SkEvent * evt)238 bool onQuery(SkEvent* evt) override {
239 if (SampleCode::TitleQ(*evt)) {
240 SampleCode::TitleR(evt, "Backdrop");
241 return true;
242 }
243 return this->INHERITED::onQuery(evt);
244 }
245
onDrawContent(SkCanvas * canvas)246 void onDrawContent(SkCanvas* canvas) override {
247 canvas->drawImage(fImage.get(), 0, 0, nullptr);
248
249 const SkScalar w = 250;
250 const SkScalar h = 150;
251 SkPath path;
252 path.addOval(SkRect::MakeXYWH(-w/2, -h/2, w, h));
253 SkMatrix m;
254 m.setRotate(fAngle);
255 m.postTranslate(fCenter.x(), fCenter.y());
256 path.transform(m);
257
258 canvas->clipPath(path, kIntersect_SkClipOp, true);
259 const SkRect bounds = path.getBounds();
260
261 SkPaint paint;
262 paint.setAlpha(0xCC);
263 canvas->saveLayer({ &bounds, &paint, fFilter.get(), 0 });
264
265 canvas->restore();
266 }
267
onAnimate(const SkAnimTimer & timer)268 bool onAnimate(const SkAnimTimer& timer) override {
269 fAngle = SkDoubleToScalar(fmod(timer.secs() * 360 / 5, 360));
270 return true;
271 }
272
onFindClickHandler(SkScalar x,SkScalar y,unsigned modi)273 SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
274 this->inval(nullptr);
275 return new Click(this);
276 }
277
onClick(Click * click)278 bool onClick(Click* click) override {
279 this->inval(nullptr);
280 fCenter = click->fCurr;
281 return this->INHERITED::onClick(click);
282 }
283
284 private:
285 typedef SampleView INHERITED;
286 };
287 DEF_SAMPLE( return new BackdropView; )
288