Flutter Engine
The Flutter Engine
smallpaths.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2015 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"
12#include "include/core/SkRect.h"
14#include "include/core/SkSize.h"
17#include <tuple>
18
19namespace {
20struct PathDY {
22 SkScalar dy;
23};
24}
25
26typedef PathDY (*MakePathProc)();
27
28static PathDY make_triangle() {
29 constexpr int gCoord[] = {
30 10, 20, 15, 5, 30, 30
31 };
32 return {
33 SkPathBuilder().moveTo(SkIntToScalar(gCoord[0]), SkIntToScalar(gCoord[1]))
34 .lineTo(SkIntToScalar(gCoord[2]), SkIntToScalar(gCoord[3]))
35 .lineTo(SkIntToScalar(gCoord[4]), SkIntToScalar(gCoord[5]))
36 .close()
37 .offset(10, 0)
38 .detach(),
39 30
40 };
41}
42
43static PathDY make_rect() {
44 SkRect r = { SkIntToScalar(10), SkIntToScalar(10),
46 return {
47 SkPath::Rect(r.makeOffset(10, 0)),
48 30
49 };
50}
51
52static PathDY make_oval() {
53 SkRect r = { SkIntToScalar(10), SkIntToScalar(10),
55 return {
56 SkPath::Oval(r.makeOffset(10, 0)),
57 30
58 };
59}
60
61static PathDY make_star(int n) {
62 const SkScalar c = SkIntToScalar(45);
63 const SkScalar r = SkIntToScalar(20);
64
65 SkScalar rad = -SK_ScalarPI / 2;
66 const SkScalar drad = (n >> 1) * SK_ScalarPI * 2 / n;
67
69 b.moveTo(c, c - r);
70 for (int i = 1; i < n; i++) {
71 rad += drad;
72 b.lineTo(c + SkScalarCos(rad) * r, c + SkScalarSin(rad) * r);
73 }
74 b.close();
75 return { b.detach(), r * 2 * 6 / 5 };
76}
77
78static PathDY make_star_5() { return make_star(5); }
79static PathDY make_star_13() { return make_star(13); }
80
81static PathDY make_three_line() {
82 static SkScalar xOffset = 34.f;
83 static SkScalar yOffset = 50.f;
85 b.moveTo(-32.5f + xOffset, 0.0f + yOffset);
86 b.lineTo(32.5f + xOffset, 0.0f + yOffset);
87
88 b.moveTo(-32.5f + xOffset, 19 + yOffset);
89 b.lineTo(32.5f + xOffset, 19 + yOffset);
90
91 b.moveTo(-32.5f + xOffset, -19 + yOffset);
92 b.lineTo(32.5f + xOffset, -19 + yOffset);
93 b.lineTo(-32.5f + xOffset, -19 + yOffset);
94
95 b.close();
96
97 return { b.detach(), 70 };
98}
99
100static PathDY make_arrow() {
101 static SkScalar xOffset = 34.f;
102 static SkScalar yOffset = 40.f;
104 b.moveTo(-26.f + xOffset, 0.0f + yOffset);
105 b.lineTo(26.f + xOffset, 0.0f + yOffset);
106
107 b.moveTo(-28.f + xOffset, -2.4748745f + yOffset);
108 b.lineTo(0 + xOffset, 25.525126f + yOffset);
109
110 b.moveTo(-28.f + xOffset, 2.4748745f + yOffset);
111 b.lineTo(0 + xOffset, -25.525126f + yOffset);
112 b.lineTo(-28.f + xOffset, 2.4748745f + yOffset);
113
114 b.close();
115
116 return { b.detach(), 70 };
117}
118
119static PathDY make_curve() {
120 static SkScalar xOffset = -382.f;
121 static SkScalar yOffset = -50.f;
123 b.moveTo(491 + xOffset, 56 + yOffset);
124 b.conicTo(435.93292f + xOffset, 56.000031f + yOffset,
125 382.61078f + xOffset, 69.752716f + yOffset,
126 0.9920463f);
127
128 return { b.detach(), 40 };
129}
130
131static PathDY make_battery() {
132 static SkScalar xOffset = 5.0f;
133
135 b.moveTo(24.67f + xOffset, 0.33000004f);
136 b.lineTo(8.3299999f + xOffset, 0.33000004f);
137 b.lineTo(8.3299999f + xOffset, 5.3299999f);
138 b.lineTo(0.33000004f + xOffset, 5.3299999f);
139 b.lineTo(0.33000004f + xOffset, 50.669998f);
140 b.lineTo(32.669998f + xOffset, 50.669998f);
141 b.lineTo(32.669998f + xOffset, 5.3299999f);
142 b.lineTo(24.67f + xOffset, 5.3299999f);
143 b.lineTo(24.67f + xOffset, 0.33000004f);
144 b.close();
145
146 b.moveTo(25.727224f + xOffset, 12.886665f);
147 b.lineTo(10.907918f + xOffset, 12.886665f);
148 b.lineTo(7.5166659f + xOffset, 28.683645f);
149 b.lineTo(14.810181f + xOffset, 28.683645f);
150 b.lineTo(7.7024879f + xOffset, 46.135998f);
151 b.lineTo(28.049999f + xOffset, 25.136419f);
152 b.lineTo(16.854223f + xOffset, 25.136419f);
153 b.lineTo(25.727224f + xOffset, 12.886665f);
154 b.close();
155 return { b.detach(), 50 };
156}
157
158static PathDY make_battery2() {
159 static SkScalar xOffset = 225.625f;
160
162 b.moveTo(32.669998f + xOffset, 9.8640003f);
163 b.lineTo(0.33000004f + xOffset, 9.8640003f);
164 b.lineTo(0.33000004f + xOffset, 50.669998f);
165 b.lineTo(32.669998f + xOffset, 50.669998f);
166 b.lineTo(32.669998f + xOffset, 9.8640003f);
167 b.close();
168
169 b.moveTo(10.907918f + xOffset, 12.886665f);
170 b.lineTo(25.727224f + xOffset, 12.886665f);
171 b.lineTo(16.854223f + xOffset, 25.136419f);
172 b.lineTo(28.049999f + xOffset, 25.136419f);
173 b.lineTo(7.7024879f + xOffset, 46.135998f);
174 b.lineTo(14.810181f + xOffset, 28.683645f);
175 b.lineTo(7.5166659f + xOffset, 28.683645f);
176 b.lineTo(10.907918f + xOffset, 12.886665f);
177 b.close();
178
179 return { b.detach(), 60 };
180}
181
182static PathDY make_ring() {
183 static SkScalar xOffset = 120;
184 static SkScalar yOffset = -270.f;
185
187 b.setFillType(SkPathFillType::kWinding);
188 b.moveTo(xOffset + 144.859f, yOffset + 285.172f);
189 b.lineTo(xOffset + 144.859f, yOffset + 285.172f);
190 b.lineTo(xOffset + 144.859f, yOffset + 285.172f);
191 b.lineTo(xOffset + 143.132f, yOffset + 284.617f);
192 b.lineTo(xOffset + 144.859f, yOffset + 285.172f);
193 b.close();
194 b.moveTo(xOffset + 135.922f, yOffset + 286.844f);
195 b.lineTo(xOffset + 135.922f, yOffset + 286.844f);
196 b.lineTo(xOffset + 135.922f, yOffset + 286.844f);
197 b.lineTo(xOffset + 135.367f, yOffset + 288.571f);
198 b.lineTo(xOffset + 135.922f, yOffset + 286.844f);
199 b.close();
200 b.moveTo(xOffset + 135.922f, yOffset + 286.844f);
201 b.cubicTo(xOffset + 137.07f, yOffset + 287.219f, xOffset + 138.242f, yOffset + 287.086f,
202 xOffset + 139.242f, yOffset + 286.578f);
203 b.cubicTo(xOffset + 140.234f, yOffset + 286.078f, xOffset + 141.031f, yOffset + 285.203f,
204 xOffset + 141.406f, yOffset + 284.055f);
205 b.lineTo(xOffset + 144.859f, yOffset + 285.172f);
206 b.cubicTo(xOffset + 143.492f, yOffset + 289.375f, xOffset + 138.992f, yOffset + 291.656f,
207 xOffset + 134.797f, yOffset + 290.297f);
208 b.lineTo(xOffset + 135.922f, yOffset + 286.844f);
209 b.close();
210 b.moveTo(xOffset + 129.68f, yOffset + 280.242f);
211 b.lineTo(xOffset + 129.68f, yOffset + 280.242f);
212 b.lineTo(xOffset + 129.68f, yOffset + 280.242f);
213 b.lineTo(xOffset + 131.407f, yOffset + 280.804f);
214 b.lineTo(xOffset + 129.68f, yOffset + 280.242f);
215 b.close();
216 b.moveTo(xOffset + 133.133f, yOffset + 281.367f);
217 b.cubicTo(xOffset + 132.758f, yOffset + 282.508f, xOffset + 132.883f, yOffset + 283.687f,
218 xOffset + 133.391f, yOffset + 284.679f);
219 b.cubicTo(xOffset + 133.907f, yOffset + 285.679f, xOffset + 134.774f, yOffset + 286.468f,
220 xOffset + 135.922f, yOffset + 286.843f);
221 b.lineTo(xOffset + 134.797f, yOffset + 290.296f);
222 b.cubicTo(xOffset + 130.602f, yOffset + 288.929f, xOffset + 128.313f, yOffset + 284.437f,
223 xOffset + 129.68f, yOffset + 280.241f);
224 b.lineTo(xOffset + 133.133f, yOffset + 281.367f);
225 b.close();
226 b.moveTo(xOffset + 139.742f, yOffset + 275.117f);
227 b.lineTo(xOffset + 139.742f, yOffset + 275.117f);
228 b.lineTo(xOffset + 139.18f, yOffset + 276.844f);
229 b.lineTo(xOffset + 139.742f, yOffset + 275.117f);
230 b.close();
231 b.moveTo(xOffset + 138.609f, yOffset + 278.57f);
232 b.cubicTo(xOffset + 137.461f, yOffset + 278.203f, xOffset + 136.297f, yOffset + 278.328f,
233 xOffset + 135.297f, yOffset + 278.836f);
234 b.cubicTo(xOffset + 134.297f, yOffset + 279.344f, xOffset + 133.508f, yOffset + 280.219f,
235 xOffset + 133.133f, yOffset + 281.367f);
236 b.lineTo(xOffset + 129.68f, yOffset + 280.242f);
237 b.cubicTo(xOffset + 131.047f, yOffset + 276.039f, xOffset + 135.539f, yOffset + 273.758f,
238 xOffset + 139.742f, yOffset + 275.117f);
239 b.lineTo(xOffset + 138.609f, yOffset + 278.57f);
240 b.close();
241 b.moveTo(xOffset + 141.406f, yOffset + 284.055f);
242 b.cubicTo(xOffset + 141.773f, yOffset + 282.907f, xOffset + 141.648f, yOffset + 281.735f,
243 xOffset + 141.148f, yOffset + 280.735f);
244 b.cubicTo(xOffset + 140.625f, yOffset + 279.735f, xOffset + 139.757f, yOffset + 278.946f,
245 xOffset + 138.609f, yOffset + 278.571f);
246 b.lineTo(xOffset + 139.742f, yOffset + 275.118f);
247 b.cubicTo(xOffset + 143.937f, yOffset + 276.493f, xOffset + 146.219f, yOffset + 280.977f,
248 xOffset + 144.859f, yOffset + 285.173f);
249 b.lineTo(xOffset + 141.406f, yOffset + 284.055f);
250 b.close();
251
252 // uncomment to reveal PathOps bug, see https://bugs.chromium.org/p/skia/issues/detail?id=9732
253 // (void) Simplify(*path, path);
254
255 return { b.detach(), 15 };
256}
257
258constexpr MakePathProc gProcs[] = {
260 make_rect,
261 make_oval,
270};
271
272constexpr SkScalar gWidths[] = {
273 2.0f,
274 3.0f,
275 4.0f,
276 5.0f,
277 6.0f,
278 7.0f,
279 7.0f,
280 14.0f,
281 0.0f,
282 0.0f,
283 0.0f
284};
285static_assert(std::size(gWidths) == std::size(gProcs));
286
287constexpr SkScalar gMiters[] = {
288 2.0f,
289 3.0f,
290 3.0f,
291 3.0f,
292 4.0f,
293 4.0f,
294 4.0f,
295 4.0f,
296 4.0f,
297 4.0f,
298 4.0f,
299};
300static_assert(std::size(gMiters) == std::size(gProcs));
301
302constexpr SkScalar gXTranslate[] = {
303 0.0f,
304 0.0f,
305 0.0f,
306 0.0f,
307 0.0f,
308 0.0f,
309 0.0f,
310 0.0f,
311 -220.625f,
312 0.0f,
313 0.0f,
314};
315static_assert(std::size(gXTranslate) == std::size(gProcs));
316
317#define N std::size(gProcs)
318
319// This GM tests out drawing small paths (i.e., for Ganesh, using the Distance
320// Field path renderer) which are filled, stroked and filledAndStroked. In
321// particular this ensures that any cache keys in use include the stroking
322// parameters.
323class SmallPathsGM : public skiagm::GM {
324 SkPath fPath[N];
325 SkScalar fDY[N];
326protected:
327 void onOnceBeforeDraw() override {
328 for (size_t i = 0; i < N; i++) {
329 auto [path, dy] = gProcs[i]();
330 fPath[i] = path;
331 fDY[i] = dy;
332 }
333 }
334
335 SkString getName() const override { return SkString("smallpaths"); }
336
337 SkISize getISize() override { return SkISize::Make(640, 512); }
338
339 void onDraw(SkCanvas* canvas) override {
341 paint.setAntiAlias(true);
342
343 // first column: filled paths
344 canvas->save();
345 for (size_t i = 0; i < N; i++) {
346 canvas->drawPath(fPath[i], paint);
347 canvas->translate(gXTranslate[i], fDY[i]);
348 }
349 canvas->restore();
350 canvas->translate(SkIntToScalar(120), SkIntToScalar(0));
351
352 // second column: stroked paths
353 canvas->save();
355 paint.setStrokeCap(SkPaint::kButt_Cap);
356 for (size_t i = 0; i < N; i++) {
357 paint.setStrokeWidth(gWidths[i]);
358 paint.setStrokeMiter(gMiters[i]);
359 canvas->drawPath(fPath[i], paint);
360 canvas->translate(gXTranslate[i], fDY[i]);
361 }
362 canvas->restore();
363 canvas->translate(SkIntToScalar(120), SkIntToScalar(0));
364
365 // third column: stroked paths with different widths
366 canvas->save();
368 paint.setStrokeCap(SkPaint::kButt_Cap);
369 for (size_t i = 0; i < N; i++) {
370 paint.setStrokeWidth(gWidths[i] + 2.0f);
371 paint.setStrokeMiter(gMiters[i]);
372 canvas->drawPath(fPath[i], paint);
373 canvas->translate(gXTranslate[i], fDY[i]);
374 }
375 canvas->restore();
376 canvas->translate(SkIntToScalar(120), SkIntToScalar(0));
377
378 // fourth column: stroked and filled paths
380 paint.setStrokeCap(SkPaint::kButt_Cap);
381 for (size_t i = 0; i < N; i++) {
382 paint.setStrokeWidth(gWidths[i]);
383 paint.setStrokeMiter(gMiters[i]);
384 canvas->drawPath(fPath[i], paint);
385 canvas->translate(gXTranslate[i], fDY[i]);
386 }
387
388 }
389
390private:
391 using INHERITED = skiagm::GM;
392};
393
394DEF_GM(return new SmallPathsGM;)
SkPath fPath
#define SkScalarSin(radians)
Definition: SkScalar.h:45
#define SkIntToScalar(x)
Definition: SkScalar.h:57
#define SkScalarCos(radians)
Definition: SkScalar.h:46
#define SK_ScalarPI
Definition: SkScalar.h:21
void restore()
Definition: SkCanvas.cpp:461
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
int save()
Definition: SkCanvas.cpp:447
void drawPath(const SkPath &path, const SkPaint &paint)
Definition: SkCanvas.cpp:1747
@ kButt_Cap
no stroke extension
Definition: SkPaint.h:334
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
@ kStrokeAndFill_Style
sets to stroke and fill geometry
Definition: SkPaint.h:195
SkPathBuilder & close()
SkPathBuilder & lineTo(SkPoint pt)
SkPathBuilder & moveTo(SkPoint pt)
SkPathBuilder & offset(SkScalar dx, SkScalar dy)
Definition: SkPath.h:59
static SkPath Rect(const SkRect &, SkPathDirection=SkPathDirection::kCW, unsigned startIndex=0)
Definition: SkPath.cpp:3586
static SkPath Oval(const SkRect &, SkPathDirection=SkPathDirection::kCW)
Definition: SkPath.cpp:3590
void onOnceBeforeDraw() override
Definition: smallpaths.cpp:327
SkString getName() const override
Definition: smallpaths.cpp:335
void onDraw(SkCanvas *canvas) override
Definition: smallpaths.cpp:339
SkISize getISize() override
Definition: smallpaths.cpp:337
Definition: gm.h:110
const Paint & paint
Definition: color_source.cc:38
float SkScalar
Definition: extension.cpp:12
static bool b
#define DEF_GM(CODE)
Definition: gm.h:40
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
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
#define N
Definition: smallpaths.cpp:317
static PathDY make_curve()
Definition: smallpaths.cpp:119
constexpr MakePathProc gProcs[]
Definition: smallpaths.cpp:258
static PathDY make_battery2()
Definition: smallpaths.cpp:158
static PathDY make_arrow()
Definition: smallpaths.cpp:100
static PathDY make_star_13()
Definition: smallpaths.cpp:79
static PathDY make_ring()
Definition: smallpaths.cpp:182
PathDY(* MakePathProc)()
Definition: smallpaths.cpp:26
static PathDY make_star_5()
Definition: smallpaths.cpp:78
static PathDY make_triangle()
Definition: smallpaths.cpp:28
static PathDY make_star(int n)
Definition: smallpaths.cpp:61
constexpr SkScalar gMiters[]
Definition: smallpaths.cpp:287
constexpr SkScalar gWidths[]
Definition: smallpaths.cpp:272
static PathDY make_rect()
Definition: smallpaths.cpp:43
static PathDY make_battery()
Definition: smallpaths.cpp:131
static PathDY make_three_line()
Definition: smallpaths.cpp:81
constexpr SkScalar gXTranslate[]
Definition: smallpaths.cpp:302
static PathDY make_oval()
Definition: smallpaths.cpp:52
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
constexpr SkRect makeOffset(float dx, float dy) const
Definition: SkRect.h:965