diff --git a/gm/aaxfermodes.cpp b/gm/aaxfermodes.cpp index 7cc209adef..f5c05a2fbe 100644 --- a/gm/aaxfermodes.cpp +++ b/gm/aaxfermodes.cpp @@ -11,7 +11,7 @@ #include "include/core/SkColor.h" #include "include/core/SkFont.h" #include "include/core/SkPaint.h" -#include "include/core/SkPath.h" +#include "include/core/SkPathBuilder.h" #include "include/core/SkPoint.h" #include "include/core/SkRect.h" #include "include/core/SkScalar.h" @@ -89,16 +89,18 @@ protected: {radius, 0}, {0, 1.33f * radius} }; - fOval.moveTo(pts[0]); - fOval.quadTo(pts[1], pts[2]); - fOval.quadTo(pts[3], pts[0]); + fOval = SkPathBuilder().moveTo(pts[0]) + .quadTo(pts[1], pts[2]) + .quadTo(pts[3], pts[0]) + .detach(); - fConcave.moveTo(-radius, 0); - fConcave.quadTo(0, 0, 0, -radius); - fConcave.quadTo(0, 0, radius, 0); - fConcave.quadTo(0, 0, 0, radius); - fConcave.quadTo(0, 0, -radius, 0); - fConcave.close(); + fConcave = SkPathBuilder().moveTo(-radius, 0) + .quadTo(0, 0, 0, -radius) + .quadTo(0, 0, radius, 0) + .quadTo(0, 0, 0, radius) + .quadTo(0, 0, -radius, 0) + .close() + .detach(); } void draw_pass(SkCanvas* canvas, DrawingPass drawingPass) { diff --git a/gm/bug615686.cpp b/gm/bug615686.cpp index bf930aa78e..b76cb0747b 100644 --- a/gm/bug615686.cpp +++ b/gm/bug615686.cpp @@ -8,15 +8,14 @@ #include "gm/gm.h" #include "include/core/SkCanvas.h" #include "include/core/SkPaint.h" -#include "include/core/SkPath.h" +#include "include/core/SkPathBuilder.h" DEF_SIMPLE_GM(bug615686, canvas, 250, 250) { SkPaint p; p.setAntiAlias(true); p.setStyle(SkPaint::kStroke_Style); p.setStrokeWidth(20); - SkPath path; - path.moveTo(0, 0); - path.cubicTo(200, 200, 0, 200, 200, 0); - canvas->drawPath(path, p); + canvas->drawPath(SkPathBuilder().moveTo(0, 0) + .cubicTo(200, 200, 0, 200, 200, 0) + .detach(), p); } diff --git a/gm/complexclip4.cpp b/gm/complexclip4.cpp index 24be22acc9..6ef34af61f 100644 --- a/gm/complexclip4.cpp +++ b/gm/complexclip4.cpp @@ -88,12 +88,12 @@ protected: emulateDeviceRestriction(canvas, SkIRect::MakeLTRB(500, 100, 800, 300)); canvas->drawColor(SK_ColorGREEN); - SkPath pathClip; - pathClip.moveTo(SkIntToScalar(650), SkIntToScalar(200)); - pathClip.lineTo(SkIntToScalar(900), SkIntToScalar(300)); - pathClip.lineTo(SkIntToScalar(650), SkIntToScalar(400)); - pathClip.lineTo(SkIntToScalar(650), SkIntToScalar(300)); - pathClip.close(); + SkPath pathClip = SkPath::Polygon({ + {650, 200}, + {900, 300}, + {650, 400}, + {650, 300}, + }, true); emulateClipPathReplace(canvas, pathClip, fDoAAClip); canvas->drawRect(SkRect::MakeLTRB(500, 200, 900, 500), p); canvas->restore(); diff --git a/gm/convex_all_line_paths.cpp b/gm/convex_all_line_paths.cpp index 582d32f02f..2568c61684 100644 --- a/gm/convex_all_line_paths.cpp +++ b/gm/convex_all_line_paths.cpp @@ -236,21 +236,22 @@ protected: points = data.get(); } - SkPath path; + SkPathBuilder builder; if (SkPathDirection::kCW == dir) { - path.moveTo(points[0]); + builder.moveTo(points[0]); for (int i = 1; i < numPts; ++i) { - path.lineTo(points[i]); + builder.lineTo(points[i]); } } else { - path.moveTo(points[numPts-1]); + builder.moveTo(points[numPts-1]); for (int i = numPts-2; i >= 0; --i) { - path.lineTo(points[i]); + builder.lineTo(points[i]); } } - path.close(); + builder.close(); + SkPath path = builder.detach(); #ifdef SK_DEBUG // Each path this method returns should be convex, only composed of // lines, wound the right direction, and short enough to fit in one @@ -339,11 +340,12 @@ protected: p.setStrokeWidth(SkIntToScalar(kStrokeWidth)); } - SkPath p1; - p1.moveTo(60.8522949f, 364.671021f); - p1.lineTo(59.4380493f, 364.671021f); - p1.lineTo(385.414276f, 690.647217f); - p1.lineTo(386.121399f, 689.940125f); + SkPath p1 = SkPath::Polygon({ + {60.8522949f, 364.671021f}, + {59.4380493f, 364.671021f}, + {385.414276f, 690.647217f}, + {386.121399f, 689.940125f}, + }, false); canvas->save(); canvas->translate(356.0f, 50.0f); canvas->drawPath(p1, p); @@ -351,20 +353,20 @@ protected: // Repro for crbug.com/869172 (SVG path incorrectly simplified when using GPU // Rasterization). This will only draw anything in the stroke-and-fill version. - SkPath p2; - p2.moveTo(10.f, 0.f); - p2.lineTo(38.f, 0.f); - p2.lineTo(66.f, 0.f); - p2.lineTo(94.f, 0.f); - p2.lineTo(122.f, 0.f); - p2.lineTo(150.f, 0.f); - p2.lineTo(150.f, 0.f); - p2.lineTo(122.f, 0.f); - p2.lineTo(94.f, 0.f); - p2.lineTo(66.f, 0.f); - p2.lineTo(38.f, 0.f); - p2.lineTo(10.f, 0.f); - p2.close(); + SkPath p2 = SkPath::Polygon({ + {10.f, 0.f}, + {38.f, 0.f}, + {66.f, 0.f}, + {94.f, 0.f}, + {122.f, 0.f}, + {150.f, 0.f}, + {150.f, 0.f}, + {122.f, 0.f}, + {94.f, 0.f}, + {66.f, 0.f}, + {38.f, 0.f}, + {10.f, 0.f}, + }, true); canvas->save(); canvas->translate(0.0f, 500.0f); canvas->drawPath(p2, p); @@ -373,20 +375,19 @@ protected: // Repro for crbug.com/856137. This path previously caused GrAAConvexTessellator to turn // inset rings into outsets when adjacent bisector angles converged outside the previous // ring due to accumulated error. - SkPath p3; - p3.setFillType(SkPathFillType::kEvenOdd); - p3.moveTo(1184.96f, 982.557f); - p3.lineTo(1183.71f, 982.865f); - p3.lineTo(1180.99f, 982.734f); - p3.lineTo(1178.5f, 981.541f); - p3.lineTo(1176.35f, 979.367f); - p3.lineTo(1178.94f, 938.854f); - p3.lineTo(1181.35f, 936.038f); - p3.lineTo(1183.96f, 934.117f); - p3.lineTo(1186.67f, 933.195f); - p3.lineTo(1189.36f, 933.342f); - p3.lineTo(1191.58f, 934.38f); - p3.close(); + SkPath p3 = SkPath::Polygon({ + {1184.96f, 982.557f}, + {1183.71f, 982.865f}, + {1180.99f, 982.734f}, + {1178.5f, 981.541f}, + {1176.35f, 979.367f}, + {1178.94f, 938.854f}, + {1181.35f, 936.038f}, + {1183.96f, 934.117f}, + {1186.67f, 933.195f}, + {1189.36f, 933.342f}, + {1191.58f, 934.38f}, + }, true, SkPathFillType::kEvenOdd); canvas->save(); SkMatrix m; m.setAll(0.0893210843f, 0, 79.1197586f, 0, 0.0893210843f, 300, 0, 0, 1); diff --git a/gm/crbug_1086705.cpp b/gm/crbug_1086705.cpp index 25085dd064..69fab47894 100644 --- a/gm/crbug_1086705.cpp +++ b/gm/crbug_1086705.cpp @@ -8,7 +8,7 @@ #include "gm/gm.h" #include "include/core/SkCanvas.h" #include "include/core/SkPaint.h" -#include "include/core/SkPath.h" +#include "include/core/SkPathBuilder.h" // See crbug.com/1086705. The convex linearizing path renderer would collapse too many of the // very-near duplicate vertices and turn the path into a triangle. Since the stroke width is larger @@ -27,12 +27,12 @@ DEF_SIMPLE_GM(crbug_1086705, canvas, 200, 200) { 100.f + 2.f * SkScalarSin(angleRads)}; } - SkPath circle; + SkPathBuilder circle; circle.moveTo(circleVertices[0]); for (int i = 1; i < 700; ++i) { circle.lineTo(circleVertices[i]); } circle.close(); - canvas->drawPath(circle, paint); + canvas->drawPath(circle.detach(), paint); } diff --git a/gm/crbug_788500.cpp b/gm/crbug_788500.cpp index a0a1ad39d4..3938b3e1c6 100644 --- a/gm/crbug_788500.cpp +++ b/gm/crbug_788500.cpp @@ -8,10 +8,10 @@ #include "gm/gm.h" #include "include/core/SkCanvas.h" #include "include/core/SkPaint.h" -#include "include/core/SkPath.h" +#include "include/core/SkPathBuilder.h" DEF_SIMPLE_GM(crbug_788500, canvas, 300, 300) { - SkPath path; + SkPathBuilder path; path.setFillType(SkPathFillType::kEvenOdd); path.moveTo(0, 0); path.moveTo(245.5f, 98.5f); @@ -19,5 +19,5 @@ DEF_SIMPLE_GM(crbug_788500, canvas, 300, 300) { SkPaint paint; paint.setAntiAlias(true); - canvas->drawPath(path, paint); + canvas->drawPath(path.detach(), paint); } diff --git a/gm/crbug_847759.cpp b/gm/crbug_847759.cpp index 2478028154..02f5e70272 100644 --- a/gm/crbug_847759.cpp +++ b/gm/crbug_847759.cpp @@ -8,14 +8,14 @@ #include "gm/gm.h" #include "include/core/SkCanvas.h" #include "include/core/SkPaint.h" -#include "include/core/SkPath.h" +#include "include/core/SkPathBuilder.h" DEF_SIMPLE_GM(crbug_847759, canvas, 500, 500) { // This path exposed an issue in GrAAHairlinePathRenderer. When converting from cubics to quads // we produced quads where the previously vertical tangents at the left and right tips of the // squashed oval-like path became slightly non-vertical. This caused a missed pixel of AA just // outside each tip. - SkPath path; + SkPathBuilder path; path.moveTo(97,374.5f); path.cubicTo(97,359.8644528f,155.8745488f,348,228.5f,348); path.cubicTo(301.1254512f,348,360,359.8644528f,360,374.5f); @@ -28,5 +28,5 @@ DEF_SIMPLE_GM(crbug_847759, canvas, 500, 500) { paint.setStrokeMiter(1.5); paint.setStyle(SkPaint::kStroke_Style); canvas->translate(-80, -330); - canvas->drawPath(path, paint); + canvas->drawPath(path.detach(), paint); } diff --git a/gm/crbug_884166.cpp b/gm/crbug_884166.cpp index c94aa8e4c5..96db8bde83 100644 --- a/gm/crbug_884166.cpp +++ b/gm/crbug_884166.cpp @@ -8,7 +8,7 @@ #include "gm/gm.h" #include "include/core/SkCanvas.h" #include "include/core/SkPaint.h" -#include "include/core/SkPath.h" +#include "include/core/SkPathBuilder.h" DEF_SIMPLE_GM(crbug_884166, canvas, 300, 300) { SkPaint paint; @@ -16,7 +16,7 @@ DEF_SIMPLE_GM(crbug_884166, canvas, 300, 300) { paint.setAntiAlias(true); paint.setStyle(SkPaint::kFill_Style); - SkPath path; + SkPathBuilder path; path.moveTo(153.25, 280.75); path.lineTo(161.75, 281.75); path.lineTo(164.25, 282.00); @@ -25,5 +25,5 @@ DEF_SIMPLE_GM(crbug_884166, canvas, 300, 300) { path.lineTo(286.25, 231.25); path.lineTo(163.75, 282.00); path.lineTo(150.00, 280.00); - canvas->drawPath(path, paint); + canvas->drawPath(path.detach(), paint); } diff --git a/gm/crbug_887103.cpp b/gm/crbug_887103.cpp index d9e8ae72f4..b6596b4c6a 100644 --- a/gm/crbug_887103.cpp +++ b/gm/crbug_887103.cpp @@ -8,7 +8,7 @@ #include "gm/gm.h" #include "include/core/SkCanvas.h" #include "include/core/SkPaint.h" -#include "include/core/SkPath.h" +#include "include/core/SkPathBuilder.h" DEF_SIMPLE_GM(crbug_887103, canvas, 520, 520) { SkPaint paint; @@ -16,7 +16,7 @@ DEF_SIMPLE_GM(crbug_887103, canvas, 520, 520) { paint.setAntiAlias(true); paint.setStyle(SkPaint::kFill_Style); - SkPath path; + SkPathBuilder path; path.moveTo(510, 20); path.lineTo(500, 20); path.lineTo(510, 500); @@ -28,5 +28,5 @@ DEF_SIMPLE_GM(crbug_887103, canvas, 520, 520) { path.moveTo(500, 30); path.lineTo(510, 10); path.lineTo( 10, 30); - canvas->drawPath(path, paint); + canvas->drawPath(path.detach(), paint); } diff --git a/gm/crbug_908646.cpp b/gm/crbug_908646.cpp index 3d11276d98..919dd08916 100644 --- a/gm/crbug_908646.cpp +++ b/gm/crbug_908646.cpp @@ -8,12 +8,12 @@ #include "gm/gm.h" #include "include/core/SkCanvas.h" #include "include/core/SkPaint.h" -#include "include/core/SkPath.h" +#include "include/core/SkPathBuilder.h" DEF_SIMPLE_GM(crbug_908646, canvas, 300, 300) { SkPaint paint; paint.setAntiAlias(true); - SkPath path; + SkPathBuilder path; path.setFillType(SkPathFillType::kEvenOdd); path.moveTo(50, 50); path.lineTo(50, 300); @@ -25,5 +25,5 @@ DEF_SIMPLE_GM(crbug_908646, canvas, 300, 300) { path.moveTo(100, 250); path.lineTo(150, 150); path.lineTo(200, 250); - canvas->drawPath(path, paint); + canvas->drawPath(path.detach(), paint); } diff --git a/gm/crbug_913349.cpp b/gm/crbug_913349.cpp index 40c8749043..cb7220a2ef 100644 --- a/gm/crbug_913349.cpp +++ b/gm/crbug_913349.cpp @@ -8,7 +8,7 @@ #include "gm/gm.h" #include "include/core/SkCanvas.h" #include "include/core/SkPaint.h" -#include "include/core/SkPath.h" +#include "include/core/SkPathBuilder.h" DEF_SIMPLE_GM(crbug_913349, canvas, 500, 600) { SkPaint paint; @@ -17,12 +17,12 @@ DEF_SIMPLE_GM(crbug_913349, canvas, 500, 600) { paint.setStyle(SkPaint::kFill_Style); // This is a reduction from crbug.com/913349 to 5 verts. - SkPath path; + SkPathBuilder path; path.moveTo( 349.5, 225.75); path.lineTo( 96.5, 74); path.lineTo( 500.50, 226); path.lineTo( 350, 226); path.lineTo( 350, 224); - canvas->drawPath(path, paint); + canvas->drawPath(path.detach(), paint); } diff --git a/gm/dashcircle.cpp b/gm/dashcircle.cpp index 7942b34bb1..c6392c1fc6 100644 --- a/gm/dashcircle.cpp +++ b/gm/dashcircle.cpp @@ -10,7 +10,7 @@ #include "include/core/SkColor.h" #include "include/core/SkMatrix.h" #include "include/core/SkPaint.h" -#include "include/core/SkPath.h" +#include "include/core/SkPathBuilder.h" #include "include/core/SkPathEffect.h" #include "include/core/SkRect.h" #include "include/core/SkRefCnt.h" @@ -63,7 +63,7 @@ protected: SkScalar arcLength = 360.f / wedge; canvas->save(); for (const DashExample& dashExample : dashExamples) { - SkPath refPath; + SkPathBuilder refPath; int dashUnits = 0; for (int index = 0; index < dashExample.length; ++index) { dashUnits += dashExample.pattern[index]; @@ -81,7 +81,7 @@ protected: } canvas->save(); canvas->rotate(fRotation); - canvas->drawPath(refPath, refPaint); + canvas->drawPath(refPath.detach(), refPaint); canvas->restore(); SkPaint p; p.setAntiAlias(true); diff --git a/gm/drawable.cpp b/gm/drawable.cpp index 857467224e..b61b8e82e7 100644 --- a/gm/drawable.cpp +++ b/gm/drawable.cpp @@ -11,7 +11,7 @@ #include "include/core/SkDrawable.h" #include "include/core/SkMatrix.h" #include "include/core/SkPaint.h" -#include "include/core/SkPath.h" +#include "include/core/SkPathBuilder.h" #include "include/core/SkRect.h" #include "include/core/SkRefCnt.h" @@ -19,9 +19,9 @@ struct MyDrawable : public SkDrawable { SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); } void onDraw(SkCanvas* canvas) override { - SkPath path; - path.moveTo(10, 10); - path.conicTo(10, 90, 50, 90, 0.9f); + SkPath path = SkPathBuilder().moveTo(10, 10) + .conicTo(10, 90, 50, 90, 0.9f) + .detach(); SkPaint paint; paint.setColor(SK_ColorBLUE); diff --git a/gm/hairlines.cpp b/gm/hairlines.cpp index 15906e5dfc..6809a37511 100644 --- a/gm/hairlines.cpp +++ b/gm/hairlines.cpp @@ -9,7 +9,7 @@ #include "include/core/SkCanvas.h" #include "include/core/SkColor.h" #include "include/core/SkPaint.h" -#include "include/core/SkPath.h" +#include "include/core/SkPathBuilder.h" #include "include/core/SkPoint.h" #include "include/core/SkRect.h" #include "include/core/SkScalar.h" @@ -32,7 +32,7 @@ protected: void onOnceBeforeDraw() override { { - SkPath* lineAnglesPath = &fPaths.push_back(); + SkPathBuilder lineAngles; enum { kNumAngles = 15, kRadius = 40, @@ -41,108 +41,78 @@ protected: SkScalar angle = SK_ScalarPI * SkIntToScalar(i) / kNumAngles; SkScalar x = kRadius * SkScalarCos(angle); SkScalar y = kRadius * SkScalarSin(angle); - lineAnglesPath->moveTo(x, y); - lineAnglesPath->lineTo(-x, -y); + lineAngles.moveTo(x, y).lineTo(-x, -y); } + fPaths.push_back(lineAngles.detach()); } - { - SkPath* kindaTightQuad = &fPaths.push_back(); - kindaTightQuad->moveTo(0, -10 * SK_Scalar1); - kindaTightQuad->quadTo(SkIntToScalar(100), SkIntToScalar(100), -10 * SK_Scalar1, 0); - } + fPaths.push_back(SkPathBuilder().moveTo(0, -10) + .quadTo(100, 100, -10, 0) + .detach()); - { - SkPath* tightQuad = &fPaths.push_back(); - tightQuad->moveTo(0, -5 * SK_Scalar1); - tightQuad->quadTo(SkIntToScalar(100), SkIntToScalar(100), -5 * SK_Scalar1, 0); - } + fPaths.push_back(SkPathBuilder().moveTo(0, -5) + .quadTo(100, 100, -5, 0) + .detach()); - { - SkPath* tighterQuad = &fPaths.push_back(); - tighterQuad->moveTo(0, -2 * SK_Scalar1); - tighterQuad->quadTo(SkIntToScalar(100), SkIntToScalar(100), -2 * SK_Scalar1, 0); - } + fPaths.push_back(SkPathBuilder().moveTo(0, -2) + .quadTo(100, 100, -2, 0) + .detach()); - { - SkPath* unevenTighterQuad = &fPaths.push_back(); - unevenTighterQuad->moveTo(0, -1 * SK_Scalar1); - SkPoint p; - p.set(-2 * SK_Scalar1 + 3 * SkIntToScalar(102) / 4, SkIntToScalar(75)); - unevenTighterQuad->quadTo(SkIntToScalar(100), SkIntToScalar(100), p.fX, p.fY); - } + fPaths.push_back(SkPathBuilder().moveTo(0, -1) + .quadTo(100, 100, -2 + 306.0f / 4, 75) + .detach()); - { - SkPath* reallyTightQuad = &fPaths.push_back(); - reallyTightQuad->moveTo(0, -1 * SK_Scalar1); - reallyTightQuad->quadTo(SkIntToScalar(100), SkIntToScalar(100), -1 * SK_Scalar1, 0); - } + fPaths.push_back(SkPathBuilder().moveTo(0, -1) + .quadTo(100, 100, -1, 0) + .detach()); - { - SkPath* closedQuad = &fPaths.push_back(); - closedQuad->moveTo(0, -0); - closedQuad->quadTo(SkIntToScalar(100), SkIntToScalar(100), 0, 0); - } + fPaths.push_back(SkPathBuilder().moveTo(0, -0) + .quadTo(100, 100, 0, 0) + .detach()); - { - SkPath* unevenClosedQuad = &fPaths.push_back(); - unevenClosedQuad->moveTo(0, -0); - unevenClosedQuad->quadTo(SkIntToScalar(100), SkIntToScalar(100), - SkIntToScalar(75), SkIntToScalar(75)); - } + fPaths.push_back(SkPathBuilder().moveTo(0, -0) + .quadTo(100, 100, 75, 75) + .detach()); // Two problem cases for gpu hairline renderer found by shapeops testing. These used // to assert that the computed bounding box didn't contain all the vertices. - { - SkPath* problem1 = &fPaths.push_back(); - problem1->moveTo(SkIntToScalar(4), SkIntToScalar(6)); - problem1->cubicTo(SkIntToScalar(5), SkIntToScalar(6), - SkIntToScalar(5), SkIntToScalar(4), - SkIntToScalar(4), SkIntToScalar(0)); - problem1->close(); - } - { - SkPath* problem2 = &fPaths.push_back(); - problem2->moveTo(SkIntToScalar(5), SkIntToScalar(1)); - problem2->lineTo(4.32787323f, 1.67212653f); - problem2->cubicTo(2.75223875f, 3.24776125f, - 3.00581908f, 4.51236057f, - 3.7580452f, 4.37367964f); - problem2->cubicTo(4.66472578f, 3.888381f, - 5.f, 2.875f, - 5.f, 1.f); - problem2->close(); - } + fPaths.push_back(SkPathBuilder().moveTo(4, 6) + .cubicTo(5, 6, 5, 4, 4, 0) + .close() + .detach()); + + fPaths.push_back(SkPathBuilder().moveTo(5, 1) + .lineTo( 4.32787323f, 1.67212653f) + .cubicTo(2.75223875f, 3.24776125f, + 3.00581908f, 4.51236057f, + 3.7580452f, 4.37367964f) + .cubicTo(4.66472578f, 3.888381f, + 5.f, 2.875f, + 5.f, 1.f) + .close() + .detach()); // Three paths that show the same bug (missing end caps) - { - // A caret (crbug.com/131770) - SkPath* bug0 = &fPaths.push_back(); - bug0->moveTo(6.5f,5.5f); - bug0->lineTo(3.5f,0.5f); - bug0->moveTo(0.5f,5.5f); - bug0->lineTo(3.5f,0.5f); - } - { - // An X (crbug.com/137317) - SkPath* bug1 = &fPaths.push_back(); + fPaths.push_back(SkPathBuilder().moveTo(6.5f,5.5f) + .lineTo(3.5f,0.5f) + .moveTo(0.5f,5.5f) + .lineTo(3.5f,0.5f) + .detach()); - bug1->moveTo(1, 1); - bug1->lineTo(6, 6); - bug1->moveTo(1, 6); - bug1->lineTo(6, 1); - } + // An X (crbug.com/137317) + fPaths.push_back(SkPathBuilder().moveTo(1, 1) + .lineTo(6, 6) + .moveTo(1, 6) + .lineTo(6, 1) + .detach()); - { - // A right angle (crbug.com/137465 and crbug.com/256776) - SkPath* bug2 = &fPaths.push_back(); - - bug2->moveTo(5.5f, 5.5f); - bug2->lineTo(5.5f, 0.5f); - bug2->lineTo(0.5f, 0.5f); - } + // A right angle (crbug.com/137465 and crbug.com/256776) + fPaths.push_back(SkPathBuilder().moveTo(5.5f, 5.5f) + .lineTo(5.5f, 0.5f) + .lineTo(0.5f, 0.5f) + .detach()); { // Arc example to test imperfect truncation bug (crbug.com/295626) @@ -150,11 +120,11 @@ protected: constexpr SkScalar kStartAngle = 262.59717f; constexpr SkScalar kSweepAngle = SkScalarHalf(17.188717f); - SkPath* bug = &fPaths.push_back(); + SkPathBuilder bug; // Add a circular arc SkRect circle = SkRect::MakeLTRB(-kRad, -kRad, kRad, kRad); - bug->addArc(circle, kStartAngle, kSweepAngle); + bug.addArc(circle, kStartAngle, kSweepAngle); // Now add the chord that should cap the circular arc SkPoint p0 = { kRad * SkScalarCos(SkDegreesToRadians(kStartAngle)), @@ -163,8 +133,9 @@ protected: SkPoint p1 = { kRad * SkScalarCos(SkDegreesToRadians(kStartAngle + kSweepAngle)), kRad * SkScalarSin(SkDegreesToRadians(kStartAngle + kSweepAngle)) }; - bug->moveTo(p0); - bug->lineTo(p1); + bug.moveTo(p0); + bug.lineTo(p1); + fPaths.push_back(bug.detach()); } } @@ -233,16 +204,16 @@ static void draw_squarehair_tests(SkCanvas* canvas, SkScalar width, SkPaint::Cap canvas->drawLine(10, 10, 20, 10, paint); canvas->drawLine(30, 10, 30, 20, paint); canvas->drawLine(40, 10, 50, 20, paint); - SkPath path; + SkPathBuilder path; path.moveTo(60, 10); path.quadTo(60, 20, 70, 20); path.conicTo(70, 10, 80, 10, 0.707f); - canvas->drawPath(path, paint); - path.reset(); + canvas->drawPath(path.detach(), paint); + path.moveTo(90, 10); path.cubicTo(90, 20, 100, 20, 100, 10); path.lineTo(110, 10); - canvas->drawPath(path, paint); + canvas->drawPath(path.detach(), paint); canvas->translate(0, 30); } diff --git a/gm/labyrinth.cpp b/gm/labyrinth.cpp index 6670b7f2f1..9364ed73b6 100644 --- a/gm/labyrinth.cpp +++ b/gm/labyrinth.cpp @@ -9,7 +9,7 @@ #include "include/core/SkCanvas.h" #include "include/core/SkPaint.h" -#include "include/core/SkPath.h" +#include "include/core/SkPathBuilder.h" /** * Repro case for https://bugs.chromium.org/p/chromium/issues/detail?id=913223 @@ -52,7 +52,7 @@ static void draw_labyrinth(SkCanvas* canvas, SkPaint::Cap cap) { {1,1,1,1,1,1,0,1,1,1}, }; - SkPath maze; + SkPathBuilder maze; for (size_t y = 0; y < SK_ARRAY_COUNT(kRows); ++y) { for (size_t x = 0; x < SK_ARRAY_COUNT(kRows[0]); ++x) { if (kRows[y][x]) { @@ -79,7 +79,7 @@ static void draw_labyrinth(SkCanvas* canvas, SkPaint::Cap cap) { canvas->translate(10.5, 10.5); canvas->scale(40, 40); - canvas->drawPath(maze, paint); + canvas->drawPath(maze.detach(), paint); } constexpr static int kWidth = 500; diff --git a/include/c/sk_path.h b/include/c/sk_path.h index 3898b629f3..ed8cbb94fe 100644 --- a/include/c/sk_path.h +++ b/include/c/sk_path.h @@ -20,40 +20,43 @@ typedef enum { CCW_SK_PATH_DIRECTION, } sk_path_direction_t; +typedef struct sk_pathbuilder_t sk_pathbuilder_t; + /** Create a new, empty path. */ -SK_API sk_path_t* sk_path_new(void); -/** Release the memory used by a sk_path_t. */ -SK_API void sk_path_delete(sk_path_t*); +SK_API sk_pathbuilder_t* sk_pathbuilder_new(void); + +/** Release the memory used by a sk_pathbuilder_t. */ +SK_API void sk_pathbuilder_delete(sk_pathbuilder_t*); /** Set the beginning of the next contour to the point (x,y). */ -SK_API void sk_path_move_to(sk_path_t*, float x, float y); +SK_API void sk_pathbuilder_move_to(sk_pathbuilder_t*, float x, float y); /** Add a line from the last point to the specified point (x,y). If no - sk_path_move_to() call has been made for this contour, the first + sk_pathbuilder_move_to() call has been made for this contour, the first point is automatically set to (0,0). */ -SK_API void sk_path_line_to(sk_path_t*, float x, float y); +SK_API void sk_pathbuilder_line_to(sk_pathbuilder_t*, float x, float y); /** Add a quadratic bezier from the last point, approaching control - point (x0,y0), and ending at (x1,y1). If no sk_path_move_to() call + point (x0,y0), and ending at (x1,y1). If no sk_pathbuilder_move_to() call has been made for this contour, the first point is automatically set to (0,0). */ -SK_API void sk_path_quad_to(sk_path_t*, float x0, float y0, float x1, float y1); +SK_API void sk_pathbuilder_quad_to(sk_pathbuilder_t*, float x0, float y0, float x1, float y1); /** Add a conic curve from the last point, approaching control point (x0,y01), and ending at (x1,y1) with weight w. If no - sk_path_move_to() call has been made for this contour, the first + sk_pathbuilder_move_to() call has been made for this contour, the first point is automatically set to (0,0). */ -SK_API void sk_path_conic_to(sk_path_t*, float x0, float y0, float x1, float y1, float w); +SK_API void sk_pathbuilder_conic_to(sk_pathbuilder_t*, float x0, float y0, float x1, float y1, float w); /** Add a cubic bezier from the last point, approaching control points (x0,y0) and (x1,y1), and ending at (x2,y2). If no - sk_path_move_to() call has been made for this contour, the first + sk_pathbuilder_move_to() call has been made for this contour, the first point is automatically set to (0,0). */ -SK_API void sk_path_cubic_to(sk_path_t*, +SK_API void sk_pathbuilder_cubic_to(sk_pathbuilder_t*, float x0, float y0, float x1, float y1, float x2, float y2); @@ -61,16 +64,31 @@ SK_API void sk_path_cubic_to(sk_path_t*, Close the current contour. If the current point is not equal to the first point of the contour, a line segment is automatically added. */ -SK_API void sk_path_close(sk_path_t*); +SK_API void sk_pathbuilder_close(sk_pathbuilder_t*); /** Add a closed rectangle contour to the path. */ -SK_API void sk_path_add_rect(sk_path_t*, const sk_rect_t*, sk_path_direction_t); +SK_API void sk_pathbuilder_add_rect(sk_pathbuilder_t*, const sk_rect_t*, sk_path_direction_t); /** Add a closed oval contour to the path */ -SK_API void sk_path_add_oval(sk_path_t*, const sk_rect_t*, sk_path_direction_t); +SK_API void sk_pathbuilder_add_oval(sk_pathbuilder_t*, const sk_rect_t*, sk_path_direction_t); + +/**** path *****/ + +/** +* Return a Path from the builder, resetting the builder to its original empty state. +*/ +SK_API sk_path_t* sk_pathbuilder_detach_path(sk_pathbuilder_t*); + +/** + * Return a Path from the builder. The builder reamins in its current state. + */ +SK_API sk_path_t* sk_pathbuilder_snapshot_path(sk_pathbuilder_t*); + +/** Release the memory used by a sk_path_t. */ +SK_API void sk_path_delete(sk_path_t*); /** * If the path is empty, return false and set the rect parameter to [0, 0, 0, 0]. diff --git a/modules/skottie/src/layers/shapelayer/Polystar.cpp b/modules/skottie/src/layers/shapelayer/Polystar.cpp index 60b56490b9..3e90363481 100644 --- a/modules/skottie/src/layers/shapelayer/Polystar.cpp +++ b/modules/skottie/src/layers/shapelayer/Polystar.cpp @@ -5,6 +5,7 @@ * found in the LICENSE file. */ +#include "include/core/SkPathBuilder.h" #include "modules/skottie/src/Adapter.h" #include "modules/skottie/src/SkottieJson.h" #include "modules/skottie/src/SkottiePriv.h" @@ -49,7 +50,7 @@ private: // TODO: inner/outer "roundness"? - SkPath poly; + SkPathBuilder poly; auto angle = SkDegreesToRadians(fRotation - 90); poly.moveTo(pt_on_circle(fPosition, fOuterRadius, angle)); @@ -64,7 +65,7 @@ private: } poly.close(); - this->node()->setPath(poly); + this->node()->setPath(poly.detach()); } const Type fType; diff --git a/src/c/sk_surface.cpp b/src/c/sk_surface.cpp index ca4c51f2e9..9afc0e3840 100644 --- a/src/c/sk_surface.cpp +++ b/src/c/sk_surface.cpp @@ -11,7 +11,7 @@ #include "include/core/SkMaskFilter.h" #include "include/core/SkMatrix.h" #include "include/core/SkPaint.h" -#include "include/core/SkPath.h" +#include "include/core/SkPathBuilder.h" #include "include/core/SkPictureRecorder.h" #include "include/core/SkSurface.h" @@ -94,6 +94,10 @@ static const SkPath& AsPath(const sk_path_t& cpath) { return reinterpret_cast(cpath); } +static SkPathBuilder* as_pathbuilder(sk_pathbuilder_t* cbuilder) { + return reinterpret_cast(cbuilder); +} + static SkPath* as_path(sk_path_t* cpath) { return reinterpret_cast(cpath); } @@ -172,50 +176,65 @@ uint32_t sk_image_get_unique_id(const sk_image_t* cimage) { /////////////////////////////////////////////////////////////////////////////////////////// -sk_path_t* sk_path_new() { return (sk_path_t*)new SkPath; } +sk_pathbuilder_t* sk_pathbuilder_new() { return (sk_pathbuilder_t*)new SkPathBuilder; } + +void sk_pathbuilder_delete(sk_pathbuilder_t* cbuilder) { delete as_pathbuilder(cbuilder); } + +void sk_pathbuilder_move_to(sk_pathbuilder_t* cbuilder, float x, float y) { + as_pathbuilder(cbuilder)->moveTo(x, y); +} + +void sk_pathbuilder_line_to(sk_pathbuilder_t* cbuilder, float x, float y) { + as_pathbuilder(cbuilder)->lineTo(x, y); +} + +void sk_pathbuilder_quad_to(sk_pathbuilder_t* cbuilder, + float x0, float y0, float x1, float y1) { + as_pathbuilder(cbuilder)->quadTo(x0, y0, x1, y1); +} + +void sk_pathbuilder_conic_to(sk_pathbuilder_t* cbuilder, + float x0, float y0, float x1, float y1, float w) { + as_pathbuilder(cbuilder)->conicTo(x0, y0, x1, y1, w); +} + +void sk_pathbuilder_cubic_to(sk_pathbuilder_t* cbuilder, + float x0, float y0, float x1, float y1, float x2, float y2) { + as_pathbuilder(cbuilder)->cubicTo(x0, y0, x1, y1, x2, y2); +} + +void sk_pathbuilder_close(sk_pathbuilder_t* cbuilder) { + as_pathbuilder(cbuilder)->close(); +} + +void sk_pathbuilder_add_rect(sk_pathbuilder_t* cbuilder, const sk_rect_t* crect, sk_path_direction_t cdir) { + SkPathDirection dir; + if (!from_c_path_direction(cdir, &dir)) { + return; + } + as_pathbuilder(cbuilder)->addRect(AsRect(*crect), dir); +} + +void sk_pathbuilder_add_oval(sk_pathbuilder_t* cbuilder, const sk_rect_t* crect, sk_path_direction_t cdir) { + SkPathDirection dir; + if (!from_c_path_direction(cdir, &dir)) { + return; + } + as_pathbuilder(cbuilder)->addOval(AsRect(*crect), dir); +} + +sk_path_t* sk_pathbuilder_detach_path(sk_pathbuilder_t* cbuilder) { + return (sk_path_t*)(new SkPath(as_pathbuilder(cbuilder)->detach())); +} + +sk_path_t* sk_pathbuilder_snapshot_path(sk_pathbuilder_t* cbuilder) { + return (sk_path_t*)(new SkPath(as_pathbuilder(cbuilder)->snapshot())); +} + +////////////////////////////////////////////////////////////////////////////////////////////////// void sk_path_delete(sk_path_t* cpath) { delete as_path(cpath); } -void sk_path_move_to(sk_path_t* cpath, float x, float y) { - as_path(cpath)->moveTo(x, y); -} - -void sk_path_line_to(sk_path_t* cpath, float x, float y) { - as_path(cpath)->lineTo(x, y); -} - -void sk_path_quad_to(sk_path_t* cpath, float x0, float y0, float x1, float y1) { - as_path(cpath)->quadTo(x0, y0, x1, y1); -} - -void sk_path_conic_to(sk_path_t* cpath, float x0, float y0, float x1, float y1, float w) { - as_path(cpath)->conicTo(x0, y0, x1, y1, w); -} - -void sk_path_cubic_to(sk_path_t* cpath, float x0, float y0, float x1, float y1, float x2, float y2) { - as_path(cpath)->cubicTo(x0, y0, x1, y1, x2, y2); -} - -void sk_path_close(sk_path_t* cpath) { - as_path(cpath)->close(); -} - -void sk_path_add_rect(sk_path_t* cpath, const sk_rect_t* crect, sk_path_direction_t cdir) { - SkPathDirection dir; - if (!from_c_path_direction(cdir, &dir)) { - return; - } - as_path(cpath)->addRect(AsRect(*crect), dir); -} - -void sk_path_add_oval(sk_path_t* cpath, const sk_rect_t* crect, sk_path_direction_t cdir) { - SkPathDirection dir; - if (!from_c_path_direction(cdir, &dir)) { - return; - } - as_path(cpath)->addOval(AsRect(*crect), dir); -} - bool sk_path_get_bounds(const sk_path_t* cpath, sk_rect_t* crect) { const SkPath& path = AsPath(*cpath); diff --git a/tools/ToolUtils.cpp b/tools/ToolUtils.cpp index c91b981c8c..392820dd74 100644 --- a/tools/ToolUtils.cpp +++ b/tools/ToolUtils.cpp @@ -12,7 +12,7 @@ #include "include/core/SkImage.h" #include "include/core/SkMatrix.h" #include "include/core/SkPaint.h" -#include "include/core/SkPath.h" +#include "include/core/SkPathBuilder.h" #include "include/core/SkPixelRef.h" #include "include/core/SkPixmap.h" #include "include/core/SkPoint3.h" @@ -235,16 +235,17 @@ void get_text_path(const SkFont& font, SkPath make_star(const SkRect& bounds, int numPts, int step) { SkASSERT(numPts != step); - SkPath path; - path.setFillType(SkPathFillType::kEvenOdd); - path.moveTo(0, -1); + SkPathBuilder builder; + builder.setFillType(SkPathFillType::kEvenOdd); + builder.moveTo(0, -1); for (int i = 1; i < numPts; ++i) { int idx = i * step % numPts; SkScalar theta = idx * 2 * SK_ScalarPI / numPts + SK_ScalarPI / 2; SkScalar x = SkScalarCos(theta); SkScalar y = -SkScalarSin(theta); - path.lineTo(x, y); + builder.lineTo(x, y); } + SkPath path = builder.detach(); path.transform(SkMatrix::MakeRectToRect(path.getBounds(), bounds, SkMatrix::kFill_ScaleToFit)); return path; }