diff options
-rw-r--r-- | src/pathops/SkOpSegment.cpp | 5 | ||||
-rw-r--r-- | src/pathops/SkOpSegment.h | 4 | ||||
-rw-r--r-- | src/pathops/SkPathOpsDebug.h | 2 | ||||
-rw-r--r-- | src/pathops/SkPathOpsOp.cpp | 29 | ||||
-rw-r--r-- | src/pathops/SkPathOpsSimplify.cpp | 26 | ||||
-rw-r--r-- | tests/PathOpsDebug.cpp | 4 | ||||
-rw-r--r-- | tests/PathOpsOpTest.cpp | 4 |
7 files changed, 42 insertions, 32 deletions
diff --git a/src/pathops/SkOpSegment.cpp b/src/pathops/SkOpSegment.cpp index 3bd925c0c3..720b34f597 100644 --- a/src/pathops/SkOpSegment.cpp +++ b/src/pathops/SkOpSegment.cpp @@ -524,13 +524,14 @@ double SkOpSegment::distSq(double t, const SkOpAngle* oppAngle) const { Opposite values result from combining coincident spans. */ SkOpSegment* SkOpSegment::findNextOp(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** nextStart, - SkOpSpanBase** nextEnd, bool* unsortable, SkPathOp op, int xorMiMask, int xorSuMask) { + SkOpSpanBase** nextEnd, bool* unsortable, bool* simple, + SkPathOp op, int xorMiMask, int xorSuMask) { SkOpSpanBase* start = *nextStart; SkOpSpanBase* end = *nextEnd; SkASSERT(start != end); int step = start->step(end); SkOpSegment* other = this->isSimple(nextStart, &step); // advances nextStart - if (other) { + if ((*simple = other)) { // mark the smaller of startIndex, endIndex done, and all adjacent // spans with the same T value (but not 'other' spans) #if DEBUG_WINDING diff --git a/src/pathops/SkOpSegment.h b/src/pathops/SkOpSegment.h index a38d785250..052a220026 100644 --- a/src/pathops/SkOpSegment.h +++ b/src/pathops/SkOpSegment.h @@ -212,8 +212,8 @@ public: const SkOpPtT* existing(double t, const SkOpSegment* opp) const; SkOpSegment* findNextOp(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** nextStart, - SkOpSpanBase** nextEnd, bool* unsortable, SkPathOp op, - int xorMiMask, int xorSuMask); + SkOpSpanBase** nextEnd, bool* unsortable, bool* simple, + SkPathOp op, int xorMiMask, int xorSuMask); SkOpSegment* findNextWinding(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** nextStart, SkOpSpanBase** nextEnd, bool* unsortable); SkOpSegment* findNextXor(SkOpSpanBase** nextStart, SkOpSpanBase** nextEnd, bool* unsortable); diff --git a/src/pathops/SkPathOpsDebug.h b/src/pathops/SkPathOpsDebug.h index 724713a74a..035ab14a05 100644 --- a/src/pathops/SkPathOpsDebug.h +++ b/src/pathops/SkPathOpsDebug.h @@ -481,6 +481,8 @@ namespace SkOpDebug { void Dump(const SkDPoint& ); + void Dump(const SkOpAngle& ); + // dummy declarations to fool msvs Visual Studio 2018 Immediate Window #define DummyDeclarations(a, b) \ void Dump(const SkDebugTCoincident##a##b& ); \ diff --git a/src/pathops/SkPathOpsOp.cpp b/src/pathops/SkPathOpsOp.cpp index f8b8a65eec..0065c7175a 100644 --- a/src/pathops/SkPathOpsOp.cpp +++ b/src/pathops/SkPathOpsOp.cpp @@ -99,8 +99,10 @@ static SkOpSegment* findChaseOp(SkTDArray<SkOpSpanBase*>& chase, SkOpSpanBase** } static bool bridgeOp(SkOpContourHead* contourList, const SkPathOp op, - const int xorMask, const int xorOpMask, SkPathWriter* simple) { + const int xorMask, const int xorOpMask, SkPathWriter* writer) { bool unsortable = false; + bool lastSimple = false; + bool simple = false; do { SkOpSpan* span = FindSortableTop(contourList); if (!span) { @@ -119,18 +121,23 @@ static bool bridgeOp(SkOpContourHead* contourList, const SkPathOp op, SkASSERT(unsortable || !current->done()); SkOpSpanBase* nextStart = start; SkOpSpanBase* nextEnd = end; + lastSimple = simple; SkOpSegment* next = current->findNextOp(&chase, &nextStart, &nextEnd, - &unsortable, op, xorMask, xorOpMask); + &unsortable, &simple, op, xorMask, xorOpMask); if (!next) { - if (!unsortable && simple->hasMove() + if (!unsortable && writer->hasMove() && current->verb() != SkPath::kLine_Verb - && !simple->isClosed()) { - if (!current->addCurveTo(start, end, simple)) { + && !writer->isClosed()) { + if (!current->addCurveTo(start, end, writer)) { return false; } - if (!simple->isClosed()) { + if (!writer->isClosed()) { SkPathOpsDebug::ShowActiveSpans(contourList); } + } else if (lastSimple) { + if (!current->addCurveTo(start, end, writer)) { + return false; + } } break; } @@ -139,23 +146,23 @@ static bool bridgeOp(SkOpContourHead* contourList, const SkPathOp op, current->debugID(), start->pt().fX, start->pt().fY, end->pt().fX, end->pt().fY); #endif - if (!current->addCurveTo(start, end, simple)) { + if (!current->addCurveTo(start, end, writer)) { return false; } current = next; start = nextStart; end = nextEnd; - } while (!simple->isClosed() && (!unsortable || !start->starter(end)->done())); - if (current->activeWinding(start, end) && !simple->isClosed()) { + } while (!writer->isClosed() && (!unsortable || !start->starter(end)->done())); + if (current->activeWinding(start, end) && !writer->isClosed()) { SkOpSpan* spanStart = start->starter(end); if (!spanStart->done()) { - if (!current->addCurveTo(start, end, simple)) { + if (!current->addCurveTo(start, end, writer)) { return false; } current->markDone(spanStart); } } - simple->finishContour(); + writer->finishContour(); } else { SkOpSpanBase* last; if (!current->markAndChaseDone(start, end, &last)) { diff --git a/src/pathops/SkPathOpsSimplify.cpp b/src/pathops/SkPathOpsSimplify.cpp index 70f730bf21..dba123d41e 100644 --- a/src/pathops/SkPathOpsSimplify.cpp +++ b/src/pathops/SkPathOpsSimplify.cpp @@ -10,7 +10,7 @@ #include "SkPathOpsCommon.h" #include "SkPathWriter.h" -static bool bridgeWinding(SkOpContourHead* contourList, SkPathWriter* simple) { +static bool bridgeWinding(SkOpContourHead* contourList, SkPathWriter* writer) { bool unsortable = false; do { SkOpSpan* span = FindSortableTop(contourList); @@ -25,7 +25,7 @@ static bool bridgeWinding(SkOpContourHead* contourList, SkPathWriter* simple) { if (current->activeWinding(start, end)) { do { if (!unsortable && current->done()) { - break; + break; } SkASSERT(unsortable || !current->done()); SkOpSpanBase* nextStart = start; @@ -40,23 +40,23 @@ static bool bridgeWinding(SkOpContourHead* contourList, SkPathWriter* simple) { current->debugID(), start->pt().fX, start->pt().fY, end->pt().fX, end->pt().fY); #endif - if (!current->addCurveTo(start, end, simple)) { + if (!current->addCurveTo(start, end, writer)) { return false; } current = next; start = nextStart; end = nextEnd; - } while (!simple->isClosed() && (!unsortable || !start->starter(end)->done())); - if (current->activeWinding(start, end) && !simple->isClosed()) { + } while (!writer->isClosed() && (!unsortable || !start->starter(end)->done())); + if (current->activeWinding(start, end) && !writer->isClosed()) { SkOpSpan* spanStart = start->starter(end); if (!spanStart->done()) { - if (!current->addCurveTo(start, end, simple)) { + if (!current->addCurveTo(start, end, writer)) { return false; } current->markDone(spanStart); } } - simple->finishContour(); + writer->finishContour(); } else { SkOpSpanBase* last; if (!current->markAndChaseDone(start, end, &last)) { @@ -86,7 +86,7 @@ static bool bridgeWinding(SkOpContourHead* contourList, SkPathWriter* simple) { } // returns true if all edges were processed -static bool bridgeXor(SkOpContourHead* contourList, SkPathWriter* simple) { +static bool bridgeXor(SkOpContourHead* contourList, SkPathWriter* writer) { bool unsortable = false; int safetyNet = 1000000; do { @@ -117,23 +117,23 @@ static bool bridgeXor(SkOpContourHead* contourList, SkPathWriter* simple) { current->debugID(), start->pt().fX, start->pt().fY, end->pt().fX, end->pt().fY); #endif - if (!current->addCurveTo(start, end, simple)) { + if (!current->addCurveTo(start, end, writer)) { return false; } current = next; start = nextStart; end = nextEnd; - } while (!simple->isClosed() && (!unsortable || !start->starter(end)->done())); - if (!simple->isClosed()) { + } while (!writer->isClosed() && (!unsortable || !start->starter(end)->done())); + if (!writer->isClosed()) { SkOpSpan* spanStart = start->starter(end); if (!spanStart->done()) { - if (!current->addCurveTo(start, end, simple)) { + if (!current->addCurveTo(start, end, writer)) { return false; } current->markDone(spanStart); } } - simple->finishContour(); + writer->finishContour(); SkPathOpsDebug::ShowActiveSpans(contourList); } while (true); return true; diff --git a/tests/PathOpsDebug.cpp b/tests/PathOpsDebug.cpp index 942f99c7ae..a93c331cb5 100644 --- a/tests/PathOpsDebug.cpp +++ b/tests/PathOpsDebug.cpp @@ -1639,6 +1639,10 @@ namespace SkOpDebug { point.dump(); } + void Dump(const SkOpAngle& angle) { + angle.dump(); + } + // dummy definitions to fool msvs Visual Studio 2018 Immediate Window #define DummyDefinitions(a, b) \ \ diff --git a/tests/PathOpsOpTest.cpp b/tests/PathOpsOpTest.cpp index 950baaf7b3..0420115ce4 100644 --- a/tests/PathOpsOpTest.cpp +++ b/tests/PathOpsOpTest.cpp @@ -5751,11 +5751,7 @@ static void testRect1_u(skiatest::Reporter* reporter, const char* filename) { testPathOp(reporter, path, pathB, kUnion_SkPathOp, filename); } -// this test fails for now; it generates partial paths that are incorrectly -// connected to form an area where it should not. The fix is to connect the -// pieces using only contours that are part of the input data set. static void filinmangust14(skiatest::Reporter* reporter, const char* filename) { - return; SkPath path, path1; path.setFillType(SkPath::kWinding_FillType); path.moveTo(SkBits2Float(0x440bc02c), SkBits2Float(0x4409c000)); // 559.003f, 551 |