58#include <initializer_list>
64 radii[index].
set(rad, rad);
82 path.quadTo(20, 50, 80, 50);
83 path.quadTo(20, 50, 20, 80);
92 const float rad = 33436320;
98 for (
int i = 0; i < 4; ++i) {
107 path->moveTo(3.747501373f, 2.724499941f);
108 path->lineTo(3.747501373f, 3.75f);
109 path->cubicTo(3.747501373f, 3.88774991f, 3.635501385f, 4.0f, 3.497501373f, 4.0f);
110 path->lineTo(0.7475013733f, 4.0f);
111 path->cubicTo(0.6095013618f, 4.0f, 0.4975013733f, 3.88774991f, 0.4975013733f, 3.75f);
112 path->lineTo(0.4975013733f, 1.0f);
113 path->cubicTo(0.4975013733f, 0.8622499704f, 0.6095013618f, 0.75f, 0.7475013733f,0.75f);
114 path->lineTo(3.497501373f, 0.75f);
115 path->cubicTo(3.50275135f, 0.75f, 3.5070014f, 0.7527500391f, 3.513001442f, 0.753000021f);
116 path->lineTo(3.715001345f, 0.5512499809f);
117 path->cubicTo(3.648251295f, 0.5194999576f, 3.575501442f, 0.4999999702f, 3.497501373f, 0.4999999702f);
118 path->lineTo(0.7475013733f, 0.4999999702f);
119 path->cubicTo(0.4715013802f, 0.4999999702f, 0.2475013733f, 0.7239999771f, 0.2475013733f, 1.0f);
120 path->lineTo(0.2475013733f, 3.75f);
121 path->cubicTo(0.2475013733f, 4.026000023f, 0.4715013504f, 4.25f, 0.7475013733f, 4.25f);
122 path->lineTo(3.497501373f, 4.25f);
123 path->cubicTo(3.773501396f, 4.25f, 3.997501373f, 4.026000023f, 3.997501373f, 3.75f);
124 path->lineTo(3.997501373f, 2.474750042f);
125 path->lineTo(3.747501373f, 2.724499941f);
130 path->moveTo(3.747501373f, 2.724499941f);
131 path->cubicTo(3.648251295f, 0.5194999576f, 3.575501442f, 0.4999999702f, 3.497501373f, 0.4999999702f);
140 path.moveTo(-540000, -720000);
141 path.lineTo(-9.10000017e-05f, 9.99999996e-13f);
157 path.moveTo(-478.805145f, 153.862549f);
158 path.lineTo(6.27216804e+19f, 6.27216804e+19f);
159 path.lineTo(-666.754272f, 155.086304f);
184 paint.setAntiAlias(
true);
226 paint.setAntiAlias(
true);
287 path->cubicTo(p1, p2, p3);
312 path->moveTo(146.939f, 1012.84f);
313 path->lineTo(181.747f, 1009.18f);
314 path->lineTo(182.165f, 1013.16f);
315 path->lineTo(147.357f, 1016.82f);
316 path->lineTo(146.939f, 1012.84f);
340 clip.setRect({0, 0, 1255, 1925});
342 for (
size_t i = 0; i < std::size(procs); ++i) {
348 path.toggleInverseFillType();
349 rgn.setPath(path,
clip);
353#ifdef SK_BUILD_FOR_WIN
354 #define SUPPRESS_VISIBILITY_WARNING
356 #define SUPPRESS_VISIBILITY_WARNING __attribute__((visibility("hidden")))
366 path.rLineTo(0, 100);
367 path.rLineTo(100, 0);
369 path.rLineTo(50, 50);
371 path.getLastPt(&last);
377 path.rLineTo(0, 100);
378 path.rLineTo(100, 0);
380 path.rQuadTo(50, 50, 75, 75);
382 path.getLastPt(&last);
388 path.rLineTo(0, 100);
389 path.rLineTo(100, 0);
391 path.rConicTo(50, 50, 85, 85, 2);
393 path.getLastPt(&last);
399 path.rLineTo(0, 100);
400 path.rLineTo(100, 0);
402 path.rCubicTo(50, 50, 85, 85, 95, 95);
404 path.getLastPt(&last);
414 const uint32_t z =
a.getGenerationID();
421 const uint32_t
y =
a.getGenerationID();
425 const uint32_t
x =
b.getGenerationID();
443#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
444 static bool kExpectGenIDToIgnoreFill =
false;
446 static bool kExpectGenIDToIgnoreFill =
true;
460 path.moveTo(13.8509f, 3.16858f);
461 path.cubicTo(-2.35893e+08f, -4.21044e+08f,
462 -2.38991e+08f, -4.26573e+08f,
463 -2.41016e+08f, -4.30188e+08f);
469 { 4595.91064f, -11596.9873f },
470 { 4597.2168f, -11595.9414f },
471 { 4598.52344f, -11594.8955f },
472 { 4599.83008f, -11593.8496f },
477 path.cubicTo(pts[1], pts[2], pts[3]);
481 paint.setStrokeWidth(20);
490 path.moveTo(17.9459f, 21.6344f);
491 path.lineTo(139.545f, -47.8105f);
492 path.lineTo(139.545f, -47.8105f);
493 path.lineTo(131.07f, -47.3888f);
494 path.lineTo(131.07f, -47.3888f);
495 path.lineTo(122.586f, -46.9532f);
496 path.lineTo(122.586f, -46.9532f);
497 path.lineTo(18076.6f, 31390.9f);
498 path.lineTo(18076.6f, 31390.9f);
499 path.lineTo(18085.1f, 31390.5f);
500 path.lineTo(18085.1f, 31390.5f);
501 path.lineTo(18076.6f, 31390.9f);
502 path.lineTo(18076.6f, 31390.9f);
503 path.lineTo(17955, 31460.3f);
504 path.lineTo(17955, 31460.3f);
505 path.lineTo(17963.5f, 31459.9f);
506 path.lineTo(17963.5f, 31459.9f);
507 path.lineTo(17971.9f, 31459.5f);
508 path.lineTo(17971.9f, 31459.5f);
509 path.lineTo(17.9551f, 21.6205f);
510 path.lineTo(17.9551f, 21.6205f);
511 path.lineTo(9.47091f, 22.0561f);
512 path.lineTo(9.47091f, 22.0561f);
513 path.lineTo(17.9459f, 21.6344f);
514 path.lineTo(17.9459f, 21.6344f);
515 path.close();path.moveTo(0.995934f, 22.4779f);
516 path.lineTo(0.986725f, 22.4918f);
517 path.lineTo(0.986725f, 22.4918f);
518 path.lineTo(17955, 31460.4f);
519 path.lineTo(17955, 31460.4f);
520 path.lineTo(17971.9f, 31459.5f);
521 path.lineTo(17971.9f, 31459.5f);
522 path.lineTo(18093.6f, 31390.1f);
523 path.lineTo(18093.6f, 31390.1f);
524 path.lineTo(18093.6f, 31390);
525 path.lineTo(18093.6f, 31390);
526 path.lineTo(139.555f, -47.8244f);
527 path.lineTo(139.555f, -47.8244f);
528 path.lineTo(122.595f, -46.9671f);
529 path.lineTo(122.595f, -46.9671f);
530 path.lineTo(0.995934f, 22.4779f);
531 path.lineTo(0.995934f, 22.4779f);
533 path.moveTo(5.43941f, 25.5223f);
534 path.lineTo(798267, -28871.1f);
535 path.lineTo(798267, -28871.1f);
536 path.lineTo(3.12512e+06f, -113102);
537 path.lineTo(3.12512e+06f, -113102);
538 path.cubicTo(5.16324e+06f, -186882, 8.15247e+06f, -295092, 1.1957e+07f, -432813);
539 path.cubicTo(1.95659e+07f, -708257, 3.04359e+07f, -1.10175e+06f, 4.34798e+07f, -1.57394e+06f);
540 path.cubicTo(6.95677e+07f, -2.51831e+06f, 1.04352e+08f, -3.77748e+06f, 1.39135e+08f, -5.03666e+06f);
541 path.cubicTo(1.73919e+08f, -6.29583e+06f, 2.08703e+08f, -7.555e+06f, 2.34791e+08f, -8.49938e+06f);
542 path.cubicTo(2.47835e+08f, -8.97157e+06f, 2.58705e+08f, -9.36506e+06f, 2.66314e+08f, -9.6405e+06f);
543 path.cubicTo(2.70118e+08f, -9.77823e+06f, 2.73108e+08f, -9.88644e+06f, 2.75146e+08f, -9.96022e+06f);
544 path.cubicTo(2.76165e+08f, -9.99711e+06f, 2.76946e+08f, -1.00254e+07f, 2.77473e+08f, -1.00444e+07f);
545 path.lineTo(2.78271e+08f, -1.00733e+07f);
546 path.lineTo(2.78271e+08f, -1.00733e+07f);
547 path.cubicTo(2.78271e+08f, -1.00733e+07f, 2.08703e+08f, -7.555e+06f, 135.238f, 23.3517f);
548 path.cubicTo(131.191f, 23.4981f, 125.995f, 23.7976f, 123.631f, 24.0206f);
549 path.cubicTo(121.267f, 24.2436f, 122.631f, 24.3056f, 126.677f, 24.1591f);
550 path.cubicTo(2.08703e+08f, -7.555e+06f, 2.78271e+08f, -1.00733e+07f, 2.78271e+08f, -1.00733e+07f);
551 path.lineTo(2.77473e+08f, -1.00444e+07f);
552 path.lineTo(2.77473e+08f, -1.00444e+07f);
553 path.cubicTo(2.76946e+08f, -1.00254e+07f, 2.76165e+08f, -9.99711e+06f, 2.75146e+08f, -9.96022e+06f);
554 path.cubicTo(2.73108e+08f, -9.88644e+06f, 2.70118e+08f, -9.77823e+06f, 2.66314e+08f, -9.6405e+06f);
555 path.cubicTo(2.58705e+08f, -9.36506e+06f, 2.47835e+08f, -8.97157e+06f, 2.34791e+08f, -8.49938e+06f);
556 path.cubicTo(2.08703e+08f, -7.555e+06f, 1.73919e+08f, -6.29583e+06f, 1.39135e+08f, -5.03666e+06f);
557 path.cubicTo(1.04352e+08f, -3.77749e+06f, 6.95677e+07f, -2.51831e+06f, 4.34798e+07f, -1.57394e+06f);
558 path.cubicTo(3.04359e+07f, -1.10175e+06f, 1.95659e+07f, -708258, 1.1957e+07f, -432814);
559 path.cubicTo(8.15248e+06f, -295092, 5.16324e+06f, -186883, 3.12513e+06f, -113103);
560 path.lineTo(798284, -28872);
561 path.lineTo(798284, -28872);
562 path.lineTo(22.4044f, 24.6677f);
563 path.lineTo(22.4044f, 24.6677f);
564 path.cubicTo(22.5186f, 24.5432f, 18.8134f, 24.6337f, 14.1287f, 24.8697f);
565 path.cubicTo(9.4439f, 25.1057f, 5.55359f, 25.3978f, 5.43941f, 25.5223f);
570 path.moveTo(126.677f, 24.1591f);
571 path.cubicTo(2.08703e+08f, -7.555e+06f, 2.78271e+08f, -1.00733e+07f, 2.78271e+08f, -1.00733e+07f);
591 bool smallConvex = smallPath.
isConvex();
596 matrix.preTranslate(100, 100);
599 bool largeConvex = largePath.
isConvex();
604 const char reducedCase[] =
612 const char originalFiddleData[] =
613 "M-0.3383152268862998,-0.11217565719203619L-0.33846085183212765,-0.11212264406895281"
614 "L-0.338509393480737,-0.11210607966681395L-0.33857792286700894,-0.1121889121487573"
615 "L-0.3383866116636664,-0.11228834570924921L-0.33842087635680235,-0.11246078673250548"
616 "L-0.33809536177201055,-0.11245415228342878L-0.33797257995493996,-0.11216571641452182"
617 "L-0.33802112160354925,-0.11201996164188659L-0.33819815585141844,-0.11218559834671019Z";
623 const char originalFiddleData[] =
624 "M-0.34004273849857214,-0.11332803232216355L-0.34008271397389744,-0.11324483772714951"
625 "L-0.3401940742265893,-0.11324483772714951L-0.34017694188002134,-0.11329807920275889"
626 "L-0.3402026403998733,-0.11333468903941245L-0.34029972369709194,-0.11334134592705701"
627 "L-0.3403054344792813,-0.11344121970007795L-0.3403140006525653,-0.11351115418399343"
628 "L-0.34024261587519866,-0.11353446986281181L-0.3402197727464413,-0.11360442946144192"
629 "L-0.34013696640469604,-0.11359110237029302L-0.34009128014718143,-0.1135877707043939"
630 "L-0.3400598708451401,-0.11360776134112742L-0.34004273849857214,-0.11355112520064405"
631 "L-0.3400113291965308,-0.11355112520064405L-0.3399970522410575,-0.11359110237029302"
632 "L-0.33997135372120546,-0.11355112520064405L-0.3399627875479215,-0.11353780084493197"
633 "L-0.3399485105924481,-0.11350782354357004L-0.3400027630232468,-0.11346452910331437"
634 "L-0.3399485105924481,-0.11340126558629839L-0.33993994441916414,-0.11340126558629839"
635 "L-0.33988283659727087,-0.11331804756574679L-0.33989140277055485,-0.11324483772714951"
636 "L-0.33997991989448945,-0.11324483772714951L-0.3399856306766788,-0.11324483772714951"
637 "L-0.34002560615200417,-0.11334467443478255ZM-0.3400684370184241,-0.11338461985124307"
638 "L-0.340154098751264,-0.11341791238732665L-0.340162664924548,-0.1134378899559977"
639 "L-0.34017979727111597,-0.11340126558629839L-0.3401655203156427,-0.11338129083212668"
640 "L-0.34012268944922275,-0.11332137577529414L-0.34007414780061346,-0.11334467443478255Z"
641 "M-0.3400027630232468,-0.11290567901106024L-0.3400113291965308,-0.11298876531245433"
642 "L-0.33997991989448945,-0.11301535852306784L-0.33990282433493346,-0.11296217481488612"
643 "L-0.33993994441916414,-0.11288906492739594Z";
650 path.conicTo(-6.62478e-08f, 4.13885e-08f, -6.36935e-08f, 3.97927e-08f, 0.729058f);
651 path.quadTo(2.28206e-09f, -1.42572e-09f, 3.91919e-09f, -2.44852e-09f);
652 path.cubicTo(-16752.2f, -26792.9f, -21.4673f, 10.9347f, -8.57322f, -7.22739f);
656 path.contains(-1.84817e-08f, 1.15465e-08f);
666 path.lineTo(FLT_EPSILON, FLT_EPSILON);
671 path.quadTo(0, 0, 0, 0);
676 path.conicTo(0, 0, 0, 0, 0.5f);
681 path.cubicTo(0, 0, 0, 0, 0, 0);
709 path->moveTo(577330, 1971.72f);
710 path->cubicTo(10.7082f, -116.596f, 262.057f, 45.6468f, 294.694f, 1.96237f);
712 path->moveTo(60.1631f, 7.70567f);
713 path->quadTo(60.1631f, 7.70567f, 0.99474f, 0.901199f);
714 path->lineTo(577379, 1977.77f);
715 path->quadTo(577364, 1979.57f, 577325, 1980.26f);
716 path->quadTo(577286, 1980.95f, 577245, 1980.13f);
717 path->quadTo(577205, 1979.3f, 577187, 1977.45f);
718 path->quadTo(577168, 1975.6f, 577183, 1973.8f);
719 path->quadTo(577198, 1972, 577238, 1971.31f);
720 path->quadTo(577277, 1970.62f, 577317, 1971.45f);
721 path->quadTo(577330, 1971.72f, 577341, 1972.11f);
722 path->cubicTo(10.7082f, -116.596f, 262.057f, 45.6468f, 294.694f, 1.96237f);
723 path->moveTo(306.718f, -32.912f);
724 path->cubicTo(30.531f, 10.0005f, 1502.47f, 13.2804f, 84.3088f, 9.99601f);
735 for (
int doReducedCase = 0; doReducedCase <= 1; ++doReducedCase) {
739 for (
int doAA = 0; doAA <= 1; ++doAA) {
747 if (expected != bounds) {
748 ERRORF(
reporter,
"path.getBounds() returned [%g %g %g %g], but expected [%g %g %g %g]",
749 bounds.left(), bounds.top(), bounds.right(), bounds.bottom(),
786 path.conicTo(3.58732e-43f, 2.72084f, 3.00392f, 3.00392f, 8.46e+37f);
804 path.cubicTo(pts[1], pts[2], pts[3]);
812 path.quadTo(157, 366, 286, 208);
813 path.arcTo(37, 442, 315, 163, 957494590897113.0f);
816 matrix.setScale(1000*1000, 1000*1000);
822 while (path.isFinite()) {
825 path.transform(matrix);
830 path.transform(matrix);
841 SkScalar rx = std::min(rect.width(), xIn);
842 SkScalar ry = std::min(rect.height(), yIn);
845 arcRect.
setLTRB(-rx, -ry, rx, ry);
846 switch (startAngle) {
884 for (
int i = 0; i < 5000; ++i) {
911 for (
int i = 0; i < 5000; ++i) {
982 path.moveTo(inf, negInf);
1002 path.lineTo(100, 100);
1004 path.moveTo(200, 200);
1020 const SkPoint srcPts[],
bool expectClose) {
1021 bool firstTime =
true;
1022 bool foundClose =
false;
1060 for (
size_t i = 0; i < std::size(pts); ++i) {
1065 for (
int doClose = 0; doClose <= 1; ++doClose) {
1119 static const char* gDegen[] = {
1123 "M 10 10 L 10 10 L 10 10",
1124 "M 10 10 Q 10 10 10 10",
1125 "M 10 10 C 10 10 10 10 10 10",
1127 for (i = 0; i < std::size(gDegen); ++i) {
1135 static const char* gCW[] = {
1136 "M 10 10 L 10 10 Q 20 10 20 20",
1137 "M 10 10 C 20 10 20 20 20 20",
1138 "M 20 10 Q 20 20 30 20 L 10 20",
1141 "M 10 10 C 10 0 10 0 20 0 L 40 0 C 50 0 50 0 50 10",
1142 "M 20 10 L 0 10 Q 10 10 20 0",
1144 for (i = 0; i < std::size(gCW); ++i) {
1151 static const char* gCCW[] = {
1152 "M 10 10 L 10 10 Q 20 10 20 -20",
1153 "M 10 10 C 20 10 20 -20 20 -20",
1154 "M 20 10 Q 20 20 10 20 L 30 20",
1157 "M 50 10 C 50 0 50 0 40 0 L 20 0 C 10 0 10 0 10 10",
1158 "M 10 10 L 30 10 Q 20 10 10 0",
1160 for (i = 0; i < std::size(gCCW); ++i) {
1188 path.conicTo(20, 0, 20, 20, 0.5f);
1193 path.lineTo(1, 1e7f);
1194 path.lineTo(1e7f, 2e7f);
1209 static const SkRect rects[] = {
1217 for (
size_t i = 0; i < std::size(rects); ++i) {
1227 path.moveTo(pts[0]);
1228 path.cubicTo(pts[1], pts[2], pts[3]);
1253 { 372.0007f, 92.000755f },
1254 { 371.99927f, 92.003922f },
1255 { 371.99826f, 92.003899f },
1262 for (
int i = 0; i < 2; ++i) {
1358 bool expectedConvexity) {
1361 bool convexity =
copy.isConvex();
1366 SkPath tinyConvexPolygon;
1367 tinyConvexPolygon.
moveTo(600.131559f, 800.112512f);
1368 tinyConvexPolygon.
lineTo(600.161735f, 800.118627f);
1369 tinyConvexPolygon.
lineTo(600.148962f, 800.142338f);
1370 tinyConvexPolygon.
lineTo(600.134891f, 800.137724f);
1371 tinyConvexPolygon.
close();
1376 platTriangle.
moveTo(0, 0);
1377 platTriangle.
lineTo(200, 0);
1378 platTriangle.
lineTo(100, 0.04f);
1379 platTriangle.
close();
1383 platTriangle.
reset();
1384 platTriangle.
moveTo(0, 0);
1385 platTriangle.
lineTo(200, 0);
1386 platTriangle.
lineTo(100, 0.03f);
1387 platTriangle.
close();
1432 redundantSquare.
moveTo(0, 0);
1433 redundantSquare.
lineTo(0, 0);
1434 redundantSquare.
lineTo(0, 0);
1444 redundantSquare.
close();
1489 for (
int i = 0; i < 2000; i++) {
1505 SkPath degenerateConcave;
1506 degenerateConcave.
moveTo(148.67912f, 191.875f);
1507 degenerateConcave.
lineTo(470.37695f, 7.5f);
1508 degenerateConcave.
lineTo(148.67912f, 191.875f);
1509 degenerateConcave.
lineTo(41.446522f, 376.25f);
1510 degenerateConcave.
lineTo(-55.971577f, 460.0f);
1511 degenerateConcave.
lineTo(41.446522f, 376.25f);
1517 badFirstVector.
moveTo(501.087708f, 319.610352f);
1518 badFirstVector.
lineTo(501.087708f, 319.610352f);
1519 badFirstVector.
cubicTo(501.087677f, 319.610321f, 449.271606f, 258.078674f, 395.084564f, 198.711182f);
1520 badFirstVector.
cubicTo(358.967072f, 159.140717f, 321.910553f, 120.650436f, 298.442322f, 101.955399f);
1521 badFirstVector.
lineTo(301.557678f, 98.044601f);
1522 badFirstVector.
cubicTo(325.283844f, 116.945084f, 362.615204f, 155.720825f, 398.777557f, 195.340454f);
1523 badFirstVector.
cubicTo(453.031860f, 254.781662f, 504.912262f, 316.389618f, 504.912292f, 316.389648f);
1524 badFirstVector.
lineTo(504.912292f, 316.389648f);
1525 badFirstVector.
lineTo(501.087708f, 319.610352f);
1526 badFirstVector.
close();
1531 falseBackEdge.
moveTo(-217.83430557928145f, -382.14948768484857f);
1532 falseBackEdge.
lineTo(-227.73867866614847f, -399.52485512718323f);
1533 falseBackEdge.
cubicTo(-158.3541047666846f, -439.0757140459542f,
1534 -79.8654464485281f, -459.875f,
1535 -1.1368683772161603e-13f, -459.875f);
1536 falseBackEdge.
lineTo(-8.08037266162413e-14f, -439.875f);
1537 falseBackEdge.
lineTo(-8.526512829121202e-14f, -439.87499999999994f);
1538 falseBackEdge.
cubicTo(-76.39209188702645f, -439.87499999999994f,
1539 -151.46727226799754f, -419.98027663161537f,
1540 -217.83430557928145f, -382.14948768484857f);
1541 falseBackEdge.
close();
1559 doubleback.
quadTo(1, 1, 2, 2);
1562 doubleback.
quadTo(1, 0, 2, 0);
1564 doubleback.
quadTo(1, 0, 0, 0);
1576 doubleback.
lineTo(-1, 0);
1577 doubleback.
lineTo(-1, 1);
1578 doubleback.
lineTo(-1, 0);
1581 for (
int i = 0; i < 4; ++i) {
1585 doubleback.
lineTo(-1, -1);
1600 doubleback.
lineTo(-1, -1);
1627 if (
nullptr == str) {
1661 path.quadTo(100, 100, 50, 50);
1664 static const struct {
1665 const char* fPathStr;
1666 bool fExpectedIsConvex;
1679 for (
size_t i = 0; i < std::size(
gRec); ++i) {
1715 static const SkPoint axisAlignedPts[] = {
1722 const size_t axisAlignedPtsCount =
sizeof(axisAlignedPts) /
sizeof(axisAlignedPts[0]);
1726 int f = (
int) (index % axisAlignedPtsCount);
1727 int g = (
int) ((f + 1) % axisAlignedPtsCount);
1729 switch (index % 13) {
1732 case 2: path.quadTo(
nonFinitePts[i], axisAlignedPts[f]);
break;
1733 case 3: path.quadTo(axisAlignedPts[f],
nonFinitePts[i]);
break;
1734 case 4: path.cubicTo(
nonFinitePts[i], axisAlignedPts[f], axisAlignedPts[f]);
break;
1735 case 5: path.cubicTo(axisAlignedPts[f],
nonFinitePts[i], axisAlignedPts[f]);
break;
1736 case 6: path.cubicTo(axisAlignedPts[f], axisAlignedPts[f],
nonFinitePts[i]);
break;
1741 case 11: path.cubicTo(
nonFinitePts[i], axisAlignedPts[f], axisAlignedPts[g]);
break;
1748 for (
int index = 0; index < (
int) (11 * axisAlignedPtsCount); ++index) {
1749 int f = (
int) (index % axisAlignedPtsCount);
1750 int g = (
int) ((f + 1) % axisAlignedPtsCount);
1752 int curveSelect = index % 11;
1753 switch (curveSelect) {
1754 case 0: path.moveTo(axisAlignedPts[f]);
break;
1755 case 1: path.lineTo(axisAlignedPts[f]);
break;
1756 case 2: path.quadTo(axisAlignedPts[f], axisAlignedPts[f]);
break;
1757 case 3: path.quadTo(axisAlignedPts[f], axisAlignedPts[g]);
break;
1758 case 4: path.quadTo(axisAlignedPts[g], axisAlignedPts[f]);
break;
1759 case 5: path.cubicTo(axisAlignedPts[f], axisAlignedPts[f], axisAlignedPts[f]);
break;
1760 case 6: path.cubicTo(axisAlignedPts[f], axisAlignedPts[f], axisAlignedPts[g]);
break;
1761 case 7: path.cubicTo(axisAlignedPts[f], axisAlignedPts[g], axisAlignedPts[f]);
break;
1762 case 8: path.cubicTo(axisAlignedPts[f], axisAlignedPts[g], axisAlignedPts[g]);
break;
1763 case 9: path.cubicTo(axisAlignedPts[g], axisAlignedPts[f], axisAlignedPts[f]);
break;
1764 case 10: path.cubicTo(axisAlignedPts[g], axisAlignedPts[f], axisAlignedPts[g]);
break;
1766 if (curveSelect == 0 || curveSelect == 1 || curveSelect == 2 || curveSelect == 5) {
1775 static const SkPoint diagonalPts[] = {
1780 const size_t diagonalPtsCount =
sizeof(diagonalPts) /
sizeof(diagonalPts[0]);
1782 for (
int index = 0; index < (
int) (7 * diagonalPtsCount); ++index) {
1783 int f = (
int) (index % diagonalPtsCount);
1784 int g = (
int) ((f + 1) % diagonalPtsCount);
1786 int curveSelect = index % 11;
1787 switch (curveSelect) {
1788 case 0: path.moveTo(diagonalPts[f]);
break;
1789 case 1: path.lineTo(diagonalPts[f]);
break;
1790 case 2: path.quadTo(diagonalPts[f], diagonalPts[f]);
break;
1791 case 3: path.quadTo(axisAlignedPts[f], diagonalPts[g]);
break;
1792 case 4: path.quadTo(diagonalPts[g], axisAlignedPts[f]);
break;
1793 case 5: path.cubicTo(diagonalPts[f], diagonalPts[f], diagonalPts[f]);
break;
1794 case 6: path.cubicTo(diagonalPts[f], diagonalPts[f], axisAlignedPts[g]);
break;
1795 case 7: path.cubicTo(diagonalPts[f], axisAlignedPts[g], diagonalPts[f]);
break;
1796 case 8: path.cubicTo(axisAlignedPts[f], diagonalPts[g], diagonalPts[g]);
break;
1797 case 9: path.cubicTo(diagonalPts[g], diagonalPts[f], axisAlignedPts[f]);
break;
1798 case 10: path.cubicTo(diagonalPts[g], axisAlignedPts[f], diagonalPts[g]);
break;
1800 if (curveSelect == 0) {
1841 path.moveTo(moveX, moveY);
1852 path.lineTo(lineX, lineY);
1868 path.quadTo(1, 1, 2, 2);
1880 circleR *= 1.75f / 2;
1893 {kBaseRect,
true,
true,
false,
false},
1900 true,
true,
true,
true},
1905 false,
true,
false,
false},
1908 false,
true,
false,
false},
1911 false,
true,
false,
false},
1914 false,
true,
false,
false},
1917 false,
true,
false,
false},
1920 false,
true,
false,
false},
1923 false,
true,
false,
false},
1934 false,
false,
false,
false},
1940 false,
false,
false,
false},
1945 true,
true,
true,
true},
1949 true,
true,
true,
true},
1954 false,
true,
false,
false},
1959 false,
true,
false,
false},
1963 for (
size_t q = 0; q < std::size(kQueries); ++q) {
1964 SkRect qRect = kQueries[q].fQueryRect;
1973 for (
int d = 0;
d < 2; ++
d) {
1976 path.addRect(kBaseRect, dir);
1978 path.conservativelyContainsRect(qRect));
1981 path.addCircle(kCircleC.
fX, kCircleC.
fY, circleR, dir);
1983 path.conservativelyContainsRect(qRect));
1986 path.addRoundRect(kBaseRect, kRRRadii[0], kRRRadii[1], dir);
1988 path.conservativelyContainsRect(qRect));
1991 path.moveTo(kBaseRect.
fLeft + kRRRadii[0], kBaseRect.
fTop);
1992 path.cubicTo(kBaseRect.
fLeft + kRRRadii[0] / 2, kBaseRect.
fTop,
1993 kBaseRect.
fLeft, kBaseRect.
fTop + kRRRadii[1] / 2,
1994 kBaseRect.
fLeft, kBaseRect.
fTop + kRRRadii[1]);
1997 path.lineTo(kBaseRect.
fRight, kBaseRect.
fTop);
2000 path.conservativelyContainsRect(qRect));
2052 path.moveTo(100, 100);
2069 path.moveTo(100, 100);
2091 path.lineTo(100, 100);
2106 path.moveTo(0, 0); path.lineTo(1, 0); path.lineTo(1, 1); path.lineTo(0, 1);
2119 SkPoint r1[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
2120 SkPoint r2[] = {{1, 0}, {1, 1}, {0, 1}, {0, 0}};
2121 SkPoint r3[] = {{1, 1}, {0, 1}, {0, 0}, {1, 0}};
2122 SkPoint r4[] = {{0, 1}, {0, 0}, {1, 0}, {1, 1}};
2123 SkPoint r5[] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
2124 SkPoint r6[] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}};
2125 SkPoint r7[] = {{1, 1}, {1, 0}, {0, 0}, {0, 1}};
2126 SkPoint r8[] = {{1, 0}, {0, 0}, {0, 1}, {1, 1}};
2127 SkPoint r9[] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}};
2128 SkPoint ra[] = {{0, 0}, {0, .5f}, {0, 1}, {.5f, 1}, {1, 1}, {1, .5f}, {1, 0}, {.5f, 0}};
2129 SkPoint rb[] = {{0, 0}, {.5f, 0}, {1, 0}, {1, .5f}, {1, 1}, {.5f, 1}, {0, 1}, {0, .5f}};
2130 SkPoint rc[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}};
2131 SkPoint rd[] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}};
2132 SkPoint re[] = {{0, 0}, {1, 0}, {1, 0}, {1, 1}, {0, 1}};
2133 SkPoint rf[] = {{1, 0}, {8, 0}, {8, 8}, {0, 8}, {0, 0}};
2136 SkPoint f1[] = {{0, 0}, {1, 0}, {1, 1}};
2137 SkPoint f2[] = {{0, 0}, {1, 1}, {0, 1}, {1, 0}};
2138 SkPoint f3[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}, {1, 0}};
2139 SkPoint f4[] = {{0, 0}, {1, 0}, {0, 0}, {1, 0}, {1, 1}, {0, 1}};
2140 SkPoint f5[] = {{0, 0}, {1, 0}, {1, 1}, {2, 0}};
2141 SkPoint f6[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 2}};
2142 SkPoint f7[] = {{0, 0}, {1, 0}, {1, 1}, {0, 2}};
2143 SkPoint f8[] = {{0, 0}, {1, 0}, {1, 1}, {1, 0}};
2144 SkPoint f9[] = {{1, 0}, {8, 0}, {8, 8}, {0, 8}, {0, 0}, {2, 0}};
2145 SkPoint fa[] = {{1, 0}, {8, 0}, {8, 8}, {0, 8}, {0, -1}, {1, -1}};
2146 SkPoint fb[] = {{1, 0}, {8, 0}, {8, 8}, {0, 8}, {0, 1}};
2149 SkPoint c1[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
2150 SkPoint c2[] = {{0, 0}, {1, 0}, {1, 2}, {0, 2}, {0, 1}};
2151 SkPoint c3[] = {{0, 0}, {1, 0}, {1, 2}, {0, 2}, {0, 1}, {0, 0}};
2154 SkPoint d1[] = {{0, 0}, {1, 0}, {1, 2}, {0, 2}, {0, 1}, {0, 2}};
2156 SkPoint d2[] = {{0, 0}, {1, 0}, {1, 2}, {0, 2}, {0, -1}};
2157 SkPoint d3[] = {{0, 0}, {1, 0}, {1, 2}, {0, 2}, {0, -1}, {0, 0}};
2165 { r1, std::size(r1),
true,
true },
2166 { r2, std::size(r2),
true,
true },
2167 { r3, std::size(r3),
true,
true },
2168 { r4, std::size(r4),
true,
true },
2169 { r5, std::size(r5),
true,
true },
2170 { r6, std::size(r6),
true,
true },
2171 { r7, std::size(r7),
true,
true },
2172 { r8, std::size(r8),
true,
true },
2173 { r9, std::size(r9),
true,
true },
2174 { ra, std::size(ra),
true,
true },
2175 { rb, std::size(rb),
true,
true },
2176 { rc, std::size(rc),
true,
true },
2177 { rd, std::size(rd),
true,
true },
2178 { re, std::size(re),
true,
true },
2179 { rf, std::size(rf),
true,
true },
2181 { f1, std::size(f1),
true,
false },
2182 { f2, std::size(f2),
true,
false },
2183 { f3, std::size(f3),
true,
false },
2184 { f4, std::size(f4),
true,
false },
2185 { f5, std::size(f5),
true,
false },
2186 { f6, std::size(f6),
true,
false },
2187 { f7, std::size(f7),
true,
false },
2188 { f8, std::size(f8),
true,
false },
2189 { f9, std::size(f9),
true,
false },
2190 { fa, std::size(fa),
true,
false },
2191 { fb, std::size(fb),
true,
false },
2193 { c1, std::size(c1),
false,
true },
2194 { c2, std::size(c2),
false,
true },
2195 { c3, std::size(c3),
false,
true },
2197 { d1, std::size(d1),
false,
false },
2198 { d2, std::size(d2),
false,
true },
2199 { d3, std::size(d3),
false,
false },
2204 for (
size_t testIndex = 0; testIndex <
testCount; ++testIndex) {
2206 path.moveTo(
tests[testIndex].fPoints[0].fX,
tests[testIndex].fPoints[0].fY);
2207 for (index = 1; index <
tests[testIndex].fPointCount; ++index) {
2208 path.lineTo(
tests[testIndex].fPoints[index].fX,
tests[testIndex].fPoints[index].fY);
2210 if (
tests[testIndex].fClose) {
2215 if (
tests[testIndex].fIsRect) {
2216 SkRect computed, expected;
2219 int pointCount =
tests[testIndex].fPointCount - (d2 ==
tests[testIndex].fPoints);
2229 computed.
setLTRB(123, 456, 789, 1011);
2230 for (
auto c : {
true,
false})
2246 for (index = 1; index <
SkToInt(std::size(r1)); ++index) {
2256 for (index = 1; index <
SkToInt(std::size(r1)); ++index) {
2267 for (index = 1; index <
SkToInt(std::size(r1)); ++index) {
2277 for (index = 1; index <
SkToInt(std::size(r1)); ++index) {
2289 for (index = 1; index <
SkToInt(std::size(r1)); ++index) {
2323 path.addRect(testRect, dir,
start);
2345 firstPt = verbPts[0];
2369 SkRect degenRect = testRect;
2375 degenRect = testRect;
2385 static constexpr unsigned kXSwapStarts[] = { 1, 0, 3, 2 };
2386 static constexpr unsigned kYSwapStarts[] = { 3, 2, 1, 0 };
2387 SkRect swapRect = testRect;
2392 swapRect = testRect;
2450 const SkScalar kStartAngles[] = { -270, -135, -45, 0, 10, 70, 180, 350 };
2451 const SkScalar kSweepAngles[] = { -350, -190, -90, -5, 5, 89, 180, 270, 350 };
2455 for (
SkRect oval : kOvals) {
2456 for (
SkScalar startAngle : kStartAngles) {
2457 for (
SkScalar sweepAngle : kSweepAngles) {
2462 path.moveTo(oval.
center());
2463 path.addArc(oval, startAngle, sweepAngle);
2468 oval == arc.
fOval &&
2476 path.addArc(oval, startAngle, sweepAngle);
2479 path.lineTo(oval.
center());
2482 path.lineTo(path.getPoint(0));
2488 path.moveTo(oval.
center());
2493 mutator = (mutator + 1) % 5;
2501 path.lineTo(kOvals[0].
center());
2502 path.addArc(kOvals[0], kStartAngles[0], kSweepAngles[0]);
2510 path.addArc(kOvals[0], kStartAngles[0], kSweepAngles[0]);
2521 SkPoint r1[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
2522 SkPoint r2[] = {{1, 0}, {1, 1}, {0, 1}, {0, 0}};
2523 SkPoint r3[] = {{1, 1}, {0, 1}, {0, 0}, {1, 0}};
2524 SkPoint r4[] = {{0, 1}, {0, 0}, {1, 0}, {1, 1}};
2525 SkPoint r5[] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
2526 SkPoint r6[] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}};
2527 SkPoint r7[] = {{1, 1}, {1, 0}, {0, 0}, {0, 1}};
2528 SkPoint r8[] = {{1, 0}, {0, 0}, {0, 1}, {1, 1}};
2529 SkPoint r9[] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}};
2530 SkPoint ra[] = {{0, 0}, {0, .5f}, {0, 1}, {.5f, 1}, {1, 1}, {1, .5f}, {1, 0}, {.5f, 0}};
2531 SkPoint rb[] = {{0, 0}, {.5f, 0}, {1, 0}, {1, .5f}, {1, 1}, {.5f, 1}, {0, 1}, {0, .5f}};
2532 SkPoint rc[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}};
2533 SkPoint rd[] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}};
2534 SkPoint re[] = {{0, 0}, {1, 0}, {1, 0}, {1, 1}, {0, 1}};
2537 SkPoint f1[] = {{0, 0}, {1, 0}, {1, 1}};
2538 SkPoint f2[] = {{0, 0}, {1, 1}, {0, 1}, {1, 0}};
2539 SkPoint f3[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}, {1, 0}};
2540 SkPoint f4[] = {{0, 0}, {1, 0}, {0, 0}, {1, 0}, {1, 1}, {0, 1}};
2541 SkPoint f5[] = {{0, 0}, {1, 0}, {1, 1}, {2, 0}};
2542 SkPoint f6[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 2}};
2543 SkPoint f7[] = {{0, 0}, {1, 0}, {1, 1}, {0, 2}};
2544 SkPoint f8[] = {{0, 0}, {1, 0}, {1, 1}, {1, 0}};
2547 SkPoint c1[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
2548 SkPoint c2[] = {{0, 0}, {1, 0}, {1, 2}, {0, 2}, {0, 1}};
2550 struct IsNestedRectTest {
2587 for (
int rectFirst = 0; rectFirst <= 1; ++rectFirst) {
2588 for (
size_t testIndex = 0; testIndex <
testCount; ++testIndex) {
2593 path.moveTo(
tests[testIndex].fPoints[0].fX,
tests[testIndex].fPoints[0].fY);
2594 for (index = 1; index <
tests[testIndex].fPointCount; ++index) {
2595 path.lineTo(
tests[testIndex].fPoints[index].fX,
tests[testIndex].fPoints[index].fY);
2597 if (
tests[testIndex].fClose) {
2605 if (
tests[testIndex].fIsNestedRect) {
2606 SkRect expected[2], computed[2];
2612 expected[1] = testBounds;
2618 expectedDirs[1] =
tests[testIndex].fDirection;
2633 for (index = 1; index <
SkToInt(std::size(r1)); ++index) {
2649 for (index = 1; index <
SkToInt(std::size(r1)); ++index) {
2666 for (index = 1; index <
SkToInt(std::size(r1)); ++index) {
2682 for (index = 1; index <
SkToInt(std::size(r1)); ++index) {
2700 for (index = 1; index <
SkToInt(std::size(r1)); ++index) {
2723 path.lineTo(10, 10);
2747 size_t size = writer.bytesWritten();
2749 writer.writeToMemory(storage.
get());
2762 unsigned start0, start1;
2778 const SkRect& origBounds = p.getBounds();
2787 static const SkPoint pts[] = {
2795 p.quadTo(pts[2], pts[3]);
2796 p.cubicTo(pts[4], pts[5], pts[6]);
2803 size_t size1 = p.writeToMemory(
nullptr);
2804 size_t size2 = p.writeToMemory(
buffer);
2837#define CONIC_PERSPECTIVE_BUG_FIXED 0
2838 static const SkPoint pts[] = {
2843#if CONIC_PERSPECTIVE_BUG_FIXED
2847 const int kPtCount = std::size(pts);
2851 p.quadTo(pts[2], pts[3]);
2852 p.cubicTo(pts[4], pts[5], pts[6]);
2853#if CONIC_PERSPECTIVE_BUG_FIXED
2854 p.conicTo(pts[4], pts[5], 0.5f);
2862 p.transform(matrix, &p1);
2873 p.transform(matrix, &p1);
2877 for (
int i = 0; i <
count; ++i) {
2886 matrix.setPerspX(4);
2894 SkRect pBounds = p.getBounds();
2911 p.transform(matrix, &p1);
2919 matrix.setScaleX(-1);
2923 p.transform(matrix, &p1);
2929 matrix.setAll(1, 1, 0, 1, 1, 0, 0, 0, 1);
2933 p.transform(matrix, &p1);
2939 p1.
addRect({ 10, 20, 30, 40 });
2941 p2.
addRect({ 10, 20, 30, 40 });
2946 matrix.setScale(2, 2);
2960 const char* testPath;
2961 const size_t numResultPts;
2962 const SkRect resultBound;
2964 const size_t numResultVerbs;
2989 static const struct zeroPathTestData gZeroLengthTests[] = {
2990 {
"M 1 1", 1, {1, 1, 1, 1}, resultVerbs1, std::size(resultVerbs1) },
2992 {
"M 1 1 z", 1, {1, 1, 1, 1}, resultVerbs3, std::size(resultVerbs3) },
3004 std::size(resultVerbs14)
3008 std::size(resultVerbs16)
3012 for (
size_t i = 0; i < std::size(gZeroLengthTests); ++i) {
3020 for (
size_t j = 0; j < gZeroLengthTests[i].numResultVerbs; ++j) {
3031#define kCurveSegmentMask (SkPath::kQuad_SegmentMask | SkPath::kCubic_SegmentMask)
3037 p.quadTo(100, 100, 200, 200);
3042 p.cubicTo(100, 100, 200, 200, 300, 300);
3050 p.cubicTo(100, 100, 200, 200, 300, 300);
3083 struct iterTestData {
3084 const char* testPath;
3085 const bool forceClose;
3086 const size_t* numResultPtsPerVerb;
3089 const size_t numResultVerbs;
3099 static const size_t resultPtsSizes1[] = { 0 };
3100 static const size_t resultPtsSizes2[] = { 1, 2, 1, 1, 0 };
3101 static const size_t resultPtsSizes3[] = { 1, 2, 1, 1, 1, 0 };
3102 static const SkPoint* resultPts1 =
nullptr;
3103 static const SkPoint resultPts2[] = {
3106 static const SkPoint resultPts3[] = {
3107 {
SK_Scalar1, 0 }, {
SK_Scalar1, 0 }, {
SK_Scalar1, 0 }, {
SK_Scalar1, 0 }, { 0, 0 }, { 0, 0 }
3109 static const struct iterTestData gIterTests[] = {
3110 {
"M 1 0",
false, resultPtsSizes1, resultPts1, resultVerbs1, std::size(resultVerbs1) },
3111 {
"z",
false, resultPtsSizes1, resultPts1, resultVerbs1, std::size(resultVerbs1) },
3112 {
"z",
true, resultPtsSizes1, resultPts1, resultVerbs1, std::size(resultVerbs1) },
3113 {
"M 1 0 L 1 0 M 0 0 z",
false, resultPtsSizes2, resultPts2, resultVerbs2, std::size(resultVerbs2) },
3114 {
"M 1 0 L 1 0 M 0 0 z",
true, resultPtsSizes3, resultPts3, resultVerbs3, std::size(resultVerbs3) }
3117 for (
size_t i = 0; i < std::size(gIterTests); ++i) {
3121 iter.
setPath(p, gIterTests[i].forceClose);
3125 for (
int k = 0; k < (
int)gIterTests[i].numResultPtsPerVerb[j]; ++k) {
3152 for (
int setNaN = 0; setNaN < 4; ++setNaN) {
3163 p.quadTo(0, 0, 0, 0);
3169 p.conicTo(0, 0, 0, 0, 0.5f);
3175 p.cubicTo(0, 0, 0, 0, 0, 0);
3188 const SkVector radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 100, 100 } };
3215 auto [verb, pts,
w] = *iter++;
3226 iter = iterate.
begin();
3228 auto [verb, pts,
w] = *iter++;
3234 auto [verb, pts,
w] = *iter++;
3240 auto [verb, pts,
w] = *iter++;
3265 iter = iterate.
begin();
3267 auto [verb, pts,
w] = *iter++;
3273 auto [verb, pts,
w] = *iter++;
3277 auto [verb, pts,
w] = *iter++;
3283 auto [verb, pts,
w] = *iter++;
3287 auto [verb, pts,
w] = *iter++;
3293 auto [verb, pts,
w] = *iter++;
3299 auto [verb, pts,
w] = *iter++;
3306 for (
int i = 0; i < 5; ++i) {
3307 for (
int j = 0; j < 5; ++j) {
3318 for (
int i = 0; i < 500; ++i) {
3320 bool lastWasClose =
true;
3321 bool haveMoveTo =
false;
3322 SkPoint lastMoveToPt = { 0, 0 };
3324 int numVerbs = (rand.
nextU() >> 16) % 10;
3325 int numIterVerbs = 0;
3326 for (
int j = 0; j < numVerbs; ++j) {
3332 expectedPts[numPoints] = randomPts[(rand.
nextU() >> 16) % 25];
3333 path.moveTo(expectedPts[numPoints]);
3334 lastMoveToPt = expectedPts[numPoints];
3336 lastWasClose =
false;
3341 expectedPts[numPoints++] = lastMoveToPt;
3345 expectedPts[numPoints] = randomPts[(rand.
nextU() >> 16) % 25];
3346 path.lineTo(expectedPts[numPoints]);
3348 lastWasClose =
false;
3352 expectedPts[numPoints++] = lastMoveToPt;
3356 expectedPts[numPoints] = randomPts[(rand.
nextU() >> 16) % 25];
3357 expectedPts[numPoints + 1] = randomPts[(rand.
nextU() >> 16) % 25];
3358 path.quadTo(expectedPts[numPoints], expectedPts[numPoints + 1]);
3360 lastWasClose =
false;
3364 expectedPts[numPoints++] = lastMoveToPt;
3368 expectedPts[numPoints] = randomPts[(rand.
nextU() >> 16) % 25];
3369 expectedPts[numPoints + 1] = randomPts[(rand.
nextU() >> 16) % 25];
3370 path.conicTo(expectedPts[numPoints], expectedPts[numPoints + 1],
3373 lastWasClose =
false;
3377 expectedPts[numPoints++] = lastMoveToPt;
3381 expectedPts[numPoints] = randomPts[(rand.
nextU() >> 16) % 25];
3382 expectedPts[numPoints + 1] = randomPts[(rand.
nextU() >> 16) % 25];
3383 expectedPts[numPoints + 2] = randomPts[(rand.
nextU() >> 16) % 25];
3384 path.cubicTo(expectedPts[numPoints], expectedPts[numPoints + 1],
3385 expectedPts[numPoints + 2]);
3387 lastWasClose =
false;
3392 lastWasClose =
true;
3397 expectedVerbs[numIterVerbs++] = nextVerb;
3400 numVerbs = numIterVerbs;
3405 lastMoveTo.
set(0, 0);
3414 lastPt = lastMoveTo = pts[0];
3443 lastPt = lastMoveTo;
3456 bool expectedCircle,
3461 unsigned isOvalStart;
3466 tmpPath.
addOval(rect, isOvalDir, isOvalStart);
3479 path.transform(m, &tmp);
3498 path.transform(m, &tmp);
3506 path.transform(m, &tmp);
3513 for (
int angle = 0; angle < 360; ++angle) {
3517 path.transform(m, &tmp);
3522 if (angle % 90 == 0) {
3537 path.transform(m, &tmp);
3554 path.transform(m, &tmp);
3574 path.transform(m, &tmp);
3642 path.addPath(circle, translate);
3647 path.addPath(
empty, translate);
3653 path.reverseAddPath(rect);
3702 path.transform(m, &tmp);
3712 path.transform(m, &tmp);
3720 path.transform(m, &tmp);
3787 SkVector radii[] = {{1, 2}, {3, 4}, {5, 6}, {7, 8}};
3788 SkRect r = {10, 20, 30, 40};
3794 p.addRoundRect(r, &radii[0].fX);
3798 p.addRoundRect(r, radii[1].fX, radii[1].fY);
3802 for (
size_t i = 0; i < std::size(radii); ++i) {
3810 p.addRoundRect(r, 0, 0);
3815 SkVector zeroRadii[] = {{0, 0}, {0, 0}, {0, 0}, {0, 0}};
3832 SkRect emptyR = {10, 20, 10, 30};
3852 SkRect emptyOval = {10, 20, 30, 20};
3854 p.addArc(emptyOval, 1, 2);
3857 SkRect oval = {10, 20, 30, 40};
3858 p.addArc(oval, 1, 0);
3863 p.addArc(oval, 0, 360);
3868 p.addArc(oval, 0, -360);
3871 p.addArc(oval, 1, 180);
3897 while (angle < 0.f) {
3900 while (angle >= 360.f) {
3922 for (
SkScalar sweep : {-720.f, -540.f, -360.f, 360.f, 432.f, 720.f}) {
3925 path.addArc(oval,
start, sweep);
3928 if (std::fmod(
start, 90.f) == 0) {
3935 for (
float start : {-180.f, -90.f, 90.f, 180.f}) {
3938 path.addArc(oval,
start + delta, sweep);
3947 auto [v, pts,
w] = *(*iter)++;
3955 auto [v, pts,
w] = *(*iter)++;
3963 auto [v, pts,
w] = *(*iter)++;
3972 auto [v, pts,
w] = *(*iter)++;
4063 p.arcTo(0, 0, 1, 2, 1);
4065 p.arcTo(1, 2, 1, 2, 1);
4067 p.arcTo(1, 2, 3, 4, 0);
4069 p.arcTo(1, 2, 0, 0, 1);
4071 p.arcTo(1, 0, 1, 1, 1);
4075 p.arcTo(1, 0, 1, -1, 1);
4078 SkRect oval = {1, 2, 3, 4};
4079 p.arcTo(oval, 0, 0,
true);
4081 p.arcTo(oval, 0, 0,
false);
4083 p.arcTo(oval, 360, 0,
true);
4085 p.arcTo(oval, 360, 0,
false);
4088 for (
float sweep = 359, delta = 0.5f; sweep != (float) (sweep + delta); ) {
4089 p.arcTo(oval, 0, sweep,
false);
4094 for (
float sweep = 361, delta = 0.5f; sweep != (float) (sweep - delta);) {
4095 p.arcTo(oval, 0, sweep,
false);
4100 SkRect noOvalWidth = {1, 2, 0, 3};
4102 p.arcTo(noOvalWidth, 0, 360,
false);
4105 SkRect noOvalHeight = {1, 2, 3, 1};
4107 p.arcTo(noOvalHeight, 0, 360,
false);
4118 int n = p.countPoints();
4124 p.arcTo(
SkRect::MakeXYWH(0, 0, 10, 10), -2.61488527e+33f, 359.992157f,
false);
4136 p.addPath(q, -4, -4);
4137 SkRect expected = {0, 0, 4, 4};
4140 p.reverseAddPath(q);
4141 SkRect reverseExpected = {4, 4, 8, 8};
4147 if (explicitMoveTo) {
4151 if (explicitMoveTo) {
4157 int verbcount = p.getVerbs(verbs, 4);
4175 int verbcount = p.getVerbs(verbs, 7);
4209 p.conicTo(1, 2, 3, 4, -1);
4213 p.conicTo(1, 2, 3, 4, 1);
4223 p.setLastPt(10, 10);
4240 (void) p.contains(-77.2027664f, 15.3066053f);
4317 p.quadTo(6, 6, 8, 8);
4318 p.quadTo(6, 8, 4, 8);
4319 p.quadTo(4, 6, 4, 4);
4332 const SkPoint qPts[] = {{6, 6}, {8, 8}, {6, 8}, {4, 8}, {4, 6}, {4, 4}, {6, 6}};
4334 for (
int index = 1; index < (
int) std::size(qPts); index += 2) {
4335 p.quadTo(qPts[index], qPts[index + 1]);
4341 for (
int index = 0; index < (
int) std::size(qPts) - 2; index += 2) {
4348 const SkPoint kPts[] = {{4, 4}, {6, 6}, {8, 8}, {6, 8}, {4, 8}, {4, 6}, {4, 4}};
4350 for (
int index = 1; index < (
int) std::size(kPts); index += 2) {
4351 p.conicTo(kPts[index], kPts[index + 1], 0.5f);
4356 for (
int index = 0; index < (
int) std::size(kPts) - 2; index += 2) {
4357 SkConic conic(&kPts[index], 0.5f);
4358 halfway = conic.evalAt(0.5f);
4367 SkPoint pts[] = {{5, 4}, {6, 5}, {7, 6}, {6, 6}, {4, 6}, {5, 7}, {5, 5}, {5, 4}, {6, 5}, {7, 6}};
4368 for (
int i = 0; i < 3; ++i) {
4371 p.moveTo(pts[i].fX, pts[i].fY);
4372 p.cubicTo(pts[i + 1].fX, pts[i + 1].fY, pts[i + 2].fX, pts[i + 2].fY, pts[i + 3].fX, pts[i + 3].fY);
4373 p.cubicTo(pts[i + 4].fX, pts[i + 4].fY, pts[i + 5].fX, pts[i + 5].fY, pts[i + 6].fX, pts[i + 6].fY);
4380 SkEvalCubicAt(&pts[i + 3], 0.5f, &halfway,
nullptr,
nullptr);
4393 + (ref.fVerbs.
capacity() - ref.fVerbs.
size()) *
sizeof(uint8_t);
4397 static const int kRepeatCnt = 10;
4408 for (
int i = 0; i < kRepeatCnt; ++i) {
4419 for (
int i = 0; i < kRepeatCnt; ++i) {
4430 for (
int i = 0; i < kRepeatCnt; ++i) {
4444 for (
int i = 0; i < kRepeatCnt; ++i) {
4455 for (
int i = 0; i < kRepeatCnt; ++i) {
4487 path.dump(&wStream, dumpAsHex);
4490 if (strlen(str) > 0) {
4503 "path.moveTo(1, 2);\n"
4504 "path.lineTo(3, 4);\n");
4508 p.quadTo(3, 4, 5, 6);
4510 "path.moveTo(1, 2);\n"
4511 "path.quadTo(3, 4, 5, 6);\n");
4515 p.conicTo(3, 4, 5, 6, 0.5f);
4517 "path.moveTo(1, 2);\n"
4518 "path.conicTo(3, 4, 5, 6, 0.5f);\n");
4522 p.cubicTo(3, 4, 5, 6, 7, 8);
4524 "path.moveTo(1, 2);\n"
4525 "path.cubicTo(3, 4, 5, 6, 7, 8);\n");
4531 "path.setFillType(SkPathFillType::kWinding);\n"
4532 "path.moveTo(SkBits2Float(0x3f800000), SkBits2Float(0x40000000)); // 1, 2\n"
4533 "path.lineTo(SkBits2Float(0x40400000), SkBits2Float(0x40800000)); // 3, 4\n");
4538 "path.moveTo(1, 2);\n"
4539 "path.lineTo(3, 4);\n");
4546 ChangeListener(
bool *changed) : fChanged(changed) { *fChanged =
false; }
4547 ~ChangeListener()
override {}
4548 void changed()
override { *fChanged =
true; }
4576 SkRect reverseExpected = {-4, -4, 8, 8};
4583 bool changed =
false;
4620 matrix.setScale(2, 2);
4621 p.transform(matrix, &q);
4659 paint.setAntiAlias(
true);
4660 surface->getCanvas()->clipPath(path,
true);
4668 paint.setAntiAlias(
true);
4700 {{125.126022f, -0.499872506f}, {125.288895f, -0.499338806f},
4701 {125.299316f, -0.499290764f}, {126.294594f, 0.505449712f},
4702 {125.999992f, 62.5047531f}, {124.0f, 62.4980202f},
4703 {124.122749f, 0.498142242f}, {125.126022f, -0.499872506f},
4704 {125.119476f, 1.50011659f}, {125.122749f, 0.50012207f},
4705 {126.122749f, 0.502101898f}, {126.0f, 62.5019798f},
4706 {125.0f, 62.5f}, {124.000008f, 62.4952469f},
4707 {124.294609f, 0.495946467f}, {125.294601f, 0.50069809f},
4708 {125.289886f, 1.50068688f}, {125.282349f, 1.50065041f},
4709 {125.119476f, 1.50011659f}};
4714 kMove,
kLine,
kLine,
kLine,
kLine,
kLine,
kLine,
kLine,
kLine,
kLine,
kLine,
kClose};
4716 for(
auto verb : verbs) {
4719 path.moveTo(
points[pointIndex++]);
4722 path.lineTo(
points[pointIndex++]);
4748 path.moveTo(10, 10);
4749 path.cubicTo(10, 20, 10, 30, 30, 30);
4750 path.lineTo(50, 20);
4751 path.lineTo(50, 10);
4970 path.moveTo(0, 512);
5048 int count = p.getPoints(pts, 4);
5052 p.getVerbs(verbs, 5);
5085 p.moveTo(bounds.fLeft + 10, bounds.fBottom + 10);
5171 path.conservativelyContainsRect({ -211747, 12.1115f, -197893, 25.0321f });
5177 for (
int i = 0; i < n; ++i) {
5180 path->lineTo(rand.
nextF()*100, rand.
nextF()*100);
5183 path->quadTo(rand.
nextF()*100, rand.
nextF()*100,
5187 path->conicTo(rand.
nextF()*100, rand.
nextF()*100,
5191 path->cubicTo(rand.
nextF()*100, rand.
nextF()*100,
5207 for (
int i = 0; i < 1000; ++i) {
5208 for (
int n = 1; n <= 10; n += 9) {
5212 SkRect bounds = path.getBounds();
5213 SkRect tight = path.computeTightBounds();
5225 SkRect ri = { 0.18554693f, 195.26283f, 0.185784385f, 752.644409f };
5227 { 1.81159976e-09f, 7.58768801e-05f },
5228 { 0.000118725002f, 0.000118725002f },
5229 { 0.000118725002f, 0.000118725002f },
5230 { 0.000118725002f, 0.486297607f }
5234 SkRect ro = { 9.18354821e-39f, 2.1710848e+9f, 2.16945843e+9f, 3.47808128e+9f };
5237 { 0.0103298295f, 0.185887396f },
5238 { 2.52999727e-29f, 169.001938f },
5239 { 195.262741f, 195.161255f }
5248 const size_t numMoves = 5;
5249 const size_t numConics = 7;
5250 const size_t numPoints = numMoves + 2 * numConics;
5251 const size_t numVerbs = numMoves + numConics;
5252 for (
size_t i = 0; i < numMoves; ++i) path.moveTo(1, 2);
5253 for (
size_t i = 0; i < numConics; ++i) path.conicTo(1, 2, 3, 4, 5);
5259 size_t bytesWritten = data->size();
5264 size_t bytesRead = readBack.
readFromMemory(data->data(), bytesWritten);
5273 size_t bytesRead = readBack.
readFromMemory(data->data(), bytesWritten - 4);
5286 const char*
tests[] = {
5287 "M50,0A50,50,0,0 1 100,50 L100,85 A15,15,0,0 1 85,100 L50,100 A50,50,0,0 1 50,0z",
5288 (
"M50,0L92,0 A8,8,0,0 1 100,8 L100,92 A8,8,0,0 1 92,100 L8,100"
5289 " A8,8,0,0 1 0,92 L 0,8 A8,8,0,0 1 8,0z"),
5290 "M50 0A50 50,0,1,1,50 100A50 50,0,1,1,50 0"
5297 SkPath scalePath = aPath;
5304 SkPath scalePath = aPath;
5318 auto canvas = surf->getCanvas();
5320 const bool aas[] = {
false,
true };
5330 for (
auto x : values) {
5332 for (
auto width : values) {
5334 for (
auto aa : aas) {
5335 paint.setAntiAlias(aa);
5336 for (
auto style : styles) {
5337 paint.setStyle(style);
5338 canvas->drawRect(r,
paint);
5339 canvas->drawOval(r,
paint);
5350 SkCanvas* canvas = surf->getCanvas();
5353 for (
bool aa : {
false,
true}) {
5356 for (
int bits = 1; bits <= 15; ++bits) {
5359 if (bits & 1) p0.
fX = -bad;
5360 if (bits & 2) p0.
fY = -bad;
5361 if (bits & 4) p1.
fX = bad;
5362 if (bits & 8) p1.
fY = bad;
5367 path.setFillType(ft);
5383 for (
size_t index = 0; index <
count; ++index) {
5384 index < 2 ? path.moveTo(
points[index]) : path.lineTo(
points[index]);
5393 for (
size_t index = 0; index <
count; ++index) {
5394 switch (verbs[index]) {
5412 SkPoint points[] = { {10, 10}, {75, 75}, {150, 75}, {150, 150}, {75, 150} };
5419 SkPoint points3[] = { {75, 50}, {100, 75}, {150, 75}, {150, 150}, {75, 150}, {75, 50} };
5420 path = makePath(points3, std::size(points3),
true);
5423 SkPoint points9[] = { {10, 10}, {75, 75}, {150, 75}, {150, 150}, {75, 150} };
5424 path = makePath(points9, std::size(points9),
true);
5426 compare.setBounds(&points9[1], std::size(points9) - 1);
5431 SkPoint points11[] = { {75, 150}, {75, 75}, {150, 75}, {150, 150}, {75, 150}, {75, 150} };
5432 path = makePath2(points11, verbs11, std::size(verbs11));
5434 compare.setBounds(&points11[0], std::size(points11));
5441 SkPoint points14[] = { {250, 75}, {250, 75}, {250, 75}, {100, 75},
5442 {150, 75}, {150, 150}, {75, 150}, {75, 75}, {0, 0} };
5443 path = makePath2(points14, verbs14, std::size(verbs14));
5448 SkPoint points15[] = { {75, 75}, {150, 75}, {150, 150}, {75, 150}, {250, 75} };
5449 path = makePath2(points15, verbs15, std::size(verbs15));
5451 compare.setBounds(&points15[0], std::size(points15) - 1);
5454 SkPoint points17[] = { {75, 10}, {75, 75}, {150, 75}, {150, 150}, {75, 150}, {75, 10} };
5455 path = makePath(points17, std::size(points17),
true);
5462 SkPoint points19[] = { {75, 75}, {75, 75}, {75, 75}, {75, 75}, {150, 75}, {150, 150},
5463 {75, 150}, {10, 10}, {30, 10}, {10, 30} };
5464 path = makePath2(points19, verbs19, std::size(verbs19));
5470 SkPoint points23[] = { {75, 75}, {75, 75}, {75, 75}, {75, 75}, {150, 75}, {150, 150},
5472 path = makePath2(points23, verbs23, std::size(verbs23));
5474 compare.setBounds(&points23[0], std::size(points23));
5480 SkPoint points29[] = { {75, 75}, {150, 75}, {150, 150}, {75, 150}, {75, 250}, {75, 75} };
5481 path = makePath2(points29, verbs29, std::size(verbs29));
5487 SkPoint points31[] = { {75, 75}, {150, 75}, {150, 150}, {75, 150}, {75, 10}, {75, 75} };
5488 path = makePath2(points31, verbs31, std::size(verbs31));
5490 compare.setBounds(&points31[0], 4);
5495 SkPoint points36[] = { {75, 75}, {150, 75}, {150, 150}, {10, 150}, {75, 75}, {75, 75} };
5496 path = makePath2(points36, verbs36, std::size(verbs36));
5501 SkPoint points39[] = { {150, 75}, {150, 150}, {75, 150}, {75, 100} };
5502 path = makePath2(points39, verbs39, std::size(verbs39));
5508 SkPoint pointsAA[] = { {32, 9.5f}, {32, 9.5f}, {32, 17}, {17, 17}, {17, 9.5f}, {17, 2},
5510 path = makePath2(pointsAA, verbsAA, std::size(verbsAA));
5512 compare.setBounds(&pointsAA[0], std::size(pointsAA));
5518 SkPoint points41[] = { {75, 75}, {150, 75}, {150, 150}, {140, 150}, {140, 75}, {75, 75} };
5519 path = makePath2(points41, verbs41, std::size(verbs41));
5521 compare.setBounds(&points41[1], 4);
5527 SkPoint points53[] = { {75, 75}, {150, 75}, {150, 150}, {140, 150}, {140, 75}, {75, 75} };
5528 path = makePath2(points53, verbs53, std::size(verbs53));
5530 compare.setBounds(&points53[1], 4);
5548 for (
int add = 0; add <
count; ++add) {
5550 path.moveTo(1, 2).lineTo(3, 4).cubicTo(1,2,3,4,5,6).conicTo(1,2,3,4,5);
5552 path.addPath(path, 1, 2);
5553 path.addPath(path, 3, 4);
5562 path.addPoly(pts, 3,
false);
5575 { 0.499069244f, 9.63295173f },
5576 { 0.499402374f, 7.88207579f },
5577 { 10.2363272f, 0.49999997f }
5591 { 0.327190518f, -114.945152f },
5592 { -0.5f, 1.00003874f },
5593 { 0.666425824f, 4304.26172f },
5600 for (
int i = 0; i <
count; ++i) {
5602 case 0: path->lineTo(10, 20);
break;
5603 case 1: path->quadTo(5, 6, 7, 8);
break;
5604 case 2: path->conicTo(1, 2, 3, 4, 0.5f);
break;
5605 case 3: path->cubicTo(2, 4, 6, 8, 10, 12);
break;
5613 for (
int verbs = 0; verbs < 100; ++verbs) {
5614 SkPath unique_path, shared_path;
5625 uint32_t cID =
copy.getGenerationID();
5667 SkPath shallowPath = path;
5699template <
typename ISA>
5714 path->transform(
x.fIM, &
path2);
5715 path->transform(
x.fIM);
5722 path->transform(
x.fTM, &
path2);
5723 path->transform(
x.fTM);
5730 path->transform(
x.fSM, &
path2);
5731 path->transform(
x.fSM);
5740 path->transform(
x.fRM, &
path2);
5741 path->transform(
x.fRM);
5755 path.addRect({10, 10, 40, 50});
5756 survive(&path,
x,
true, r, [](
const SkPath& p) {
return p.isRect(
nullptr); });
5759 path.addOval({10, 10, 40, 50});
5760 survive(&path,
x,
true, r, [](
const SkPath& p) {
return p.isOval(
nullptr); });
5764 survive(&path,
x,
true, r, [](
const SkPath& p) {
return p.isRRect(
nullptr); });
5768 path.moveTo(0, 0).lineTo(100, 0).lineTo(70, 100).lineTo(30, 100);
5770 survive(&path,
x,
false, r, [](
const SkPath& p) {
return true; });
5778 const char text[] =
"hello";
5779 constexpr size_t len =
sizeof(
text) - 1;
5788 ((
SkPath*)ctx)->addPath(*src, mx);
5792 SkScalar radii[] = { 80, 100, 0, 0, 40, 60, 0, 0 };
5794 path.addRoundRect({10, 10, 110, 110}, radii);
5795 path.offset(0, 5, &(copyPath));
5797 copyPath.
rConicTo(1, 1, 3, 3, 0.707107f);
5801 const std::initializer_list<SkPath::Verb>& in,
5802 const std::initializer_list<SkPath::Verb>& expected) {
5815 for (
auto v : expected) {
5816 auto e = iter.
next();
5824 const SkPath& path,
const std::initializer_list<SkPoint>& list) {
5825 const SkPoint* expected = list.begin();
5827 for (
size_t i = 0;;) {
5829 switch (iter.
next(pts)) {
5849 const SkRect r = {1, 2, 3, 4};
5858 for (
int i = 0; i < 4; ++i) {
5860 path.addRect(r, dir, i);
5864 for (
int j = 0; j < 4; ++j) {
5865 int index = (i + j*increment) % 4;
5869 e[0], e[1], e[2], e[3]
5875 e[0], e[1], e[2], e[3],
5890 p[2], p[3], p[0], p[1],
5918 SkPoint p = path.getPoint(path.countPoints() - 1);
5921 const SkPoint newLineTo = {1234, 5678};
5922 path.lineTo(newLineTo);
5924 p = path.getPoint(path.countPoints() - 2);
5927 p = path.getPoint(path.countPoints() - 1);
5953 test_before_after_lineto(path1c, {20,50}, {20,30});
5954 test_before_after_lineto(
path2, {20,50}, {20,30});
5955 test_before_after_lineto(path2c, {20,50}, {20,30});
5961 test_before_after_lineto(
path1, {20,50}, {20,50});
5962 test_before_after_lineto(
path3, {20,50}, {20,50});
5963 test_before_after_lineto(path3c, {20,50}, {20,50});
5980 test_edger(r, {
M, L, L,
M, L, L }, { L, L, L, L, L, L });
5991 p1.
addRect({143,226,200,241});
5994 SkPoint rectangleStart = {143, 226};
6026 SkRect rects[] = {{207.0f, 237.0f, 300.0f, 237.0f},
6027 {207.0f, 237.0f, 300.0f, 267.0f}};
6029 for (
SkRect rect: rects) {
6030 for (
int numExtraMoveTos : {0, 1, 2, 3}) {
6034 for (
int i = 0; i < numExtraMoveTos; ++i) {
6050 SkRect query = rect.makeInset(10.f, 0.f);
6063 path.moveTo(3.25f, 115.5f);
6064 path.conicTo(9.98099e+17f, 2.83874e+15f, 1.75098e-30f, 1.75097e-30f, 1.05385e+18f);
6065 path.conicTo(9.96938e+17f, 6.3804e+19f, 9.96934e+17f, 1.75096e-30f, 1.75096e-30f);
6066 path.quadTo(1.28886e+10f, 9.9647e+17f, 9.98101e+17f, 2.61006e+15f);
6069 SkPath pathWithExtraMoveTo;
6071 pathWithExtraMoveTo.
moveTo(5.90043e-39f, 1.34525e-43f);
6072 pathWithExtraMoveTo.
addPath(path);
6083 path.moveTo(0.00665998459f, 2);
6084 path.quadTo(0.00665998459f, 4, -1.99334002f, 4);
6085 path.quadTo(-3.99334002f, 4, -3.99334002f, 2);
6086 path.quadTo(-3.99334002f, 0, -1.99334002f, 0);
6087 path.quadTo(0.00665998459f, 0, 0.00665998459f, 2);
6091 paint.setAntiAlias(
true);
static SkM44 inv(const SkM44 &m)
static bool compare(const SkBitmap &ref, const SkIRect &iref, const SkBitmap &test, const SkIRect &itest)
static const struct @223 gRec[]
static constexpr SkScalar kClose
static const int points[]
static const size_t testCount
static const SkPoint nonFinitePts[]
const size_t nonFinitePtsCount
static void test_circle_translate(skiatest::Reporter *reporter, const SkPath &path, SkPathFirstDirection dir)
static void test_arb_round_rect_is_convex(skiatest::Reporter *reporter)
static void test_transform(skiatest::Reporter *reporter)
static void test_fuzz_crbug_638223()
static void test_arc_ovals(skiatest::Reporter *reporter)
static void test_addPath_and_injected_moveTo(skiatest::Reporter *reporter)
static void check_convex_bounds(skiatest::Reporter *reporter, const SkPath &p, const SkRect &bounds)
static void test_bad_cubic_crbug229478()
static void test_skbug_6947()
static void test_arcTo(skiatest::Reporter *reporter)
static void test_conicTo_special_case(skiatest::Reporter *reporter)
static void test_isNestedFillRects(skiatest::Reporter *reporter)
static void test_interp(skiatest::Reporter *reporter)
static bool conditional_convex(const SkPath &path, bool is_convex)
static void test_arb_zero_rad_round_rect_is_rect(skiatest::Reporter *reporter)
static void test_range_iter(skiatest::Reporter *reporter)
static void test_path_crbug389050(skiatest::Reporter *reporter)
static void test_isRect_open_close(skiatest::Reporter *reporter)
static void write_and_read_back(skiatest::Reporter *reporter, const SkPath &p)
void survive(SkPath *path, const Xforms &x, bool isAxisAligned, skiatest::Reporter *reporter, ISA isa_proc)
static void make_arb_round_rect(SkPath *path, const SkRect &r, SkScalar xCorner, SkScalar yCorner)
static void test_rMoveTo(skiatest::Reporter *reporter)
static SkScalar oval_start_index_to_angle(unsigned start)
static void test_iterative_intersect_line()
static void add_rect(SkPath *path, const SkRect &r)
static bool nearly_equal(const SkRect &a, const SkRect &b)
static void test_get_point(skiatest::Reporter *reporter)
#define kCurveSegmentMask
static void test_is_closed_rect(skiatest::Reporter *reporter)
static void test_circle(skiatest::Reporter *reporter)
static void test_direction(skiatest::Reporter *reporter)
static void test_circle_rotate(skiatest::Reporter *reporter, const SkPath &path, SkPathFirstDirection dir)
static void test_addPathMode(skiatest::Reporter *reporter, bool explicitMoveTo, bool extend)
static void check_convexity(skiatest::Reporter *reporter, const SkPath &path, bool expectedConvexity)
static void test_bad_cubic_crbug234190()
static void test_bounds_crbug_513799(skiatest::Reporter *reporter)
static void test_convexity(skiatest::Reporter *reporter)
static void stroke_tiny_cubic()
static void test_dump(skiatest::Reporter *reporter)
static void dump_if_ne(skiatest::Reporter *reporter, const SkRect &expected, const SkRect &bounds)
static void test_fuzz_crbug_627414(skiatest::Reporter *reporter)
static void test_zero_length_paths(skiatest::Reporter *reporter)
static void test_isLine(skiatest::Reporter *reporter)
static void test_fuzz_crbug_643933()
static void test_mask_overflow()
static void test_rect_isfinite(skiatest::Reporter *reporter)
static void test_path_crbugskia5995()
static void test_empty(skiatest::Reporter *reporter, const SkPath &p)
static void test_addrect_isfinite(skiatest::Reporter *reporter)
static void test_convexity2(skiatest::Reporter *reporter)
static SkScalar canonical_start_angle(float angle)
static void test_rrect_convexity_is_unknown(skiatest::Reporter *reporter, SkPath *path, SkPathDirection dir)
static void test_add_rrect(skiatest::Reporter *reporter, const SkRect &bounds, const SkVector radii[4])
static void test_poly(skiatest::Reporter *reporter, const SkPath &path, const SkPoint srcPts[], bool expectClose)
static void compare_dump(skiatest::Reporter *reporter, const SkPath &path, bool dumpAsHex, const char *str)
static void test_iter(skiatest::Reporter *reporter)
static void build_path_170666(SkPath &path)
static void test_fuzz_crbug_668907()
static void stroke_cubic(const SkPoint pts[4])
static void check_done_and_reset(skiatest::Reporter *reporter, SkPath *p, SkPathPriv::RangeIter *iter)
static void check_line(skiatest::Reporter *reporter, SkPathPriv::RangeIter *iter, SkScalar x1, SkScalar y1)
static void test_fuzz_crbug_662780()
static void test_close(skiatest::Reporter *reporter)
static void test_isArc(skiatest::Reporter *reporter)
static void test_arc(skiatest::Reporter *reporter)
static void make_path_crbug364224(SkPath *path)
static void test_skbug_7435()
static void test_isRect(skiatest::Reporter *reporter)
static void check_path_is_line_pair_and_reset(skiatest::Reporter *reporter, SkPath *p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2)
static void draw_triangle(SkCanvas *canvas, const SkPoint pts[])
static void test_crbug_629455(skiatest::Reporter *reporter)
static void test_clipped_cubic()
static void check_direction(skiatest::Reporter *reporter, const SkPath &path, SkPathFirstDirection expected)
static void test_edger(skiatest::Reporter *r, const std::initializer_list< SkPath::Verb > &in, const std::initializer_list< SkPath::Verb > &expected)
static void test_extendClosedPath(skiatest::Reporter *reporter)
static void test_isfinite_after_transform(skiatest::Reporter *reporter)
static void test_skbug_3469(skiatest::Reporter *reporter)
static void build_path_simple_170666(SkPath &path)
static void test_contains(skiatest::Reporter *reporter)
static void test_draw_AA_path(int width, int height, const SkPath &path)
static void test_circle_with_add_paths(skiatest::Reporter *reporter)
static void make_path0(SkPath *path)
static void test_crbug_493450(skiatest::Reporter *reporter)
static void assert_points(skiatest::Reporter *reporter, const SkPath &path, const std::initializer_list< SkPoint > &list)
static void test_operatorEqual(skiatest::Reporter *reporter)
static void test_islastcontourclosed(skiatest::Reporter *reporter)
static void check_quad(skiatest::Reporter *reporter, SkPathPriv::RangeIter *iter, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2)
static void test_circle_mirror_x(skiatest::Reporter *reporter, const SkPath &path, SkPathFirstDirection dir)
static void test_addrect(skiatest::Reporter *reporter)
static void test_circle_mirror_xy(skiatest::Reporter *reporter, const SkPath &path, SkPathFirstDirection dir)
static void test_bounds(skiatest::Reporter *reporter)
static void test_skbug_7015()
static void test_tricky_cubic()
static void check_path_is_line(skiatest::Reporter *reporter, SkPath *p, SkScalar x1, SkScalar y1)
static void test_addPoly(skiatest::Reporter *reporter)
#define SUPPRESS_VISIBILITY_WARNING
static void test_segment_masks(skiatest::Reporter *reporter)
static void test_strokerec(skiatest::Reporter *reporter)
static void make_path1(SkPath *path)
static void test_isfinite(skiatest::Reporter *reporter)
static void add_verbs(SkPath *path, int count)
static void test_circle_mirror_y(skiatest::Reporter *reporter, const SkPath &path, SkPathFirstDirection dir)
static void add_corner_arc(SkPath *path, const SkRect &rect, SkScalar xIn, SkScalar yIn, int startAngle)
static void test_fuzz_crbug_662730(skiatest::Reporter *reporter)
static void test_skbug_7051()
static void check_path_is_move_and_reset(skiatest::Reporter *reporter, SkPath *p, SkScalar x0, SkScalar y0)
static void check_done(skiatest::Reporter *reporter, SkPath *p, SkPathPriv::RangeIter *iter)
static void test_fuzz_crbug_662952(skiatest::Reporter *reporter)
static void test_convexity_doubleback(skiatest::Reporter *reporter)
static void check_simple_rect(skiatest::Reporter *reporter, const SkPath &path, bool isClosed, const SkRect &rect, SkPathDirection dir, unsigned start)
static void test_skbug_3239(skiatest::Reporter *reporter)
static void test_path_crbugskia2820(skiatest::Reporter *reporter)
static void set_radii(SkVector radii[4], int index, float rad)
static void test_oval(skiatest::Reporter *reporter)
static void check_for_circle(skiatest::Reporter *reporter, const SkPath &path, bool expectedCircle, SkPathFirstDirection expectedDir)
static void test_circle_with_direction(skiatest::Reporter *reporter, SkPathDirection inDir)
static void test_path_close_issue1474(skiatest::Reporter *reporter)
static void test_rrect(skiatest::Reporter *reporter)
static void build_big_path(SkPath *path, bool reducedCase)
static void test_crbug_613918()
static void check_path_is_line_and_reset(skiatest::Reporter *reporter, SkPath *p, SkScalar x1, SkScalar y1)
static void test_crbug_170666()
static void make_path_crbug364224_simplified(SkPath *path)
static void test_fuzz_crbug_647922()
static void rand_path(SkPath *path, SkRandom &rand, SkPath::Verb verb, int n)
static void test_addEmptyPath(skiatest::Reporter *reporter, SkPath::AddPathMode mode)
void(* PathProc)(SkPath *)
static void test_crbug_495894(skiatest::Reporter *reporter)
static void test_gen_id(skiatest::Reporter *reporter)
static void test_flattening(skiatest::Reporter *reporter)
static void test_rrect_is_convex(skiatest::Reporter *reporter, SkPath *path, SkPathDirection dir)
static void check_oval_arc(skiatest::Reporter *reporter, SkScalar start, SkScalar sweep, const SkPath &path)
static void test_addPath(skiatest::Reporter *reporter)
static void test_path_isfinite(skiatest::Reporter *reporter)
static void test_addRect_and_trailing_lineTo(skiatest::Reporter *reporter)
const SkPathFirstDirection kDontCheckDir
static void make_path_crbugskia2820(SkPath *path, skiatest::Reporter *reporter)
static void test_path_to_region(skiatest::Reporter *reporter)
static void test_path_crbugskia6003()
static void check_path_is_quad_and_reset(skiatest::Reporter *reporter, SkPath *p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2)
static void setFromString(SkPath *path, const char str[])
static void test_sect_with_horizontal_needs_pinning()
static void test_path_crbug364224()
static void check_move(skiatest::Reporter *reporter, SkPathPriv::RangeIter *iter, SkScalar x0, SkScalar y0)
static void test_circle_skew(skiatest::Reporter *reporter, const SkPath &path, SkPathFirstDirection dir)
static void test_conservativelyContains(skiatest::Reporter *reporter)
static void test_tiny_path_convexity(skiatest::Reporter *reporter, const char *pathBug, SkScalar tx, SkScalar ty, SkScalar scale)
static void check_close(skiatest::Reporter *reporter, const SkPath &path)
#define SkAssertResult(cond)
#define SkDEBUGFAIL(message)
@ kSrcOver
r = s + (1-sa)*d
constexpr SkColor SK_ColorBLACK
static float SkBits2Float(uint32_t bits)
constexpr float SK_FloatNegativeInfinity
static bool isAxisAligned(const SkScalerContextRec &rec)
@ kUTF8
uses bytes to represent UTF-8 or ASCII
void SkEvalCubicAt(const SkPoint src[4], SkScalar t, SkPoint *loc, SkVector *tangent, SkVector *curvature)
void SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint *pt, SkVector *tangent)
static void sk_bzero(void *buffer, size_t size)
@ kNo
Don't pre-clip the geometry before applying the (perspective) matrix.
SK_API std::unique_ptr< SkCanvas > SkMakeNullCanvas()
static const int kPtCount[]
bool SK_API TightBounds(const SkPath &path, SkRect *result)
@ kClose
SkPath::RawIter returns 0 points.
@ kCubic
SkPath::RawIter returns 4 points.
@ kConic
SkPath::RawIter returns 3 points + 1 weight.
@ kQuad
SkPath::RawIter returns 3 points.
@ kMove
SkPath::RawIter returns 1 point.
@ kLine
SkPath::RawIter returns 2 points.
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
static bool equals(T *a, T *b)
void swap(sk_sp< T > &a, sk_sp< T > &b)
#define SkScalarSin(radians)
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
#define SkDoubleToScalar(x)
#define SK_ScalarNearlyZero
#define SK_ScalarInfinity
#define SK_ScalarRoot2Over2
#define SK_ScalarNegativeInfinity
constexpr int SkToInt(S x)
static constexpr bool SkToBool(const T &x)
#define DEF_TEST(name, reporter)
#define REPORTER_ASSERT(r, cond,...)
static SkScalar center(float pos0, float pos1)
Type::kYUV Type::kRGBA() int(0.7 *637)
static size_t GetFreeSpace(const SkPathRef &ref)
static void TestPathRef(skiatest::Reporter *reporter)
static void TestPathTo(skiatest::Reporter *reporter)
static size_t GetFreeSpace(const SkPath &path)
static void TestPathrefListeners(skiatest::Reporter *reporter)
void writePath(const SkPath &path) override
void drawRect(const SkRect &rect, const SkPaint &paint)
virtual bool isClipEmpty() const
void clipPath(const SkPath &path, SkClipOp op, bool doAntiAlias)
void drawPath(const SkPath &path, const SkPaint &paint)
void drawVertices(const SkVertices *vertices, SkBlendMode mode, const SkPaint &paint)
sk_sp< SkData > detachAsData()
static SkMatrix Scale(SkScalar sx, SkScalar sy)
static SkMatrix RotateDeg(SkScalar deg)
static SkMatrix Translate(SkScalar dx, SkScalar dy)
SkMatrix & setTranslate(SkScalar dx, SkScalar dy)
SkMatrix & setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
SkMatrix & setRotate(SkScalar degrees, SkScalar px, SkScalar py)
static const SkMatrix & I()
void setStyle(Style style)
@ kStroke_Style
set to stroke geometry
@ kFill_Style
set to fill geometry
@ kStrokeAndFill_Style
sets to stroke and fill geometry
void setStrokeWidth(SkScalar width)
static bool FromSVGString(const char str[], SkPath *)
static const char * FindScalar(const char str[], SkScalar *value)
SkPathBuilder & lineTo(SkPoint pt)
SkPathBuilder & moveTo(SkPoint pt)
static SkPath::Verb EdgeToVerb(Edge e)
static bool IsRRect(const SkPath &path, SkRRect *rrect, SkPathDirection *dir, unsigned *start)
static bool IsNestedFillRects(const SkPath &, SkRect rect[2], SkPathDirection dirs[2]=nullptr)
static bool IsSimpleRect(const SkPath &path, bool isSimpleFill, SkRect *rect, SkPathDirection *direction, unsigned *start)
static void ForceComputeConvexity(const SkPath &path)
static bool IsOval(const SkPath &path, SkRect *rect, SkPathDirection *dir, unsigned *start)
static SkPathFirstDirection AsFirstDirection(SkPathDirection dir)
static SkPathFirstDirection ComputeFirstDirection(const SkPath &)
static int LeadingMoveToCount(const SkPath &path)
static void AddGenIDChangeListener(const SkPath &path, sk_sp< SkIDChangeListener > listener)
static SkPathConvexity GetConvexityOrUnknown(const SkPath &path)
static void ShrinkToFit(SkPath *path)
SkPath::RangeIter RangeIter
void resetToSize(int newVerbCnt, int newPointCnt, int newConicCount)
SkPoint * growForRepeatedVerb(int verb, int numVbs, SkScalar **weights=nullptr)
bool isClosedContour() const
void setPath(const SkPath &path, bool forceClose)
Verb next(SkPoint pts[4])
SkScalar conicWeight() const
size_t readFromMemory(const void *buffer, size_t length)
uint32_t getGenerationID() const
SkPath & addCircle(SkScalar x, SkScalar y, SkScalar radius, SkPathDirection dir=SkPathDirection::kCW)
SkPath & rConicTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2, SkScalar w)
SkPoint getPoint(int index) const
SkPath & moveTo(SkScalar x, SkScalar y)
int getPoints(SkPoint points[], int max) const
void setFillType(SkPathFillType ft)
SkPath & lineTo(SkScalar x, SkScalar y)
SkPath & addPath(const SkPath &src, SkScalar dx, SkScalar dy, AddPathMode mode=kAppend_AddPathMode)
void toggleInverseFillType()
bool isInterpolatable(const SkPath &compare) const
bool interpolate(const SkPath &ending, SkScalar weight, SkPath *out) const
bool isOval(SkRect *bounds) const
@ kLarge_ArcSize
larger of arc pair
SkPath & quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2)
const SkRect & getBounds() const
uint32_t getSegmentMasks() const
size_t writeToMemory(void *buffer) const
SkPath & addOval(const SkRect &oval, SkPathDirection dir=SkPathDirection::kCW)
SkPath & cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar x3, SkScalar y3)
SkPath & conicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar w)
bool isRect(SkRect *rect, bool *isClosed=nullptr, SkPathDirection *direction=nullptr) const
void transform(const SkMatrix &matrix, SkPath *dst, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
bool isRRect(SkRRect *rrect) const
SkPath & addRect(const SkRect &rect, SkPathDirection dir, unsigned start)
void incReserve(int extraPtCount, int extraVerbCount=0, int extraConicCount=0)
const SkRect & rect() const
static SkRRect MakeRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
void setRectRadii(const SkRect &rect, const SkVector radii[4])
void readPath(SkPath *path)
bool setPath(const SkPath &path, const SkRegion &clip)
void setStrokeStyle(SkScalar width, bool strokeAndFill=false)
bool isHairlineStyle() const
bool applyToPath(SkPath *dst, const SkPath &src) const
static sk_sp< SkVertices > MakeCopy(VertexMode mode, int vertexCount, const SkPoint positions[], const SkPoint texs[], const SkColor colors[], int indexCount, const uint16_t indices[])
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
EMSCRIPTEN_KEEPALIVE void empty()
static const uint8_t buffer[]
static float max(float r, float g, float b)
static float min(float r, float g, float b)
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
SK_API bool FillPathWithPaint(const SkPath &src, const SkPaint &paint, SkPath *dst, const SkRect *cullRect, SkScalar resScale=1)
static SkImageInfo MakeN32Premul(int width, int height)
SkPath::RangeIter begin()
static constexpr SkPoint Make(float x, float y)
void set(float x, float y)
static constexpr SkRect MakeEmpty()
SkScalar fBottom
larger y-axis bounds
constexpr float left() const
constexpr float top() const
SkScalar fLeft
smaller x-axis bounds
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
SkScalar fRight
larger x-axis bounds
constexpr float centerX() const
void offset(float dx, float dy)
constexpr float height() const
constexpr float right() const
bool setBoundsCheck(const SkPoint pts[], int count)
void setLTRB(float left, float top, float right, float bottom)
void setBounds(const SkPoint pts[], int count)
constexpr float centerY() const
constexpr float width() const
constexpr SkPoint center() const
static constexpr SkRect MakeWH(float w, float h)
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
constexpr float bottom() const
SkScalar fTop
smaller y-axis bounds
static constexpr SkSize Make(SkScalar w, SkScalar h)