use pathbuilder

Change-Id: I4b40107b45cd829595e89d75e19fd063acee4221
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/311106
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
Mike Reed 2020-08-17 14:14:13 -04:00 committed by Skia Commit-Bot
parent f5931f3399
commit e9d783c4d2
19 changed files with 261 additions and 249 deletions

View File

@ -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) {

View File

@ -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);
}

View File

@ -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();

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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;

View File

@ -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].

View File

@ -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;

View File

@ -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<const SkPath&>(cpath);
}
static SkPathBuilder* as_pathbuilder(sk_pathbuilder_t* cbuilder) {
return reinterpret_cast<SkPathBuilder*>(cbuilder);
}
static SkPath* as_path(sk_path_t* cpath) {
return reinterpret_cast<SkPath*>(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);

View File

@ -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;
}