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