xref: /aosp_15_r20/external/skia/gm/ovals.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2013 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 "gm/gm.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkColor.h"
11 #include "include/core/SkMatrix.h"
12 #include "include/core/SkPaint.h"
13 #include "include/core/SkPoint.h"
14 #include "include/core/SkRect.h"
15 #include "include/core/SkScalar.h"
16 #include "include/core/SkShader.h"
17 #include "include/core/SkSize.h"
18 #include "include/core/SkString.h"
19 #include "include/core/SkTileMode.h"
20 #include "include/core/SkTypes.h"
21 #include "include/effects/SkGradientShader.h"
22 #include "include/private/base/SkTArray.h"
23 #include "src/base/SkRandom.h"
24 #include "tools/ToolUtils.h"
25 
26 using namespace skia_private;
27 
28 namespace skiagm {
29 
30 class OvalGM : public GM {
31 public:
OvalGM()32     OvalGM() {
33         this->setBGColor(0xFF000000);
34         this->makePaints();
35         this->makeMatrices();
36     }
37 
38 protected:
getName() const39     SkString getName() const override { return SkString("ovals"); }
40 
getISize()41     SkISize getISize() override { return SkISize::Make(1200, 900); }
42 
makePaints()43     void makePaints() {
44         {
45         // no AA
46         SkPaint p;
47         fPaints.push_back(p);
48         }
49 
50         {
51         // AA
52         SkPaint p;
53         p.setAntiAlias(true);
54         fPaints.push_back(p);
55         }
56 
57         {
58         // AA with stroke style
59         SkPaint p;
60         p.setAntiAlias(true);
61         p.setStyle(SkPaint::kStroke_Style);
62         p.setStrokeWidth(SkIntToScalar(5));
63         fPaints.push_back(p);
64         }
65 
66         {
67         // AA with stroke style, width = 0
68         SkPaint p;
69         p.setAntiAlias(true);
70         p.setStyle(SkPaint::kStroke_Style);
71         fPaints.push_back(p);
72         }
73 
74         {
75         // AA with stroke and fill style
76         SkPaint p;
77         p.setAntiAlias(true);
78         p.setStyle(SkPaint::kStrokeAndFill_Style);
79         p.setStrokeWidth(SkIntToScalar(3));
80         fPaints.push_back(p);
81         }
82     }
83 
makeMatrices()84     void makeMatrices() {
85         {
86         SkMatrix m;
87         m.setIdentity();
88         fMatrices.push_back(m);
89         }
90 
91         {
92         SkMatrix m;
93         m.setScale(SkIntToScalar(3), SkIntToScalar(2));
94         fMatrices.push_back(m);
95         }
96 
97         {
98         SkMatrix m;
99         m.setScale(SkIntToScalar(2), SkIntToScalar(2));
100         fMatrices.push_back(m);
101         }
102 
103         {
104         SkMatrix m;
105         m.setScale(SkIntToScalar(1), SkIntToScalar(2));
106         fMatrices.push_back(m);
107         }
108 
109         {
110         SkMatrix m;
111         m.setScale(SkIntToScalar(4), SkIntToScalar(1));
112         fMatrices.push_back(m);
113         }
114 
115         {
116         SkMatrix m;
117         m.setRotate(SkIntToScalar(90));
118         fMatrices.push_back(m);
119         }
120 
121         {
122         SkMatrix m;
123         m.setSkew(SkIntToScalar(2), SkIntToScalar(3));
124         fMatrices.push_back(m);
125         }
126 
127         {
128         SkMatrix m;
129         m.setRotate(SkIntToScalar(60));
130         fMatrices.push_back(m);
131         }
132     }
133 
genColor(SkRandom * rand)134     SkColor genColor(SkRandom* rand) {
135         SkScalar hsv[3];
136         hsv[0] = rand->nextRangeF(0.0f, 360.0f);
137         hsv[1] = rand->nextRangeF(0.75f, 1.0f);
138         hsv[2] = rand->nextRangeF(0.75f, 1.0f);
139 
140         return ToolUtils::color_to_565(SkHSVToColor(hsv));
141     }
142 
onDraw(SkCanvas * canvas)143     void onDraw(SkCanvas* canvas) override {
144         SkRandom rand(1);
145         canvas->translate(20 * SK_Scalar1, 20 * SK_Scalar1);
146         const SkRect kOval = SkRect::MakeLTRB(-20, -30, 20, 30);
147 
148         const SkScalar kXStart = 60.0f;
149         const SkScalar kYStart = 80.0f;
150         const int kXStep = 150;
151         const int kYStep = 160;
152         int maxX = fMatrices.size();
153 
154         SkPaint rectPaint;
155         rectPaint.setAntiAlias(true);
156         rectPaint.setStyle(SkPaint::kStroke_Style);
157         rectPaint.setStrokeWidth(SkIntToScalar(0));
158         rectPaint.setColor(SK_ColorLTGRAY);
159 
160         int testCount = 0;
161         for (int i = 0; i < fPaints.size(); ++i) {
162             for (int j = 0; j < fMatrices.size(); ++j) {
163                 canvas->save();
164                 SkMatrix mat = fMatrices[j];
165                 // position the oval, and make it at off-integer coords.
166                 mat.postTranslate(kXStart + SK_Scalar1 * kXStep * (testCount % maxX) +
167                                   SK_Scalar1 / 4,
168                                   kYStart + SK_Scalar1 * kYStep * (testCount / maxX) +
169                                   3 * SK_Scalar1 / 4);
170                 canvas->concat(mat);
171 
172                 SkColor color = genColor(&rand);
173                 fPaints[i].setColor(color);
174 
175                 canvas->drawRect(kOval, rectPaint);
176                 canvas->drawOval(kOval, fPaints[i]);
177 
178                 canvas->restore();
179 
180                 ++testCount;
181             }
182         }
183 
184         // special cases
185 
186         // non-scaled tall and skinny oval
187         for (int i = 0; i < fPaints.size(); ++i) {
188             SkRect oval = SkRect::MakeLTRB(-20, -60, 20, 60);
189             canvas->save();
190             // position the oval, and make it at off-integer coords.
191             canvas->translate(kXStart + SK_Scalar1 * kXStep * 2.55f + SK_Scalar1 / 4,
192                               kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4);
193 
194             SkColor color = genColor(&rand);
195             fPaints[i].setColor(color);
196 
197             canvas->drawRect(oval, rectPaint);
198             canvas->drawOval(oval, fPaints[i]);
199             canvas->restore();
200         }
201 
202         // non-scaled wide and short oval
203         for (int i = 0; i < fPaints.size(); ++i) {
204             SkRect oval = SkRect::MakeLTRB(-80, -30, 80, 30);
205             canvas->save();
206             // position the oval, and make it at off-integer coords.
207             canvas->translate(kXStart + SK_Scalar1 * kXStep * 4 + SK_Scalar1 / 4,
208                               kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
209                               SK_ScalarHalf * kYStep);
210 
211             SkColor color = genColor(&rand);
212             fPaints[i].setColor(color);
213 
214             canvas->drawRect(oval, rectPaint);
215             canvas->drawOval(oval, fPaints[i]);
216             canvas->restore();
217         }
218 
219         // super skinny oval
220         for (int i = 0; i < fPaints.size(); ++i) {
221             SkRect oval = SkRect::MakeLTRB(0, -60, 1, 60);
222             canvas->save();
223             // position the oval, and make it at off-integer coords.
224             canvas->translate(kXStart + SK_Scalar1 * kXStep * 3.25f + SK_Scalar1 / 4,
225                               kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4);
226 
227             SkColor color = genColor(&rand);
228             fPaints[i].setColor(color);
229 
230             canvas->drawOval(oval, fPaints[i]);
231             canvas->restore();
232         }
233 
234         // super short oval
235         for (int i = 0; i < fPaints.size(); ++i) {
236             SkRect oval = SkRect::MakeLTRB(-80, -1, 80, 0);
237             canvas->save();
238             // position the oval, and make it at off-integer coords.
239             canvas->translate(kXStart + SK_Scalar1 * kXStep * 2.5f + SK_Scalar1 / 4,
240                               kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
241                               SK_ScalarHalf * kYStep);
242 
243             SkColor color = genColor(&rand);
244             fPaints[i].setColor(color);
245 
246             canvas->drawOval(oval, fPaints[i]);
247             canvas->restore();
248         }
249 
250         // radial gradient
251         SkPoint center = SkPoint::Make(SkIntToScalar(0), SkIntToScalar(0));
252         SkColor colors[] = { SK_ColorBLUE, SK_ColorRED, SK_ColorGREEN };
253         SkScalar pos[] = { 0, SK_ScalarHalf, SK_Scalar1 };
254         auto shader = SkGradientShader::MakeRadial(center, 20, colors, pos, std::size(colors),
255                                                    SkTileMode::kClamp);
256 
257         for (int i = 0; i < fPaints.size(); ++i) {
258             canvas->save();
259             // position the path, and make it at off-integer coords.
260             canvas->translate(kXStart + SK_Scalar1 * kXStep * 0 + SK_Scalar1 / 4,
261                               kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
262                               SK_ScalarHalf * kYStep);
263 
264             SkColor color = genColor(&rand);
265             fPaints[i].setColor(color);
266             fPaints[i].setShader(shader);
267 
268             canvas->drawRect(kOval, rectPaint);
269             canvas->drawOval(kOval, fPaints[i]);
270 
271             fPaints[i].setShader(nullptr);
272 
273             canvas->restore();
274         }
275 
276         // reflected oval
277         for (int i = 0; i < fPaints.size(); ++i) {
278             SkRect oval = SkRect::MakeLTRB(-30, -30, 30, 30);
279             canvas->save();
280             // position the oval, and make it at off-integer coords.
281             canvas->translate(kXStart + SK_Scalar1 * kXStep * 5 + SK_Scalar1 / 4,
282                               kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
283                               SK_ScalarHalf * kYStep);
284             canvas->rotate(90);
285             canvas->scale(1, -1);
286             canvas->scale(1, 0.66f);
287 
288             SkColor color = genColor(&rand);
289             fPaints[i].setColor(color);
290 
291             canvas->drawRect(oval, rectPaint);
292             canvas->drawOval(oval, fPaints[i]);
293             canvas->restore();
294         }
295     }
296 
297 private:
298     TArray<SkPaint> fPaints;
299     TArray<SkMatrix> fMatrices;
300 
301     using INHERITED = GM;
302 };
303 
304 //////////////////////////////////////////////////////////////////////////////
305 
306 DEF_GM( return new OvalGM; )
307 
308 }  // namespace skiagm
309