SampleLayers.cpp revision ede860e91c2a0021266907885ea2c9b4be09e121
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
28static 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
37static 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
100class RedFilter : public SkDrawFilter {
101public:
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
110private:
111    SkColor fColor;
112};
113
114class LayersView : public SkView {
115public:
116    LayersView() {}
117
118protected:
119    // overrides from SkEventSink
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
128    void drawBG(SkCanvas* canvas) {
129        canvas->drawColor(SK_ColorGRAY);
130    }
131
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
193private:
194    typedef SkView INHERITED;
195};
196DEF_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
207class BackdropView : public SampleView {
208    SkPoint fCenter;
209    SkScalar fAngle;
210    sk_sp<SkImage> fImage;
211    sk_sp<SkImageFilter> fFilter;
212public:
213    BackdropView() {
214        fCenter.set(200, 150);
215        fAngle = 0;
216        fImage = GetResourceAsImage("mandrill_512.png");
217        fFilter = SkDilateImageFilter::Make(8, 8, nullptr);
218    }
219
220protected:
221    // overrides from SkEventSink
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
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
252    bool onAnimate(const SkAnimTimer& timer) override {
253        fAngle = SkDoubleToScalar(fmod(timer.secs() * 360 / 5, 360));
254        return true;
255    }
256
257    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
258        return new Click(this);
259    }
260
261    bool onClick(Click* click) override {
262        fCenter = click->fCurr;
263        return this->INHERITED::onClick(click);
264    }
265
266private:
267    typedef SampleView INHERITED;
268};
269DEF_SAMPLE( return new BackdropView; )
270