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; |