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 |