use pathbuilder
Change-Id: Icb4d3f98440b53ba38270cc1f43fc43e6724d36b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/315736
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>
diff --git a/gm/complexclip.cpp b/gm/complexclip.cpp
index 4a7e0ec..368e3ea 100644
--- a/gm/complexclip.cpp
+++ b/gm/complexclip.cpp
@@ -12,7 +12,7 @@
#include "include/core/SkFont.h"
#include "include/core/SkFontTypes.h"
#include "include/core/SkPaint.h"
-#include "include/core/SkPath.h"
+#include "include/core/SkPathBuilder.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
@@ -54,21 +54,22 @@
SkISize onISize() override { return SkISize::Make(388, 780); }
void onDraw(SkCanvas* canvas) override {
- SkPath path;
- path.moveTo(0, 50)
- .quadTo(0, 0, 50, 0)
- .lineTo(175, 0)
- .quadTo(200, 0, 200, 25)
- .lineTo(200, 150)
- .quadTo(200, 200, 150, 200)
- .lineTo(0, 200)
- .close()
- .moveTo(50, 50)
- .lineTo(150, 50)
- .lineTo(150, 125)
- .quadTo(150, 150, 125, 150)
- .lineTo(50, 150)
- .close();
+ SkPath path = SkPathBuilder()
+ .moveTo(0, 50)
+ .quadTo(0, 0, 50, 0)
+ .lineTo(175, 0)
+ .quadTo(200, 0, 200, 25)
+ .lineTo(200, 150)
+ .quadTo(200, 200, 150, 200)
+ .lineTo(0, 200)
+ .close()
+ .moveTo(50, 50)
+ .lineTo(150, 50)
+ .lineTo(150, 125)
+ .quadTo(150, 150, 125, 150)
+ .lineTo(50, 150)
+ .close()
+ .detach();
if (fInvertDraw) {
path.setFillType(SkPathFillType::kInverseEvenOdd);
} else {
@@ -78,11 +79,9 @@
pathPaint.setAntiAlias(true);
pathPaint.setColor(gPathColor);
- SkPath clipA;
- clipA.addPoly({{10, 20}, {165, 22}, {70, 105}, {165, 177}, {-5, 180}}, false).close();
+ SkPath clipA = SkPath::Polygon({{10, 20}, {165, 22}, {70, 105}, {165, 177}, {-5, 180}}, true);
- SkPath clipB;
- clipB.addPoly({{40, 10}, {190, 15}, {195, 190}, {40, 185}, {155, 100}}, false).close();
+ SkPath clipB = SkPath::Polygon({{40, 10}, {190, 15}, {195, 190}, {40, 185}, {155, 100}}, true);
SkFont font(ToolUtils::create_portable_typeface(), 20);
diff --git a/gm/convexpolyclip.cpp b/gm/convexpolyclip.cpp
index 3e78054..0953ee7 100644
--- a/gm/convexpolyclip.cpp
+++ b/gm/convexpolyclip.cpp
@@ -207,8 +207,7 @@
canvas->save();
}
canvas->translate(x, y);
- SkPath closedClipPath;
- clip->asClosedPath(&closedClipPath);
+ SkPath closedClipPath = clip->asClosedPath();
canvas->drawPath(closedClipPath, clipOutlinePaint);
clip->setOnCanvas(canvas, kIntersect_SkClipOp, SkToBool(aa));
canvas->scale(1.f, 1.8f);
@@ -240,7 +239,7 @@
void setOnCanvas(SkCanvas* canvas, SkClipOp op, bool aa) const {
switch (fClipType) {
case kPath_ClipType:
- canvas->clipPath(fPath, op, aa);
+ canvas->clipPath(fPathBuilder.snapshot(), op, aa);
break;
case kRect_ClipType:
canvas->clipRect(fRect, op, aa);
@@ -251,31 +250,29 @@
}
}
- void asClosedPath(SkPath* path) const {
+ SkPath asClosedPath() const {
switch (fClipType) {
case kPath_ClipType:
- *path = fPath;
- path->close();
+ return SkPathBuilder(fPathBuilder).close().detach();
break;
case kRect_ClipType:
- path->reset();
- path->addRect(fRect);
- break;
+ return SkPath::Rect(fRect);
case kNone_ClipType:
SkDEBUGFAIL("Uninitialized Clip.");
break;
}
+ return SkPath();
}
void setPath(const SkPath& path) {
fClipType = kPath_ClipType;
- fPath = path;
+ fPathBuilder = path;
}
void setRect(const SkRect& rect) {
fClipType = kRect_ClipType;
fRect = rect;
- fPath.reset();
+ fPathBuilder.reset();
}
ClipType getType() const { return fClipType; }
@@ -283,7 +280,7 @@
void getBounds(SkRect* bounds) const {
switch (fClipType) {
case kPath_ClipType:
- *bounds = fPath.getBounds();
+ *bounds = fPathBuilder.computeBounds();
break;
case kRect_ClipType:
*bounds = fRect;
@@ -296,7 +293,7 @@
private:
ClipType fClipType;
- SkPath fPath;
+ SkPathBuilder fPathBuilder;
SkRect fRect;
};
diff --git a/include/core/SkPathBuilder.h b/include/core/SkPathBuilder.h
index 79941957..0cda81d 100644
--- a/include/core/SkPathBuilder.h
+++ b/include/core/SkPathBuilder.h
@@ -16,9 +16,18 @@
class SK_API SkPathBuilder {
public:
SkPathBuilder();
+ SkPathBuilder(SkPathFillType);
+ SkPathBuilder(const SkPath&);
+ SkPathBuilder(const SkPathBuilder&) = default;
~SkPathBuilder();
- SkPath snapshot(); // the builder is unchanged after returning this path
+ SkPathBuilder& operator=(const SkPath&);
+ SkPathBuilder& operator=(const SkPathBuilder&) = default;
+
+ SkPathFillType fillType() const { return fFillType; }
+ SkRect computeBounds() const;
+
+ SkPath snapshot() const; // the builder is unchanged after returning this path
SkPath detach(); // the builder is reset to empty after returning this path
SkPathBuilder& setFillType(SkPathFillType ft) { fFillType = ft; return *this; }
diff --git a/src/core/SkPathBuilder.cpp b/src/core/SkPathBuilder.cpp
index 9d442db..6a300ea 100644
--- a/src/core/SkPathBuilder.cpp
+++ b/src/core/SkPathBuilder.cpp
@@ -18,6 +18,10 @@
this->reset();
}
+SkPathBuilder::SkPathBuilder(const SkPath& src) {
+ *this = src;
+}
+
SkPathBuilder::~SkPathBuilder() {
}
@@ -40,11 +44,33 @@
return *this;
}
+SkPathBuilder& SkPathBuilder::operator=(const SkPath& src) {
+ this->reset().setFillType(src.getFillType());
+
+ for (auto [verb, pts, w] : SkPathPriv::Iterate(src)) {
+ switch (verb) {
+ case SkPathVerb::kMove: this->moveTo(pts[0]); break;
+ case SkPathVerb::kLine: this->lineTo(pts[1]); break;
+ case SkPathVerb::kQuad: this->quadTo(pts[1], pts[2]); break;
+ case SkPathVerb::kConic: this->conicTo(pts[1], pts[2], w[0]); break;
+ case SkPathVerb::kCubic: this->cubicTo(pts[1], pts[2], pts[3]); break;
+ case SkPathVerb::kClose: this->close(); break;
+ }
+ }
+ return *this;
+}
+
void SkPathBuilder::incReserve(int extraPtCount, int extraVbCount) {
fPts.setReserve( Sk32_sat_add(fPts.count(), extraPtCount));
fVerbs.setReserve(Sk32_sat_add(fVerbs.count(), extraVbCount));
}
+SkRect SkPathBuilder::computeBounds() const {
+ SkRect bounds;
+ bounds.setBounds(fPts.begin(), fPts.count());
+ return bounds;
+}
+
/*
* Some old behavior in SkPath -- should we keep it?
*
@@ -178,7 +204,7 @@
return SkPath(std::move(pr), fFillType, fIsVolatile, convexity, dir);
}
-SkPath SkPathBuilder::snapshot() {
+SkPath SkPathBuilder::snapshot() const {
return this->make(sk_sp<SkPathRef>(new SkPathRef(fPts,
fVerbs,
fConicWeights,
diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp
index 5049523..30c8fec 100644
--- a/src/gpu/GrReducedClip.cpp
+++ b/src/gpu/GrReducedClip.cpp
@@ -675,10 +675,10 @@
return ClipResult::kClipped;
}
- SkPath deviceSpacePath;
+ SkPathBuilder deviceSpacePath;
deviceSpacePath.setIsVolatile(true);
deviceSpacePath.addRRect(deviceSpaceRRect);
- return this->addAnalyticPath(deviceSpacePath, invert, aa);
+ return this->addAnalyticPath(deviceSpacePath.detach(), invert, aa);
}
GrReducedClip::ClipResult GrReducedClip::addAnalyticPath(const SkPath& deviceSpacePath,
diff --git a/src/gpu/GrTestUtils.cpp b/src/gpu/GrTestUtils.cpp
index d60a358..5b51215 100644
--- a/src/gpu/GrTestUtils.cpp
+++ b/src/gpu/GrTestUtils.cpp
@@ -8,7 +8,7 @@
#include "src/gpu/GrTestUtils.h"
#include "include/core/SkMatrix.h"
-#include "include/core/SkPath.h"
+#include "include/core/SkPathBuilder.h"
#include "include/core/SkRRect.h"
#include "src/core/SkRectPriv.h"
#include "src/gpu/GrColorInfo.h"
@@ -168,36 +168,43 @@
if (!gOnce) {
gOnce = true;
// line
- gPath[0].moveTo(0.f, 0.f);
- gPath[0].lineTo(10.f, 10.f);
+ gPath[0] = SkPathBuilder().moveTo(0.f, 0.f)
+ .lineTo(10.f, 10.f)
+ .detach();
// quad
- gPath[1].moveTo(0.f, 0.f);
- gPath[1].quadTo(10.f, 10.f, 20.f, 20.f);
+ gPath[1] = SkPathBuilder().moveTo(0.f, 0.f)
+ .quadTo(10.f, 10.f, 20.f, 20.f)
+ .detach();
// conic
- gPath[2].moveTo(0.f, 0.f);
- gPath[2].conicTo(10.f, 10.f, 20.f, 20.f, 1.f);
+ gPath[2] = SkPathBuilder().moveTo(0.f, 0.f)
+ .conicTo(10.f, 10.f, 20.f, 20.f, 1.f)
+ .detach();
// cubic
- gPath[3].moveTo(0.f, 0.f);
- gPath[3].cubicTo(10.f, 10.f, 20.f, 20.f, 30.f, 30.f);
+ gPath[3] = SkPathBuilder().moveTo(0.f, 0.f)
+ .cubicTo(10.f, 10.f, 20.f, 20.f, 30.f, 30.f)
+ .detach();
// all three
- gPath[4].moveTo(0.f, 0.f);
- gPath[4].lineTo(10.f, 10.f);
- gPath[4].quadTo(10.f, 10.f, 20.f, 20.f);
- gPath[4].conicTo(10.f, 10.f, 20.f, 20.f, 1.f);
- gPath[4].cubicTo(10.f, 10.f, 20.f, 20.f, 30.f, 30.f);
+ gPath[4] = SkPathBuilder().moveTo(0.f, 0.f)
+ .lineTo(10.f, 10.f)
+ .quadTo(10.f, 10.f, 20.f, 20.f)
+ .conicTo(10.f, 10.f, 20.f, 20.f, 1.f)
+ .cubicTo(10.f, 10.f, 20.f, 20.f, 30.f, 30.f)
+ .detach();
// convex
- gPath[5].moveTo(0.0f, 0.0f);
- gPath[5].lineTo(10.0f, 0.0f);
- gPath[5].lineTo(10.0f, 10.0f);
- gPath[5].lineTo(0.0f, 10.0f);
- gPath[5].close();
+ gPath[5] = SkPathBuilder().moveTo(0.0f, 0.0f)
+ .lineTo(10.0f, 0.0f)
+ .lineTo(10.0f, 10.0f)
+ .lineTo(0.0f, 10.0f)
+ .close()
+ .detach();
// concave
- gPath[6].moveTo(0.0f, 0.0f);
- gPath[6].lineTo(5.0f, 5.0f);
- gPath[6].lineTo(10.0f, 0.0f);
- gPath[6].lineTo(10.0f, 10.0f);
- gPath[6].lineTo(0.0f, 10.0f);
- gPath[6].close();
+ gPath[6] = SkPathBuilder().moveTo(0.0f, 0.0f)
+ .lineTo(5.0f, 5.0f)
+ .lineTo(10.0f, 0.0f)
+ .lineTo(10.0f, 10.0f)
+ .lineTo(0.0f, 10.0f)
+ .close()
+ .detach();
}
return gPath[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gPath)))];
@@ -209,25 +216,25 @@
if (!gOnce) {
gOnce = true;
// narrow rect
- gPath[0].moveTo(-1.5f, -50.0f);
- gPath[0].lineTo(-1.5f, -50.0f);
- gPath[0].lineTo( 1.5f, -50.0f);
- gPath[0].lineTo( 1.5f, 50.0f);
- gPath[0].lineTo(-1.5f, 50.0f);
+ gPath[0] = SkPath::Polygon({{-1.5f, -50.0f},
+ {-1.5f, -50.0f},
+ { 1.5f, -50.0f},
+ { 1.5f, 50.0f},
+ {-1.5f, 50.0f}}, false);
// degenerate
- gPath[1].moveTo(-0.025f, -0.025f);
- gPath[1].lineTo(-0.025f, -0.025f);
- gPath[1].lineTo( 0.025f, -0.025f);
- gPath[1].lineTo( 0.025f, 0.025f);
- gPath[1].lineTo(-0.025f, 0.025f);
+ gPath[1] = SkPath::Polygon({{-0.025f, -0.025f},
+ {-0.025f, -0.025f},
+ { 0.025f, -0.025f},
+ { 0.025f, 0.025f},
+ {-0.025f, 0.025f}}, false);
// clipped triangle
- gPath[2].moveTo(-10.0f, -50.0f);
- gPath[2].lineTo(-10.0f, -50.0f);
- gPath[2].lineTo( 10.0f, -50.0f);
- gPath[2].lineTo( 50.0f, 31.0f);
- gPath[2].lineTo( 40.0f, 50.0f);
- gPath[2].lineTo(-40.0f, 50.0f);
- gPath[2].lineTo(-50.0f, 31.0f);
+ gPath[2] = SkPath::Polygon({{-10.0f, -50.0f},
+ {-10.0f, -50.0f},
+ { 10.0f, -50.0f},
+ { 50.0f, 31.0f},
+ { 40.0f, 50.0f},
+ {-40.0f, 50.0f},
+ {-50.0f, 31.0f}}, false);
for (size_t i = 0; i < SK_ARRAY_COUNT(gPath); i++) {
SkASSERT(gPath[i].isConvex());
diff --git a/src/utils/SkLua.cpp b/src/utils/SkLua.cpp
index bba28f9..958e645 100644
--- a/src/utils/SkLua.cpp
+++ b/src/utils/SkLua.cpp
@@ -20,7 +20,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/SkPictureRecorder.h"
#include "include/core/SkRRect.h"
#include "include/core/SkString.h"
@@ -62,6 +62,7 @@
DEF_MTNAME(SkRRect)
DEF_MTNAME(SkPath)
DEF_MTNAME(SkPaint)
+DEF_MTNAME(SkPathBuilder)
DEF_MTNAME(SkPathEffect)
DEF_MTNAME(SkPicture)
DEF_MTNAME(SkPictureRecorder)
@@ -530,7 +531,7 @@
}
static int lcanvas_drawPath(lua_State* L) {
- get_ref<SkCanvas>(L, 1)->drawPath(*get_obj<SkPath>(L, 2),
+ get_ref<SkCanvas>(L, 1)->drawPath(get_obj<SkPathBuilder>(L, 2)->snapshot(),
*get_obj<SkPaint>(L, 3));
return 0;
}
@@ -879,19 +880,6 @@
return 0;
}
-static int lpaint_getFillPath(lua_State* L) {
- const SkPaint* paint = get_obj<SkPaint>(L, 1);
- const SkPath* path = get_obj<SkPath>(L, 2);
-
- SkPath fillpath;
- paint->getFillPath(*path, &fillpath);
-
- SkLua lua(L);
- lua.pushPath(fillpath);
-
- return 1;
-}
-
static int lpaint_gc(lua_State* L) {
get_obj<SkPaint>(L, 1)->~SkPaint();
return 0;
@@ -923,7 +911,6 @@
{ "getShader", lpaint_getShader },
{ "setShader", lpaint_setShader },
{ "getPathEffect", lpaint_getPathEffect },
- { "getFillPath", lpaint_getFillPath },
{ "__gc", lpaint_gc },
{ nullptr, nullptr }
};
@@ -1243,7 +1230,7 @@
///////////////////////////////////////////////////////////////////////////////
static int lpath_getBounds(lua_State* L) {
- SkLua(L).pushRect(get_obj<SkPath>(L, 1)->getBounds());
+ SkLua(L).pushRect(get_obj<SkPathBuilder>(L, 1)->computeBounds());
return 1;
}
@@ -1262,7 +1249,7 @@
}
static int lpath_getFillType(lua_State* L) {
- SkPathFillType fill = get_obj<SkPath>(L, 1)->getFillType();
+ SkPathFillType fill = get_obj<SkPathBuilder>(L, 1)->fillType();
SkLua(L).pushString(fill_type_to_str(fill));
return 1;
}
@@ -1303,25 +1290,25 @@
}
static int lpath_getSegmentTypes(lua_State* L) {
- uint32_t segMasks = get_obj<SkPath>(L, 1)->getSegmentMasks();
+ uint32_t segMasks = get_obj<SkPathBuilder>(L, 1)->snapshot().getSegmentMasks();
SkLua(L).pushString(segment_masks_to_str(segMasks));
return 1;
}
static int lpath_isConvex(lua_State* L) {
- bool isConvex = get_obj<SkPath>(L, 1)->isConvex();
+ bool isConvex = get_obj<SkPathBuilder>(L, 1)->snapshot().isConvex();
SkLua(L).pushBool(isConvex);
return 1;
}
static int lpath_isEmpty(lua_State* L) {
- lua_pushboolean(L, get_obj<SkPath>(L, 1)->isEmpty());
+ lua_pushboolean(L, get_obj<SkPathBuilder>(L, 1)->snapshot().isEmpty());
return 1;
}
static int lpath_isRect(lua_State* L) {
SkRect r;
- bool pred = get_obj<SkPath>(L, 1)->isRect(&r);
+ bool pred = get_obj<SkPathBuilder>(L, 1)->snapshot().isRect(&r);
int ret_count = 1;
lua_pushboolean(L, pred);
if (pred) {
@@ -1332,13 +1319,13 @@
}
static int lpath_countPoints(lua_State* L) {
- lua_pushinteger(L, get_obj<SkPath>(L, 1)->countPoints());
+ lua_pushinteger(L, get_obj<SkPathBuilder>(L, 1)->snapshot().countPoints());
return 1;
}
static int lpath_getVerbs(lua_State* L) {
- const SkPath* path = get_obj<SkPath>(L, 1);
- SkPath::Iter iter(*path, false);
+ SkPath path = get_obj<SkPathBuilder>(L, 1)->snapshot();
+ SkPath::Iter iter(path, false);
SkPoint pts[4];
lua_newtable(L);
@@ -1376,40 +1363,40 @@
}
static int lpath_reset(lua_State* L) {
- get_obj<SkPath>(L, 1)->reset();
+ get_obj<SkPathBuilder>(L, 1)->reset();
return 0;
}
static int lpath_moveTo(lua_State* L) {
- get_obj<SkPath>(L, 1)->moveTo(lua2scalar(L, 2), lua2scalar(L, 3));
+ get_obj<SkPathBuilder>(L, 1)->moveTo(lua2scalar(L, 2), lua2scalar(L, 3));
return 0;
}
static int lpath_lineTo(lua_State* L) {
- get_obj<SkPath>(L, 1)->lineTo(lua2scalar(L, 2), lua2scalar(L, 3));
+ get_obj<SkPathBuilder>(L, 1)->lineTo(lua2scalar(L, 2), lua2scalar(L, 3));
return 0;
}
static int lpath_quadTo(lua_State* L) {
- get_obj<SkPath>(L, 1)->quadTo(lua2scalar(L, 2), lua2scalar(L, 3),
+ get_obj<SkPathBuilder>(L, 1)->quadTo(lua2scalar(L, 2), lua2scalar(L, 3),
lua2scalar(L, 4), lua2scalar(L, 5));
return 0;
}
static int lpath_cubicTo(lua_State* L) {
- get_obj<SkPath>(L, 1)->cubicTo(lua2scalar(L, 2), lua2scalar(L, 3),
+ get_obj<SkPathBuilder>(L, 1)->cubicTo(lua2scalar(L, 2), lua2scalar(L, 3),
lua2scalar(L, 4), lua2scalar(L, 5),
lua2scalar(L, 6), lua2scalar(L, 7));
return 0;
}
static int lpath_close(lua_State* L) {
- get_obj<SkPath>(L, 1)->close();
+ get_obj<SkPathBuilder>(L, 1)->close();
return 0;
}
static int lpath_gc(lua_State* L) {
- get_obj<SkPath>(L, 1)->~SkPath();
+ get_obj<SkPathBuilder>(L, 1)->~SkPathBuilder();
return 0;
}
@@ -1824,7 +1811,7 @@
}
static int lsk_newPath(lua_State* L) {
- push_new<SkPath>(L);
+ push_new<SkPathBuilder>(L);
return 1;
}