SampleLayers.cpp revision 73603f3c52ffd89fe9d035be827b566a0e7d3b79
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 "SkXfermode.h"
27#include "SkDrawFilter.h"
28
29static 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->setXfermodeMode(SkXfermode::kDstIn_Mode);
35}
36
37// test drawing with strips of fading gradient above and below
38static 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
101class RedFilter : public SkDrawFilter {
102public:
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
111private:
112    SkColor fColor;
113};
114
115class LayersView : public SkView {
116public:
117    LayersView() {}
118
119protected:
120    // overrides from SkEventSink
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
129    void drawBG(SkCanvas* canvas) {
130        canvas->drawColor(SK_ColorGRAY);
131    }
132
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.setXfermodeMode(SkXfermode::kSrc_Mode);
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
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
200    bool onClick(Click* click) override {
201        return this->INHERITED::onClick(click);
202    }
203
204    virtual bool handleKey(SkKey) {
205        this->inval(nullptr);
206        return true;
207    }
208
209private:
210    typedef SkView INHERITED;
211};
212DEF_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
223class BackdropView : public SampleView {
224    SkPoint fCenter;
225    SkScalar fAngle;
226    sk_sp<SkImage> fImage;
227    sk_sp<SkImageFilter> fFilter;
228public:
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
236protected:
237    // overrides from SkEventSink
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
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, SkCanvas::kIntersect_Op, 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
268    bool onAnimate(const SkAnimTimer& timer) override {
269        fAngle = SkDoubleToScalar(fmod(timer.secs() * 360 / 5, 360));
270        return true;
271    }
272
273    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
274        this->inval(nullptr);
275        return new Click(this);
276    }
277
278    bool onClick(Click* click) override {
279        this->inval(nullptr);
280        fCenter = click->fCurr;
281        return this->INHERITED::onClick(click);
282    }
283
284private:
285    typedef SampleView INHERITED;
286};
287DEF_SAMPLE( return new BackdropView; )
288