Start to migrate pathops to builder Change-Id: Ie95aeaa9154ba924db0fa400d50c9b80f5ac30c2 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1056517 Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Mike Reed <mike@reedtribe.org> Reviewed-by: Florin Malita <fmalita@google.com>
diff --git a/src/core/SkPathPriv.h b/src/core/SkPathPriv.h index e8c12cd..804bc1f 100644 --- a/src/core/SkPathPriv.h +++ b/src/core/SkPathPriv.h
@@ -408,6 +408,10 @@ builder->privateReverseAddPath(reverseMe); } + static void ReversePathTo(SkPathBuilder* builder, const SkPath& reverseMe) { + builder->privateReversePathTo(reverseMe); + } + static std::optional<SkPoint> GetPoint(const SkPathBuilder& builder, int index) { if ((unsigned)index < (unsigned)builder.fPts.size()) { return builder.fPts.at(index);
diff --git a/src/pathops/SkOpBuilder.cpp b/src/pathops/SkOpBuilder.cpp index 3fea4e9..f9c72ed 100644 --- a/src/pathops/SkOpBuilder.cpp +++ b/src/pathops/SkOpBuilder.cpp
@@ -105,8 +105,8 @@ path->setFillType(fillType); return true; } - SkPath empty; - SkPathWriter woundPath(empty); + + SkPathWriter woundPath(fillType); SkOpContour* test = &contourHead; do { if (!test->count()) { @@ -118,8 +118,7 @@ test->toPath(&woundPath); } } while ((test = test->next())); - *path = *woundPath.nativePath(); - path->setFillType(fillType); + *path = woundPath.nativePath(); return true; }
diff --git a/src/pathops/SkOpEdgeBuilder.h b/src/pathops/SkOpEdgeBuilder.h index 7c01756..1b5e1bb 100644 --- a/src/pathops/SkOpEdgeBuilder.h +++ b/src/pathops/SkOpEdgeBuilder.h
@@ -20,16 +20,6 @@ class SkOpEdgeBuilder { public: - SkOpEdgeBuilder(const SkPathWriter& path, SkOpContourHead* contours2, - SkOpGlobalState* globalState) - : fGlobalState(globalState) - , fPath(path.nativePath()) - , fContourBuilder(contours2) - , fContoursHead(contours2) - , fAllowOpenContours(true) { - init(); - } - SkOpEdgeBuilder(const SkPath& path, SkOpContourHead* contours2, SkOpGlobalState* globalState) : fGlobalState(globalState) , fPath(&path)
diff --git a/src/pathops/SkPathOpsOp.cpp b/src/pathops/SkPathOpsOp.cpp index ad7665f..4389248 100644 --- a/src/pathops/SkPathOpsOp.cpp +++ b/src/pathops/SkPathOpsOp.cpp
@@ -358,15 +358,12 @@ contourList->dumpSegments("aligned"); #endif // construct closed contours - SkPath original = *result; - result->reset(); - result->setFillType(fillType); - SkPathWriter wrapper(*result); + SkPathWriter wrapper(fillType); if (!bridgeOp(contourList, op, xorMask, xorOpMask, &wrapper)) { - *result = original; return false; } wrapper.assemble(); // if some edges could not be resolved, assemble remaining + *result = wrapper.nativePath(); #if DEBUG_T_SECT_LOOP_COUNT static SkMutex& debugWorstLoop = *(new SkMutex); {
diff --git a/src/pathops/SkPathOpsSimplify.cpp b/src/pathops/SkPathOpsSimplify.cpp index ae45680..a78bf06 100644 --- a/src/pathops/SkPathOpsSimplify.cpp +++ b/src/pathops/SkPathOpsSimplify.cpp
@@ -266,14 +266,13 @@ contour.dumpSegments("aligned"); #endif // construct closed contours - result->reset(); - result->setFillType(fillType); - SkPathWriter wrapper(*result); + SkPathWriter wrapper(fillType); if (builder.xorMask() == kWinding_PathOpsMask ? !bridgeWinding(contourList, &wrapper) : !bridgeXor(contourList, &wrapper)) { return false; } wrapper.assemble(); // if some edges could not be resolved, assemble remaining + *result = wrapper.nativePath(); return true; }
diff --git a/src/pathops/SkPathWriter.cpp b/src/pathops/SkPathWriter.cpp index 1f88fd4..4c6a550 100644 --- a/src/pathops/SkPathWriter.cpp +++ b/src/pathops/SkPathWriter.cpp
@@ -9,6 +9,7 @@ #include "include/core/SkTypes.h" #include "include/private/base/SkMath.h" #include "src/base/SkTSort.h" +#include "src/core/SkPathPriv.h" #include "src/pathops/SkOpSegment.h" #include "src/pathops/SkOpSpan.h" #include "src/pathops/SkPathOpsDebug.h" @@ -16,10 +17,7 @@ using namespace skia_private; -// wrap path to keep track of whether the contour is initialized and non-empty -SkPathWriter::SkPathWriter(SkPath& path) - : fPathPtr(&path) -{ +SkPathWriter::SkPathWriter(SkPathFillType ft) : fBuilder(ft) { init(); } @@ -32,7 +30,7 @@ SkDebugf("path.close();\n"); #endif fCurrent.close(); - fPathPtr->addPath(fCurrent); + fBuilder.addPath(fCurrent); fCurrent.reset(); init(); } @@ -228,8 +226,7 @@ // lengthen any partial contour adjacent to a simple segment for (int pIndex = 0; pIndex < endCount; pIndex++) { SkOpPtT* opPtT = const_cast<SkOpPtT*>(runs[pIndex]); - SkPath p; - SkPathWriter partWriter(p); + SkPathWriter partWriter(SkPathFillType::kDefault); do { if (!zero_or_one(opPtT->fT)) { break; @@ -356,16 +353,17 @@ do { const SkPath& contour = fPartials[rIndex]; if (!first) { - SkPoint prior, next; - if (!fPathPtr->getLastPt(&prior)) { + auto prior = fBuilder.getLastPt(); + if (!prior) { return; } + SkPoint next; if (forward) { next = contour.getPoint(0); } else { SkAssertResult(contour.getLastPt(&next)); } - if (prior != next) { + if (*prior != next) { /* TODO: if there is a gap between open path written so far and path to come, connect by following segments from one to the other, rather than introducing a diagonal to connect the two. @@ -373,11 +371,11 @@ } } if (forward) { - fPathPtr->addPath(contour, + fBuilder.addPath(contour, first ? SkPath::kAppend_AddPathMode : SkPath::kExtend_AddPathMode); } else { SkASSERT(!first); - fPathPtr->reversePathTo(contour); + SkPathPriv::ReversePathTo(&fBuilder, contour); } if (first) { first = false; @@ -388,7 +386,7 @@ sIndex == ((rIndex != eIndex) ^ forward ? eIndex : ~eIndex)); #endif if (sIndex == ((rIndex != eIndex) ^ forward ? eIndex : ~eIndex)) { - fPathPtr->close(); + fBuilder.close(); break; } if (forward) {
diff --git a/src/pathops/SkPathWriter.h b/src/pathops/SkPathWriter.h index 6b6626f..2760796 100644 --- a/src/pathops/SkPathWriter.h +++ b/src/pathops/SkPathWriter.h
@@ -8,6 +8,7 @@ #define SkPathWriter_DEFINED #include "include/core/SkPath.h" +#include "include/core/SkPathBuilder.h" #include "include/core/SkPoint.h" #include "include/core/SkScalar.h" #include "include/private/base/SkTArray.h" @@ -21,7 +22,7 @@ class SkPathWriter { public: - SkPathWriter(SkPath& path); + SkPathWriter(SkPathFillType); void assemble(); void conicTo(const SkPoint& pt1, const SkOpPtT* pt2, SkScalar weight); void cubicTo(const SkPoint& pt1, const SkPoint& pt2, const SkOpPtT* pt3); @@ -31,7 +32,7 @@ bool hasMove() const { return !fFirstPtT; } void init(); bool isClosed() const; - const SkPath* nativePath() const { return fPathPtr; } + SkPath nativePath() { return fBuilder.detach(); } void quadTo(const SkPoint& pt1, const SkOpPtT* pt2); private: @@ -45,10 +46,10 @@ bool someAssemblyRequired(); SkPoint update(const SkOpPtT* pt); + SkPathBuilder fBuilder; SkPath fCurrent; // contour under construction skia_private::TArray<SkPath> fPartials; // contours with mismatched starts and ends SkTDArray<const SkOpPtT*> fEndPtTs; // possible pt values for partial starts and ends - SkPath* fPathPtr; // closed contours are written here const SkOpPtT* fDefer[2]; // [0] deferred move, [1] deferred line const SkOpPtT* fFirstPtT; // first in current contour };