| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 #include "SkIntersections.h" | 7 #include "SkIntersections.h" |
| 8 #include "SkOpContour.h" | 8 #include "SkOpContour.h" |
| 9 #include "SkOpSegment.h" | 9 #include "SkOpSegment.h" |
| 10 #include "SkPathWriter.h" | 10 #include "SkPathWriter.h" |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 default: | 400 default: |
| 401 SkASSERT(0); | 401 SkASSERT(0); |
| 402 } | 402 } |
| 403 } | 403 } |
| 404 } | 404 } |
| 405 // return ePtr[SkPathOpsVerbToPoints(fVerb)]; | 405 // return ePtr[SkPathOpsVerbToPoints(fVerb)]; |
| 406 } | 406 } |
| 407 | 407 |
| 408 void SkOpSegment::addEndSpan(int endIndex) { | 408 void SkOpSegment::addEndSpan(int endIndex) { |
| 409 SkASSERT(span(endIndex).fT == 1 || (span(endIndex).fTiny | 409 SkASSERT(span(endIndex).fT == 1 || (span(endIndex).fTiny |
| 410 && approximately_greater_than_one(span(endIndex).fT))); | 410 // && approximately_greater_than_one(span(endIndex).fT) |
| 411 )); |
| 411 int spanCount = fTs.count(); | 412 int spanCount = fTs.count(); |
| 412 int startIndex = endIndex - 1; | 413 int startIndex = endIndex - 1; |
| 413 while (fTs[startIndex].fT == 1 || fTs[startIndex].fTiny) { | 414 while (fTs[startIndex].fT == 1 || fTs[startIndex].fTiny) { |
| 414 --startIndex; | 415 --startIndex; |
| 415 SkASSERT(startIndex > 0); | 416 SkASSERT(startIndex > 0); |
| 416 --endIndex; | 417 --endIndex; |
| 417 } | 418 } |
| 418 SkOpAngle& angle = fAngles.push_back(); | 419 SkOpAngle& angle = fAngles.push_back(); |
| 419 angle.set(this, spanCount - 1, startIndex); | 420 angle.set(this, spanCount - 1, startIndex); |
| 420 #if DEBUG_ANGLE | 421 #if DEBUG_ANGLE |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 612 span->fNear = false; | 613 span->fNear = false; |
| 613 span->fMultiple = false; | 614 span->fMultiple = false; |
| 614 span->fSmall = false; | 615 span->fSmall = false; |
| 615 span->fTiny = false; | 616 span->fTiny = false; |
| 616 if ((span->fDone = newT == 1)) { | 617 if ((span->fDone = newT == 1)) { |
| 617 ++fDoneSpans; | 618 ++fDoneSpans; |
| 618 } | 619 } |
| 619 int less = -1; | 620 int less = -1; |
| 620 // FIXME: note that this relies on spans being a continguous array | 621 // FIXME: note that this relies on spans being a continguous array |
| 621 // find range of spans with nearly the same point as this one | 622 // find range of spans with nearly the same point as this one |
| 623 // FIXME: SkDPoint::ApproximatelyEqual is better but breaks tests at the mom
ent |
| 622 while (&span[less + 1] - fTs.begin() > 0 && AlmostEqualUlps(span[less].fPt,
pt)) { | 624 while (&span[less + 1] - fTs.begin() > 0 && AlmostEqualUlps(span[less].fPt,
pt)) { |
| 623 if (fVerb == SkPath::kCubic_Verb) { | 625 if (fVerb == SkPath::kCubic_Verb) { |
| 624 double tInterval = newT - span[less].fT; | 626 double tInterval = newT - span[less].fT; |
| 625 double tMid = newT - tInterval / 2; | 627 double tMid = newT - tInterval / 2; |
| 626 SkDPoint midPt = dcubic_xy_at_t(fPts, tMid); | 628 SkDPoint midPt = dcubic_xy_at_t(fPts, tMid); |
| 627 if (!midPt.approximatelyEqual(xyAtT(span))) { | 629 if (!midPt.approximatelyEqual(xyAtT(span))) { |
| 628 break; | 630 break; |
| 629 } | 631 } |
| 630 } | 632 } |
| 631 --less; | 633 --less; |
| 632 } | 634 } |
| 633 int more = 1; | 635 int more = 1; |
| 636 // FIXME: SkDPoint::ApproximatelyEqual is better but breaks tests at the mom
ent |
| 634 while (fTs.end() - &span[more - 1] > 1 && AlmostEqualUlps(span[more].fPt, pt
)) { | 637 while (fTs.end() - &span[more - 1] > 1 && AlmostEqualUlps(span[more].fPt, pt
)) { |
| 635 if (fVerb == SkPath::kCubic_Verb) { | 638 if (fVerb == SkPath::kCubic_Verb) { |
| 636 double tEndInterval = span[more].fT - newT; | 639 double tEndInterval = span[more].fT - newT; |
| 637 double tMid = newT - tEndInterval / 2; | 640 double tMid = newT - tEndInterval / 2; |
| 638 SkDPoint midEndPt = dcubic_xy_at_t(fPts, tMid); | 641 SkDPoint midEndPt = dcubic_xy_at_t(fPts, tMid); |
| 639 if (!midEndPt.approximatelyEqual(xyAtT(span))) { | 642 if (!midEndPt.approximatelyEqual(xyAtT(span))) { |
| 640 break; | 643 break; |
| 641 } | 644 } |
| 642 } | 645 } |
| 643 ++more; | 646 ++more; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 697 --index; | 700 --index; |
| 698 } | 701 } |
| 699 bool oFoundEnd = false; | 702 bool oFoundEnd = false; |
| 700 int oIndex = other->fTs.count(); | 703 int oIndex = other->fTs.count(); |
| 701 while (startPt != other->fTs[--oIndex].fPt) { // look for startPt match | 704 while (startPt != other->fTs[--oIndex].fPt) { // look for startPt match |
| 702 SkASSERT(oIndex > 0); | 705 SkASSERT(oIndex > 0); |
| 703 } | 706 } |
| 704 double oStartT = other->fTs[oIndex].fT; | 707 double oStartT = other->fTs[oIndex].fT; |
| 705 // look for first point beyond match | 708 // look for first point beyond match |
| 706 while (startPt == other->fTs[--oIndex].fPt || precisely_equal(oStartT, other
->fTs[oIndex].fT)) { | 709 while (startPt == other->fTs[--oIndex].fPt || precisely_equal(oStartT, other
->fTs[oIndex].fT)) { |
| 707 SkASSERT(oIndex > 0); | 710 if (!oIndex) { |
| 711 return; // tiny spans may move in the wrong direction |
| 712 } |
| 708 } | 713 } |
| 709 SkOpSpan* test = &fTs[index]; | 714 SkOpSpan* test = &fTs[index]; |
| 710 SkOpSpan* oTest = &other->fTs[oIndex]; | 715 SkOpSpan* oTest = &other->fTs[oIndex]; |
| 711 SkSTArray<kOutsideTrackedTCount, SkPoint, true> outsidePts; | 716 SkSTArray<kOutsideTrackedTCount, SkPoint, true> outsidePts; |
| 712 SkSTArray<kOutsideTrackedTCount, SkPoint, true> oOutsidePts; | 717 SkSTArray<kOutsideTrackedTCount, SkPoint, true> oOutsidePts; |
| 713 bool decrement, track, bigger; | 718 bool decrement, track, bigger; |
| 714 int originalWindValue; | 719 int originalWindValue; |
| 715 const SkPoint* testPt; | 720 const SkPoint* testPt; |
| 716 const SkPoint* oTestPt; | 721 const SkPoint* oTestPt; |
| 717 do { | 722 do { |
| (...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1401 } | 1406 } |
| 1402 if (!other->done() && oOutsidePts.count()) { | 1407 if (!other->done() && oOutsidePts.count()) { |
| 1403 other->addCoinOutsides(oOutsidePts[0], endPt, this); | 1408 other->addCoinOutsides(oOutsidePts[0], endPt, this); |
| 1404 } | 1409 } |
| 1405 setCoincidentRange(startPt, endPt, other); | 1410 setCoincidentRange(startPt, endPt, other); |
| 1406 other->setCoincidentRange(startPt, endPt, this); | 1411 other->setCoincidentRange(startPt, endPt, this); |
| 1407 } | 1412 } |
| 1408 | 1413 |
| 1409 // FIXME: this doesn't prevent the same span from being added twice | 1414 // FIXME: this doesn't prevent the same span from being added twice |
| 1410 // fix in caller, SkASSERT here? | 1415 // fix in caller, SkASSERT here? |
| 1416 // FIXME: this may erroneously reject adds for cubic loops |
| 1411 const SkOpSpan* SkOpSegment::addTPair(double t, SkOpSegment* other, double other
T, bool borrowWind, | 1417 const SkOpSpan* SkOpSegment::addTPair(double t, SkOpSegment* other, double other
T, bool borrowWind, |
| 1412 const SkPoint& pt, const SkPoint& pt2) { | 1418 const SkPoint& pt, const SkPoint& pt2) { |
| 1413 int tCount = fTs.count(); | 1419 int tCount = fTs.count(); |
| 1414 for (int tIndex = 0; tIndex < tCount; ++tIndex) { | 1420 for (int tIndex = 0; tIndex < tCount; ++tIndex) { |
| 1415 const SkOpSpan& span = fTs[tIndex]; | 1421 const SkOpSpan& span = fTs[tIndex]; |
| 1416 if (!approximately_negative(span.fT - t)) { | 1422 if (!approximately_negative(span.fT - t)) { |
| 1417 break; | 1423 break; |
| 1418 } | 1424 } |
| 1419 if (approximately_negative(span.fT - t) && span.fOther == other | 1425 if (span.fOther == other) { |
| 1420 && approximately_equal(span.fOtherT, otherT)) { | 1426 bool tsMatch = approximately_equal(span.fT, t); |
| 1427 bool otherTsMatch = approximately_equal(span.fOtherT, otherT); |
| 1428 // FIXME: add cubic loop detecting logic here |
| 1429 // if fLoop bit is set on span, that could be enough if addOtherT co
pies the bit |
| 1430 // or if a new bit is added ala fOtherLoop |
| 1431 if (tsMatch || otherTsMatch) { |
| 1421 #if DEBUG_ADD_T_PAIR | 1432 #if DEBUG_ADD_T_PAIR |
| 1422 SkDebugf("%s addTPair duplicate this=%d %1.9g other=%d %1.9g\n", | 1433 SkDebugf("%s addTPair duplicate this=%d %1.9g other=%d %1.9g\n", |
| 1423 __FUNCTION__, fID, t, other->fID, otherT); | 1434 __FUNCTION__, fID, t, other->fID, otherT); |
| 1424 #endif | 1435 #endif |
| 1425 return NULL; | 1436 return NULL; |
| 1437 } |
| 1438 } |
| 1439 } |
| 1440 int oCount = other->count(); |
| 1441 for (int oIndex = 0; oIndex < oCount; ++oIndex) { |
| 1442 const SkOpSpan& oSpan = other->span(oIndex); |
| 1443 if (!approximately_negative(oSpan.fT - otherT)) { |
| 1444 break; |
| 1445 } |
| 1446 if (oSpan.fOther == this) { |
| 1447 bool otherTsMatch = approximately_equal(oSpan.fT, otherT); |
| 1448 bool tsMatch = approximately_equal(oSpan.fOtherT, t); |
| 1449 if (otherTsMatch || tsMatch) { |
| 1450 #if DEBUG_ADD_T_PAIR |
| 1451 SkDebugf("%s addTPair other duplicate this=%d %1.9g other=%d %1.
9g\n", |
| 1452 __FUNCTION__, fID, t, other->fID, otherT); |
| 1453 #endif |
| 1454 return NULL; |
| 1455 } |
| 1426 } | 1456 } |
| 1427 } | 1457 } |
| 1428 #if DEBUG_ADD_T_PAIR | 1458 #if DEBUG_ADD_T_PAIR |
| 1429 SkDebugf("%s addTPair this=%d %1.9g other=%d %1.9g\n", | 1459 SkDebugf("%s addTPair this=%d %1.9g other=%d %1.9g\n", |
| 1430 __FUNCTION__, fID, t, other->fID, otherT); | 1460 __FUNCTION__, fID, t, other->fID, otherT); |
| 1431 #endif | 1461 #endif |
| 1462 SkASSERT(other != this); |
| 1432 int insertedAt = addT(other, pt, t); | 1463 int insertedAt = addT(other, pt, t); |
| 1433 int otherInsertedAt = other->addT(this, pt2, otherT); | 1464 int otherInsertedAt = other->addT(this, pt2, otherT); |
| 1434 addOtherT(insertedAt, otherT, otherInsertedAt); | 1465 addOtherT(insertedAt, otherT, otherInsertedAt); |
| 1435 other->addOtherT(otherInsertedAt, t, insertedAt); | 1466 other->addOtherT(otherInsertedAt, t, insertedAt); |
| 1436 matchWindingValue(insertedAt, t, borrowWind); | 1467 matchWindingValue(insertedAt, t, borrowWind); |
| 1437 other->matchWindingValue(otherInsertedAt, otherT, borrowWind); | 1468 other->matchWindingValue(otherInsertedAt, otherT, borrowWind); |
| 1438 SkOpSpan& span = this->fTs[insertedAt]; | 1469 SkOpSpan& span = this->fTs[insertedAt]; |
| 1439 if (pt != pt2) { | 1470 if (pt != pt2) { |
| 1440 span.fNear = true; | 1471 span.fNear = true; |
| 1441 SkOpSpan& oSpan = other->fTs[otherInsertedAt]; | 1472 SkOpSpan& oSpan = other->fTs[otherInsertedAt]; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1562 while (span->fTiny /* || span->fSmall */) { | 1593 while (span->fTiny /* || span->fSmall */) { |
| 1563 span = &fTs[++tIndex]; | 1594 span = &fTs[++tIndex]; |
| 1564 } | 1595 } |
| 1565 return isCanceled(tIndex) ? -1 : tIndex; | 1596 return isCanceled(tIndex) ? -1 : tIndex; |
| 1566 } | 1597 } |
| 1567 | 1598 |
| 1568 // at this point, the span is already ordered, or unorderable | 1599 // at this point, the span is already ordered, or unorderable |
| 1569 int SkOpSegment::computeSum(int startIndex, int endIndex, SkOpAngle::IncludeType
includeType) { | 1600 int SkOpSegment::computeSum(int startIndex, int endIndex, SkOpAngle::IncludeType
includeType) { |
| 1570 SkASSERT(includeType != SkOpAngle::kUnaryXor); | 1601 SkASSERT(includeType != SkOpAngle::kUnaryXor); |
| 1571 SkOpAngle* firstAngle = spanToAngle(endIndex, startIndex); | 1602 SkOpAngle* firstAngle = spanToAngle(endIndex, startIndex); |
| 1572 if (NULL == firstAngle) { | 1603 if (NULL == firstAngle || NULL == firstAngle->next()) { |
| 1573 return SK_NaN32; | 1604 return SK_NaN32; |
| 1574 } | 1605 } |
| 1575 // if all angles have a computed winding, | 1606 // if all angles have a computed winding, |
| 1576 // or if no adjacent angles are orderable, | 1607 // or if no adjacent angles are orderable, |
| 1577 // or if adjacent orderable angles have no computed winding, | 1608 // or if adjacent orderable angles have no computed winding, |
| 1578 // there's nothing to do | 1609 // there's nothing to do |
| 1579 // if two orderable angles are adjacent, and both are next to orderable angl
es, | 1610 // if two orderable angles are adjacent, and both are next to orderable angl
es, |
| 1580 // and one has winding computed, transfer to the other | 1611 // and one has winding computed, transfer to the other |
| 1581 SkOpAngle* baseAngle = NULL; | 1612 SkOpAngle* baseAngle = NULL; |
| 1582 bool tryReverse = false; | 1613 bool tryReverse = false; |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2155 #if DEBUG_CHECK_ENDS | 2186 #if DEBUG_CHECK_ENDS |
| 2156 SkDebugf("%s id=%d missing t=%1.9g other=%d otherT=%1.9g pt=(%1.9g,%
1.9g)\n", | 2187 SkDebugf("%s id=%d missing t=%1.9g other=%d otherT=%1.9g pt=(%1.9g,%
1.9g)\n", |
| 2157 __FUNCTION__, fID, t, match->fID, matchT, peekSpan.fPt.fX, p
eekSpan.fPt.fY); | 2188 __FUNCTION__, fID, t, match->fID, matchT, peekSpan.fPt.fX, p
eekSpan.fPt.fY); |
| 2158 #endif | 2189 #endif |
| 2159 // this segment is missing a entry that the other contains | 2190 // this segment is missing a entry that the other contains |
| 2160 // remember so we can add the missing one and recompute the indices | 2191 // remember so we can add the missing one and recompute the indices |
| 2161 { | 2192 { |
| 2162 MissingSpan& missing = missingSpans.push_back(); | 2193 MissingSpan& missing = missingSpans.push_back(); |
| 2163 SkDEBUGCODE(sk_bzero(&missing, sizeof(missing))); | 2194 SkDEBUGCODE(sk_bzero(&missing, sizeof(missing))); |
| 2164 missing.fT = t; | 2195 missing.fT = t; |
| 2196 SkASSERT(this != match); |
| 2165 missing.fOther = match; | 2197 missing.fOther = match; |
| 2166 missing.fOtherT = matchT; | 2198 missing.fOtherT = matchT; |
| 2167 missing.fPt = peekSpan.fPt; | 2199 missing.fPt = peekSpan.fPt; |
| 2168 } | 2200 } |
| 2169 break; | 2201 break; |
| 2170 nextPeekIndex: | 2202 nextPeekIndex: |
| 2171 ; | 2203 ; |
| 2172 } | 2204 } |
| 2173 } | 2205 } |
| 2174 if (missingSpans.count() == 0) { | 2206 if (missingSpans.count() == 0) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2197 const SkOpSpan* first = fTs.begin(); | 2229 const SkOpSpan* first = fTs.begin(); |
| 2198 const SkOpSpan* last = fTs.end() - 1; | 2230 const SkOpSpan* last = fTs.end() - 1; |
| 2199 SkASSERT(base >= first && last >= base); | 2231 SkASSERT(base >= first && last >= base); |
| 2200 const SkOpSegment* other = base->fOther; | 2232 const SkOpSegment* other = base->fOther; |
| 2201 const SkOpSpan* oFirst = other->fTs.begin(); | 2233 const SkOpSpan* oFirst = other->fTs.begin(); |
| 2202 const SkOpSpan* oLast = other->fTs.end() - 1; | 2234 const SkOpSpan* oLast = other->fTs.end() - 1; |
| 2203 const SkOpSpan* oSpan = &other->fTs[base->fOtherIndex]; | 2235 const SkOpSpan* oSpan = &other->fTs[base->fOtherIndex]; |
| 2204 const SkOpSpan* test = base; | 2236 const SkOpSpan* test = base; |
| 2205 const SkOpSpan* missing = NULL; | 2237 const SkOpSpan* missing = NULL; |
| 2206 while (test > first && (--test)->fPt == base->fPt) { | 2238 while (test > first && (--test)->fPt == base->fPt) { |
| 2239 if (this == test->fOther) { |
| 2240 continue; |
| 2241 } |
| 2207 CheckOneLink(test, oSpan, oFirst, oLast, &missing, missingSpans); | 2242 CheckOneLink(test, oSpan, oFirst, oLast, &missing, missingSpans); |
| 2208 } | 2243 } |
| 2209 test = base; | 2244 test = base; |
| 2210 while (test < last && (++test)->fPt == base->fPt) { | 2245 while (test < last && (++test)->fPt == base->fPt) { |
| 2246 SkASSERT(this != test->fOther); |
| 2211 CheckOneLink(test, oSpan, oFirst, oLast, &missing, missingSpans); | 2247 CheckOneLink(test, oSpan, oFirst, oLast, &missing, missingSpans); |
| 2212 } | 2248 } |
| 2213 } | 2249 } |
| 2214 | 2250 |
| 2215 // see if spans with two or more intersections all agree on common t and point v
alues | 2251 // see if spans with two or more intersections all agree on common t and point v
alues |
| 2216 void SkOpSegment::checkMultiples() { | 2252 void SkOpSegment::checkMultiples() { |
| 2217 debugValidate(); | 2253 debugValidate(); |
| 2218 int index; | 2254 int index; |
| 2219 int end = 0; | 2255 int end = 0; |
| 2220 while (fTs[++end].fT == 0) | 2256 while (fTs[++end].fT == 0) |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2449 if (!SkDPoint::ApproximatelyEqual(mid, oMid)) { | 2485 if (!SkDPoint::ApproximatelyEqual(mid, oMid)) { |
| 2450 return; | 2486 return; |
| 2451 } | 2487 } |
| 2452 } | 2488 } |
| 2453 // FIXME: again, be overly conservative to avoid breaking existing tests | 2489 // FIXME: again, be overly conservative to avoid breaking existing tests |
| 2454 const SkOpSpan& oSpan = oStartIndex < oEndIndex ? other->fTs[oStartIndex] | 2490 const SkOpSpan& oSpan = oStartIndex < oEndIndex ? other->fTs[oStartIndex] |
| 2455 : other->fTs[oEndIndex]; | 2491 : other->fTs[oEndIndex]; |
| 2456 if (checkMultiple && !oSpan.fSmall) { | 2492 if (checkMultiple && !oSpan.fSmall) { |
| 2457 return; | 2493 return; |
| 2458 } | 2494 } |
| 2459 SkASSERT(oSpan.fSmall); | 2495 // SkASSERT(oSpan.fSmall); |
| 2460 if (oStartIndex < oEndIndex) { | 2496 if (oStartIndex < oEndIndex) { |
| 2461 addTCoincident(span.fPt, next->fPt, next->fT, other); | 2497 addTCoincident(span.fPt, next->fPt, next->fT, other); |
| 2462 } else { | 2498 } else { |
| 2463 addTCancel(span.fPt, next->fPt, other); | 2499 addTCancel(span.fPt, next->fPt, other); |
| 2464 } | 2500 } |
| 2465 if (!checkMultiple) { | 2501 if (!checkMultiple) { |
| 2466 return; | 2502 return; |
| 2467 } | 2503 } |
| 2468 // check to see if either segment is coincident with a third segment -- if i
t is, and if | 2504 // check to see if either segment is coincident with a third segment -- if i
t is, and if |
| 2469 // the opposite segment is not already coincident with the third, make it so | 2505 // the opposite segment is not already coincident with the third, make it so |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2570 #if DEBUG_CHECK_TINY | 2606 #if DEBUG_CHECK_TINY |
| 2571 SkDebugf("%s [%d] add coincidence [%d] [%d]\n", __FUNCTION__, fI
D, | 2607 SkDebugf("%s [%d] add coincidence [%d] [%d]\n", __FUNCTION__, fI
D, |
| 2572 thisOther->fID, nextOther->fID); | 2608 thisOther->fID, nextOther->fID); |
| 2573 #endif | 2609 #endif |
| 2574 // this segment is missing a entry that the other contains | 2610 // this segment is missing a entry that the other contains |
| 2575 // remember so we can add the missing one and recompute the indi
ces | 2611 // remember so we can add the missing one and recompute the indi
ces |
| 2576 MissingSpan& missing = missingSpans.push_back(); | 2612 MissingSpan& missing = missingSpans.push_back(); |
| 2577 SkDEBUGCODE(sk_bzero(&missing, sizeof(missing))); | 2613 SkDEBUGCODE(sk_bzero(&missing, sizeof(missing))); |
| 2578 missing.fSegment = thisOther; | 2614 missing.fSegment = thisOther; |
| 2579 missing.fT = thisSpan->fOtherT; | 2615 missing.fT = thisSpan->fOtherT; |
| 2616 SkASSERT(this != nextOther); |
| 2580 missing.fOther = nextOther; | 2617 missing.fOther = nextOther; |
| 2581 missing.fOtherT = nextSpan->fOtherT; | 2618 missing.fOtherT = nextSpan->fOtherT; |
| 2582 missing.fPt = thisSpan->fPt; | 2619 missing.fPt = thisSpan->fPt; |
| 2583 } | 2620 } |
| 2584 } | 2621 } |
| 2585 } | 2622 } |
| 2586 int missingCount = missingSpans.count(); | 2623 int missingCount = missingSpans.count(); |
| 2587 if (!missingCount) { | 2624 if (!missingCount) { |
| 2588 return; | 2625 return; |
| 2589 } | 2626 } |
| (...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3480 while ((other = other->nextChase(&index, &step, &min, &last))) { | 3517 while ((other = other->nextChase(&index, &step, &min, &last))) { |
| 3481 if (other->fTs[min].fWindSum != SK_MinS32) { | 3518 if (other->fTs[min].fWindSum != SK_MinS32) { |
| 3482 #ifdef SK_DEBUG | 3519 #ifdef SK_DEBUG |
| 3483 if (!other->fTs[min].fLoop) { | 3520 if (!other->fTs[min].fLoop) { |
| 3484 if (fOperand == other->fOperand) { | 3521 if (fOperand == other->fOperand) { |
| 3485 // FIXME: this is probably a bug -- rects4 asserts here | 3522 // FIXME: this is probably a bug -- rects4 asserts here |
| 3486 // SkASSERT(other->fTs[min].fWindSum == winding); | 3523 // SkASSERT(other->fTs[min].fWindSum == winding); |
| 3487 // FIXME: this is probably a bug -- rects3 asserts here | 3524 // FIXME: this is probably a bug -- rects3 asserts here |
| 3488 // SkASSERT(other->fTs[min].fOppSum == oppWinding); | 3525 // SkASSERT(other->fTs[min].fOppSum == oppWinding); |
| 3489 } else { | 3526 } else { |
| 3490 SkASSERT(other->fTs[min].fWindSum == oppWinding); | 3527 // FIXME: this is probably a bug -- issue414409b asserts here |
| 3528 // SkASSERT(other->fTs[min].fWindSum == oppWinding); |
| 3491 // FIXME: this is probably a bug -- skpwww_joomla_org_23 asserts here | 3529 // FIXME: this is probably a bug -- skpwww_joomla_org_23 asserts here |
| 3492 // SkASSERT(other->fTs[min].fOppSum == winding); | 3530 // SkASSERT(other->fTs[min].fOppSum == winding); |
| 3493 } | 3531 } |
| 3494 } | 3532 } |
| 3495 SkASSERT(!last); | 3533 SkASSERT(!last); |
| 3496 #endif | 3534 #endif |
| 3497 break; | 3535 break; |
| 3498 } | 3536 } |
| 3499 if (fOperand == other->fOperand) { | 3537 if (fOperand == other->fOperand) { |
| 3500 other->markWinding(min, winding, oppWinding); | 3538 other->markWinding(min, winding, oppWinding); |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3895 } | 3933 } |
| 3896 other = endSpan.fOther; | 3934 other = endSpan.fOther; |
| 3897 foundIndex = endSpan.fOtherIndex; | 3935 foundIndex = endSpan.fOtherIndex; |
| 3898 otherEnd = other->nextExactSpan(foundIndex, step); | 3936 otherEnd = other->nextExactSpan(foundIndex, step); |
| 3899 } else { | 3937 } else { |
| 3900 int loopCount = angle->loopCount(); | 3938 int loopCount = angle->loopCount(); |
| 3901 if (loopCount > 2) { | 3939 if (loopCount > 2) { |
| 3902 return set_last(last, &endSpan); | 3940 return set_last(last, &endSpan); |
| 3903 } | 3941 } |
| 3904 const SkOpAngle* next = angle->next(); | 3942 const SkOpAngle* next = angle->next(); |
| 3943 if (NULL == next) { |
| 3944 return NULL; |
| 3945 } |
| 3905 if (angle->sign() != next->sign()) { | 3946 if (angle->sign() != next->sign()) { |
| 3906 #if DEBUG_WINDING | 3947 #if DEBUG_WINDING |
| 3907 SkDebugf("%s mismatched signs\n", __FUNCTION__); | 3948 SkDebugf("%s mismatched signs\n", __FUNCTION__); |
| 3908 #endif | 3949 #endif |
| 3909 // return set_last(last, &endSpan); | 3950 // return set_last(last, &endSpan); |
| 3910 } | 3951 } |
| 3911 other = next->segment(); | 3952 other = next->segment(); |
| 3912 foundIndex = end = next->start(); | 3953 foundIndex = end = next->start(); |
| 3913 otherEnd = next->end(); | 3954 otherEnd = next->end(); |
| 3914 } | 3955 } |
| 3915 int foundStep = foundIndex < otherEnd ? 1 : -1; | 3956 int foundStep = foundIndex < otherEnd ? 1 : -1; |
| 3916 if (*stepPtr != foundStep) { | 3957 if (*stepPtr != foundStep) { |
| 3917 return set_last(last, &endSpan); | 3958 return set_last(last, &endSpan); |
| 3918 } | 3959 } |
| 3919 SkASSERT(*indexPtr >= 0); | 3960 SkASSERT(*indexPtr >= 0); |
| 3920 SkASSERT(otherEnd >= 0); | 3961 if (otherEnd < 0) { |
| 3962 return NULL; |
| 3963 } |
| 3964 // SkASSERT(otherEnd >= 0); |
| 3921 #if 1 | 3965 #if 1 |
| 3922 int origMin = origIndex + (step < 0 ? step : 0); | 3966 int origMin = origIndex + (step < 0 ? step : 0); |
| 3923 const SkOpSpan& orig = this->span(origMin); | 3967 const SkOpSpan& orig = this->span(origMin); |
| 3924 #endif | 3968 #endif |
| 3925 int foundMin = SkMin32(foundIndex, otherEnd); | 3969 int foundMin = SkMin32(foundIndex, otherEnd); |
| 3926 #if 1 | 3970 #if 1 |
| 3927 const SkOpSpan& found = other->span(foundMin); | 3971 const SkOpSpan& found = other->span(foundMin); |
| 3928 if (found.fWindValue != orig.fWindValue || found.fOppValue != orig.fOppValue
) { | 3972 if (found.fWindValue != orig.fWindValue || found.fOppValue != orig.fOppValue
) { |
| 3929 return set_last(last, &endSpan); | 3973 return set_last(last, &endSpan); |
| 3930 } | 3974 } |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4397 SkASSERT(span->fWindValue > 0 || span->fOppValue != 0); | 4441 SkASSERT(span->fWindValue > 0 || span->fOppValue != 0); |
| 4398 span->fWindValue = 0; | 4442 span->fWindValue = 0; |
| 4399 span->fOppValue = 0; | 4443 span->fOppValue = 0; |
| 4400 if (span->fTiny || span->fSmall) { | 4444 if (span->fTiny || span->fSmall) { |
| 4401 return; | 4445 return; |
| 4402 } | 4446 } |
| 4403 SkASSERT(!span->fDone); | 4447 SkASSERT(!span->fDone); |
| 4404 span->fDone = true; | 4448 span->fDone = true; |
| 4405 ++fDoneSpans; | 4449 ++fDoneSpans; |
| 4406 } | 4450 } |
| OLD | NEW |