Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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) {
340 path->addRect(bounds, SkPathDirection::kCW);
341 path->addRect(inset(bounds), SkPathDirection::kCW);
342 title->set("CW CW");
343 }
344
345 static void make1(SkPath* path, const SkRect& bounds, SkString* title) {
346 path->addRect(bounds, SkPathDirection::kCW);
347 path->addRect(inset(bounds), SkPathDirection::kCCW);
348 title->set("CW CCW");
349 }
350
351 static void make2(SkPath* path, const SkRect& bounds, SkString* title) {
352 path->addOval(bounds, SkPathDirection::kCW);
353 path->addOval(inset(bounds), SkPathDirection::kCW);
354 title->set("CW CW");
355 }
356
357 static void make3(SkPath* path, const SkRect& bounds, SkString* title) {
358 path->addOval(bounds, SkPathDirection::kCW);
359 path->addOval(inset(bounds), SkPathDirection::kCCW);
360 title->set("CW CCW");
361 }
362
363 static void make4(SkPath* path, const SkRect& bounds, SkString* title) {
364 path->addRect(bounds, SkPathDirection::kCW);
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) {
372 path->addRect(bounds, SkPathDirection::kCW);
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}
SkPath fPath
const char * options
SkColor4f color
#define SkAssertResult(cond)
Definition SkAssert.h:123
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 drawRect(const SkRect &rect, const SkPaint &paint)
void drawOval(const SkRect &oval, const SkPaint &paint)
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
void restore()
Definition SkCanvas.cpp:465
void translate(SkScalar dx, SkScalar dy)
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)
void clear(SkColor color)
Definition SkCanvas.h:1199
void rotate(SkScalar degrees)
void drawRoundRect(const SkRect &rect, SkScalar rx, SkScalar ry, const SkPaint &paint)
int save()
Definition SkCanvas.cpp:451
void drawPath(const SkPath &path, const SkPaint &paint)
void scale(SkScalar sx, SkScalar sy)
void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint &paint)
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 *)
SkPath & addCircle(SkScalar x, SkScalar y, SkScalar radius, SkPathDirection dir=SkPathDirection::kCW)
Definition SkPath.cpp:1149
SkPath & moveTo(SkScalar x, SkScalar y)
Definition SkPath.cpp:678
SkPath & lineTo(SkScalar x, SkScalar y)
Definition SkPath.cpp:718
static SkPath Polygon(const SkPoint pts[], int count, bool isClosed, SkPathFillType=SkPathFillType::kWinding, bool isVolatile=false)
Definition SkPath.cpp:3546
SkPath & addRect(const SkRect &rect, SkPathDirection dir, unsigned start)
Definition SkPath.cpp:854
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
SkString getName() const override
Definition strokes.cpp:61
void onDraw(SkCanvas *canvas) override
Definition strokes.cpp:72
SkString getName() const override
Definition strokes.cpp:179
SkISize getISize() override
Definition strokes.cpp:181
void onDraw(SkCanvas *canvas) override
Definition strokes.cpp:197
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
virtual void modifyGraphiteContextOptions(skgpu::graphite::ContextOptions *) const
Definition gm.h:179
const Paint & paint
float SkScalar
Definition extension.cpp:12
#define DEF_GM(CODE)
Definition gm.h:40
#define DEF_SIMPLE_GM(NAME, CANVAS, W, H)
Definition gm.h:50
double y
double x
SkColor color_to_565(SkColor color)
SK_API bool FillPathWithPaint(const SkPath &src, const SkPaint &paint, SkPath *dst, const SkRect *cullRect, SkScalar resScale=1)
SkScalar w
SkScalar h
const Scalar scale
#define N
Definition strokes.cpp:35
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
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20
float fX
x-axis value
float fY
y-axis value
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