Flutter Engine
The Flutter Engine
dashing.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2012 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"
11#include "include/core/SkFont.h"
17#include "include/core/SkRect.h"
19#include "include/core/SkSize.h"
24#include "tools/ToolUtils.h"
26
27#include <math.h>
28#include <initializer_list>
29
30static void drawline(SkCanvas* canvas, int on, int off, const SkPaint& paint,
31 SkScalar finalX = SkIntToScalar(600), SkScalar finalY = SkIntToScalar(0),
32 SkScalar phase = SkIntToScalar(0),
33 SkScalar startX = SkIntToScalar(0), SkScalar startY = SkIntToScalar(0)) {
35
36 const SkScalar intervals[] = {
37 SkIntToScalar(on),
38 SkIntToScalar(off),
39 };
40
41 p.setPathEffect(SkDashPathEffect::Make(intervals, 2, phase));
42 canvas->drawLine(startX, startY, finalX, finalY, p);
43}
44
45// earlier bug stopped us from drawing very long single-segment dashes, because
46// SkPathMeasure was skipping very small delta-T values (nearlyzero). This is
47// now fixes, so this giant dash should appear.
48static void show_giant_dash(SkCanvas* canvas) {
50
51 drawline(canvas, 1, 1, paint, SkIntToScalar(20 * 1000));
52}
53
54static void show_zero_len_dash(SkCanvas* canvas) {
56
57 drawline(canvas, 2, 2, paint, SkIntToScalar(0));
58 paint.setStroke(true);
59 paint.setStrokeWidth(SkIntToScalar(2));
60 canvas->translate(0, SkIntToScalar(20));
61 drawline(canvas, 4, 4, paint, SkIntToScalar(0));
62}
63
64class DashingGM : public skiagm::GM {
65 SkString getName() const override { return SkString("dashing"); }
66
67 SkISize getISize() override { return {640, 340}; }
68
69 void onDraw(SkCanvas* canvas) override {
70 struct Intervals {
71 int fOnInterval;
72 int fOffInterval;
73 };
74
76 paint.setStroke(true);
77
78 canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
79 canvas->translate(0, SK_ScalarHalf);
80 for (int width = 0; width <= 2; ++width) {
81 for (const Intervals& data : {Intervals{1, 1},
82 Intervals{4, 1}}) {
83 for (bool aa : {false, true}) {
84 int w = width * width * width;
85 paint.setAntiAlias(aa);
86 paint.setStrokeWidth(SkIntToScalar(w));
87
88 int scale = w ? w : 1;
89
90 drawline(canvas, data.fOnInterval * scale, data.fOffInterval * scale,
91 paint);
92 canvas->translate(0, SkIntToScalar(20));
93 }
94 }
95 }
96
97 show_giant_dash(canvas);
98 canvas->translate(0, SkIntToScalar(20));
99 show_zero_len_dash(canvas);
100 canvas->translate(0, SkIntToScalar(20));
101 // Draw 0 on, 0 off dashed line
102 paint.setStrokeWidth(SkIntToScalar(8));
103 drawline(canvas, 0, 0, paint);
104 }
105};
106
107///////////////////////////////////////////////////////////////////////////////
108
109static SkPath make_unit_star(int n) {
110 SkScalar rad = -SK_ScalarPI / 2;
111 const SkScalar drad = (n >> 1) * SK_ScalarPI * 2 / n;
112
114 b.moveTo(0, -SK_Scalar1);
115 for (int i = 1; i < n; i++) {
116 rad += drad;
117 b.lineTo(SkScalarCos(rad), SkScalarSin(rad));
118 }
119 return b.close().detach();
120}
121
123 return SkPathBuilder().moveTo(bounds.left(), bounds.top())
124 .lineTo(bounds.right(), bounds.bottom())
125 .detach();
126}
127
129 return SkPath::Rect(bounds);
130}
131
133 return SkPath::Oval(bounds);
134}
135
139 return path.makeTransform(matrix);
140}
141
142class Dashing2GM : public skiagm::GM {
143 SkString getName() const override { return SkString("dashing2"); }
144
145 SkISize getISize() override { return {640, 480}; }
146
147 void onDraw(SkCanvas* canvas) override {
148 constexpr int gIntervals[] = {
149 3, // 3 dashes: each count [0] followed by intervals [1..count]
150 2, 10, 10,
151 4, 20, 5, 5, 5,
152 2, 2, 2
153 };
154
155 SkPath (*gProc[])(const SkRect&) = {
157 };
158
160 paint.setAntiAlias(true);
161 paint.setStroke(true);
162 paint.setStrokeWidth(SkIntToScalar(6));
163
165 bounds.offset(SkIntToScalar(20), SkIntToScalar(20));
166 SkScalar dx = bounds.width() * 4 / 3;
167 SkScalar dy = bounds.height() * 4 / 3;
168
169 const int* intervals = &gIntervals[1];
170 for (int y = 0; y < gIntervals[0]; ++y) {
171 SkScalar vals[std::size(gIntervals)]; // more than enough
172 int count = *intervals++;
173 for (int i = 0; i < count; ++i) {
174 vals[i] = SkIntToScalar(*intervals++);
175 }
176 SkScalar phase = vals[0] / 2;
177 paint.setPathEffect(SkDashPathEffect::Make(vals, count, phase));
178
179 for (size_t x = 0; x < std::size(gProc); ++x) {
180 SkPath path;
181 SkRect r = bounds;
182 r.offset(x * dx, y * dy);
183 canvas->drawPath(gProc[x](r), paint);
184 }
185 }
186 }
187};
188
189//////////////////////////////////////////////////////////////////////////////
190
191// Test out the on/off line dashing Chrome if fond of
192class Dashing3GM : public skiagm::GM {
193 SkString getName() const override { return SkString("dashing3"); }
194
195 SkISize getISize() override { return {640, 480}; }
196
197 // Draw a 100x100 block of dashed lines. The horizontal ones are BW
198 // while the vertical ones are AA.
199 void drawDashedLines(SkCanvas* canvas,
200 SkScalar lineLength,
201 SkScalar phase,
202 SkScalar dashLength,
203 int strokeWidth,
204 bool circles) {
205 SkPaint p;
206 p.setColor(SK_ColorBLACK);
207 p.setStroke(true);
208 p.setStrokeWidth(SkIntToScalar(strokeWidth));
209
210 if (circles) {
211 p.setStrokeCap(SkPaint::kRound_Cap);
212 }
213
214 SkScalar intervals[2] = { dashLength, dashLength };
215
216 p.setPathEffect(SkDashPathEffect::Make(intervals, 2, phase));
217
218 SkPoint pts[2];
219
220 for (int y = 0; y < 100; y += 10*strokeWidth) {
221 pts[0].set(0, SkIntToScalar(y));
222 pts[1].set(lineLength, SkIntToScalar(y));
223
224 canvas->drawPoints(SkCanvas::kLines_PointMode, 2, pts, p);
225 }
226
227 p.setAntiAlias(true);
228
229 for (int x = 0; x < 100; x += 14*strokeWidth) {
230 pts[0].set(SkIntToScalar(x), 0);
231 pts[1].set(SkIntToScalar(x), lineLength);
232
233 canvas->drawPoints(SkCanvas::kLines_PointMode, 2, pts, p);
234 }
235 }
236
237 void onDraw(SkCanvas* canvas) override {
238 // 1on/1off 1x1 squares with phase of 0 - points fastpath
239 canvas->save();
240 canvas->translate(2, 0);
241 this->drawDashedLines(canvas, 100, 0, SK_Scalar1, 1, false);
242 canvas->restore();
243
244 // 1on/1off 1x1 squares with phase of .5 - rects fastpath (due to partial squares)
245 canvas->save();
246 canvas->translate(112, 0);
247 this->drawDashedLines(canvas, 100, SK_ScalarHalf, SK_Scalar1, 1, false);
248 canvas->restore();
249
250 // 1on/1off 1x1 squares with phase of 1 - points fastpath
251 canvas->save();
252 canvas->translate(222, 0);
253 this->drawDashedLines(canvas, 100, SK_Scalar1, SK_Scalar1, 1, false);
254 canvas->restore();
255
256 // 1on/1off 1x1 squares with phase of 1 and non-integer length - rects fastpath
257 canvas->save();
258 canvas->translate(332, 0);
259 this->drawDashedLines(canvas, 99.5f, SK_ScalarHalf, SK_Scalar1, 1, false);
260 canvas->restore();
261
262 // 255on/255off 1x1 squares with phase of 0 - rects fast path
263 canvas->save();
264 canvas->translate(446, 0);
265 this->drawDashedLines(canvas, 100, 0, SkIntToScalar(255), 1, false);
266 canvas->restore();
267
268 // 1on/1off 3x3 squares with phase of 0 - points fast path
269 canvas->save();
270 canvas->translate(2, 110);
271 this->drawDashedLines(canvas, 100, 0, SkIntToScalar(3), 3, false);
272 canvas->restore();
273
274 // 1on/1off 3x3 squares with phase of 1.5 - rects fast path
275 canvas->save();
276 canvas->translate(112, 110);
277 this->drawDashedLines(canvas, 100, 1.5f, SkIntToScalar(3), 3, false);
278 canvas->restore();
279
280 // 1on/1off 1x1 circles with phase of 1 - no fast path yet
281 canvas->save();
282 canvas->translate(2, 220);
283 this->drawDashedLines(canvas, 100, SK_Scalar1, SK_Scalar1, 1, true);
284 canvas->restore();
285
286 // 1on/1off 3x3 circles with phase of 1 - no fast path yet
287 canvas->save();
288 canvas->translate(112, 220);
289 this->drawDashedLines(canvas, 100, 0, SkIntToScalar(3), 3, true);
290 canvas->restore();
291
292 // 1on/1off 1x1 squares with rotation - should break fast path
293 canvas->save();
294 canvas->translate(332+SK_ScalarRoot2Over2*100, 110+SK_ScalarRoot2Over2*100);
295 canvas->rotate(45);
296 canvas->translate(-50, -50);
297
298 this->drawDashedLines(canvas, 100, SK_Scalar1, SK_Scalar1, 1, false);
299 canvas->restore();
300
301 // 3on/3off 3x1 rects - should use rect fast path regardless of phase
302 for (int phase = 0; phase <= 3; ++phase) {
303 canvas->save();
304 canvas->translate(SkIntToScalar(phase*110+2),
305 SkIntToScalar(330));
306 this->drawDashedLines(canvas, 100, SkIntToScalar(phase), SkIntToScalar(3), 1, false);
307 canvas->restore();
308 }
309 }
310
311};
312
313//////////////////////////////////////////////////////////////////////////////
314
315class Dashing4GM : public skiagm::GM {
316 SkString getName() const override { return SkString("dashing4"); }
317
318 SkISize getISize() override { return {640, 1100}; }
319
320 void onDraw(SkCanvas* canvas) override {
321 struct Intervals {
322 int fOnInterval;
323 int fOffInterval;
324 };
325
327 paint.setStroke(true);
328
329 canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
331
332 for (int width = 0; width <= 2; ++width) {
333 for (const Intervals& data : {Intervals{1, 1},
334 Intervals{4, 2},
335 Intervals{0, 4}}) { // test for zero length on interval.
336 // zero length intervals should draw
337 // a line of squares or circles
338 for (bool aa : {false, true}) {
339 for (auto cap : {SkPaint::kRound_Cap, SkPaint::kSquare_Cap}) {
340 int w = width * width * width;
341 paint.setAntiAlias(aa);
342 paint.setStrokeWidth(SkIntToScalar(w));
343 paint.setStrokeCap(cap);
344
345 int scale = w ? w : 1;
346
347 drawline(canvas, data.fOnInterval * scale, data.fOffInterval * scale,
348 paint);
349 canvas->translate(0, SkIntToScalar(20));
350 }
351 }
352 }
353 }
354
355 for (int aa = 0; aa <= 1; ++aa) {
356 paint.setAntiAlias(SkToBool(aa));
357 paint.setStrokeWidth(8.f);
358 paint.setStrokeCap(SkPaint::kSquare_Cap);
359 // Single dash element that is cut off at start and end
360 drawline(canvas, 32, 16, paint, 20.f, 0, 5.f);
361 canvas->translate(0, SkIntToScalar(20));
362
363 // Two dash elements where each one is cut off at beginning and end respectively
364 drawline(canvas, 32, 16, paint, 56.f, 0, 5.f);
365 canvas->translate(0, SkIntToScalar(20));
366
367 // Many dash elements where first and last are cut off at beginning and end respectively
368 drawline(canvas, 32, 16, paint, 584.f, 0, 5.f);
369 canvas->translate(0, SkIntToScalar(20));
370
371 // Diagonal dash line where src pnts are not axis aligned (as apposed to being diagonal from
372 // a canvas rotation)
373 drawline(canvas, 32, 16, paint, 600.f, 30.f);
374 canvas->translate(0, SkIntToScalar(20));
375
376 // Case where only the off interval exists on the line. Thus nothing should be drawn
377 drawline(canvas, 32, 16, paint, 8.f, 0.f, 40.f);
378 canvas->translate(0, SkIntToScalar(20));
379 }
380
381 // Test overlapping circles.
382 canvas->translate(SkIntToScalar(5), SkIntToScalar(20));
383 paint.setAntiAlias(true);
384 paint.setStrokeCap(SkPaint::kRound_Cap);
385 paint.setColor(0x44000000);
386 paint.setStrokeWidth(40);
387 drawline(canvas, 0, 30, paint);
388
389 canvas->translate(0, SkIntToScalar(50));
390 paint.setStrokeCap(SkPaint::kSquare_Cap);
391 drawline(canvas, 0, 30, paint);
392
393 // Test we draw the cap when the line length is zero.
394 canvas->translate(0, SkIntToScalar(50));
395 paint.setStrokeCap(SkPaint::kRound_Cap);
396 paint.setColor(0xFF000000);
397 paint.setStrokeWidth(11);
398 drawline(canvas, 0, 30, paint, 0);
399
400 canvas->translate(SkIntToScalar(100), 0);
401 drawline(canvas, 1, 30, paint, 0);
402 }
403};
404
405//////////////////////////////////////////////////////////////////////////////
406
407class Dashing5GM : public skiagm::GM {
408public:
409 Dashing5GM(bool doAA) : fDoAA(doAA) {}
410
411private:
412 bool runAsBench() const override { return true; }
413
414 SkString getName() const override { return SkString(fDoAA ? "dashing5_aa" : "dashing5_bw"); }
415
416 SkISize getISize() override { return {400, 200}; }
417
418 void onDraw(SkCanvas* canvas) override {
419 constexpr int kOn = 4;
420 constexpr int kOff = 4;
421 constexpr int kIntervalLength = kOn + kOff;
422
423 constexpr SkColor gColors[kIntervalLength] = {
432 };
433
435 paint.setStroke(true);
436
437 paint.setAntiAlias(fDoAA);
438
439 SkMatrix rot;
440 rot.setRotate(90);
441 SkASSERT(rot.rectStaysRect());
442
443 canvas->concat(rot);
444
445 int sign; // used to toggle the direction of the lines
446 int phase = 0;
447
448 for (int x = 0; x < 200; x += 10) {
449 paint.setStrokeWidth(SkIntToScalar(phase+1));
450 paint.setColor(gColors[phase]);
451 sign = (x % 20) ? 1 : -1;
452 drawline(canvas, kOn, kOff, paint,
453 SkIntToScalar(x), -sign * SkIntToScalar(10003),
454 SkIntToScalar(phase),
455 SkIntToScalar(x), sign * SkIntToScalar(10003));
456 phase = (phase + 1) % kIntervalLength;
457 }
458
459 for (int y = -400; y < 0; y += 10) {
460 paint.setStrokeWidth(SkIntToScalar(phase+1));
461 paint.setColor(gColors[phase]);
462 sign = (y % 20) ? 1 : -1;
463 drawline(canvas, kOn, kOff, paint,
464 -sign * SkIntToScalar(10003), SkIntToScalar(y),
465 SkIntToScalar(phase),
466 sign * SkIntToScalar(10003), SkIntToScalar(y));
467 phase = (phase + 1) % kIntervalLength;
468 }
469 }
470
471private:
472 bool fDoAA;
473};
474
475DEF_SIMPLE_GM(longpathdash, canvas, 612, 612) {
477 for (int x = 32; x < 256; x += 16) {
478 for (SkScalar a = 0; a < 3.141592f * 2; a += 0.03141592f) {
479 SkPoint pts[2] = {
480 { 256 + (float) sin(a) * x,
481 256 + (float) cos(a) * x },
482 { 256 + (float) sin(a + 3.141592 / 3) * (x + 64),
483 256 + (float) cos(a + 3.141592 / 3) * (x + 64) }
484 };
485 lines.moveTo(pts[0]);
486 for (SkScalar i = 0; i < 1; i += 0.05f) {
487 lines.lineTo(pts[0].fX * (1 - i) + pts[1].fX * i,
488 pts[0].fY * (1 - i) + pts[1].fY * i);
489 }
490 }
491 }
492 SkPaint p;
493 p.setAntiAlias(true);
494 p.setStroke(true);
495 p.setStrokeWidth(1);
496 const SkScalar intervals[] = { 1, 1 };
497 p.setPathEffect(SkDashPathEffect::Make(intervals, std::size(intervals), 0));
498
499 canvas->translate(50, 50);
500 canvas->drawPath(lines, p);
501}
502
503DEF_SIMPLE_GM(longlinedash, canvas, 512, 512) {
504 SkPaint p;
505 p.setAntiAlias(true);
506 p.setStroke(true);
507 p.setStrokeWidth(80);
508
509 const SkScalar intervals[] = { 2, 2 };
510 p.setPathEffect(SkDashPathEffect::Make(intervals, std::size(intervals), 0));
511 canvas->drawRect(SkRect::MakeXYWH(-10000, 100, 20000, 20), p);
512}
513
514DEF_SIMPLE_GM(dashbigrects, canvas, 256, 256) {
515 SkRandom rand;
516
517 constexpr int kHalfStrokeWidth = 8;
518 constexpr int kOnOffInterval = 2*kHalfStrokeWidth;
519
520 canvas->clear(SkColors::kBlack);
521
522 SkPaint p;
523 p.setAntiAlias(true);
524 p.setStroke(true);
525 p.setStrokeWidth(2*kHalfStrokeWidth);
526 p.setStrokeCap(SkPaint::kButt_Cap);
527
528 constexpr SkScalar intervals[] = { kOnOffInterval, kOnOffInterval };
529 p.setPathEffect(SkDashPathEffect::Make(intervals, std::size(intervals), 0));
530
531 constexpr float gWidthHeights[] = {
532 1000000000.0f * kOnOffInterval + kOnOffInterval/2.0f,
533 1000000.0f * kOnOffInterval + kOnOffInterval/2.0f,
534 1000.0f * kOnOffInterval + kOnOffInterval/2.0f,
535 100.0f * kOnOffInterval + kOnOffInterval/2.0f,
536 10.0f * kOnOffInterval + kOnOffInterval/2.0f,
537 9.0f * kOnOffInterval + kOnOffInterval/2.0f,
538 8.0f * kOnOffInterval + kOnOffInterval/2.0f,
539 7.0f * kOnOffInterval + kOnOffInterval/2.0f,
540 6.0f * kOnOffInterval + kOnOffInterval/2.0f,
541 5.0f * kOnOffInterval + kOnOffInterval/2.0f,
542 4.0f * kOnOffInterval + kOnOffInterval/2.0f,
543 };
544
545 for (size_t i = 0; i < std::size(gWidthHeights); ++i) {
546 p.setColor(ToolUtils::color_to_565(rand.nextU() | (0xFF << 24)));
547
548 int offset = 2 * i * kHalfStrokeWidth + kHalfStrokeWidth;
549 canvas->drawRect(SkRect::MakeXYWH(offset, offset, gWidthHeights[i], gWidthHeights[i]), p);
550 }
551}
552
553DEF_SIMPLE_GM(longwavyline, canvas, 512, 512) {
554 SkPaint p;
555 p.setAntiAlias(true);
556 p.setStroke(true);
557 p.setStrokeWidth(2);
558
559 SkPath wavy;
560 wavy.moveTo(-10000, 100);
561 for (SkScalar i = -10000; i < 10000; i += 20) {
562 wavy.quadTo(i + 5, 95, i + 10, 100);
563 wavy.quadTo(i + 15, 105, i + 20, 100);
564 }
565 canvas->drawPath(wavy, p);
566}
567
568DEF_SIMPLE_GM(dashtextcaps, canvas, 512, 512) {
569 SkPaint p;
570 p.setAntiAlias(true);
571 p.setStroke(true);
572 p.setStrokeWidth(10);
573 p.setStrokeCap(SkPaint::kRound_Cap);
574 p.setStrokeJoin(SkPaint::kRound_Join);
575 p.setARGB(0xff, 0xbb, 0x00, 0x00);
576
578
579 const SkScalar intervals[] = { 12, 12 };
580 p.setPathEffect(SkDashPathEffect::Make(intervals, std::size(intervals), 0));
581 canvas->drawString("Sausages", 10, 90, font, p);
582 canvas->drawLine(8, 120, 456, 120, p);
583}
584
585DEF_SIMPLE_GM(dash_line_zero_off_interval, canvas, 160, 330) {
586 static constexpr SkScalar kIntervals[] = {5.f, 0.f, 2.f, 0.f};
587 SkPaint dashPaint;
588 dashPaint.setPathEffect(SkDashPathEffect::Make(kIntervals, std::size(kIntervals), 0.f));
589 SkASSERT(dashPaint.getPathEffect());
590 dashPaint.setStroke(true);
591 dashPaint.setStrokeWidth(20.f);
592 static constexpr struct {
593 SkPoint fA, fB;
594 } kLines[] = {{{0.5f, 0.5f}, {30.5f, 0.5f}}, // horizontal
595 {{0.5f, 0.5f}, {0.5f, 30.5f}}, // vertical
596 {{0.5f, 0.5f}, {0.5f, 0.5f}}, // point
597 {{0.5f, 0.5f}, {25.5f, 25.5f}}}; // diagonal
598 SkScalar pad = 5.f + dashPaint.getStrokeWidth();
599 canvas->translate(pad / 2.f, pad / 2.f);
600 canvas->save();
601 SkScalar h = 0.f;
602 for (const auto& line : kLines) {
603 h = std::max(h, SkScalarAbs(line.fA.fY - line.fB.fY));
604 }
605 for (const auto& line : kLines) {
606 SkScalar w = SkScalarAbs(line.fA.fX - line.fB.fX);
608 dashPaint.setStrokeCap(cap);
609 for (auto aa : {false, true}) {
610 dashPaint.setAntiAlias(aa);
611 canvas->drawLine(line.fA, line.fB, dashPaint);
612 canvas->translate(0.f, pad + h);
613 }
614 }
615 canvas->restore();
616 canvas->translate(pad + w, 0.f);
617 canvas->save();
618 }
619}
620
621DEF_SIMPLE_GM(thin_aa_dash_lines, canvas, 330, 110) {
623 static constexpr SkScalar kScale = 100.f;
624 static constexpr SkScalar kIntervals[] = {10/kScale, 5/kScale};
625 paint.setPathEffect(SkDashPathEffect::Make(kIntervals, std::size(kIntervals), 0.f));
626 paint.setAntiAlias(true);
627 paint.setStrokeWidth(0.25f/kScale);
628 // substep moves the subpixel offset every iteration.
629 static constexpr SkScalar kSubstep = 0.05f/kScale;
630 // We will draw a grid of horiz/vertical lines that pass through each other's off intervals.
631 static constexpr SkScalar kStep = kIntervals[0] + kIntervals[1];
632 canvas->scale(kScale, kScale);
633 canvas->translate(kIntervals[1], kIntervals[1]);
635 paint.setStrokeCap(c);
636 for (SkScalar x = -.5f*kIntervals[1]; x < 105/kScale; x += (kStep + kSubstep)) {
637 canvas->drawLine({x, 0}, {x, 100/kScale}, paint);
638 canvas->drawLine({0, x}, {100/kScale, x}, paint);
639 }
640 canvas->translate(110/kScale, 0);
641 }
642}
643
644DEF_SIMPLE_GM(path_effect_empty_result, canvas, 100, 100) {
645 SkPaint p;
646 p.setStroke(true);
647 p.setStrokeWidth(1);
648
649 SkPath path;
650 float r = 70;
651 float l = 70;
652 float t = 70;
653 float b = 70;
654 path.moveTo(l, t);
655 path.lineTo(r, t);
656 path.lineTo(r, b);
657 path.lineTo(l, b);
658 path.close();
659
660 float dashes[] = {2.f, 2.f};
661 p.setPathEffect(SkDashPathEffect::Make(dashes, 2, 0.f));
662
663 canvas->drawPath(path, p);
664}
665
666//////////////////////////////////////////////////////////////////////////////
667
668DEF_GM(return new DashingGM;)
669DEF_GM(return new Dashing2GM;)
670DEF_GM(return new Dashing3GM;)
671DEF_GM(return new Dashing4GM;)
672DEF_GM(return new Dashing5GM(true);)
673DEF_GM(return new Dashing5GM(false);)
static const int strokeWidth
Definition: BlurTest.cpp:60
int count
Definition: FontMgrTest.cpp:50
static const SkColor gColors[]
#define SkASSERT(cond)
Definition: SkAssert.h:116
constexpr SkColor SK_ColorYELLOW
Definition: SkColor.h:139
constexpr SkColor SK_ColorMAGENTA
Definition: SkColor.h:147
uint32_t SkColor
Definition: SkColor.h:37
constexpr SkColor SK_ColorCYAN
Definition: SkColor.h:143
constexpr SkColor SK_ColorGRAY
Definition: SkColor.h:113
constexpr SkColor SK_ColorBLUE
Definition: SkColor.h:135
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
constexpr SkColor SK_ColorBLACK
Definition: SkColor.h:103
constexpr SkColor SK_ColorGREEN
Definition: SkColor.h:131
constexpr SkColor SK_ColorDKGRAY
Definition: SkColor.h:108
static int sign(SkScalar x)
Definition: SkPath.cpp:2205
#define SkScalarSin(radians)
Definition: SkScalar.h:45
#define SK_Scalar1
Definition: SkScalar.h:18
#define SK_ScalarHalf
Definition: SkScalar.h:19
#define SkIntToScalar(x)
Definition: SkScalar.h:57
#define SkScalarCos(radians)
Definition: SkScalar.h:46
#define SK_ScalarRoot2Over2
Definition: SkScalar.h:23
#define SkScalarAbs(x)
Definition: SkScalar.h:39
#define SK_ScalarPI
Definition: SkScalar.h:21
static constexpr bool SkToBool(const T &x)
Definition: SkTo.h:35
static const SlideProc gProc[]
Dashing5GM(bool doAA)
Definition: dashing.cpp:409
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint &paint)
Definition: SkCanvas.cpp:1710
void restore()
Definition: SkCanvas.cpp:461
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint &paint)
Definition: SkCanvas.cpp:2700
void clear(SkColor color)
Definition: SkCanvas.h:1199
void rotate(SkScalar degrees)
Definition: SkCanvas.cpp:1300
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 concat(const SkMatrix &matrix)
Definition: SkCanvas.cpp:1318
void drawString(const char str[], SkScalar x, SkScalar y, const SkFont &font, const SkPaint &paint)
Definition: SkCanvas.h:1803
@ kLines_PointMode
draw each pair of points as a line segment
Definition: SkCanvas.h:1242
static sk_sp< SkPathEffect > Make(const SkScalar intervals[], int count, SkScalar phase)
Definition: SkFont.h:35
static SkMatrix RectToRect(const SkRect &src, const SkRect &dst, ScaleToFit mode=kFill_ScaleToFit)
Definition: SkMatrix.h:157
@ kCenter_ScaleToFit
scales and aligns to center
Definition: SkMatrix.h:139
bool rectStaysRect() const
Definition: SkMatrix.h:271
SkMatrix & setRotate(SkScalar degrees, SkScalar px, SkScalar py)
Definition: SkMatrix.cpp:452
@ 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
SkPathEffect * getPathEffect() const
Definition: SkPaint.h:506
void setAntiAlias(bool aa)
Definition: SkPaint.h:170
void setStrokeCap(Cap cap)
Definition: SkPaint.cpp:179
void setPathEffect(sk_sp< SkPathEffect > pathEffect)
SkScalar getStrokeWidth() const
Definition: SkPaint.h:300
@ kRound_Join
adds circle
Definition: SkPaint.h:360
void setStroke(bool)
Definition: SkPaint.cpp:115
void setStrokeWidth(SkScalar width)
Definition: SkPaint.cpp:159
SkPathBuilder & lineTo(SkPoint pt)
SkPathBuilder & moveTo(SkPoint pt)
Definition: SkPath.h:59
static SkPath Rect(const SkRect &, SkPathDirection=SkPathDirection::kCW, unsigned startIndex=0)
Definition: SkPath.cpp:3586
SkPath & moveTo(SkScalar x, SkScalar y)
Definition: SkPath.cpp:688
SkPath & quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2)
Definition: SkPath.cpp:746
static SkPath Oval(const SkRect &, SkPathDirection=SkPathDirection::kCW)
Definition: SkPath.cpp:3590
uint32_t nextU()
Definition: SkRandom.h:42
Definition: gm.h:110
SkScalar width()
Definition: gm.h:159
const Paint & paint
Definition: color_source.cc:38
static SkPath make_path_rect(const SkRect &bounds)
Definition: dashing.cpp:128
static SkPath make_unit_star(int n)
Definition: dashing.cpp:109
static SkPath make_path_line(const SkRect &bounds)
Definition: dashing.cpp:122
DEF_SIMPLE_GM(longpathdash, canvas, 612, 612)
Definition: dashing.cpp:475
static SkPath make_path_star(const SkRect &bounds)
Definition: dashing.cpp:136
static void show_zero_len_dash(SkCanvas *canvas)
Definition: dashing.cpp:54
static void drawline(SkCanvas *canvas, int on, int off, const SkPaint &paint, SkScalar finalX=SkIntToScalar(600), SkScalar finalY=SkIntToScalar(0), SkScalar phase=SkIntToScalar(0), SkScalar startX=SkIntToScalar(0), SkScalar startY=SkIntToScalar(0))
Definition: dashing.cpp:30
static void show_giant_dash(SkCanvas *canvas)
Definition: dashing.cpp:48
static SkPath make_path_oval(const SkRect &bounds)
Definition: dashing.cpp:132
float SkScalar
Definition: extension.cpp:12
static bool b
struct MyStruct a[10]
#define DEF_GM(CODE)
Definition: gm.h:40
static float max(float r, float g, float b)
Definition: hsl.cpp:49
double y
double x
constexpr SkColor4f kBlack
Definition: SkColor.h:435
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
Optional< SkRect > bounds
Definition: SkRecords.h:189
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition: SkRecords.h:208
sk_sp< SkTypeface > DefaultPortableTypeface()
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
font
Font Metadata and Metrics.
SkScalar w
SkScalar h
const Scalar scale
SeparatedVector2 offset
Definition: SkSize.h:16
float fX
x-axis value
Definition: SkPoint_impl.h:164
void set(float x, float y)
Definition: SkPoint_impl.h:200
float fY
y-axis value
Definition: SkPoint_impl.h:165
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659
void offset(float dx, float dy)
Definition: SkRect.h:1016
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63