aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Cary Clark <caryclark@skia.org>2018-07-11 11:01:43 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-07-11 15:30:28 +0000
commit1857ddbe218afd8ef32f672619ab13c0f853436c (patch)
treee8d562ec9910743e3020098e8e3c9d02e3305567
parentcd3e13a130e3d99790e80b329ef6d13591615fe0 (diff)
propogate simple angles in pathops
If an edge is unsortable, its winding value is untrustworthy; it cannot be added to the output on that alone. If one end adjoins a trusted edge, and that edge is added to the output, the untrusted edge can be added as well. Also add in msvs debugging for angles. With this change, all extended tests pass. TBR=reed@google.com Bug: skia:8125 Change-Id: I049c6efa2fa83edd7b49cdd598ec94c356481b0f Reviewed-on: https://skia-review.googlesource.com/140562 Commit-Queue: Cary Clark <caryclark@skia.org> Auto-Submit: Cary Clark <caryclark@skia.org> Reviewed-by: Cary Clark <caryclark@skia.org>
-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