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