| Index: src/pathops/SkOpContour.cpp
|
| diff --git a/src/pathops/SkOpContour.cpp b/src/pathops/SkOpContour.cpp
|
| index f3861a1e0b230131c2d47794d4cd17ae7fc6d6e6..facba87f78226337bf389eaac69190551e9bd8f4 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;
|
|
|