aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pathops/SkOpContour.cpp
diff options
context:
space:
mode:
authorGravatar caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-09-16 15:55:01 +0000
committerGravatar caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-09-16 15:55:01 +0000
commit570863f2e22b8ea7d7c504bd15e4f766af097df2 (patch)
treeaa07d18266edd483ee71d7be9491da622cf400f3 /src/pathops/SkOpContour.cpp
parentcf7854057638dfa75e788f3f8babed75d587d444 (diff)
path ops work in progress
path ops work in progress BUG= Review URL: https://codereview.chromium.org/21359002 git-svn-id: http://skia.googlecode.com/svn/trunk@11291 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/pathops/SkOpContour.cpp')
-rw-r--r--src/pathops/SkOpContour.cpp121
1 files changed, 76 insertions, 45 deletions
diff --git a/src/pathops/SkOpContour.cpp b/src/pathops/SkOpContour.cpp
index f3861a1e0b..facba87f78 100644
--- a/src/pathops/SkOpContour.cpp
+++ b/src/pathops/SkOpContour.cpp
@@ -12,8 +12,7 @@
void SkOpContour::addCoincident(int index, SkOpContour* other, int otherIndex,
const SkIntersections& ts, bool swap) {
SkCoincidence& coincidence = fCoincidences.push_back();
- coincidence.fContours[0] = this; // FIXME: no need to store
- coincidence.fContours[1] = other;
+ coincidence.fOther = other;
coincidence.fSegments[0] = index;
coincidence.fSegments[1] = otherIndex;
coincidence.fTs[swap][0] = ts[0][0];
@@ -48,10 +47,9 @@ void SkOpContour::addCoincidentPoints() {
int count = fCoincidences.count();
for (int index = 0; index < count; ++index) {
SkCoincidence& coincidence = fCoincidences[index];
- SkASSERT(coincidence.fContours[0] == this);
int thisIndex = coincidence.fSegments[0];
SkOpSegment& thisOne = fSegments[thisIndex];
- SkOpContour* otherContour = coincidence.fContours[1];
+ SkOpContour* otherContour = coincidence.fOther;
int otherIndex = coincidence.fSegments[1];
SkOpSegment& other = otherContour->fSegments[otherIndex];
if ((thisOne.done() || other.done()) && thisOne.complete() && other.complete()) {
@@ -103,51 +101,84 @@ void SkOpContour::addCoincidentPoints() {
}
}
+void SkOpContour::addPartialCoincident(int index, SkOpContour* other, int otherIndex,
+ const SkIntersections& ts, int ptIndex, bool swap) {
+ SkCoincidence& coincidence = fPartialCoincidences.push_back();
+ coincidence.fOther = other;
+ coincidence.fSegments[0] = index;
+ coincidence.fSegments[1] = otherIndex;
+ coincidence.fTs[swap][0] = ts[0][index];
+ coincidence.fTs[swap][1] = ts[0][index + 1];
+ coincidence.fTs[!swap][0] = ts[1][index];
+ coincidence.fTs[!swap][1] = ts[1][index + 1];
+ coincidence.fPts[0] = ts.pt(index).asSkPoint();
+ coincidence.fPts[1] = ts.pt(index + 1).asSkPoint();
+}
+
void SkOpContour::calcCoincidentWinding() {
int count = fCoincidences.count();
+#if DEBUG_CONCIDENT
+ if (count > 0) {
+ SkDebugf("%s count=%d\n", __FUNCTION__, count);
+ }
+#endif
for (int index = 0; index < count; ++index) {
SkCoincidence& coincidence = fCoincidences[index];
- SkASSERT(coincidence.fContours[0] == this);
- int thisIndex = coincidence.fSegments[0];
- SkOpSegment& thisOne = fSegments[thisIndex];
- if (thisOne.done()) {
- continue;
- }
- SkOpContour* otherContour = coincidence.fContours[1];
- int otherIndex = coincidence.fSegments[1];
- SkOpSegment& other = otherContour->fSegments[otherIndex];
- if (other.done()) {
- continue;
- }
- double startT = coincidence.fTs[0][0];
- double endT = coincidence.fTs[0][1];
- bool cancelers;
- if ((cancelers = startT > endT)) {
- SkTSwap<double>(startT, endT);
- }
- SkASSERT(!approximately_negative(endT - startT));
- double oStartT = coincidence.fTs[1][0];
- double oEndT = coincidence.fTs[1][1];
- if (oStartT > oEndT) {
- SkTSwap<double>(oStartT, oEndT);
- cancelers ^= true;
- }
- SkASSERT(!approximately_negative(oEndT - oStartT));
- if (cancelers) {
- // make sure startT and endT have t entries
- if (!thisOne.done() && !other.done()) {
- thisOne.addTCancel(startT, endT, &other, oStartT, oEndT);
- }
- } else {
- if (!thisOne.done() && !other.done()) {
- thisOne.addTCoincident(startT, endT, &other, oStartT, oEndT);
- }
- }
- #if DEBUG_CONCIDENT
- thisOne.debugShowTs();
- other.debugShowTs();
- #endif
+ calcCommonCoincidentWinding(coincidence);
+ }
+}
+
+void SkOpContour::calcPartialCoincidentWinding() {
+ int count = fPartialCoincidences.count();
+#if DEBUG_CONCIDENT
+ if (count > 0) {
+ SkDebugf("%s count=%d\n", __FUNCTION__, count);
+ }
+#endif
+ for (int index = 0; index < count; ++index) {
+ SkCoincidence& coincidence = fPartialCoincidences[index];
+ calcCommonCoincidentWinding(coincidence);
+ }
+}
+
+void SkOpContour::calcCommonCoincidentWinding(const SkCoincidence& coincidence) {
+ int thisIndex = coincidence.fSegments[0];
+ SkOpSegment& thisOne = fSegments[thisIndex];
+ if (thisOne.done()) {
+ return;
}
+ SkOpContour* otherContour = coincidence.fOther;
+ int otherIndex = coincidence.fSegments[1];
+ SkOpSegment& other = otherContour->fSegments[otherIndex];
+ if (other.done()) {
+ return;
+ }
+ double startT = coincidence.fTs[0][0];
+ double endT = coincidence.fTs[0][1];
+ const SkPoint* startPt = &coincidence.fPts[0];
+ const SkPoint* endPt = &coincidence.fPts[1];
+ bool cancelers;
+ if ((cancelers = startT > endT)) {
+ SkTSwap<double>(startT, endT);
+ SkTSwap<const SkPoint*>(startPt, endPt);
+ }
+ SkASSERT(!approximately_negative(endT - startT));
+ double oStartT = coincidence.fTs[1][0];
+ double oEndT = coincidence.fTs[1][1];
+ if (oStartT > oEndT) {
+ SkTSwap<double>(oStartT, oEndT);
+ cancelers ^= true;
+ }
+ SkASSERT(!approximately_negative(oEndT - oStartT));
+ if (cancelers) {
+ thisOne.addTCancel(*startPt, *endPt, &other);
+ } else {
+ thisOne.addTCoincident(*startPt, *endPt, &other);
+ }
+#if DEBUG_CONCIDENT
+ thisOne.debugShowTs();
+ other.debugShowTs();
+#endif
}
void SkOpContour::sortSegments() {
@@ -229,7 +260,7 @@ int SkOpContour::debugShowWindingValues(int totalSegments, int ofInterest) {
return sum;
}
-static void SkOpContour::debugShowWindingValues(const SkTArray<SkOpContour*, true>& contourList) {
+void SkOpContour::debugShowWindingValues(const SkTArray<SkOpContour*, true>& contourList) {
// int ofInterest = 1 << 1 | 1 << 5 | 1 << 9 | 1 << 13;
// int ofInterest = 1 << 4 | 1 << 8 | 1 << 12 | 1 << 16;
int ofInterest = 1 << 5 | 1 << 8;