Flutter Engine
The Flutter Engine
roundrects.cpp
Go to the documentation of this file.
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"
15#include "include/core/SkRect.h"
18#include "include/core/SkSize.h"
24#include "src/base/SkRandom.h"
25#include "tools/ToolUtils.h"
26
27using namespace skia_private;
28
29namespace skiagm {
30
31static SkColor gen_color(SkRandom* rand) {
32 SkScalar hsv[3];
33 hsv[0] = rand->nextRangeF(0.0f, 360.0f);
34 hsv[1] = rand->nextRangeF(0.75f, 1.0f);
35 hsv[2] = rand->nextRangeF(0.75f, 1.0f);
36
38}
39
40class RoundRectGM : public GM {
41public:
43 this->setBGColor(0xFF000000);
44 this->makePaints();
45 this->makeMatrices();
46 }
47
48protected:
49 SkString getName() const override { return SkString("roundrects"); }
50
51 SkISize getISize() override { return SkISize::Make(1200, 900); }
52
53 void makePaints() {
54 {
55 // no AA
56 SkPaint p;
57 fPaints.push_back(p);
58 }
59
60 {
61 // AA
62 SkPaint p;
63 p.setAntiAlias(true);
64 fPaints.push_back(p);
65 }
66
67 {
68 // AA with stroke style
69 SkPaint p;
70 p.setAntiAlias(true);
71 p.setStyle(SkPaint::kStroke_Style);
72 p.setStrokeWidth(SkIntToScalar(5));
73 fPaints.push_back(p);
74 }
75
76 {
77 // AA with stroke style, width = 0
78 SkPaint p;
79 p.setAntiAlias(true);
80 p.setStyle(SkPaint::kStroke_Style);
81 fPaints.push_back(p);
82 }
83
84 {
85 // AA with stroke and fill style
86 SkPaint p;
87 p.setAntiAlias(true);
89 p.setStrokeWidth(SkIntToScalar(3));
90 fPaints.push_back(p);
91 }
92 }
93
94 void makeMatrices() {
95 {
96 SkMatrix m;
97 m.setIdentity();
98 fMatrices.push_back(m);
99 }
100
101 {
102 SkMatrix m;
103 m.setScale(SkIntToScalar(3), SkIntToScalar(2));
104 fMatrices.push_back(m);
105 }
106
107 {
108 SkMatrix m;
109 m.setScale(SkIntToScalar(2), SkIntToScalar(2));
110 fMatrices.push_back(m);
111 }
112
113 {
114 SkMatrix m;
115 m.setScale(SkIntToScalar(1), SkIntToScalar(2));
116 fMatrices.push_back(m);
117 }
118
119 {
120 SkMatrix m;
121 m.setScale(SkIntToScalar(4), SkIntToScalar(1));
122 fMatrices.push_back(m);
123 }
124
125 {
126 SkMatrix m;
127 m.setRotate(SkIntToScalar(90));
128 fMatrices.push_back(m);
129 }
130
131 {
132 SkMatrix m;
133 m.setSkew(SkIntToScalar(2), SkIntToScalar(3));
134 fMatrices.push_back(m);
135 }
136
137 {
138 SkMatrix m;
139 m.setRotate(SkIntToScalar(60));
140 fMatrices.push_back(m);
141 }
142 }
143
144 void onDraw(SkCanvas* canvas) override {
145 SkRandom rand(1);
146 canvas->translate(20 * SK_Scalar1, 20 * SK_Scalar1);
147 const SkRect kRect = SkRect::MakeLTRB(-20, -30, 20, 30);
148 SkRRect circleRRect;
149 circleRRect.setRectXY(kRect, 5, 5);
150
151 const SkScalar kXStart = 60.0f;
152 const SkScalar kYStart = 80.0f;
153 const int kXStep = 150;
154 const int kYStep = 160;
155 int maxX = fMatrices.size();
156
157 SkPaint rectPaint;
158 rectPaint.setAntiAlias(true);
160 rectPaint.setStrokeWidth(SkIntToScalar(0));
161 rectPaint.setColor(SK_ColorLTGRAY);
162
163 int testCount = 0;
164 for (int i = 0; i < fPaints.size(); ++i) {
165 for (int j = 0; j < fMatrices.size(); ++j) {
166 canvas->save();
167 SkMatrix mat = fMatrices[j];
168 // position the roundrect, and make it at off-integer coords.
169 mat.postTranslate(kXStart + SK_Scalar1 * kXStep * (testCount % maxX) +
170 SK_Scalar1 / 4,
171 kYStart + SK_Scalar1 * kYStep * (testCount / maxX) +
172 3 * SK_Scalar1 / 4);
173 canvas->concat(mat);
174
175 SkColor color = gen_color(&rand);
176 fPaints[i].setColor(color);
177
178 canvas->drawRect(kRect, rectPaint);
179 canvas->drawRRect(circleRRect, fPaints[i]);
180
181 canvas->restore();
182
183 ++testCount;
184 }
185 }
186
187 // special cases
188
189 // non-scaled tall and skinny roundrect
190 for (int i = 0; i < fPaints.size(); ++i) {
191 SkRect rect = SkRect::MakeLTRB(-20, -60, 20, 60);
192 SkRRect ellipseRect;
193 ellipseRect.setRectXY(rect, 5, 10);
194
195 canvas->save();
196 // position the roundrect, and make it at off-integer coords.
197 canvas->translate(kXStart + SK_Scalar1 * kXStep * 2.55f + SK_Scalar1 / 4,
198 kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4);
199
200 SkColor color = gen_color(&rand);
201 fPaints[i].setColor(color);
202
203 canvas->drawRect(rect, rectPaint);
204 canvas->drawRRect(ellipseRect, fPaints[i]);
205 canvas->restore();
206 }
207
208 // non-scaled wide and short roundrect
209 for (int i = 0; i < fPaints.size(); ++i) {
210 SkRect rect = SkRect::MakeLTRB(-80, -30, 80, 30);
211 SkRRect ellipseRect;
212 ellipseRect.setRectXY(rect, 20, 5);
213
214 canvas->save();
215 // position the roundrect, and make it at off-integer coords.
216 canvas->translate(kXStart + SK_Scalar1 * kXStep * 4 + SK_Scalar1 / 4,
217 kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
218 SK_ScalarHalf * kYStep);
219
220 SkColor color = gen_color(&rand);
221 fPaints[i].setColor(color);
222
223 canvas->drawRect(rect, rectPaint);
224 canvas->drawRRect(ellipseRect, fPaints[i]);
225 canvas->restore();
226 }
227
228 // super skinny roundrect
229 for (int i = 0; i < fPaints.size(); ++i) {
230 SkRect rect = SkRect::MakeLTRB(0, -60, 1, 60);
231 SkRRect circleRect;
232 circleRect.setRectXY(rect, 5, 5);
233
234 canvas->save();
235 // position the roundrect, and make it at off-integer coords.
236 canvas->translate(kXStart + SK_Scalar1 * kXStep * 3.25f + SK_Scalar1 / 4,
237 kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4);
238
239 SkColor color = gen_color(&rand);
240 fPaints[i].setColor(color);
241
242 canvas->drawRRect(circleRect, fPaints[i]);
243 canvas->restore();
244 }
245
246 // super short roundrect
247 for (int i = 0; i < fPaints.size(); ++i) {
248 SkRect rect = SkRect::MakeLTRB(-80, -1, 80, 0);
249 SkRRect circleRect;
250 circleRect.setRectXY(rect, 5, 5);
251
252 canvas->save();
253 // position the roundrect, and make it at off-integer coords.
254 canvas->translate(kXStart + SK_Scalar1 * kXStep * 2.5f + SK_Scalar1 / 4,
255 kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
256 SK_ScalarHalf * kYStep);
257
258 SkColor color = gen_color(&rand);
259 fPaints[i].setColor(color);
260
261 canvas->drawRRect(circleRect, fPaints[i]);
262 canvas->restore();
263 }
264
265 // radial gradient
269 auto shader = SkGradientShader::MakeRadial(center, 20, colors, pos, std::size(colors),
271
272 for (int i = 0; i < fPaints.size(); ++i) {
273 canvas->save();
274 // position the path, and make it at off-integer coords.
275 canvas->translate(kXStart + SK_Scalar1 * kXStep * 0 + SK_Scalar1 / 4,
276 kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
277 SK_ScalarHalf * kYStep);
278
279 SkColor color = gen_color(&rand);
280 fPaints[i].setColor(color);
281 fPaints[i].setShader(shader);
282
283 canvas->drawRect(kRect, rectPaint);
284 canvas->drawRRect(circleRRect, fPaints[i]);
285
286 fPaints[i].setShader(nullptr);
287
288 canvas->restore();
289 }
290
291 // strokes and radii
292 {
293 SkScalar radii[][2] = {
294 {10,10},
295 {5,15},
296 {5,15},
297 {5,15}
298 };
299
300 SkScalar strokeWidths[] = {
301 20, 10, 20, 40
302 };
303
304 for (int i = 0; i < 4; ++i) {
305 SkRRect circleRect;
306 circleRect.setRectXY(kRect, radii[i][0], radii[i][1]);
307
308 canvas->save();
309 // position the roundrect, and make it at off-integer coords.
310 canvas->translate(kXStart + SK_Scalar1 * kXStep * 5 + SK_Scalar1 / 4,
311 kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
312 SK_ScalarHalf * kYStep);
313
314 SkColor color = gen_color(&rand);
315
316 SkPaint p;
317 p.setAntiAlias(true);
318 p.setStyle(SkPaint::kStroke_Style);
319 p.setStrokeWidth(strokeWidths[i]);
320 p.setColor(color);
321
322 canvas->drawRRect(circleRect, p);
323 canvas->restore();
324 }
325 }
326
327 // test old entry point ( https://bug.skia.org/3786 )
328 {
329 canvas->save();
330
331 canvas->translate(kXStart + SK_Scalar1 * kXStep * 5 + SK_Scalar1 / 4,
332 kYStart + SK_Scalar1 * kYStep * 4 + SK_Scalar1 / 4 +
333 SK_ScalarHalf * kYStep);
334
335 const SkColor color = gen_color(&rand);
336
337 SkPaint p;
338 p.setColor(color);
339
340 const SkRect oooRect = { 20, 30, -20, -30 }; // intentionally out of order
341 canvas->drawRoundRect(oooRect, 10, 10, p);
342
343 canvas->restore();
344 }
345
346 // rrect with stroke > radius/2
347 {
348 SkRect smallRect = { -30, -20, 30, 20 };
349 SkRRect circleRect;
350 circleRect.setRectXY(smallRect, 5, 5);
351
352 canvas->save();
353 // position the roundrect, and make it at off-integer coords.
354 canvas->translate(kXStart + SK_Scalar1 * kXStep * 5 + SK_Scalar1 / 4,
355 kYStart - SK_Scalar1 * kYStep + 73 * SK_Scalar1 / 4 +
356 SK_ScalarHalf * kYStep);
357
358 SkColor color = gen_color(&rand);
359
360 SkPaint p;
361 p.setAntiAlias(true);
362 p.setStyle(SkPaint::kStroke_Style);
363 p.setStrokeWidth(25);
364 p.setColor(color);
365
366 canvas->drawRRect(circleRect, p);
367 canvas->restore();
368 }
369 }
370
371private:
372 TArray<SkPaint> fPaints;
373 TArray<SkMatrix> fMatrices;
374
375 using INHERITED = GM;
376};
377
378//////////////////////////////////////////////////////////////////////////////
379
380DEF_GM( return new RoundRectGM; )
381
382} // namespace skiagm
SkPoint pos
static const size_t testCount
constexpr SkColor SK_ColorLTGRAY
Definition: SkColor.h:118
uint32_t SkColor
Definition: SkColor.h:37
SK_API SkColor SkHSVToColor(U8CPU alpha, const SkScalar hsv[3])
Definition: SkColor.cpp:78
constexpr SkColor SK_ColorBLUE
Definition: SkColor.h:135
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
constexpr SkColor SK_ColorGREEN
Definition: SkColor.h:131
#define SK_Scalar1
Definition: SkScalar.h:18
#define SK_ScalarHalf
Definition: SkScalar.h:19
#define SkIntToScalar(x)
Definition: SkScalar.h:57
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
void restore()
Definition: SkCanvas.cpp:461
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
void drawRRect(const SkRRect &rrect, const SkPaint &paint)
Definition: SkCanvas.cpp:1705
void drawRoundRect(const SkRect &rect, SkScalar rx, SkScalar ry, const SkPaint &paint)
Definition: SkCanvas.cpp:2717
int save()
Definition: SkCanvas.cpp:447
void concat(const SkMatrix &matrix)
Definition: SkCanvas.cpp:1318
static sk_sp< SkShader > MakeRadial(const SkPoint &center, SkScalar radius, const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, uint32_t flags=0, const SkMatrix *localMatrix=nullptr)
SkMatrix & postTranslate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.cpp:281
void setStyle(Style style)
Definition: SkPaint.cpp:105
void setColor(SkColor color)
Definition: SkPaint.cpp:119
void setAntiAlias(bool aa)
Definition: SkPaint.h:170
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
@ kStrokeAndFill_Style
sets to stroke and fill geometry
Definition: SkPaint.h:195
void setStrokeWidth(SkScalar width)
Definition: SkPaint.cpp:159
void setRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
Definition: SkRRect.cpp:52
float nextRangeF(float min, float max)
Definition: SkRandom.h:64
int size() const
Definition: SkTArray.h:421
Definition: gm.h:110
GM(SkColor backgroundColor=SK_ColorWHITE)
Definition: gm.cpp:81
void setBGColor(SkColor)
Definition: gm.cpp:159
SkISize getISize() override
Definition: roundrects.cpp:51
SkString getName() const override
Definition: roundrects.cpp:49
void onDraw(SkCanvas *canvas) override
Definition: roundrects.cpp:144
DlColor color
float SkScalar
Definition: extension.cpp:12
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
PODArray< SkColor > colors
Definition: SkRecords.h:276
SkColor color_to_565(SkColor color)
Definition: ToolUtils.cpp:139
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
static SkColor gen_color(SkRandom *rand)
Definition: manypaths.cpp:22
DEF_GM(return F(C(clipbox), 0.0f, 0.0f, {})) DEF_GM(return F(C(clipbox)
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
static constexpr SkPoint Make(float x, float y)
Definition: SkPoint_impl.h:173
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition: SkRect.h:646