1 /*
2  * Copyright 2012 Intel 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 "gm/gm.h"
9 #include "include/core/SkBlurTypes.h"
10 #include "include/core/SkCanvas.h"
11 #include "include/core/SkColor.h"
12 #include "include/core/SkDrawLooper.h"
13 #include "include/core/SkMaskFilter.h"
14 #include "include/core/SkMatrix.h"
15 #include "include/core/SkPaint.h"
16 #include "include/core/SkPoint.h"
17 #include "include/core/SkScalar.h"
18 #include "include/core/SkShader.h"
19 #include "include/core/SkSize.h"
20 #include "include/core/SkString.h"
21 #include "include/core/SkTileMode.h"
22 #include "include/core/SkTypes.h"
23 #include "include/effects/SkBlurDrawLooper.h"
24 #include "include/effects/SkGradientShader.h"
25 #include "include/private/SkTArray.h"
26 #include "include/utils/SkRandom.h"
27 #include "src/core/SkBlurMask.h"
28 
29 namespace skiagm {
30 
31 class CircleGM : public GM {
32     sk_sp<SkDrawLooper> fLooper;
33     enum {
34         kLooperColorSentinel = 0x01020304
35     };
36 
37 protected:
onOnceBeforeDraw()38     void onOnceBeforeDraw() override {
39         this->setBGColor(0xFF000000);
40         this->makePaints();
41         this->makeMatrices();
42     }
43 
onShortName()44     SkString onShortName() override {
45         return SkString("circles");
46     }
47 
onISize()48     SkISize onISize() override {
49         return SkISize::Make(1200, 900);
50     }
51 
makePaints()52     void makePaints() {
53         {
54         // no AA
55         SkPaint p;
56         fPaints.push_back(p);
57         }
58 
59         {
60         // AA
61         SkPaint p;
62         p.setAntiAlias(true);
63         fPaints.push_back(p);
64         }
65 
66         {
67         // AA with mask filter
68         SkPaint p;
69         p.setAntiAlias(true);
70         p.setMaskFilter(SkMaskFilter::MakeBlur(
71                                kNormal_SkBlurStyle,
72                                SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(5))));
73         fPaints.push_back(p);
74         }
75 
76         {
77         // AA with radial shader
78         SkPaint p;
79         p.setAntiAlias(true);
80         SkPoint center = SkPoint::Make(SkIntToScalar(40), SkIntToScalar(40));
81         SkColor colors[] = { SK_ColorBLUE, SK_ColorRED, SK_ColorGREEN };
82         SkScalar pos[] = { 0, SK_ScalarHalf, SK_Scalar1 };
83         p.setShader(SkGradientShader::MakeRadial(center, 20, colors, pos, SK_ARRAY_COUNT(colors),
84                                                  SkTileMode::kClamp));
85         fPaints.push_back(p);
86         }
87 
88         fLooper = SkBlurDrawLooper::Make(SK_ColorBLUE, SkBlurMask::ConvertRadiusToSigma(10),5,10);
89         {
90             SkPaint p;
91             p.setColor(kLooperColorSentinel);
92             p.setAntiAlias(true);
93             fPaints.push_back(p);
94         }
95         {
96         // AA with stroke style
97         SkPaint p;
98         p.setAntiAlias(true);
99         p.setStroke(true);
100         p.setStrokeWidth(SkIntToScalar(3));
101         fPaints.push_back(p);
102         }
103 
104         {
105         // AA with stroke style, width = 0
106         SkPaint p;
107         p.setAntiAlias(true);
108         p.setStroke(true);
109         fPaints.push_back(p);
110         }
111 
112         {
113         // AA with stroke and fill style
114         SkPaint p;
115         p.setAntiAlias(true);
116         p.setStyle(SkPaint::kStrokeAndFill_Style);
117         p.setStrokeWidth(SkIntToScalar(2));
118         fPaints.push_back(p);
119         }
120     }
121 
makeMatrices()122     void makeMatrices() {
123         {
124         SkMatrix m;
125         m.setScale(SkIntToScalar(2), SkIntToScalar(3));
126         fMatrices.push_back(m);
127         }
128 
129         {
130         SkMatrix m;
131         m.setScale(SkIntToScalar(2), SkIntToScalar(2));
132         fMatrices.push_back(m);
133         }
134 
135         {
136         SkMatrix m;
137         m.setSkew(SkIntToScalar(2), SkIntToScalar(3));
138         fMatrices.push_back(m);
139         }
140 
141         {
142         SkMatrix m;
143         m.setSkew(SkIntToScalar(2), SkIntToScalar(2));
144         fMatrices.push_back(m);
145         }
146 
147         {
148         SkMatrix m;
149         m.setRotate(SkIntToScalar(30));
150         fMatrices.push_back(m);
151         }
152     }
153 
onDraw(SkCanvas * canvas)154     void onDraw(SkCanvas* canvas) override {
155         // Draw a giant AA circle as the background.
156         SkISize size = this->getISize();
157         SkScalar giantRadius = std::min(SkIntToScalar(size.fWidth),
158                                       SkIntToScalar(size.fHeight)) / 2.f;
159         SkPoint giantCenter = SkPoint::Make(SkIntToScalar(size.fWidth/2),
160                                             SkIntToScalar(size.fHeight/2));
161         SkPaint giantPaint;
162         giantPaint.setAntiAlias(true);
163         giantPaint.setColor(0x80808080);
164         canvas->drawCircle(giantCenter, giantRadius, giantPaint);
165 
166         SkRandom rand;
167         canvas->translate(20 * SK_Scalar1, 20 * SK_Scalar1);
168         int i;
169         for (i = 0; i < fPaints.count(); ++i) {
170             canvas->save();
171             // position the path, and make it at off-integer coords.
172             canvas->translate(SK_Scalar1 * 200 * (i % 5) + SK_Scalar1 / 4,
173                               SK_Scalar1 * 200 * (i / 5) + 3 * SK_Scalar1 / 4);
174             SkPaint p = fPaints[i];
175             p.setColor(rand.nextU() | 0xff000000);
176             if (fPaints[i].getColor() == kLooperColorSentinel) {
177                 fLooper->apply(canvas, p, [](SkCanvas* c, const SkPaint& p) {
178                     c->drawCircle(40, 40, 20, p);
179                 });
180             } else {
181                 canvas->drawCircle(40, 40, 20, p);
182             }
183             canvas->restore();
184         }
185 
186         for (int j = 0; j < fMatrices.count(); ++j, ++i) {
187             canvas->save();
188 
189             canvas->translate(SK_Scalar1 * 200 * (i % 5) + SK_Scalar1 / 4,
190                               SK_Scalar1 * 200 * (i / 5) + 3 * SK_Scalar1 / 4);
191 
192             canvas->concat(fMatrices[j]);
193 
194             SkPaint paint;
195             paint.setAntiAlias(true);
196             paint.setColor(rand.nextU() | 0xff000000);
197             canvas->drawCircle(40, 40, 20, paint);
198 
199             canvas->restore();
200         }
201     }
202 
203 private:
204     using INHERITED = GM;
205     SkTArray<SkPaint> fPaints;
206     SkTArray<SkMatrix> fMatrices;
207 };
208 
209 //////////////////////////////////////////////////////////////////////////////
210 
211 DEF_GM( return new CircleGM; )
212 
213 }  // namespace skiagm
214