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