Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
PathSlide.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
12#include "include/core/SkFont.h"
22#include "src/base/SkTime.h"
23#include "src/base/SkUTF.h"
24#include "src/core/SkGeometry.h"
28
29#include <stdlib.h>
30
31// http://code.google.com/p/skia/issues/detail?id=32
32static void test_cubic() {
33 SkPoint src[4] = {
34 { 556.25000f, 523.03003f },
35 { 556.23999f, 522.96002f },
36 { 556.21997f, 522.89001f },
37 { 556.21997f, 522.82001f }
38 };
39 SkPoint dst[11];
40 dst[10].set(42, -42); // one past the end, that we don't clobber these
41 SkScalar tval[] = { 0.33333334f, 0.99999994f };
42
43 SkChopCubicAt(src, dst, tval, 2);
44
45#if 0
46 for (int i = 0; i < 11; i++) {
47 SkDebugf("--- %d [%g %g]\n", i, dst[i].fX, dst[i].fY);
48 }
49#endif
50}
51
52static void test_cubic2() {
53 const char* str = "M2242 -590088L-377758 9.94099e+07L-377758 9.94099e+07L2242 -590088Z";
54 SkPath path;
56
57 {
58 SkRect r = path.getBounds();
59 SkIRect ir;
60 r.round(&ir);
61 SkDebugf("[%g %g %g %g] [%x %x %x %x]\n",
64 (uint32_t)ir.fLeft, (uint32_t)ir.fTop, (uint32_t)ir.fRight, (uint32_t)ir.fBottom);
65 }
66
68 bitmap.allocN32Pixels(300, 200);
69
70 SkCanvas canvas(bitmap);
72 paint.setAntiAlias(true);
73 canvas.drawPath(path, paint);
74}
75
77 SkScalar fPrevSecs;
78 SkScalar fDStroke, fStroke, fMinStroke, fMaxStroke;
79 SkPath fPath[6];
80 bool fShowHairline;
81
82public:
84 fPrevSecs = 0;
85 fName = "Paths";
86 }
87
88 void load(SkScalar w, SkScalar h) override {
89 test_cubic();
91
92 fShowHairline = false;
93
94 fDStroke = 1;
95 fStroke = 10;
96 fMinStroke = 10;
97 fMaxStroke = 180;
98
99 const SkScalar V = 85;
100
101 fPath[0].moveTo(40, 70);
102 fPath[0].lineTo(70, 70 + SK_ScalarHalf);
103 fPath[0].lineTo(110, 70);
104
105 fPath[1].moveTo(40, 70);
106 fPath[1].lineTo(70, 70 - SK_ScalarHalf);
107 fPath[1].lineTo(110, 70);
108
109 fPath[2].moveTo(V, V);
110 fPath[2].lineTo(50, V);
111 fPath[2].lineTo(50, 50);
112
113 fPath[3].moveTo(50, 50);
114 fPath[3].lineTo(50, V);
115 fPath[3].lineTo(V, V);
116
117 fPath[4].moveTo(50, 50);
118 fPath[4].lineTo(50, V);
119 fPath[4].lineTo(52, 50);
120
121 fPath[5].moveTo(52, 50);
122 fPath[5].lineTo(50, V);
123 fPath[5].lineTo(50, 50);
124 }
125
126 void drawPath(SkCanvas* canvas, const SkPath& path, SkPaint::Join j) {
128
129 paint.setAntiAlias(true);
131 paint.setStrokeJoin(j);
132 paint.setStrokeWidth(fStroke);
133
134 if (fShowHairline) {
135 SkPath fill;
136
138 paint.setStrokeWidth(0);
139 canvas->drawPath(fill, paint);
140 } else {
141 canvas->drawPath(path, paint);
142 }
143
144 paint.setColor(SK_ColorRED);
145 paint.setStrokeWidth(0);
146 canvas->drawPath(path, paint);
147 }
148
149 void draw(SkCanvas* canvas) override {
150 canvas->clear(0xFFDDDDDD);
151
152 canvas->translate(50, 50);
153
154 static const SkPaint::Join gJoins[] = {
158 };
159
160 for (size_t i = 0; i < std::size(gJoins); i++) {
161 canvas->save();
162 for (size_t j = 0; j < std::size(fPath); j++) {
163 this->drawPath(canvas, fPath[j], gJoins[i]);
164 canvas->translate(200, 0);
165 }
166 canvas->restore();
167
168 canvas->translate(0, 200);
169 }
170 }
171
172 bool animate(double nanos) override {
173 SkScalar currSecs = TimeUtils::Scaled(1e-9 * nanos, 100);
174 SkScalar delta = currSecs - fPrevSecs;
175 fPrevSecs = currSecs;
176
177 fStroke += fDStroke * delta;
178 if (fStroke > fMaxStroke || fStroke < fMinStroke) {
179 fDStroke = -fDStroke;
180 }
181 return true;
182 }
183
185 fShowHairline = !fShowHairline;
186 return nullptr;
187 }
188
189 bool onClick(ClickHandlerSlide::Click*) override { return false; }
190};
191
192DEF_SLIDE( return new PathSlide; )
193
194//////////////////////////////////////////////////////////////////////////////
195
196#include "include/effects/SkCornerPathEffect.h"
197#include "src/base/SkRandom.h"
198
200 bool fDoFrame, fDoCorner, fDoConic;
201 SkPaint fPtsPaint, fSkeletonPaint, fCornerPaint;
202 enum {
203 N = 4
204 };
205 SkPoint fPts[N];
206
207public:
208 ArcToSlide() : fDoFrame(false), fDoCorner(false), fDoConic(false) {
209 SkRandom rand;
210 for (int i = 0; i < N; ++i) {
211 fPts[i].fX = 20 + rand.nextUScalar1() * 640;
212 fPts[i].fY = 20 + rand.nextUScalar1() * 480;
213 }
214
215 const SkScalar rad = 50;
216
217 fPtsPaint.setAntiAlias(true);
218 fPtsPaint.setStrokeWidth(15);
220
221 fCornerPaint.setAntiAlias(true);
222 fCornerPaint.setStyle(SkPaint::kStroke_Style);
223 fCornerPaint.setStrokeWidth(13);
224 fCornerPaint.setColor(SK_ColorGREEN);
225 fCornerPaint.setPathEffect(SkCornerPathEffect::Make(rad*2));
226
227 fSkeletonPaint.setAntiAlias(true);
228 fSkeletonPaint.setStyle(SkPaint::kStroke_Style);
229 fSkeletonPaint.setColor(SK_ColorRED);
230
231 fName = "ArcTo";
232 }
233
234 bool onChar(SkUnichar uni) override {
235 switch (uni) {
236 case '1': this->toggle(fDoFrame); return true;
237 case '2': this->toggle(fDoCorner); return true;
238 case '3': this->toggle(fDoConic); return true;
239 default: break;
240 }
241 return false;
242 }
243 void draw(SkCanvas* canvas) override {
244 canvas->drawPoints(SkCanvas::kPoints_PointMode, N, fPts, fPtsPaint);
245
246 SkPath path;
247 this->makePath(&path);
248
249 if (fDoCorner) {
250 canvas->drawPath(path, fCornerPaint);
251 }
252
253 canvas->drawPath(path, fSkeletonPaint);
254 }
255
256protected:
258 const SkScalar tol = 4;
259 const SkRect r = SkRect::MakeXYWH(x - tol, y - tol, tol * 2, tol * 2);
260 for (int i = 0; i < N; ++i) {
261 if (r.intersects(SkRect::MakeXYWH(fPts[i].fX, fPts[i].fY, 1, 1))) {
262 return new Click([this, i](Click* c) {
263 fPts[i] = c->fCurr;
264 return true;
265 });
266 }
267 }
268 return nullptr;
269 }
270
271 bool onClick(ClickHandlerSlide::Click *) override { return false; }
272
273private:
274 void makePath(SkPath* path) {
275 path->moveTo(fPts[0]);
276 for (int i = 1; i < N; ++i) {
277 path->lineTo(fPts[i]);
278 }
279 if (!fDoFrame) {
280 path->close();
281 }
282 }
283
284 void toggle(bool& value) {
285 value = !value;
286 }
287};
288DEF_SLIDE( return new ArcToSlide; )
289
290/////////////
291
293 bool fClosed, fShowStroke, fShowHidden, fShowSkeleton, fAsCurves = false;
294 int fJoinType, fCapType;
295 float fWidth = 30;
296 SkPaint fPtsPaint, fHiddenPaint, fSkeletonPaint, fStrokePaint;
297
298 enum {
299 N = 4
300 };
301 SkPoint fPts[N];
302
303public:
305 : fClosed(false)
306 , fShowStroke(true)
307 , fShowHidden(false)
308 , fShowSkeleton(true)
309 , fJoinType(0)
310 , fCapType(0) {
311 SkRandom rand;
312 for (int i = 0; i < N; ++i) {
313 fPts[i].fX = 20 + rand.nextUScalar1() * 640;
314 fPts[i].fY = 20 + rand.nextUScalar1() * 480;
315 }
316
317 fPtsPaint.setAntiAlias(true);
318 fPtsPaint.setStrokeWidth(10);
320
321 fHiddenPaint.setAntiAlias(true);
322 fHiddenPaint.setStyle(SkPaint::kStroke_Style);
323 fHiddenPaint.setColor(0xFF0000FF);
324
325 fStrokePaint.setAntiAlias(true);
326 fStrokePaint.setStyle(SkPaint::kStroke_Style);
327 fStrokePaint.setStrokeWidth(50);
328 fStrokePaint.setColor(0x8000FF00);
329
330 fSkeletonPaint.setAntiAlias(true);
331 fSkeletonPaint.setStyle(SkPaint::kStroke_Style);
332 fSkeletonPaint.setColor(SK_ColorRED);
333
334 fName = "FatStroke";
335 }
336 bool onChar(SkUnichar uni) override {
337 switch (uni) {
338 case '1': this->toggle(fShowSkeleton); return true;
339 case '2': this->toggle(fShowStroke); return true;
340 case '3': this->toggle(fShowHidden); return true;
341 case '4': this->toggle3(fJoinType); return true;
342 case '5': this->toggle3(fCapType); return true;
343 case '6': this->toggle(fClosed); return true;
344 case 'c': this->toggle(fAsCurves); return true;
345 case '-': fWidth -= 5; return true;
346 case '=': fWidth += 5; return true;
347 default: break;
348 }
349 return false;
350 }
351
352 void draw(SkCanvas* canvas) override {
353 canvas->drawColor(0xFFEEEEEE);
354
355 SkPath path;
356 this->makePath(&path);
357
358 fStrokePaint.setStrokeWidth(fWidth);
359 fStrokePaint.setStrokeJoin((SkPaint::Join)fJoinType);
360 fStrokePaint.setStrokeCap((SkPaint::Cap)fCapType);
361
362 if (fShowStroke) {
363 canvas->drawPath(path, fStrokePaint);
364 }
365 if (fShowHidden) {
366 SkPath hidden;
367 skpathutils::FillPathWithPaint(path, fStrokePaint, &hidden);
368 canvas->drawPath(hidden, fHiddenPaint);
369 }
370 if (fShowSkeleton) {
371 canvas->drawPath(path, fSkeletonPaint);
372 }
373 canvas->drawPoints(SkCanvas::kPoints_PointMode, N, fPts, fPtsPaint);
374 }
375
376protected:
378 const SkScalar tol = 4;
379 const SkRect r = SkRect::MakeXYWH(x - tol, y - tol, tol * 2, tol * 2);
380 for (int i = 0; i < N; ++i) {
381 if (r.intersects(SkRect::MakeXYWH(fPts[i].fX, fPts[i].fY, 1, 1))) {
382 return new Click([this, i](Click* c) {
383 fPts[i] = c->fCurr;
384 return true;
385 });
386 }
387 }
388 return nullptr;
389 }
390
391 bool onClick(ClickHandlerSlide::Click *) override { return false; }
392
393private:
394 void toggle(bool& value) {
395 value = !value;
396 }
397
398 void toggle3(int& value) {
399 value = (value + 1) % 3;
400 }
401
402 void makePath(SkPath* path) {
403 path->moveTo(fPts[0]);
404 if (fAsCurves) {
405 for (int i = 1; i < N-2; ++i) {
406 path->quadTo(fPts[i], (fPts[i+1] + fPts[i]) * 0.5f);
407 }
408 path->quadTo(fPts[N-2], fPts[N-1]);
409 } else {
410 for (int i = 1; i < N; ++i) {
411 path->lineTo(fPts[i]);
412 }
413 }
414 if (fClosed) {
415 path->close();
416 }
417 }
418};
419DEF_SLIDE( return new FatStrokeSlide; )
420
421static int compute_parallel_to_base(const SkPoint pts[4], SkScalar t[2]) {
422 // F = At^3 + Bt^2 + Ct + D
423 SkVector A = pts[3] - pts[0] + (pts[1] - pts[2]) * 3.0f;
424 SkVector B = (pts[0] - pts[1] - pts[1] + pts[2]) * 3.0f;
425 SkVector C = (pts[1] - pts[0]) * 3.0f;
426 SkVector DA = pts[3] - pts[0];
427
428 // F' = 3At^2 + 2Bt + C
429 SkScalar a = 3 * A.cross(DA);
430 SkScalar b = 2 * B.cross(DA);
431 SkScalar c = C.cross(DA);
432
433 int n = SkFindUnitQuadRoots(a, b, c, t);
434 SkString str;
435 for (int i = 0; i < n; ++i) {
436 str.appendf(" %g", t[i]);
437 }
438 SkDebugf("roots %s\n", str.c_str());
439 return n;
440}
441
443 enum {
444 N = 4
445 };
446 SkPoint fPts[N];
447
448public:
450 SkRandom rand;
451 for (int i = 0; i < N; ++i) {
452 fPts[i].fX = 20 + rand.nextUScalar1() * 640;
453 fPts[i].fY = 20 + rand.nextUScalar1() * 480;
454 }
455 fName = "CubicCurve";
456 }
457
458 void draw(SkCanvas* canvas) override {
460 paint.setAntiAlias(true);
461
462 {
463 SkPath path;
464 path.moveTo(fPts[0]);
465 path.cubicTo(fPts[1], fPts[2], fPts[3]);
467 canvas->drawPath(path, paint);
468 }
469
470 {
471 paint.setColor(SK_ColorRED);
472 SkScalar t[2];
473 int n = compute_parallel_to_base(fPts, t);
474 SkPoint loc;
475 SkVector tan;
476 for (int i = 0; i < n; ++i) {
477 SkEvalCubicAt(fPts, t[i], &loc, &tan, nullptr);
478 tan.setLength(30);
479 canvas->drawLine(loc - tan, loc + tan, paint);
480 }
481 paint.setStrokeWidth(0.5f);
482 canvas->drawLine(fPts[0], fPts[3], paint);
483
484 paint.setColor(SK_ColorBLUE);
485 paint.setStrokeWidth(6);
486 SkEvalCubicAt(fPts, 0.5f, &loc, nullptr, nullptr);
487 canvas->drawPoint(loc, paint);
488
489 paint.setColor(0xFF008800);
490 SkEvalCubicAt(fPts, 1.0f/3, &loc, nullptr, nullptr);
491 canvas->drawPoint(loc, paint);
492 SkEvalCubicAt(fPts, 2.0f/3, &loc, nullptr, nullptr);
493 canvas->drawPoint(loc, paint);
494
495 // n = SkFindCubicInflections(fPts, t);
496 // printf("inflections %d %g %g\n", n, t[0], t[1]);
497 }
498
499 {
500 paint.setStyle(SkPaint::kFill_Style);
501 paint.setColor(SK_ColorRED);
502 for (SkPoint p : fPts) {
503 canvas->drawCircle(p.fX, p.fY, 8, paint);
504 }
505 }
506 }
507
508protected:
510 const SkScalar tol = 8;
511 const SkRect r = SkRect::MakeXYWH(x - tol, y - tol, tol * 2, tol * 2);
512 for (int i = 0; i < N; ++i) {
513 if (r.intersects(SkRect::MakeXYWH(fPts[i].fX, fPts[i].fY, 1, 1))) {
514 return new Click([this, i](Click* c) {
515 fPts[i] = c->fCurr;
516 return true;
517 });
518 }
519 }
520 return nullptr;
521 }
522
523 bool onClick(ClickHandlerSlide::Click *) override { return false; }
524};
525DEF_SLIDE( return new CubicCurveSlide; )
526
527static SkPoint lerp(SkPoint a, SkPoint b, float t) {
528 return a * (1 - t) + b * t;
529}
530
531static int find_max_deviation_cubic(const SkPoint src[4], SkScalar ts[2]) {
532 // deviation = F' x (d - a) == 0, solve for t(s)
533 // F = At^3 + Bt^2 + Ct + D
534 // F' = 3At^2 + 2Bt + C
535 // Z = d - a
536 // F' x Z = 3(A x Z)t^2 + 2(B x Z)t + (C x Z)
537 //
538 SkVector A = src[3] + (src[1] - src[2]) * 3 - src[0];
539 SkVector B = (src[2] - src[1] - src[1] + src[0]) * 3;
540 SkVector C = (src[1] - src[0]) * 3;
541 SkVector Z = src[3] - src[0];
542 // now forumlate the quadratic coefficients we need to solve for t : F' x Z
543 return SkFindUnitQuadRoots(3 * A.cross(Z), 2 * B.cross(Z), C.cross(Z), ts);
544}
545
547 enum {
548 N = 7
549 };
550 SkPoint fPts[N];
551 SkPoint* fQuad = fPts + 4;
552 SkScalar fT = 0.5f;
553 bool fShowSub = false;
554 bool fShowFlatness = false;
555 bool fShowInnerQuads = false;
556 SkScalar fScale = 0.75;
557
558public:
560 fPts[0] = { 90, 300 };
561 fPts[1] = { 30, 60 };
562 fPts[2] = { 250, 30 };
563 fPts[3] = { 350, 200 };
564
565 fQuad[0] = fPts[0] + SkVector{ 300, 0};
566 fQuad[1] = fPts[1] + SkVector{ 300, 0};
567 fQuad[2] = fPts[2] + SkVector{ 300, 0};
568
569 fName = "CubicCurve2";
570 }
571
572 bool onChar(SkUnichar uni) override {
573 switch (uni) {
574 case 's': fShowSub = !fShowSub; break;
575 case 'f': fShowFlatness = !fShowFlatness; break;
576 case '-': fT -= 1.0f / 32; break;
577 case '=': fT += 1.0f / 32; break;
578 case 'q': fShowInnerQuads = !fShowInnerQuads; break;
579 default: return false;
580 }
581 fT = std::min(1.0f, std::max(0.0f, fT));
582 return true;
583 }
584
585 static void Dot(SkCanvas* canvas, SkPoint p, SkScalar radius, SkColor c) {
587 paint.setAntiAlias(true);
588 paint.setColor(c);
589 canvas->drawCircle(p.fX, p.fY, radius, paint);
590 }
591
592 void draw(SkCanvas* canvas) override {
594 paint.setAntiAlias(true);
595
596 {
598 SkPath path;
599 path.moveTo(fPts[0]);
600 path.cubicTo(fPts[1], fPts[2], fPts[3]);
601 path.moveTo(fQuad[0]);
602 path.quadTo(fQuad[1], fQuad[2]);
603 canvas->drawPath(path, paint);
604 }
605
606 if (fShowSub) {
607 paint.setColor(SK_ColorRED);
608 paint.setStrokeWidth(1.7f);
609 this->showFrame(canvas, fPts, 3, paint);
610 this->showFrame(canvas, fQuad, 2, paint);
611
612 paint.setColor(SK_ColorBLACK);
613 paint.setStyle(SkPaint::kFill_Style);
615 canvas->drawString(SkStringPrintf("t = %g", fT), 20, 20, font, paint);
616 }
617
618 if (fShowFlatness) {
619 this->showFlattness(canvas);
620 }
621
622 if (fShowInnerQuads) {
623 this->showInnerQuads(canvas);
624 }
625
626 paint.setColor(SK_ColorGRAY);
627 paint.setStroke(true);
628 canvas->drawPath(SkPathBuilder().addPolygon(fPts, 4, false).detach(), paint);
629 canvas->drawPath(SkPathBuilder().addPolygon(fQuad, 3, false).detach(), paint);
630
631 for (SkPoint p : fPts) {
632 Dot(canvas, p, 7, SK_ColorBLACK);
633 }
634
635 if ((false)) {
636 SkScalar ts[2];
637 int n = SkFindCubicInflections(fPts, ts);
638 for (int i = 0; i < n; ++i) {
639 SkPoint p;
640 SkEvalCubicAt(fPts, ts[i], &p, nullptr, nullptr);
641 canvas->drawCircle(p.fX, p.fY, 3, paint);
642 }
643 }
644
645 }
646
647protected:
649 const SkScalar tol = 8;
650 const SkRect r = SkRect::MakeXYWH(x - tol, y - tol, tol * 2, tol * 2);
651 for (int i = 0; i < N; ++i) {
652 if (r.intersects(SkRect::MakeXYWH(fPts[i].fX, fPts[i].fY, 1, 1))) {
653 return new Click([this, i](Click* c) {
654 fPts[i] = c->fCurr;
655 return true;
656 });
657 }
658 }
659 return nullptr;
660 }
661
662 bool onClick(ClickHandlerSlide::Click *) override { return false; }
663
664private:
665 void showFrame(SkCanvas* canvas, const SkPoint pts[], int count, const SkPaint& p) {
666 SkPaint paint(p);
667 SkPoint storage[3 + 2 + 1];
668 SkPoint* tmp = storage;
669 const SkPoint* prev = pts;
670 for (int n = count; n > 0; --n) {
671 for (int i = 0; i < n; ++i) {
672 canvas->drawLine(prev[i], prev[i+1], paint);
673 tmp[i] = lerp(prev[i], prev[i+1], fT);
674 }
675 prev = tmp;
676 tmp += n;
677 }
678
679 paint.setColor(SK_ColorBLUE);
680 paint.setStyle(SkPaint::kFill_Style);
681 int n = tmp - storage;
682 for (int i = 0; i < n; ++i) {
683 Dot(canvas, storage[i], 4, SK_ColorBLUE);
684 }
685 }
686
687 void showFlattness(SkCanvas* canvas) {
690 paint.setAntiAlias(true);
691
692 SkPaint paint2(paint);
693 paint2.setColor(0xFF008800);
694
695 paint.setColor(0xFF888888);
696 canvas->drawLine(fPts[0], fPts[3], paint);
697 canvas->drawLine(fQuad[0], fQuad[2], paint);
698
699 paint.setColor(0xFF0000FF);
700 SkPoint pts[2];
701 pts[0] = (fQuad[0] + fQuad[1] + fQuad[1] + fQuad[2])*0.25;
702 pts[1] = (fQuad[0] + fQuad[2]) * 0.5;
703 canvas->drawLine(pts[0], pts[1], paint);
704
705 // cubic
706
707 SkVector v0 = (fPts[0] - fPts[1] - fPts[1] + fPts[2]) * fScale;
708 SkVector v1 = (fPts[1] - fPts[2] - fPts[2] + fPts[3]) * fScale;
709 SkVector v = (v0 + v1) * 0.5f;
710
711 SkPoint anchor;
712 SkScalar ts[2];
713 int n = find_max_deviation_cubic(fPts, ts);
714 if (n > 0) {
715 SkEvalCubicAt(fPts, ts[0], &anchor, nullptr, nullptr);
716 canvas->drawLine(anchor, anchor + v, paint2);
717 canvas->drawLine(anchor, anchor + v0, paint);
718 if (n == 2) {
719 SkEvalCubicAt(fPts, ts[1], &anchor, nullptr, nullptr);
720 canvas->drawLine(anchor, anchor + v, paint2);
721 }
722 canvas->drawLine(anchor, anchor + v1, paint);
723 }
724 // not sure we can get here
725 }
726
727 void showInnerQuads(SkCanvas* canvas) {
728 auto draw_quad = [canvas](SkPoint a, SkPoint b, SkPoint c, SkColor color) {
730 paint.setAntiAlias(true);
731 paint.setStroke(true);
732 paint.setColor(color);
733
734 canvas->drawPath(SkPathBuilder().moveTo(a).quadTo(b, c).detach(), paint);
735 };
736
737 SkPoint p0 = SkEvalQuadAt(&fPts[0], fT),
738 p1 = SkEvalQuadAt(&fPts[1], fT),
739 p2 = lerp(p0, p1, fT);
740
741 draw_quad(fPts[0], fPts[1], fPts[2], SK_ColorRED);
742 Dot(canvas, p0, 4, SK_ColorRED);
743
744 draw_quad(fPts[1], fPts[2], fPts[3], SK_ColorBLUE);
745 Dot(canvas, p1, 4, SK_ColorBLUE);
746
748 paint.setAntiAlias(true);
749 paint.setColor(0xFF008800);
750 canvas->drawLine(p0, p1, paint);
751 Dot(canvas, p2, 4, 0xFF00AA00);
752 }
753};
754DEF_SLIDE( return new CubicCurve2Slide; )
755
SkPoint fPts[2]
SkPath fPath
static const char * draw_quad(const BezierRec *rec, int count)
const char * fName
int count
SkColor4f color
static float prev(float f)
static SkPoint lerp(SkPoint a, SkPoint b, float t)
static void test_cubic2()
Definition PathSlide.cpp:52
static int find_max_deviation_cubic(const SkPoint src[4], SkScalar ts[2])
static int compute_parallel_to_base(const SkPoint pts[4], SkScalar t[2])
static void test_cubic()
Definition PathSlide.cpp:32
uint32_t SkColor
Definition SkColor.h:37
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
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
void SkChopCubicAt(const SkPoint src[4], SkPoint dst[7], SkScalar t)
void SkEvalCubicAt(const SkPoint src[4], SkScalar t, SkPoint *loc, SkVector *tangent, SkVector *curvature)
int SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2])
void SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint *pt, SkVector *tangent)
int SkFindCubicInflections(const SkPoint src[4], SkScalar tValues[2])
#define SkScalarToDouble(x)
Definition SkScalar.h:63
#define SK_ScalarHalf
Definition SkScalar.h:19
SK_API SkString static SkString SkStringPrintf()
Definition SkString.h:287
int32_t SkUnichar
Definition SkTypes.h:175
#define DEF_SLIDE(code)
Definition Slide.h:25
#define N
Definition beziers.cpp:19
#define Z
Click * onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override
bool onClick(ClickHandlerSlide::Click *) override
bool onChar(SkUnichar uni) override
void draw(SkCanvas *canvas) override
bool onClick(ClickHandlerSlide::Click *) override
void draw(SkCanvas *canvas) override
Click * onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override
static void Dot(SkCanvas *canvas, SkPoint p, SkScalar radius, SkColor c)
bool onChar(SkUnichar uni) override
void draw(SkCanvas *canvas) override
Click * onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override
bool onClick(ClickHandlerSlide::Click *) override
void draw(SkCanvas *canvas) override
bool onClick(ClickHandlerSlide::Click *) override
Click * onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override
bool onChar(SkUnichar uni) override
Click * onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override
void load(SkScalar w, SkScalar h) override
Definition PathSlide.cpp:88
bool onClick(ClickHandlerSlide::Click *) override
void drawPath(SkCanvas *canvas, const SkPath &path, SkPaint::Join j)
void draw(SkCanvas *canvas) override
bool animate(double nanos) override
void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint &paint)
void restore()
Definition SkCanvas.cpp:465
void drawPoint(SkScalar x, SkScalar y, const SkPaint &paint)
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
int save()
Definition SkCanvas.cpp:451
void drawPath(const SkPath &path, const SkPaint &paint)
void drawString(const char str[], SkScalar x, SkScalar y, const SkFont &font, const SkPaint &paint)
Definition SkCanvas.h:1803
@ kPoints_PointMode
draw each point separately
Definition SkCanvas.h:1241
void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint &paint)
static sk_sp< SkPathEffect > Make(SkScalar radius)
@ kRound_Cap
adds circle
Definition SkPaint.h:335
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
@ kFill_Style
set to fill geometry
Definition SkPaint.h:193
void setStrokeJoin(Join join)
Definition SkPaint.cpp:189
void setPathEffect(sk_sp< SkPathEffect > pathEffect)
@ kRound_Join
adds circle
Definition SkPaint.h:360
@ kMiter_Join
extends to miter limit
Definition SkPaint.h:359
@ kBevel_Join
connects outside edges
Definition SkPaint.h:361
void setStrokeWidth(SkScalar width)
Definition SkPaint.cpp:159
static bool FromSVGString(const char str[], SkPath *)
SkPathBuilder & moveTo(SkPoint pt)
SkPathBuilder & quadTo(SkPoint pt1, SkPoint pt2)
SkPath & moveTo(SkScalar x, SkScalar y)
Definition SkPath.cpp:678
SkPath & lineTo(SkScalar x, SkScalar y)
Definition SkPath.cpp:718
SkScalar nextUScalar1()
Definition SkRandom.h:101
const char * c_str() const
Definition SkString.h:133
void void void appendf(const char format[],...) SK_PRINTF_LIKE(2
Definition SkString.cpp:550
SkString fName
Definition Slide.h:54
const Paint & paint
float SkScalar
Definition extension.cpp:12
static bool b
struct MyStruct a[10]
uint8_t value
T __attribute__((ext_vector_type(N))) V
double y
double x
static float Scaled(float time, float speed, float period=0)
Definition TimeUtils.h:27
sk_sp< SkTypeface > DefaultTypeface()
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
SK_API bool FillPathWithPaint(const SkPath &src, const SkPaint &paint, SkPath *dst, const SkRect *cullRect, SkScalar resScale=1)
ModifierKey
Definition ModifierKey.h:9
SkScalar w
SkScalar h
int32_t fBottom
larger y-axis bounds
Definition SkRect.h:36
int32_t fTop
smaller y-axis bounds
Definition SkRect.h:34
int32_t fLeft
smaller x-axis bounds
Definition SkRect.h:33
int32_t fRight
larger x-axis bounds
Definition SkRect.h:35
bool setLength(float length)
Definition SkPoint.cpp:30
float fX
x-axis value
float fY
y-axis value
SkScalar fBottom
larger y-axis bounds
Definition extension.cpp:17
SkScalar fLeft
smaller x-axis bounds
Definition extension.cpp:14
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition SkRect.h:659
bool intersects(const SkRect &r) const
Definition SkRect.h:1121
SkScalar fRight
larger x-axis bounds
Definition extension.cpp:16
void round(SkIRect *dst) const
Definition SkRect.h:1228
SkScalar fTop
smaller y-axis bounds
Definition extension.cpp:15