| Index: src/pathops/SkOpSegment.cpp
|
| diff --git a/src/pathops/SkOpSegment.cpp b/src/pathops/SkOpSegment.cpp
|
| index c233c0f9b671e954bac223dcbf82576af189ef6f..95046e2fd2d3da7b8b1aafc085392c5a26f16707 100644
|
| --- a/src/pathops/SkOpSegment.cpp
|
| +++ b/src/pathops/SkOpSegment.cpp
|
| @@ -160,10 +160,6 @@
|
| bool SkOpSegment::activeOp(int index, int endIndex, int xorMiMask, int xorSuMask, SkPathOp op) {
|
| int sumMiWinding = updateWinding(endIndex, index);
|
| int sumSuWinding = updateOppWinding(endIndex, index);
|
| -#if DEBUG_LIMIT_WIND_SUM
|
| - SkASSERT(abs(sumMiWinding) <= DEBUG_LIMIT_WIND_SUM);
|
| - SkASSERT(abs(sumSuWinding) <= DEBUG_LIMIT_WIND_SUM);
|
| -#endif
|
| if (fOperand) {
|
| SkTSwap<int>(sumMiWinding, sumSuWinding);
|
| }
|
| @@ -621,11 +617,6 @@
|
| if ((span->fDone = newT == 1)) {
|
| ++fDoneSpans;
|
| }
|
| - setSpanFlags(pt, newT, span);
|
| - return insertedAt;
|
| -}
|
| -
|
| -void SkOpSegment::setSpanFlags(const SkPoint& pt, double newT, SkOpSpan* span) {
|
| int less = -1;
|
| // FIXME: note that this relies on spans being a continguous array
|
| // find range of spans with nearly the same point as this one
|
| @@ -661,10 +652,10 @@
|
| --more;
|
| }
|
| if (less == more) {
|
| - return;
|
| + return insertedAt;
|
| }
|
| if (precisely_negative(span[more].fT - span[less].fT)) {
|
| - return;
|
| + return insertedAt;
|
| }
|
| // if the total range of t values is big enough, mark all tiny
|
| bool tiny = span[less].fPt == span[more].fPt;
|
| @@ -677,80 +668,7 @@
|
| ++fDoneSpans;
|
| }
|
| } while (++index < more);
|
| - return;
|
| -}
|
| -
|
| -void SkOpSegment::resetSpanFlags() {
|
| - fSmall = fTiny = false;
|
| - fDoneSpans = 0;
|
| - int start = 0;
|
| - int last = this->count() - 1;
|
| - do {
|
| - SkOpSpan* startSpan = &this->fTs[start];
|
| - double startT = startSpan->fT;
|
| - startSpan->fSmall = startSpan->fTiny = false; // sets range initial
|
| - bool terminus = startT == 1;
|
| - if ((startSpan->fDone = !startSpan->fWindValue | terminus)) {
|
| - ++fDoneSpans;
|
| - }
|
| - ++start; // range initial + 1
|
| - if (terminus) {
|
| - continue;
|
| - }
|
| - const SkPoint& pt = startSpan->fPt;
|
| - int end = start; // range initial + 1
|
| - while (end <= last) {
|
| - const SkOpSpan& endSpan = this->span(end);
|
| - if (!AlmostEqualUlps(endSpan.fPt, pt)) {
|
| - break;
|
| - }
|
| - if (fVerb == SkPath::kCubic_Verb) {
|
| - double tMid = (startSpan->fT + endSpan.fT) / 2;
|
| - SkDPoint midEndPt = dcubic_xy_at_t(fPts, tMid);
|
| - if (!midEndPt.approximatelyEqual(xyAtT(startSpan))) {
|
| - break;
|
| - }
|
| - }
|
| - ++end;
|
| - }
|
| - if (start == end) { // end == range final + 1
|
| - continue;
|
| - }
|
| - while (--end >= start) { // end == range final
|
| - const SkOpSpan& endSpan = this->span(end);
|
| - const SkOpSpan& priorSpan = this->span(end - 1);
|
| - if (endSpan.fPt != priorSpan.fPt || endSpan.fT != priorSpan.fT) {
|
| - break; // end == range final + 1
|
| - }
|
| - }
|
| - if (end < start) { // end == range final + 1
|
| - continue;
|
| - }
|
| - int index = start - 1; // index == range initial
|
| - start = end; // start = range final + 1
|
| - const SkOpSpan& nextSpan = this->span(end);
|
| - if (precisely_negative(nextSpan.fT - startSpan->fT)) {
|
| - while (++index < end) {
|
| - startSpan = &this->fTs[index];
|
| - startSpan->fSmall = startSpan->fTiny = false; // sets range initial + 1
|
| - if ((startSpan->fDone = !startSpan->fWindValue)) {
|
| - ++fDoneSpans;
|
| - }
|
| - }
|
| - continue;
|
| - }
|
| - if (!startSpan->fWindValue) {
|
| - --fDoneSpans; // added back below
|
| - }
|
| - bool tiny = nextSpan.fPt == startSpan->fPt;
|
| - do {
|
| - fSmall = startSpan->fSmall = true; // sets range initial
|
| - fTiny |= startSpan->fTiny = tiny;
|
| - startSpan->fDone = true;
|
| - ++fDoneSpans;
|
| - startSpan = &this->fTs[++index];
|
| - } while (index < end); // loop through tiny small range end (last)
|
| - } while (start <= last);
|
| + return insertedAt;
|
| }
|
|
|
| // set spans from start to end to decrement by one
|
| @@ -1052,151 +970,6 @@
|
| debugValidate();
|
| }
|
|
|
| -void SkOpSegment::alignRange(int lower, int upper,
|
| - const SkOpSegment* other, int oLower, int oUpper) {
|
| - for (int oIndex = oLower; oIndex <= oUpper; ++oIndex) {
|
| - const SkOpSpan& oSpan = other->span(oIndex);
|
| - const SkOpSegment* oOther = oSpan.fOther;
|
| - if (oOther == this) {
|
| - continue;
|
| - }
|
| - SkOpSpan* matchSpan;
|
| - int matchIndex;
|
| - const SkOpSpan* refSpan;
|
| - for (int iIndex = lower; iIndex <= upper; ++iIndex) {
|
| - const SkOpSpan& iSpan = this->span(iIndex);
|
| - const SkOpSegment* iOther = iSpan.fOther;
|
| - if (iOther == other) {
|
| - continue;
|
| - }
|
| - if (iOther == oOther) {
|
| - goto nextI;
|
| - }
|
| - }
|
| - {
|
| - // oSpan does not have a match in this
|
| - int iCount = this->count();
|
| - const SkOpSpan* iMatch = NULL;
|
| - double iMatchTDiff;
|
| - matchIndex = -1;
|
| - for (int iIndex = 0; iIndex < iCount; ++iIndex) {
|
| - const SkOpSpan& iSpan = this->span(iIndex);
|
| - const SkOpSegment* iOther = iSpan.fOther;
|
| - if (iOther != oOther) {
|
| - continue;
|
| - }
|
| - double testTDiff = fabs(iSpan.fOtherT - oSpan.fOtherT);
|
| - if (!iMatch || testTDiff < iMatchTDiff) {
|
| - matchIndex = iIndex;
|
| - iMatch = &iSpan;
|
| - iMatchTDiff = testTDiff;
|
| - }
|
| - }
|
| - if (matchIndex < 0) {
|
| - continue; // the entry is missing, & will be picked up later (FIXME: fix it here?)
|
| - }
|
| - matchSpan = &this->fTs[matchIndex];
|
| - refSpan = &this->span(lower);
|
| - if (!SkDPoint::ApproximatelyEqual(matchSpan->fPt, refSpan->fPt)) {
|
| - goto nextI;
|
| - }
|
| - if (matchIndex != lower - 1 && matchIndex != upper + 1) {
|
| - // the consecutive spans need to be rearranged to get the missing one close
|
| - continue; // FIXME: more work to do
|
| - }
|
| - }
|
| - {
|
| - this->fixOtherTIndex();
|
| - SkScalar newT;
|
| - if (matchSpan->fT != 0 && matchSpan->fT != 1) {
|
| - newT = matchSpan->fT = refSpan->fT;
|
| - matchSpan->fOther->fTs[matchSpan->fOtherIndex].fOtherT = refSpan->fT;
|
| - } else { // leave span at the start or end there and adjust the neighbors
|
| - newT = matchSpan->fT;
|
| - for (int iIndex = lower; iIndex <= upper; ++iIndex) {
|
| - matchSpan = &this->fTs[iIndex];
|
| - matchSpan->fT = newT;
|
| - matchSpan->fOther->fTs[matchSpan->fOtherIndex].fOtherT = newT;
|
| - }
|
| - }
|
| - this->resetSpanFlags(); // fix up small / tiny / done
|
| - // align ts of other ranges with adjacent spans that match the aligned points
|
| - lower = SkTMin(lower, matchIndex);
|
| - while (lower > 0) {
|
| - const SkOpSpan& span = this->span(lower - 1);
|
| - if (span.fT != newT) {
|
| - break;
|
| - }
|
| - --lower;
|
| - }
|
| - upper = SkTMax(upper, matchIndex);
|
| - int last = this->count() - 1;
|
| - while (upper < last) {
|
| - const SkOpSpan& span = this->span(upper + 1);
|
| - if (span.fT != newT) {
|
| - break;
|
| - }
|
| - ++upper;
|
| - }
|
| - for (int iIndex = lower; iIndex <= upper; ++iIndex) {
|
| - const SkOpSpan& span = this->span(iIndex);
|
| - SkOpSegment* aOther = span.fOther;
|
| - int aLower = span.fOtherIndex;
|
| - SkScalar aT = span.fOtherT;
|
| - bool aResetFlags = false;
|
| - while (aLower > 0) {
|
| - SkOpSpan* aSpan = &aOther->fTs[aLower - 1];
|
| - for (int iIndex = lower; iIndex <= upper; ++iIndex) {
|
| - if (aSpan->fPt == this->fTs[iIndex].fPt) {
|
| - goto matchFound;
|
| - }
|
| - }
|
| - break;
|
| - matchFound:
|
| - --aLower;
|
| - }
|
| - int aUpper = span.fOtherIndex;
|
| - int aLast = aOther->count() - 1;
|
| - while (aUpper < aLast) {
|
| - SkOpSpan* aSpan = &aOther->fTs[aUpper + 1];
|
| - for (int iIndex = lower; iIndex <= upper; ++iIndex) {
|
| - if (aSpan->fPt == this->fTs[iIndex].fPt) {
|
| - goto matchFound2;
|
| - }
|
| - }
|
| - break;
|
| - matchFound2:
|
| - ++aUpper;
|
| - }
|
| - if (aOther->fTs[aLower].fT == 0) {
|
| - aT = 0;
|
| - } else if (aOther->fTs[aUpper].fT == 1) {
|
| - aT = 1;
|
| - }
|
| - bool aFixed = false;
|
| - for (int aIndex = aLower; aIndex <= aUpper; ++aIndex) {
|
| - SkOpSpan* aSpan = &aOther->fTs[aIndex];
|
| - if (aSpan->fT == aT) {
|
| - continue;
|
| - }
|
| - SkASSERT(way_roughly_equal(aSpan->fT, aT));
|
| - if (!aFixed) {
|
| - aOther->fixOtherTIndex();
|
| - aFixed = true;
|
| - }
|
| - aSpan->fT = aT;
|
| - aSpan->fOther->fTs[aSpan->fOtherIndex].fOtherT = aT;
|
| - aResetFlags = true;
|
| - }
|
| - if (aResetFlags) {
|
| - aOther->resetSpanFlags();
|
| - }
|
| - }
|
| - }
|
| -nextI: ;
|
| - }
|
| -}
|
| -
|
| void SkOpSegment::alignSpan(const SkPoint& newPt, double newT, const SkOpSegment* other,
|
| double otherT, const SkOpSegment* other2, SkOpSpan* oSpan,
|
| SkTDArray<AlignedSpan>* alignedArray) {
|
| @@ -1472,8 +1245,8 @@
|
| // may not have the same intermediate points. Compute the corresponding
|
| // intermediate T values (using this as the master, other as the follower)
|
| // and walk other conditionally -- hoping that it catches up in the end
|
| -bool SkOpSegment::bumpCoincidentOther(const SkOpSpan& test, int* oIndexPtr,
|
| - SkTArray<SkPoint, true>* oOutsidePts, const SkPoint& oEndPt) {
|
| +void SkOpSegment::bumpCoincidentOther(const SkOpSpan& test, int* oIndexPtr,
|
| + SkTArray<SkPoint, true>* oOutsidePts) {
|
| int oIndex = *oIndexPtr;
|
| SkOpSpan* const oTest = &fTs[oIndex];
|
| SkOpSpan* oEnd = oTest;
|
| @@ -1486,14 +1259,11 @@
|
| TrackOutside(oOutsidePts, startPt);
|
| }
|
| #endif
|
| - bool foundEnd = false;
|
| while (oStartPt == oEnd->fPt || precisely_equal(oStartT, oEnd->fT)) {
|
| - foundEnd |= oEndPt == oEnd->fPt;
|
| zeroSpan(oEnd);
|
| oEnd = &fTs[++oIndex];
|
| }
|
| *oIndexPtr = oIndex;
|
| - return foundEnd;
|
| }
|
|
|
| // FIXME: need to test this case:
|
| @@ -1543,7 +1313,6 @@
|
| }
|
|
|
| // consolidate the winding count even if done
|
| - bool foundEnd = false;
|
| if ((test->fWindValue == 0 && test->fOppValue == 0)
|
| || (oTest->fWindValue == 0 && oTest->fOppValue == 0)) {
|
| SkDEBUGCODE(int firstWind = test->fWindValue);
|
| @@ -1567,12 +1336,12 @@
|
| if (!bumpCoincidentThis(*oTest, binary, &index, &outsidePts)) {
|
| return false;
|
| }
|
| - foundEnd = other->bumpCoincidentOther(*test, &oIndex, &oOutsidePts, endPt);
|
| + other->bumpCoincidentOther(*test, &oIndex, &oOutsidePts);
|
| } else {
|
| if (!other->bumpCoincidentThis(*test, binary, &oIndex, &oOutsidePts)) {
|
| return false;
|
| }
|
| - foundEnd = bumpCoincidentOther(*oTest, &index, &outsidePts, endPt);
|
| + bumpCoincidentOther(*oTest, &index, &outsidePts);
|
| }
|
| }
|
| test = &fTs[index];
|
| @@ -1581,9 +1350,6 @@
|
| oTest = &other->fTs[oIndex];
|
| oTestPt = &oTest->fPt;
|
| if (endPt == *testPt || precisely_equal(endT, testT)) {
|
| - break;
|
| - }
|
| - if (0 && foundEnd) { // FIXME: this is likely needed but wait until a test case triggers it
|
| break;
|
| }
|
| // SkASSERT(AlmostEqualUlps(*testPt, *oTestPt));
|
| @@ -1598,7 +1364,6 @@
|
| test->fWindValue = lastWind;
|
| test->fOppValue = lastOpp;
|
| if (zero) {
|
| - SkASSERT(!test->fDone);
|
| test->fDone = true;
|
| ++fDoneSpans;
|
| }
|
| @@ -1637,9 +1402,7 @@
|
| if (success) {
|
| do {
|
| if (!binary || test->fWindValue + oTest->fOppValue >= 0) {
|
| - if (other->bumpCoincidentOther(*test, &oIndex, &oOutsidePts, endPt)) {
|
| - break;
|
| - }
|
| + other->bumpCoincidentOther(*test, &oIndex, &oOutsidePts);
|
| } else {
|
| if (!other->bumpCoincidentThis(*test, binary, &oIndex, &oOutsidePts)) {
|
| return false;
|
| @@ -1713,9 +1476,9 @@
|
| SkASSERT(other != this);
|
| int insertedAt = addT(other, pt, t);
|
| int otherInsertedAt = other->addT(this, pt2, otherT);
|
| - this->addOtherT(insertedAt, otherT, otherInsertedAt);
|
| + addOtherT(insertedAt, otherT, otherInsertedAt);
|
| other->addOtherT(otherInsertedAt, t, insertedAt);
|
| - this->matchWindingValue(insertedAt, t, borrowWind);
|
| + matchWindingValue(insertedAt, t, borrowWind);
|
| other->matchWindingValue(otherInsertedAt, otherT, borrowWind);
|
| SkOpSpan& span = this->fTs[insertedAt];
|
| if (pt != pt2) {
|
| @@ -1723,27 +1486,6 @@
|
| SkOpSpan& oSpan = other->fTs[otherInsertedAt];
|
| oSpan.fNear = true;
|
| }
|
| - // if the newly inserted spans match a neighbor on one but not the other, make them agree
|
| - int lower = this->nextExactSpan(insertedAt, -1) + 1;
|
| - int upper = this->nextExactSpan(insertedAt, 1) - 1;
|
| - if (upper < 0) {
|
| - upper = this->count() - 1;
|
| - }
|
| - int oLower = other->nextExactSpan(otherInsertedAt, -1) + 1;
|
| - int oUpper = other->nextExactSpan(otherInsertedAt, 1) - 1;
|
| - if (oUpper < 0) {
|
| - oUpper = other->count() - 1;
|
| - }
|
| - if (lower == upper && oLower == oUpper) {
|
| - return &span;
|
| - }
|
| -#if DEBUG_CONCIDENT
|
| - SkDebugf("%s id=%d lower=%d upper=%d other=%d oLower=%d oUpper=%d\n", __FUNCTION__,
|
| - debugID(), lower, upper, other->debugID(), oLower, oUpper);
|
| -#endif
|
| - // find the nearby spans in one range missing in the other
|
| - this->alignRange(lower, upper, other, oLower, oUpper);
|
| - other->alignRange(oLower, oUpper, this, lower, upper);
|
| return &span;
|
| }
|
|
|
| @@ -2151,10 +1893,8 @@
|
| span->fOppValue &= 1;
|
| }
|
| if (!span->fWindValue && !span->fOppValue) {
|
| - if (!span->fDone) {
|
| - span->fDone = true;
|
| - ++fDoneSpans;
|
| - }
|
| + span->fDone = true;
|
| + ++fDoneSpans;
|
| return true;
|
| }
|
| return false;
|
| @@ -2378,7 +2118,7 @@
|
| }
|
|
|
| // look to see if the curve end intersects an intermediary that intersects the other
|
| -bool SkOpSegment::checkEnds() {
|
| +void SkOpSegment::checkEnds() {
|
| debugValidate();
|
| SkSTArray<kMissingSpanCount, MissingSpan, true> missingSpans;
|
| int count = fTs.count();
|
| @@ -2453,14 +2193,11 @@
|
| if (lastMissing.fT == t
|
| && lastMissing.fOther == match
|
| && lastMissing.fOtherT == matchT) {
|
| - SkASSERT(SkDPoint::ApproximatelyEqual(lastMissing.fPt, peekSpan.fPt));
|
| + SkASSERT(lastMissing.fPt == peekSpan.fPt);
|
| continue;
|
| }
|
| }
|
| - if (this == match) {
|
| - return false; // extremely large paths can trigger this
|
| - }
|
| -#if DEBUG_CHECK_ALIGN
|
| +#if DEBUG_CHECK_ENDS
|
| SkDebugf("%s id=%d missing t=%1.9g other=%d otherT=%1.9g pt=(%1.9g,%1.9g)\n",
|
| __FUNCTION__, fID, t, match->fID, matchT, peekSpan.fPt.fX, peekSpan.fPt.fY);
|
| #endif
|
| @@ -2482,7 +2219,7 @@
|
| }
|
| if (missingSpans.count() == 0) {
|
| debugValidate();
|
| - return true;
|
| + return;
|
| }
|
| debugValidate();
|
| int missingCount = missingSpans.count();
|
| @@ -2499,7 +2236,6 @@
|
| missingSpans[index].fOther->fixOtherTIndex();
|
| }
|
| debugValidate();
|
| - return true;
|
| }
|
|
|
| void SkOpSegment::checkLinks(const SkOpSpan* base,
|
| @@ -2521,7 +2257,7 @@
|
| }
|
| test = base;
|
| while (test < last && (++test)->fPt == base->fPt) {
|
| - SkASSERT(this != test->fOther || test->fLoop);
|
| + SkASSERT(this != test->fOther);
|
| CheckOneLink(test, oSpan, oFirst, oLast, &missing, missingSpans);
|
| }
|
| }
|
| @@ -3375,8 +3111,6 @@
|
| return -1;
|
| }
|
|
|
| -
|
| -
|
| int SkOpSegment::findOtherT(double t, const SkOpSegment* match) const {
|
| int count = this->count();
|
| for (int index = 0; index < count; ++index) {
|
| @@ -3463,19 +3197,14 @@
|
| SkOpSegment* next = angle->segment();
|
| SkPathOpsBounds bounds;
|
| next->subDivideBounds(angle->end(), angle->start(), &bounds);
|
| - bool nearSame = AlmostEqualUlps(top, bounds.top());
|
| - bool lowerSector = !firstAngle || angle->sectorEnd() < firstAngle->sectorStart();
|
| - bool lesserSector = top > bounds.fTop;
|
| - if (lesserSector && (!nearSame || lowerSector)) {
|
| + if (approximately_greater(top, bounds.fTop)) {
|
| top = bounds.fTop;
|
| firstAngle = angle;
|
| }
|
| }
|
| angle = angle->next();
|
| } while (angle != baseAngle);
|
| - if (!firstAngle) {
|
| - return NULL; // if all are unorderable, give up
|
| - }
|
| + SkASSERT(firstAngle);
|
| #if DEBUG_SORT
|
| SkDebugf("%s\n", __FUNCTION__);
|
| firstAngle->debugLoop();
|
| @@ -3572,72 +3301,6 @@
|
| return foundEnds == 0x3 || foundEnds == 0x5 || foundEnds == 0x6; // two bits set
|
| }
|
|
|
| -bool SkOpSegment::inconsistentAngle(int maxWinding, int sumWinding, int oppMaxWinding,
|
| - int oppSumWinding, const SkOpAngle* angle) const {
|
| - SkASSERT(angle->segment() == this);
|
| - if (UseInnerWinding(maxWinding, sumWinding)) {
|
| - maxWinding = sumWinding;
|
| - }
|
| - if (oppMaxWinding != oppSumWinding && UseInnerWinding(oppMaxWinding, oppSumWinding)) {
|
| - oppMaxWinding = oppSumWinding;
|
| - }
|
| - return inconsistentWinding(angle, maxWinding, oppMaxWinding);
|
| -}
|
| -
|
| -bool SkOpSegment::inconsistentWinding(const SkOpAngle* angle, int winding,
|
| - int oppWinding) const {
|
| - int index = angle->start();
|
| - int endIndex = angle->end();
|
| - int min = SkMin32(index, endIndex);
|
| - int step = SkSign32(endIndex - index);
|
| - if (inconsistentWinding(min, winding, oppWinding)) {
|
| - return true;
|
| - }
|
| - const SkOpSegment* other = this;
|
| - while ((other = other->nextChase(&index, &step, &min, NULL))) {
|
| - if (other->fTs[min].fWindSum != SK_MinS32) {
|
| - break;
|
| - }
|
| - if (fOperand == other->fOperand) {
|
| - if (other->inconsistentWinding(min, winding, oppWinding)) {
|
| - return true;
|
| - }
|
| - } else {
|
| - if (other->inconsistentWinding(min, oppWinding, winding)) {
|
| - return true;
|
| - }
|
| - }
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool SkOpSegment::inconsistentWinding(int index, int winding, int oppWinding) const {
|
| - SkASSERT(winding || oppWinding);
|
| - double referenceT = this->span(index).fT;
|
| - int lesser = index;
|
| - while (--lesser >= 0 && precisely_negative(referenceT - fTs[lesser].fT)) {
|
| - if (inconsistentWinding(__FUNCTION__, lesser, winding, oppWinding)) {
|
| - return true;
|
| - }
|
| - }
|
| - do {
|
| - if (inconsistentWinding(__FUNCTION__, index, winding, oppWinding)) {
|
| - return true;
|
| - }
|
| - } while (++index < fTs.count() && precisely_negative(fTs[index].fT - referenceT));
|
| - return false;
|
| -}
|
| -
|
| -bool SkOpSegment::inconsistentWinding(const char* funName, int tIndex, int winding,
|
| - int oppWinding) const {
|
| - const SkOpSpan& span = this->span(tIndex);
|
| - if (span.fDone && !span.fSmall) {
|
| - return false;
|
| - }
|
| - return (span.fWindSum != SK_MinS32 && span.fWindSum != winding)
|
| - || (span.fOppSum != SK_MinS32 && span.fOppSum != oppWinding);
|
| -}
|
| -
|
| void SkOpSegment::init(const SkPoint pts[], SkPath::Verb verb, bool operand, bool evenOdd) {
|
| fDoneSpans = 0;
|
| fOperand = operand;
|
| @@ -3649,18 +3312,16 @@
|
|
|
| void SkOpSegment::initWinding(int start, int end, SkOpAngle::IncludeType angleIncludeType) {
|
| int local = spanSign(start, end);
|
| - SkDEBUGCODE(bool success);
|
| if (angleIncludeType == SkOpAngle::kBinarySingle) {
|
| int oppLocal = oppSign(start, end);
|
| - SkDEBUGCODE(success =) markAndChaseWinding(start, end, local, oppLocal, NULL);
|
| + (void) markAndChaseWinding(start, end, local, oppLocal);
|
| // OPTIMIZATION: the reverse mark and chase could skip the first marking
|
| - SkDEBUGCODE(success |=) markAndChaseWinding(end, start, local, oppLocal, NULL);
|
| + (void) markAndChaseWinding(end, start, local, oppLocal);
|
| } else {
|
| - SkDEBUGCODE(success =) markAndChaseWinding(start, end, local, NULL);
|
| + (void) markAndChaseWinding(start, end, local);
|
| // OPTIMIZATION: the reverse mark and chase could skip the first marking
|
| - SkDEBUGCODE(success |=) markAndChaseWinding(end, start, local, NULL);
|
| - }
|
| - SkASSERT(success);
|
| + (void) markAndChaseWinding(end, start, local);
|
| + }
|
| }
|
|
|
| /*
|
| @@ -3672,7 +3333,7 @@
|
| from has the same x direction as this span, the winding should change. If the dx is opposite, then
|
| the same winding is shared by both.
|
| */
|
| -bool SkOpSegment::initWinding(int start, int end, double tHit, int winding, SkScalar hitDx,
|
| +void SkOpSegment::initWinding(int start, int end, double tHit, int winding, SkScalar hitDx,
|
| int oppWind, SkScalar hitOppDx) {
|
| SkASSERT(hitDx || !winding);
|
| SkScalar dx = (*CurveSlopeAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, tHit).fX;
|
| @@ -3700,11 +3361,9 @@
|
| #if DEBUG_WINDING_AT_T
|
| SkDebugf(" winding=%d oppWind=%d\n", winding, oppWind);
|
| #endif
|
| - // if this fails to mark (because the edges are too small) inform caller to try again
|
| - bool success = markAndChaseWinding(start, end, winding, oppWind, NULL);
|
| + (void) markAndChaseWinding(start, end, winding, oppWind);
|
| // OPTIMIZATION: the reverse mark and chase could skip the first marking
|
| - success |= markAndChaseWinding(end, start, winding, oppWind, NULL);
|
| - return success;
|
| + (void) markAndChaseWinding(end, start, winding, oppWind);
|
| }
|
|
|
| bool SkOpSegment::inLoop(const SkOpAngle* baseAngle, int spanCount, int* indexPtr) const {
|
| @@ -3768,9 +3427,7 @@
|
| if (otherWind == 0) {
|
| return false;
|
| }
|
| - if (next < 0) {
|
| - return false; // can happen if t values were adjusted but coincident ts were not
|
| - }
|
| + SkASSERT(next >= 0);
|
| int tIndex = 0;
|
| do {
|
| SkOpSpan* test = &fTs[tIndex];
|
| @@ -3785,9 +3442,7 @@
|
| if (cancel) {
|
| match->addTCancel(startPt, endPt, other);
|
| } else {
|
| - if (!match->addTCoincident(startPt, endPt, endT, other)) {
|
| - return false;
|
| - }
|
| + SkAssertResult(match->addTCoincident(startPt, endPt, endT, other));
|
| }
|
| return true;
|
| }
|
| @@ -3831,16 +3486,29 @@
|
| return last;
|
| }
|
|
|
| -bool SkOpSegment::markAndChaseWinding(const SkOpAngle* angle, int winding, SkOpSpan** lastPtr) {
|
| +SkOpSpan* SkOpSegment::markAndChaseWinding(const SkOpAngle* angle, int winding) {
|
| int index = angle->start();
|
| int endIndex = angle->end();
|
| - return markAndChaseWinding(index, endIndex, winding, lastPtr);
|
| -}
|
| -
|
| -bool SkOpSegment::markAndChaseWinding(int index, int endIndex, int winding, SkOpSpan** lastPtr) {
|
| + int step = SkSign32(endIndex - index);
|
| + int min = SkMin32(index, endIndex);
|
| + markWinding(min, winding);
|
| + SkOpSpan* last = NULL;
|
| + SkOpSegment* other = this;
|
| + while ((other = other->nextChase(&index, &step, &min, &last))) {
|
| + if (other->fTs[min].fWindSum != SK_MinS32) {
|
| +// SkASSERT(other->fTs[min].fWindSum == winding);
|
| + SkASSERT(!last);
|
| + break;
|
| + }
|
| + other->markWinding(min, winding);
|
| + }
|
| + return last;
|
| +}
|
| +
|
| +SkOpSpan* SkOpSegment::markAndChaseWinding(int index, int endIndex, int winding) {
|
| int min = SkMin32(index, endIndex);
|
| int step = SkSign32(endIndex - index);
|
| - bool success = markWinding(min, winding);
|
| + markWinding(min, winding);
|
| SkOpSpan* last = NULL;
|
| SkOpSegment* other = this;
|
| while ((other = other->nextChase(&index, &step, &min, &last))) {
|
| @@ -3849,19 +3517,15 @@
|
| SkASSERT(!last);
|
| break;
|
| }
|
| - (void) other->markWinding(min, winding);
|
| - }
|
| - if (lastPtr) {
|
| - *lastPtr = last;
|
| - }
|
| - return success;
|
| -}
|
| -
|
| -bool SkOpSegment::markAndChaseWinding(int index, int endIndex, int winding, int oppWinding,
|
| - SkOpSpan** lastPtr) {
|
| + other->markWinding(min, winding);
|
| + }
|
| + return last;
|
| +}
|
| +
|
| +SkOpSpan* SkOpSegment::markAndChaseWinding(int index, int endIndex, int winding, int oppWinding) {
|
| int min = SkMin32(index, endIndex);
|
| int step = SkSign32(endIndex - index);
|
| - bool success = markWinding(min, winding, oppWinding);
|
| + markWinding(min, winding, oppWinding);
|
| SkOpSpan* last = NULL;
|
| SkOpSegment* other = this;
|
| while ((other = other->nextChase(&index, &step, &min, &last))) {
|
| @@ -3885,22 +3549,18 @@
|
| break;
|
| }
|
| if (fOperand == other->fOperand) {
|
| - (void) other->markWinding(min, winding, oppWinding);
|
| + other->markWinding(min, winding, oppWinding);
|
| } else {
|
| - (void) other->markWinding(min, oppWinding, winding);
|
| - }
|
| - }
|
| - if (lastPtr) {
|
| - *lastPtr = last;
|
| - }
|
| - return success;
|
| -}
|
| -
|
| -bool SkOpSegment::markAndChaseWinding(const SkOpAngle* angle, int winding, int oppWinding,
|
| - SkOpSpan** lastPtr) {
|
| + other->markWinding(min, oppWinding, winding);
|
| + }
|
| + }
|
| + return last;
|
| +}
|
| +
|
| +SkOpSpan* SkOpSegment::markAndChaseWinding(const SkOpAngle* angle, int winding, int oppWinding) {
|
| int start = angle->start();
|
| int end = angle->end();
|
| - return markAndChaseWinding(start, end, winding, oppWinding, lastPtr);
|
| + return markAndChaseWinding(start, end, winding, oppWinding);
|
| }
|
|
|
| SkOpSpan* SkOpSegment::markAngle(int maxWinding, int sumWinding, const SkOpAngle* angle) {
|
| @@ -3908,8 +3568,7 @@
|
| if (UseInnerWinding(maxWinding, sumWinding)) {
|
| maxWinding = sumWinding;
|
| }
|
| - SkOpSpan* last;
|
| - SkAssertResult(markAndChaseWinding(angle, maxWinding, &last));
|
| + SkOpSpan* last = markAndChaseWinding(angle, maxWinding);
|
| #if DEBUG_WINDING
|
| if (last) {
|
| SkDebugf("%s last id=%d windSum=", __FUNCTION__,
|
| @@ -3930,9 +3589,7 @@
|
| if (oppMaxWinding != oppSumWinding && UseInnerWinding(oppMaxWinding, oppSumWinding)) {
|
| oppMaxWinding = oppSumWinding;
|
| }
|
| - SkOpSpan* last;
|
| - // caller doesn't require that this marks anything
|
| - (void) markAndChaseWinding(angle, maxWinding, oppMaxWinding, &last);
|
| + SkOpSpan* last = markAndChaseWinding(angle, maxWinding, oppMaxWinding);
|
| #if DEBUG_WINDING
|
| if (last) {
|
| SkDebugf("%s last id=%d windSum=", __FUNCTION__,
|
| @@ -3975,18 +3632,6 @@
|
| debugValidate();
|
| }
|
|
|
| -void SkOpSegment::markDoneFinal(int index) {
|
| - double referenceT = fTs[index].fT;
|
| - int lesser = index;
|
| - while (--lesser >= 0 && precisely_negative(referenceT - fTs[lesser].fT)) {
|
| - markOneDoneFinal(__FUNCTION__, lesser);
|
| - }
|
| - do {
|
| - markOneDoneFinal(__FUNCTION__, index);
|
| - } while (++index < fTs.count() && precisely_negative(fTs[index].fT - referenceT));
|
| - debugValidate();
|
| -}
|
| -
|
| void SkOpSegment::markDoneUnary(int index) {
|
| double referenceT = fTs[index].fT;
|
| int lesser = index;
|
| @@ -4000,22 +3645,12 @@
|
| }
|
|
|
| void SkOpSegment::markOneDone(const char* funName, int tIndex, int winding) {
|
| - SkOpSpan* span;
|
| - (void) markOneWinding(funName, tIndex, winding, &span); // allowed to do nothing
|
| - if (span->fDone) {
|
| + SkOpSpan* span = markOneWinding(funName, tIndex, winding);
|
| + if (!span || span->fDone) {
|
| return;
|
| }
|
| span->fDone = true;
|
| - ++fDoneSpans;
|
| -}
|
| -
|
| -void SkOpSegment::markOneDoneFinal(const char* funName, int tIndex) {
|
| - SkOpSpan* span = &fTs[tIndex];
|
| - if (span->fDone) {
|
| - return;
|
| - }
|
| - span->fDone = true;
|
| - ++fDoneSpans;
|
| + fDoneSpans++;
|
| }
|
|
|
| void SkOpSegment::markOneDoneBinary(const char* funName, int tIndex) {
|
| @@ -4025,7 +3660,7 @@
|
| }
|
| SkASSERT(!span->fDone);
|
| span->fDone = true;
|
| - ++fDoneSpans;
|
| + fDoneSpans++;
|
| }
|
|
|
| void SkOpSegment::markOneDoneUnary(const char* funName, int tIndex) {
|
| @@ -4038,52 +3673,46 @@
|
| }
|
| SkASSERT(!span->fDone);
|
| span->fDone = true;
|
| - ++fDoneSpans;
|
| -}
|
| -
|
| -bool SkOpSegment::markOneWinding(const char* funName, int tIndex, int winding, SkOpSpan** lastPtr) {
|
| - SkOpSpan* span = &fTs[tIndex];
|
| - if (lastPtr) {
|
| - *lastPtr = span;
|
| - }
|
| - if (span->fDone && !span->fSmall) {
|
| - return false;
|
| + fDoneSpans++;
|
| +}
|
| +
|
| +SkOpSpan* SkOpSegment::markOneWinding(const char* funName, int tIndex, int winding) {
|
| + SkOpSpan& span = fTs[tIndex];
|
| + if (span.fDone && !span.fSmall) {
|
| + return NULL;
|
| }
|
| #if DEBUG_MARK_DONE
|
| - debugShowNewWinding(funName, *span, winding);
|
| -#endif
|
| - SkASSERT(span->fWindSum == SK_MinS32 || span->fWindSum == winding);
|
| + debugShowNewWinding(funName, span, winding);
|
| +#endif
|
| + SkASSERT(span.fWindSum == SK_MinS32 || span.fWindSum == winding);
|
| #if DEBUG_LIMIT_WIND_SUM
|
| SkASSERT(abs(winding) <= DEBUG_LIMIT_WIND_SUM);
|
| #endif
|
| - span->fWindSum = winding;
|
| - return true;
|
| -}
|
| -
|
| -bool SkOpSegment::markOneWinding(const char* funName, int tIndex, int winding,
|
| - int oppWinding, SkOpSpan** lastPtr) {
|
| - SkOpSpan* span = &fTs[tIndex];
|
| - if (span->fDone && !span->fSmall) {
|
| - return false;
|
| + span.fWindSum = winding;
|
| + return &span;
|
| +}
|
| +
|
| +SkOpSpan* SkOpSegment::markOneWinding(const char* funName, int tIndex, int winding,
|
| + int oppWinding) {
|
| + SkOpSpan& span = fTs[tIndex];
|
| + if (span.fDone && !span.fSmall) {
|
| + return NULL;
|
| }
|
| #if DEBUG_MARK_DONE
|
| - debugShowNewWinding(funName, *span, winding, oppWinding);
|
| -#endif
|
| - SkASSERT(span->fWindSum == SK_MinS32 || span->fWindSum == winding);
|
| + debugShowNewWinding(funName, span, winding, oppWinding);
|
| +#endif
|
| + SkASSERT(span.fWindSum == SK_MinS32 || span.fWindSum == winding);
|
| #if DEBUG_LIMIT_WIND_SUM
|
| SkASSERT(abs(winding) <= DEBUG_LIMIT_WIND_SUM);
|
| #endif
|
| - span->fWindSum = winding;
|
| - SkASSERT(span->fOppSum == SK_MinS32 || span->fOppSum == oppWinding);
|
| + span.fWindSum = winding;
|
| + SkASSERT(span.fOppSum == SK_MinS32 || span.fOppSum == oppWinding);
|
| #if DEBUG_LIMIT_WIND_SUM
|
| SkASSERT(abs(oppWinding) <= DEBUG_LIMIT_WIND_SUM);
|
| #endif
|
| - span->fOppSum = oppWinding;
|
| + span.fOppSum = oppWinding;
|
| debugValidate();
|
| - if (lastPtr) {
|
| - *lastPtr = span;
|
| - }
|
| - return true;
|
| + return &span;
|
| }
|
|
|
| // from http://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-points-are-in-clockwise-order
|
| @@ -4207,36 +3836,32 @@
|
| return &span;
|
| }
|
|
|
| -bool SkOpSegment::markWinding(int index, int winding) {
|
| +void SkOpSegment::markWinding(int index, int winding) {
|
| // SkASSERT(!done());
|
| SkASSERT(winding);
|
| double referenceT = fTs[index].fT;
|
| int lesser = index;
|
| - bool success = false;
|
| while (--lesser >= 0 && precisely_negative(referenceT - fTs[lesser].fT)) {
|
| - success |= markOneWinding(__FUNCTION__, lesser, winding, NULL);
|
| + markOneWinding(__FUNCTION__, lesser, winding);
|
| }
|
| do {
|
| - success |= markOneWinding(__FUNCTION__, index, winding, NULL);
|
| + markOneWinding(__FUNCTION__, index, winding);
|
| } while (++index < fTs.count() && precisely_negative(fTs[index].fT - referenceT));
|
| debugValidate();
|
| - return success;
|
| -}
|
| -
|
| -bool SkOpSegment::markWinding(int index, int winding, int oppWinding) {
|
| +}
|
| +
|
| +void SkOpSegment::markWinding(int index, int winding, int oppWinding) {
|
| // SkASSERT(!done());
|
| SkASSERT(winding || oppWinding);
|
| double referenceT = fTs[index].fT;
|
| int lesser = index;
|
| - bool success = false;
|
| while (--lesser >= 0 && precisely_negative(referenceT - fTs[lesser].fT)) {
|
| - success |= markOneWinding(__FUNCTION__, lesser, winding, oppWinding, NULL);
|
| + markOneWinding(__FUNCTION__, lesser, winding, oppWinding);
|
| }
|
| do {
|
| - success |= markOneWinding(__FUNCTION__, index, winding, oppWinding, NULL);
|
| + markOneWinding(__FUNCTION__, index, winding, oppWinding);
|
| } while (++index < fTs.count() && precisely_negative(fTs[index].fT - referenceT));
|
| debugValidate();
|
| - return success;
|
| }
|
|
|
| void SkOpSegment::matchWindingValue(int tIndex, double t, bool borrowWind) {
|
| @@ -4299,20 +3924,19 @@
|
| return true;
|
| }
|
|
|
| -static SkOpSegment* set_last(SkOpSpan** last, const SkOpSpan* endSpan) {
|
| +static SkOpSegment* set_last(SkOpSpan** last, SkOpSpan* endSpan) {
|
| if (last && !endSpan->fSmall) {
|
| - *last = const_cast<SkOpSpan*>(endSpan); // FIXME: get rid of cast
|
| + *last = endSpan;
|
| }
|
| return NULL;
|
| }
|
|
|
| -SkOpSegment* SkOpSegment::nextChase(int* indexPtr, int* stepPtr, int* minPtr,
|
| - SkOpSpan** last) const {
|
| +SkOpSegment* SkOpSegment::nextChase(int* indexPtr, int* stepPtr, int* minPtr, SkOpSpan** last) {
|
| int origIndex = *indexPtr;
|
| int step = *stepPtr;
|
| int end = nextExactSpan(origIndex, step);
|
| SkASSERT(end >= 0);
|
| - const SkOpSpan& endSpan = this->span(end);
|
| + SkOpSpan& endSpan = fTs[end];
|
| SkOpAngle* angle = step > 0 ? endSpan.fFromAngle : endSpan.fToAngle;
|
| int foundIndex;
|
| int otherEnd;
|
|
|