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 "include/core/SkCanvas.h"
9#include "include/core/SkColorFilter.h"
10#include "include/core/SkColorPriv.h"
11#include "include/core/SkImage.h"
12#include "include/core/SkMaskFilter.h"
13#include "include/core/SkPath.h"
14#include "include/core/SkRegion.h"
15#include "include/core/SkShader.h"
16#include "include/core/SkTime.h"
17#include "include/core/SkTypeface.h"
18#include "include/effects/SkGradientShader.h"
19#include "include/utils/SkCamera.h"
20#include "samplecode/Sample.h"
21#include "src/utils/SkUTF.h"
22
23static void make_paint(SkPaint* paint, const SkMatrix& localMatrix) {
24    SkColor colors[] = { 0, SK_ColorWHITE };
25    SkPoint pts[] = { { 0, 0 }, { 0, SK_Scalar1*20 } };
26    paint->setShader(SkGradientShader::MakeLinear(pts, colors, nullptr, 2,
27                                                  SkTileMode::kClamp, 0, &localMatrix));
28    paint->setBlendMode(SkBlendMode::kDstIn);
29}
30
31// test drawing with strips of fading gradient above and below
32static void test_fade(SkCanvas* canvas) {
33    SkAutoCanvasRestore ar(canvas, true);
34
35    SkRect r;
36
37    SkAutoCanvasRestore ar2(canvas, false);
38
39    // create the layers
40
41    r.setWH(100, 100);
42    canvas->clipRect(r);
43
44    r.fBottom = SkIntToScalar(20);
45    canvas->saveLayer(&r, nullptr);
46
47    r.fTop = SkIntToScalar(80);
48    r.fBottom = SkIntToScalar(100);
49    canvas->saveLayer(&r, nullptr);
50
51    // now draw the "content"
52
53    if (true) {
54        r.setWH(100, 100);
55
56        canvas->saveLayerAlpha(&r, 0x80);
57
58        SkPaint p;
59        p.setColor(SK_ColorRED);
60        p.setAntiAlias(true);
61        canvas->drawOval(r, p);
62
63        canvas->restore();
64    } else {
65        r.setWH(100, 100);
66
67        SkPaint p;
68        p.setColor(SK_ColorRED);
69        p.setAntiAlias(true);
70        canvas->drawOval(r, p);
71    }
72
73//    return;
74
75    // now apply an effect
76    SkMatrix m;
77    m.setScale(SK_Scalar1, -SK_Scalar1);
78    m.postTranslate(0, SkIntToScalar(100));
79
80    SkPaint paint;
81    make_paint(&paint, m);
82    r.setWH(100, 20);
83//    SkDebugf("--------- draw top grad\n");
84    canvas->drawRect(r, paint);
85
86    r.fTop = SkIntToScalar(80);
87    r.fBottom = SkIntToScalar(100);
88//    SkDebugf("--------- draw bot grad\n");
89    canvas->drawRect(r, paint);
90}
91
92class LayersView : public Sample {
93public:
94    LayersView() {}
95
96protected:
97    SkString name() override { return SkString("Layers"); }
98
99    void drawBG(SkCanvas* canvas) {
100        canvas->drawColor(SK_ColorGRAY);
101    }
102
103    void onDrawContent(SkCanvas* canvas) override {
104        this->drawBG(canvas);
105
106        if (true) {
107            SkRect r;
108            r.setWH(220, 120);
109            SkPaint p;
110            canvas->saveLayer(&r, &p);
111            canvas->drawColor(0xFFFF0000);
112            p.setAlpha(0);  // or 0
113            p.setBlendMode(SkBlendMode::kSrc);
114            canvas->drawOval(r, p);
115            canvas->restore();
116            return;
117        }
118
119        if (false) {
120            SkRect r;
121            r.setWH(220, 120);
122            SkPaint p;
123            p.setAlpha(0x88);
124            p.setAntiAlias(true);
125
126            if (true) {
127                canvas->saveLayer(&r, &p);
128                p.setColor(0xFFFF0000);
129                canvas->drawOval(r, p);
130                canvas->restore();
131            }
132
133            p.setColor(0xFF0000FF);
134            r.offset(SkIntToScalar(20), SkIntToScalar(50));
135            canvas->drawOval(r, p);
136        }
137
138        if (false) {
139            SkPaint p;
140            p.setAlpha(0x88);
141            p.setAntiAlias(true);
142
143            canvas->translate(SkIntToScalar(300), 0);
144
145            SkRect r;
146            r.setWH(220, 60);
147
148            canvas->saveLayer(&r, &p);
149
150            r.setWH(220, 120);
151            p.setColor(SK_ColorBLUE);
152            canvas->drawOval(r, p);
153            canvas->restore();
154            return;
155        }
156
157        test_fade(canvas);
158    }
159
160private:
161    using INHERITED = Sample;
162};
163DEF_SAMPLE( return new LayersView; )
164
165//////////////////////////////////////////////////////////////////////////////
166
167#include "include/effects/SkImageFilters.h"
168
169#include "tools/Resources.h"
170
171class BackdropView : public Sample {
172    SkPoint fCenter;
173    SkScalar fAngle;
174    sk_sp<SkImage> fImage;
175    sk_sp<SkImageFilter> fFilter;
176public:
177    BackdropView() {
178        fCenter.set(200, 150);
179        fAngle = 0;
180        fImage = GetResourceAsImage("images/mandrill_512.png");
181        fFilter = SkImageFilters::Dilate(8, 8, nullptr);
182    }
183
184protected:
185    SkString name() override { return SkString("Backdrop"); }
186
187    void onDrawContent(SkCanvas* canvas) override {
188        canvas->drawImage(fImage.get(), 0, 0);
189
190        const SkScalar w = 250;
191        const SkScalar h = 150;
192        SkPath path;
193        path.addOval(SkRect::MakeXYWH(-w/2, -h/2, w, h));
194        SkMatrix m;
195        m.setRotate(fAngle);
196        m.postTranslate(fCenter.x(), fCenter.y());
197        path.transform(m);
198
199        canvas->clipPath(path, SkClipOp::kIntersect, true);
200        const SkRect bounds = path.getBounds();
201
202        SkPaint paint;
203        paint.setAlpha(0xCC);
204        canvas->saveLayer(SkCanvas::SaveLayerRec(&bounds, &paint, fFilter.get(), 0));
205
206        canvas->restore();
207    }
208
209    bool onAnimate(double nanos) override {
210        fAngle = SkDoubleToScalar(fmod(1e-9 * nanos * 360 / 5, 360));
211        return true;
212    }
213
214    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
215        return new Click();
216    }
217
218    bool onClick(Click* click) override {
219        fCenter = click->fCurr;
220        return true;
221    }
222
223private:
224    using INHERITED = Sample;
225};
226DEF_SAMPLE( return new BackdropView; )
227