Flutter Engine
The Flutter Engine
strokes.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2011 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/SkPath.h"
16#include "include/core/SkRect.h"
18#include "include/core/SkSize.h"
24#include "src/base/SkRandom.h"
25#include "tools/ToolUtils.h"
26
27#include <string.h>
28
29#if defined(SK_GRAPHITE)
31#endif
32
33#define W 400
34#define H 400
35#define N 50
36
39
40static void rnd_rect(SkRect* r, SkPaint* paint, SkRandom& rand) {
41 SkScalar x = rand.nextUScalar1() * W;
42 SkScalar y = rand.nextUScalar1() * H;
43 SkScalar w = rand.nextUScalar1() * (W >> 2);
44 SkScalar h = rand.nextUScalar1() * (H >> 2);
45 SkScalar hoffset = rand.nextSScalar1();
46 SkScalar woffset = rand.nextSScalar1();
47
48 r->setXYWH(x, y, w, h);
49 r->offset(-w/2 + woffset, -h/2 + hoffset);
50
51 paint->setColor(rand.nextU());
52 paint->setAlphaf(1.0f);
53}
54
55
56class StrokesGM : public skiagm::GM {
57public:
59
60protected:
61 SkString getName() const override { return SkString("strokes_round"); }
62
63 SkISize getISize() override { return SkISize::Make(W, H * 2); }
64
65#if defined(SK_GRAPHITE)
67 options->fMaxPathAtlasTextureSize = 0;
68 options->fAllowMultipleAtlasTextures = false;
69 }
70#endif
71
72 void onDraw(SkCanvas* canvas) override {
75 paint.setStrokeWidth(SkIntToScalar(9)/2);
76
77 for (int y = 0; y < 2; y++) {
78 paint.setAntiAlias(!!y);
79 SkAutoCanvasRestore acr(canvas, true);
80 canvas->translate(0, SH * y);
83 , SW - SkIntToScalar(2), SH - SkIntToScalar(2)
84 ));
85
86 SkRandom rand;
87 for (int i = 0; i < N; i++) {
88 SkRect r;
89 rnd_rect(&r, &paint, rand);
90 canvas->drawOval(r, paint);
91 rnd_rect(&r, &paint, rand);
92 canvas->drawRoundRect(r, r.width()/4, r.height()/4, paint);
93 rnd_rect(&r, &paint, rand);
94 }
95 }
96 }
97
98private:
99 using INHERITED = skiagm::GM;
100};
101
102/* See
103 https://code.google.com/p/chromium/issues/detail?id=422974 and
104 http://jsfiddle.net/1xnku3sg/2/
105 */
107 SkPath fMoveHfPath, fMoveZfPath, fDashedfPath, fRefPath[4];
108 SkPath fCubicPath, fQuadPath, fLinePath;
109protected:
110 void onOnceBeforeDraw() override {
111
112 SkAssertResult(SkParsePath::FromSVGString("M0,0h0M10,0h0M20,0h0", &fMoveHfPath));
113 SkAssertResult(SkParsePath::FromSVGString("M0,0zM10,0zM20,0z", &fMoveZfPath));
114 SkAssertResult(SkParsePath::FromSVGString("M0,0h25", &fDashedfPath));
115 SkAssertResult(SkParsePath::FromSVGString("M 0 0 C 0 0 0 0 0 0", &fCubicPath));
116 SkAssertResult(SkParsePath::FromSVGString("M 0 0 Q 0 0 0 0", &fQuadPath));
117 SkAssertResult(SkParsePath::FromSVGString("M 0 0 L 0 0", &fLinePath));
118
119 for (int i = 0; i < 3; ++i) {
120 fRefPath[0].addCircle(i * 10.f, 0, 5);
121 fRefPath[1].addCircle(i * 10.f, 0, 10);
122 fRefPath[2].addRect(i * 10.f - 4, -2, i * 10.f + 4, 6);
123 fRefPath[3].addRect(i * 10.f - 10, -10, i * 10.f + 10, 10);
124 }
125 }
126
127 SkString getName() const override { return SkString("zeroPath"); }
128
129 SkISize getISize() override { return SkISize::Make(W, H * 2); }
130
131 void onDraw(SkCanvas* canvas) override {
132 SkPaint fillPaint, strokePaint, dashPaint;
133 fillPaint.setAntiAlias(true);
134 strokePaint = fillPaint;
135 strokePaint.setStyle(SkPaint::kStroke_Style);
136 for (int i = 0; i < 2; ++i) {
137 fillPaint.setAlphaf(1.0f);
138 strokePaint.setAlphaf(1.0f);
139 strokePaint.setStrokeWidth(i ? 8.f : 10.f);
141 canvas->save();
142 canvas->translate(10 + i * 100.f, 10);
143 canvas->drawPath(fMoveHfPath, strokePaint);
144 canvas->translate(0, 20);
145 canvas->drawPath(fMoveZfPath, strokePaint);
146 dashPaint = strokePaint;
147 const SkScalar intervals[] = { 0, 10 };
148 dashPaint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0));
149 SkPath fillPath;
150 skpathutils::FillPathWithPaint(fDashedfPath, dashPaint, &fillPath);
151 canvas->translate(0, 20);
152 canvas->drawPath(fDashedfPath, dashPaint);
153 canvas->translate(0, 20);
154 canvas->drawPath(fRefPath[i * 2], fillPaint);
155 strokePaint.setStrokeWidth(20);
156 strokePaint.setAlphaf(0.5f);
157 canvas->translate(0, 50);
158 canvas->drawPath(fMoveHfPath, strokePaint);
159 canvas->translate(0, 30);
160 canvas->drawPath(fMoveZfPath, strokePaint);
161 canvas->translate(0, 30);
162 fillPaint.setAlphaf(0.5f);
163 canvas->drawPath(fRefPath[1 + i * 2], fillPaint);
164 canvas->translate(0, 30);
165 canvas->drawPath(fCubicPath, strokePaint);
166 canvas->translate(0, 30);
167 canvas->drawPath(fQuadPath, strokePaint);
168 canvas->translate(0, 30);
169 canvas->drawPath(fLinePath, strokePaint);
170 canvas->restore();
171 }
172 }
173
174private:
175 using INHERITED = skiagm::GM;
176};
177
179 SkString getName() const override { return SkString("teenyStrokes"); }
180
181 SkISize getISize() override { return SkISize::Make(W, H * 2); }
182
183 static void line(SkScalar scale, SkCanvas* canvas, SkColor color) {
184 SkPaint p;
185 p.setAntiAlias(true);
186 p.setStyle(SkPaint::kStroke_Style);
187 p.setColor(color);
188 canvas->translate(50, 0);
189 canvas->save();
190 p.setStrokeWidth(scale * 5);
191 canvas->scale(1 / scale, 1 / scale);
192 canvas->drawLine(20 * scale, 20 * scale, 20 * scale, 100 * scale, p);
193 canvas->drawLine(20 * scale, 20 * scale, 100 * scale, 100 * scale, p);
194 canvas->restore();
195 }
196
197 void onDraw(SkCanvas* canvas) override {
198 line(0.00005f, canvas, SK_ColorBLACK);
199 line(0.000045f, canvas, SK_ColorRED);
200 line(0.0000035f, canvas, SK_ColorGREEN);
201 line(0.000003f, canvas, SK_ColorBLUE);
202 line(0.000002f, canvas, SK_ColorBLACK);
203 }
204private:
205 using INHERITED = skiagm::GM;
206};
207
208DEF_SIMPLE_GM(CubicStroke, canvas, 384, 384) {
209 SkPaint p;
210 p.setAntiAlias(true);
211 p.setStyle(SkPaint::kStroke_Style);
212 p.setStrokeWidth(1.0720f);
213 SkPath path;
214 path.moveTo(-6000,-6000);
215 path.cubicTo(-3500,5500,-500,5500,2500,-6500);
216 canvas->drawPath(path, p);
217 p.setStrokeWidth(1.0721f);
218 canvas->translate(10, 10);
219 canvas->drawPath(path, p);
220 p.setStrokeWidth(1.0722f);
221 canvas->translate(10, 10);
222 canvas->drawPath(path, p);
223}
224
225DEF_SIMPLE_GM(zerolinestroke, canvas, 90, 120) {
228 paint.setStrokeWidth(20);
229 paint.setAntiAlias(true);
230 paint.setStrokeCap(SkPaint::kRound_Cap);
231
232 SkPath path;
233 path.moveTo(30, 90);
234 path.lineTo(30, 90);
235 path.lineTo(60, 90);
236 path.lineTo(60, 90);
237 canvas->drawPath(path, paint);
238
239 path.reset();
240 path.moveTo(30, 30);
241 path.lineTo(60, 30);
242 canvas->drawPath(path, paint);
243
244 path.reset();
245 path.moveTo(30, 60);
246 path.lineTo(30, 60);
247 path.lineTo(60, 60);
248 canvas->drawPath(path, paint);
249}
250
251DEF_SIMPLE_GM(quadcap, canvas, 200, 200) {
252 SkPaint p;
253 p.setAntiAlias(true);
254 p.setStyle(SkPaint::kStroke_Style);
255 p.setStrokeWidth(0);
256 SkPath path;
257 SkPoint pts[] = {{105.738571f,13.126318f},
258 {105.738571f,13.126318f},
259 {123.753784f,1.f}};
260 SkVector tangent = pts[1] - pts[2];
261 tangent.normalize();
262 SkPoint pts2[3];
263 memcpy(pts2, pts, sizeof(pts));
264 const SkScalar capOutset = SK_ScalarPI / 8;
265 pts2[0].fX += tangent.fX * capOutset;
266 pts2[0].fY += tangent.fY * capOutset;
267 pts2[1].fX += tangent.fX * capOutset;
268 pts2[1].fY += tangent.fY * capOutset;
269 pts2[2].fX += -tangent.fX * capOutset;
270 pts2[2].fY += -tangent.fY * capOutset;
271 path.moveTo(pts2[0]);
272 path.quadTo(pts2[1], pts2[2]);
273 canvas->drawPath(path, p);
274
275 path.reset();
276 path.moveTo(pts[0]);
277 path.quadTo(pts[1], pts[2]);
278 p.setStrokeCap(SkPaint::kRound_Cap);
279 canvas->translate(30, 0);
280 canvas->drawPath(path, p);
281}
282
283class Strokes2GM : public skiagm::GM {
284 SkPath fPath;
285protected:
286 void onOnceBeforeDraw() override {
287 SkRandom rand;
288 fPath.moveTo(0, 0);
289 for (int i = 0; i < 13; i++) {
290 SkScalar x = rand.nextUScalar1() * (W >> 1);
291 SkScalar y = rand.nextUScalar1() * (H >> 1);
292 fPath.lineTo(x, y);
293 }
294 }
295
296 SkString getName() const override { return SkString("strokes_poly"); }
297
298 SkISize getISize() override { return SkISize::Make(W, H * 2); }
299
300 void onDraw(SkCanvas* canvas) override {
301 canvas->drawColor(SK_ColorWHITE);
302
305 paint.setStrokeWidth(SkIntToScalar(9)/2);
306
307 for (int y = 0; y < 2; y++) {
308 paint.setAntiAlias(!!y);
309 SkAutoCanvasRestore acr(canvas, true);
310 canvas->translate(0, SH * y);
312 SkIntToScalar(2),
313 SW - SkIntToScalar(2),
314 SH - SkIntToScalar(2)));
315
316 SkRandom rand;
317 for (int i = 0; i < N/2; i++) {
318 SkRect r;
319 rnd_rect(&r, &paint, rand);
320 canvas->rotate(SkIntToScalar(15), SW/2, SH/2);
321 canvas->drawPath(fPath, paint);
322 }
323 }
324 }
325
326private:
327 using INHERITED = skiagm::GM;
328};
329
330//////////////////////////////////////////////////////////////////////////////
331
332static SkRect inset(const SkRect& r) {
333 SkRect rr(r);
334 rr.inset(r.width()/10, r.height()/10);
335 return rr;
336}
337
338class Strokes3GM : public skiagm::GM {
339 static void make0(SkPath* path, const SkRect& bounds, SkString* title) {
342 title->set("CW CW");
343 }
344
345 static void make1(SkPath* path, const SkRect& bounds, SkString* title) {
348 title->set("CW CCW");
349 }
350
351 static void make2(SkPath* path, const SkRect& bounds, SkString* title) {
354 title->set("CW CW");
355 }
356
357 static void make3(SkPath* path, const SkRect& bounds, SkString* title) {
360 title->set("CW CCW");
361 }
362
363 static void make4(SkPath* path, const SkRect& bounds, SkString* title) {
365 SkRect r = bounds;
366 r.inset(bounds.width() / 10, -bounds.height() / 10);
367 path->addOval(r, SkPathDirection::kCW);
368 title->set("CW CW");
369 }
370
371 static void make5(SkPath* path, const SkRect& bounds, SkString* title) {
373 SkRect r = bounds;
374 r.inset(bounds.width() / 10, -bounds.height() / 10);
375 path->addOval(r, SkPathDirection::kCCW);
376 title->set("CW CCW");
377 }
378
379public:
381
382protected:
383 SkString getName() const override { return SkString("strokes3"); }
384
385 SkISize getISize() override { return SkISize::Make(1500, 1500); }
386
387 void onDraw(SkCanvas* canvas) override {
388 SkPaint origPaint;
389 origPaint.setAntiAlias(true);
391 SkPaint fillPaint(origPaint);
392 fillPaint.setColor(SK_ColorRED);
393 SkPaint strokePaint(origPaint);
394 strokePaint.setColor(ToolUtils::color_to_565(0xFF4444FF));
395
396 void (*procs[])(SkPath*, const SkRect&, SkString*) = {
397 make0, make1, make2, make3, make4, make5
398 };
399
400 canvas->translate(SkIntToScalar(20), SkIntToScalar(80));
401
403 SkScalar dx = bounds.width() * 4/3;
404 SkScalar dy = bounds.height() * 5;
405
406 for (size_t i = 0; i < std::size(procs); ++i) {
407 SkPath orig;
408 SkString str;
409 procs[i](&orig, bounds, &str);
410
411 canvas->save();
412 for (int j = 0; j < 13; ++j) {
413 strokePaint.setStrokeWidth(SK_Scalar1 * j * j);
414 canvas->drawPath(orig, strokePaint);
415 canvas->drawPath(orig, origPaint);
416 SkPath fill;
417 skpathutils::FillPathWithPaint(orig, strokePaint, &fill);
418 canvas->drawPath(fill, fillPaint);
419 canvas->translate(dx + strokePaint.getStrokeWidth(), 0);
420 }
421 canvas->restore();
422 canvas->translate(0, dy);
423 }
424 }
425
426private:
427 using INHERITED = skiagm::GM;
428};
429
430class Strokes4GM : public skiagm::GM {
431public:
433
434protected:
435 SkString getName() const override { return SkString("strokes_zoomed"); }
436
437 SkISize getISize() override { return SkISize::Make(W, H * 2); }
438
439 void onDraw(SkCanvas* canvas) override {
442 paint.setStrokeWidth(0.055f);
443
444 canvas->scale(1000, 1000);
445 canvas->drawCircle(0, 2, 1.97f, paint);
446 }
447
448private:
449 using INHERITED = skiagm::GM;
450};
451
452// Test stroking for curves that produce degenerate tangents when t is 0 or 1 (see bug 4191)
453class Strokes5GM : public skiagm::GM {
454public:
456
457protected:
458 SkString getName() const override { return SkString("zero_control_stroke"); }
459
460 SkISize getISize() override { return SkISize::Make(W, H * 2); }
461
462 void onDraw(SkCanvas* canvas) override {
463 SkPaint p;
464 p.setColor(SK_ColorRED);
465 p.setAntiAlias(true);
466 p.setStyle(SkPaint::kStroke_Style);
467 p.setStrokeWidth(40);
468 p.setStrokeCap(SkPaint::kButt_Cap);
469
470 SkPath path;
471 path.moveTo(157.474f,111.753f);
472 path.cubicTo(128.5f,111.5f,35.5f,29.5f,35.5f,29.5f);
473 canvas->drawPath(path, p);
474 path.reset();
475 path.moveTo(250, 50);
476 path.quadTo(280, 80, 280, 80);
477 canvas->drawPath(path, p);
478 path.reset();
479 path.moveTo(150, 50);
480 path.conicTo(180, 80, 180, 80, 0.707f);
481 canvas->drawPath(path, p);
482
483 path.reset();
484 path.moveTo(157.474f,311.753f);
485 path.cubicTo(157.474f,311.753f,85.5f,229.5f,35.5f,229.5f);
486 canvas->drawPath(path, p);
487 path.reset();
488 path.moveTo(280, 250);
489 path.quadTo(280, 250, 310, 280);
490 canvas->drawPath(path, p);
491 path.reset();
492 path.moveTo(180, 250);
493 path.conicTo(180, 250, 210, 280, 0.707f);
494 canvas->drawPath(path, p);
495 }
496
497private:
498 using INHERITED = skiagm::GM;
499};
500
501
502//////////////////////////////////////////////////////////////////////////////
503
504DEF_GM( return new StrokesGM; )
505DEF_GM( return new Strokes2GM; )
506DEF_GM( return new Strokes3GM; )
507DEF_GM( return new Strokes4GM; )
508DEF_GM( return new Strokes5GM; )
509
510DEF_GM( return new ZeroLenStrokesGM; )
511DEF_GM( return new TeenyStrokesGM; )
512
513DEF_SIMPLE_GM(zerolinedash, canvas, 256, 256) {
514 canvas->clear(SK_ColorWHITE);
515
517 paint.setColor(SkColorSetARGB(255, 0, 0, 0));
518 paint.setStrokeWidth(11);
519 paint.setStrokeCap(SkPaint::kRound_Cap);
520 paint.setStrokeJoin(SkPaint::kBevel_Join);
521
522 SkScalar dash_pattern[] = {1, 5};
523 paint.setPathEffect(SkDashPathEffect::Make(dash_pattern, 2, 0));
524
525 canvas->drawLine(100, 100, 100, 100, paint);
526}
527
528#ifdef PDF_IS_FIXED_SO_THIS_DOESNT_BREAK_IT
529DEF_SIMPLE_GM(longrect_dash, canvas, 250, 250) {
530 canvas->clear(SK_ColorWHITE);
531
533 paint.setColor(SkColorSetARGB(255, 0, 0, 0));
534 paint.setStrokeWidth(5);
535 paint.setStrokeCap(SkPaint::kRound_Cap);
536 paint.setStrokeJoin(SkPaint::kBevel_Join);
538 SkScalar dash_pattern[] = {1, 5};
539 paint.setPathEffect(SkDashPathEffect::Make(dash_pattern, 2, 0));
540 // try all combinations of stretching bounds
541 for (auto left : { 20.f, -100001.f } ) {
542 for (auto top : { 20.f, -100001.f } ) {
543 for (auto right : { 40.f, 100001.f } ) {
544 for (auto bottom : { 40.f, 100001.f } ) {
545 canvas->save();
546 canvas->clipRect({10, 10, 50, 50});
547 canvas->drawRect({left, top, right, bottom}, paint);
548 canvas->restore();
549 canvas->translate(60, 0);
550 }
551 }
552 canvas->translate(-60 * 4, 60);
553 }
554 }
555}
556#endif
557
558DEF_SIMPLE_GM(inner_join_geometry, canvas, 1000, 700) {
559 // These paths trigger cases where we must add inner join geometry.
560 // skbug.com/11964
561 const SkPoint pathPoints[] = {
562 /*moveTo*/ /*lineTo*/ /*lineTo*/
563 {119, 71}, {129, 151}, {230, 24},
564 {200, 144}, {129, 151}, {230, 24},
565 {192, 176}, {224, 175}, {281, 103},
566 {233, 205}, {224, 175}, {281, 103},
567 {121, 216}, {234, 189}, {195, 147},
568 {141, 216}, {254, 189}, {238, 250},
569 {159, 202}, {269, 197}, {289, 165},
570 {159, 202}, {269, 197}, {287, 227},
571 };
572
573 SkPaint pathPaint;
574 pathPaint.setStroke(true);
575 pathPaint.setAntiAlias(true);
576 pathPaint.setStrokeWidth(100);
577
578 SkPaint skeletonPaint;
579 skeletonPaint.setStroke(true);
580 skeletonPaint.setAntiAlias(true);
581 skeletonPaint.setStrokeWidth(0);
582 skeletonPaint.setColor(SK_ColorRED);
583
584 canvas->translate(0, 50);
585 for (size_t i = 0; i < std::size(pathPoints) / 3; i++) {
586 auto path = SkPath::Polygon(pathPoints + i * 3, 3, false);
587 canvas->drawPath(path, pathPaint);
588
589 SkPath fillPath;
590 skpathutils::FillPathWithPaint(path, pathPaint, &fillPath);
591 canvas->drawPath(fillPath, skeletonPaint);
592
593 canvas->translate(200, 0);
594 if ((i + 1) % 4 == 0) {
595 canvas->translate(-800, 200);
596 }
597 }
598}
599
600DEF_SIMPLE_GM(skbug12244, canvas, 150, 150) {
601 // Should look like a stroked triangle; these vertices are the results of the SkStroker
602 // but we draw as a filled path in order to highlight that it's the GPU triangulating path
603 // renderer that's the source of the problem, and not the stroking operation. The original
604 // path was a simple:
605 // m(0,0), l(100, 40), l(0, 80), l(0,0) with a stroke width of 15px
606 SkPath path;
607 path.moveTo(2.7854299545288085938, -6.9635753631591796875);
608 path.lineTo( 120.194366455078125, 40);
609 path.lineTo(-7.5000004768371582031, 91.07775115966796875);
610 path.lineTo(-7.5000004768371582031, -11.077748298645019531);
611 path.lineTo(2.7854299545288085938, -6.9635753631591796875);
612 path.moveTo(-2.7854299545288085938, 6.9635753631591796875);
613 path.lineTo( 0, 0);
614 path.lineTo( 7.5, 0);
615 path.lineTo(7.5000004768371582031, 68.92224884033203125);
616 path.lineTo( 79.805633544921875, 40);
617 path.lineTo(-2.7854299545288085938, 6.9635753631591796875);
618
619 SkPaint p;
620 p.setColor(SK_ColorGREEN);
621
622 canvas->translate(20.f, 20.f);
623 canvas->drawPath(path, p);
624}
625
626DEF_SIMPLE_GM(b_340982297, canvas, 80, 50) {
628 paint.setAntiAlias(true);
629
630 SkPath path;
631 path.moveTo(30.23983f, 48.5674667f);
632 path.lineTo(1.30884242f, 45.5222702f);
633 path.lineTo(2.97688866f, 29.6749554f);
634 path.lineTo(17.4423828f, 31.1975555f);
635 path.lineTo(2.94269657f, 30.0452003f);
636 path.lineTo(4.38597536f, 11.8849154f);
637 path.lineTo(33.3853493f, 14.1896257f);
638 path.close();
639
640 canvas->drawPath(path, paint);
641
642 path.reset();
643 path.moveTo(73.3853455f, 4.18963623f);
644 path.lineTo(69.995636f, 39.1360626f);
645 path.lineTo(42.83145142f, 21.056778f);
646 path.lineTo(42.97689819f, 19.6749573f);
647 path.lineTo(57.4423828f, 21.1975555f);
648 path.lineTo(42.94268799f, 20.0451965f);
649 path.lineTo(44.38595581f, 1.88491821f);
650 path.close();
651
652 canvas->drawPath(path, paint);
653}
SkPath fPath
const char * options
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
uint32_t SkColor
Definition: SkColor.h:37
constexpr SkColor SK_ColorBLUE
Definition: SkColor.h:135
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
static constexpr SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
Definition: SkColor.h:49
constexpr SkColor SK_ColorBLACK
Definition: SkColor.h:103
constexpr SkColor SK_ColorGREEN
Definition: SkColor.h:131
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
#define SK_Scalar1
Definition: SkScalar.h:18
#define SkIntToScalar(x)
Definition: SkScalar.h:57
#define SK_ScalarPI
Definition: SkScalar.h:21
void drawOval(const SkRect &oval, const SkPaint &paint)
Definition: SkCanvas.cpp:1698
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
Definition: SkCanvas.cpp:1361
void restore()
Definition: SkCanvas.cpp:461
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
void drawColor(SkColor color, SkBlendMode mode=SkBlendMode::kSrcOver)
Definition: SkCanvas.h:1182
void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint &paint)
Definition: SkCanvas.cpp:2700
void rotate(SkScalar degrees)
Definition: SkCanvas.cpp:1300
void drawRoundRect(const SkRect &rect, SkScalar rx, SkScalar ry, const SkPaint &paint)
Definition: SkCanvas.cpp:2717
int save()
Definition: SkCanvas.cpp:447
void drawPath(const SkPath &path, const SkPaint &paint)
Definition: SkCanvas.cpp:1747
void scale(SkScalar sx, SkScalar sy)
Definition: SkCanvas.cpp:1289
void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint &paint)
Definition: SkCanvas.cpp:2707
static sk_sp< SkPathEffect > Make(const SkScalar intervals[], int count, SkScalar phase)
@ kRound_Cap
adds circle
Definition: SkPaint.h:335
@ kButt_Cap
no stroke extension
Definition: SkPaint.h:334
@ kSquare_Cap
adds square
Definition: SkPaint.h:336
void setStyle(Style style)
Definition: SkPaint.cpp:105
void setColor(SkColor color)
Definition: SkPaint.cpp:119
void setAntiAlias(bool aa)
Definition: SkPaint.h:170
void setStrokeCap(Cap cap)
Definition: SkPaint.cpp:179
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
void setPathEffect(sk_sp< SkPathEffect > pathEffect)
SkScalar getStrokeWidth() const
Definition: SkPaint.h:300
@ kBevel_Join
connects outside edges
Definition: SkPaint.h:361
void setStroke(bool)
Definition: SkPaint.cpp:115
void setStrokeWidth(SkScalar width)
Definition: SkPaint.cpp:159
void setAlphaf(float a)
Definition: SkPaint.cpp:130
static bool FromSVGString(const char str[], SkPath *)
Definition: SkPath.h:59
SkPath & addCircle(SkScalar x, SkScalar y, SkScalar radius, SkPathDirection dir=SkPathDirection::kCW)
Definition: SkPath.cpp:1213
SkPath & moveTo(SkScalar x, SkScalar y)
Definition: SkPath.cpp:688
SkPath & lineTo(SkScalar x, SkScalar y)
Definition: SkPath.cpp:728
static SkPath Polygon(const SkPoint pts[], int count, bool isClosed, SkPathFillType=SkPathFillType::kWinding, bool isVolatile=false)
Definition: SkPath.cpp:3614
SkPath & addRect(const SkRect &rect, SkPathDirection dir, unsigned start)
Definition: SkPath.cpp:864
uint32_t nextU()
Definition: SkRandom.h:42
SkScalar nextUScalar1()
Definition: SkRandom.h:101
SkScalar nextSScalar1()
Definition: SkRandom.h:113
void set(const SkString &src)
Definition: SkString.h:186
void onOnceBeforeDraw() override
Definition: strokes.cpp:286
SkISize getISize() override
Definition: strokes.cpp:298
void onDraw(SkCanvas *canvas) override
Definition: strokes.cpp:300
SkString getName() const override
Definition: strokes.cpp:296
SkString getName() const override
Definition: strokes.cpp:383
SkISize getISize() override
Definition: strokes.cpp:385
void onDraw(SkCanvas *canvas) override
Definition: strokes.cpp:387
SkISize getISize() override
Definition: strokes.cpp:437
SkString getName() const override
Definition: strokes.cpp:435
void onDraw(SkCanvas *canvas) override
Definition: strokes.cpp:439
SkString getName() const override
Definition: strokes.cpp:458
SkISize getISize() override
Definition: strokes.cpp:460
void onDraw(SkCanvas *canvas) override
Definition: strokes.cpp:462
SkISize getISize() override
Definition: strokes.cpp:63
StrokesGM()
Definition: strokes.cpp:58
SkString getName() const override
Definition: strokes.cpp:61
void onDraw(SkCanvas *canvas) override
Definition: strokes.cpp:72
void onOnceBeforeDraw() override
Definition: strokes.cpp:110
SkString getName() const override
Definition: strokes.cpp:127
SkISize getISize() override
Definition: strokes.cpp:129
void onDraw(SkCanvas *canvas) override
Definition: strokes.cpp:131
Definition: gm.h:110
virtual void modifyGraphiteContextOptions(skgpu::graphite::ContextOptions *) const
Definition: gm.h:179
const Paint & paint
Definition: color_source.cc:38
DlColor color
float SkScalar
Definition: extension.cpp:12
#define DEF_GM(CODE)
Definition: gm.h:40
double y
double x
Optional< SkRect > bounds
Definition: SkRecords.h:189
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition: SkRecords.h:208
SkColor color_to_565(SkColor color)
Definition: ToolUtils.cpp:139
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
SK_API bool FillPathWithPaint(const SkPath &src, const SkPaint &paint, SkPath *dst, const SkRect *cullRect, SkScalar resScale=1)
Definition: SkPathUtils.cpp:23
SkScalar w
SkScalar h
const Scalar scale
#define N
Definition: strokes.cpp:35
DEF_SIMPLE_GM(CubicStroke, canvas, 384, 384)
Definition: strokes.cpp:208
constexpr SkScalar SH
Definition: strokes.cpp:38
#define W
Definition: strokes.cpp:33
#define H
Definition: strokes.cpp:34
constexpr SkScalar SW
Definition: strokes.cpp:37
static void rnd_rect(SkRect *r, SkPaint *paint, SkRandom &rand)
Definition: strokes.cpp:40
static SkRect inset(const SkRect &r)
Definition: strokes.cpp:332
Definition: SkMD5.cpp:130
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
float fX
x-axis value
Definition: SkPoint_impl.h:164
float fY
y-axis value
Definition: SkPoint_impl.h:165
bool normalize()
Definition: SkPoint.cpp:22
void inset(float dx, float dy)
Definition: SkRect.h:1060
void setXYWH(float x, float y, float width, float height)
Definition: SkRect.h:931
void offset(float dx, float dy)
Definition: SkRect.h:1016
constexpr float height() const
Definition: SkRect.h:769
constexpr float width() const
Definition: SkRect.h:762
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition: SkRect.h:646