aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pathops
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 /src/pathops
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>
Diffstat (limited to 'src/pathops')
-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
5 files changed, 38 insertions, 28 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;