aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/pathops/SkOpSegment.cpp5
-rw-r--r--src/pathops/SkOpSegment.h4
-rw-r--r--src/pathops/SkPathOpsDebug.h2
-rw-r--r--src/pathops/SkPathOpsOp.cpp29
-rw-r--r--src/pathops/SkPathOpsSimplify.cpp26
-rw-r--r--tests/PathOpsDebug.cpp4
-rw-r--r--tests/PathOpsOpTest.cpp4
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