| Index: src/pathops/SkOpSegment.cpp
|
| ===================================================================
|
| --- src/pathops/SkOpSegment.cpp (revision 9040)
|
| +++ src/pathops/SkOpSegment.cpp (working copy)
|
| @@ -450,6 +450,11 @@
|
| span->fT = newT;
|
| span->fOther = other;
|
| span->fPt = pt;
|
| +#if 0
|
| + // cubics, for instance, may not be exact enough to satisfy this check (e.g., cubicOp69d)
|
| + SkASSERT(approximately_equal(xyAtT(newT).fX, pt.fX)
|
| + && approximately_equal(xyAtT(newT).fY, pt.fY));
|
| +#endif
|
| span->fWindSum = SK_MinS32;
|
| span->fOppSum = SK_MinS32;
|
| span->fWindValue = 1;
|
| @@ -533,13 +538,16 @@
|
|
|
| // set spans from start to end to decrement by one
|
| // note this walks other backwards
|
| -// FIMXE: there's probably an edge case that can be constructed where
|
| +// FIXME: there's probably an edge case that can be constructed where
|
| // two span in one segment are separated by float epsilon on one span but
|
| // not the other, if one segment is very small. For this
|
| // case the counts asserted below may or may not be enough to separate the
|
| // spans. Even if the counts work out, what if the spans aren't correctly
|
| // sorted? It feels better in such a case to match the span's other span
|
| // pointer since both coincident segments must contain the same spans.
|
| +// FIXME? It seems that decrementing by one will fail for complex paths that
|
| +// have three or more coincident edges. Shouldn't this subtract the difference
|
| +// between the winding values?
|
| void SkOpSegment::addTCancel(double startT, double endT, SkOpSegment* other,
|
| double oStartT, double oEndT) {
|
| SkASSERT(!approximately_negative(endT - startT));
|
| @@ -558,14 +566,19 @@
|
| SkTDArray<double> outsideTs;
|
| SkTDArray<double> oOutsideTs;
|
| do {
|
| - bool decrement = test->fWindValue && oTest->fWindValue && !binary;
|
| + bool decrement = test->fWindValue && oTest->fWindValue;
|
| bool track = test->fWindValue || oTest->fWindValue;
|
| + bool bigger = test->fWindValue >= oTest->fWindValue;
|
| double testT = test->fT;
|
| double oTestT = oTest->fT;
|
| SkOpSpan* span = test;
|
| do {
|
| if (decrement) {
|
| - decrementSpan(span);
|
| + if (binary && bigger) {
|
| + span->fOppValue--;
|
| + } else {
|
| + decrementSpan(span);
|
| + }
|
| } else if (track && span->fT < 1 && oTestT < 1) {
|
| TrackOutside(&outsideTs, span->fT, oTestT);
|
| }
|
| @@ -581,7 +594,11 @@
|
| SkASSERT(originalWindValue == oSpan->fWindValue);
|
| #endif
|
| if (decrement) {
|
| - other->decrementSpan(oSpan);
|
| + if (binary && !bigger) {
|
| + oSpan->fOppValue--;
|
| + } else {
|
| + other->decrementSpan(oSpan);
|
| + }
|
| } else if (track && oSpan->fT < 1 && testT < 1) {
|
| TrackOutside(&oOutsideTs, oSpan->fT, testT);
|
| }
|
| @@ -758,14 +775,14 @@
|
| void SkOpSegment::addTwoAngles(int start, int end, SkTDArray<SkOpAngle>* angles) const {
|
| // add edge leading into junction
|
| int min = SkMin32(end, start);
|
| - if (fTs[min].fWindValue > 0 || fTs[min].fOppValue > 0) {
|
| + if (fTs[min].fWindValue > 0 || fTs[min].fOppValue != 0) {
|
| addAngle(angles, end, start);
|
| }
|
| // add edge leading away from junction
|
| int step = SkSign32(end - start);
|
| int tIndex = nextExactSpan(end, step);
|
| min = SkMin32(end, tIndex);
|
| - if (tIndex >= 0 && (fTs[min].fWindValue > 0 || fTs[min].fOppValue > 0)) {
|
| + if (tIndex >= 0 && (fTs[min].fWindValue > 0 || fTs[min].fOppValue != 0)) {
|
| addAngle(angles, end, tIndex);
|
| }
|
| }
|
| @@ -912,6 +929,10 @@
|
| if (oppoSign && UseInnerWinding(maxWinding, winding)) {
|
| maxWinding = winding;
|
| }
|
| +#ifdef SK_DEBUG
|
| + SkASSERT(abs(maxWinding) <= gDebugMaxWindSum);
|
| + SkASSERT(abs(oMaxWinding) <= gDebugMaxWindSum);
|
| +#endif
|
| (void) segment->markAndChaseWinding(angle, oMaxWinding, maxWinding);
|
| } else {
|
| if (UseInnerWinding(maxWinding, winding)) {
|
| @@ -920,6 +941,10 @@
|
| if (oppoSign && UseInnerWinding(oMaxWinding, oWinding)) {
|
| oMaxWinding = oWinding;
|
| }
|
| +#ifdef SK_DEBUG
|
| + SkASSERT(abs(maxWinding) <= gDebugMaxWindSum);
|
| + SkASSERT(abs(binary ? oMaxWinding : 0) <= gDebugMaxWindSum);
|
| +#endif
|
| (void) segment->markAndChaseWinding(angle, maxWinding,
|
| binary ? oMaxWinding : 0);
|
| }
|
| @@ -2241,6 +2266,10 @@
|
| int otherEnd = other->nextExactSpan(*index, step);
|
| SkASSERT(otherEnd >= 0);
|
| *min = SkMin32(*index, otherEnd);
|
| + if (other->fTs[*min].fTiny) {
|
| + *last = NULL;
|
| + return NULL;
|
| + }
|
| return other;
|
| }
|
|
|
| @@ -2489,7 +2518,7 @@
|
| }
|
|
|
| void SkOpSegment::zeroSpan(SkOpSpan* span) {
|
| - SkASSERT(span->fWindValue > 0 || span->fOppValue > 0);
|
| + SkASSERT(span->fWindValue > 0 || span->fOppValue != 0);
|
| span->fWindValue = 0;
|
| span->fOppValue = 0;
|
| SkASSERT(!span->fDone);
|
| @@ -2557,7 +2586,7 @@
|
| }
|
| #endif
|
|
|
| -#if DEBUG_ACTIVE_SPANS
|
| +#if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY
|
| void SkOpSegment::debugShowActiveSpans() const {
|
| if (done()) {
|
| return;
|
| @@ -2572,6 +2601,7 @@
|
| if (fTs[i].fDone) {
|
| continue;
|
| }
|
| + SkASSERT(i < fTs.count() - 1);
|
| #if DEBUG_ACTIVE_SPANS_SHORT_FORM
|
| if (lastId == fID && lastT == fTs[i].fT) {
|
| continue;
|
|
|