| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 #ifndef SkPathOpsTSect_DEFINED | 7 #ifndef SkPathOpsTSect_DEFINED |
| 8 #define SkPathOpsTSect_DEFINED | 8 #define SkPathOpsTSect_DEFINED |
| 9 | 9 |
| 10 #include "SkChunkAlloc.h" | 10 #include "SkChunkAlloc.h" |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 } | 130 } |
| 131 | 131 |
| 132 SkDEBUGCODE(SkOpGlobalState* globalState() const { return fDebugGlobalState;
}) | 132 SkDEBUGCODE(SkOpGlobalState* globalState() const { return fDebugGlobalState;
}) |
| 133 | 133 |
| 134 bool hasOppT(double t) const { | 134 bool hasOppT(double t) const { |
| 135 return SkToBool(oppT(t)); | 135 return SkToBool(oppT(t)); |
| 136 } | 136 } |
| 137 | 137 |
| 138 int hullsIntersect(SkTSpan<OppCurve, TCurve>* span, bool* start, bool* oppSt
art); | 138 int hullsIntersect(SkTSpan<OppCurve, TCurve>* span, bool* start, bool* oppSt
art); |
| 139 void init(const TCurve& ); | 139 void init(const TCurve& ); |
| 140 void initBounds(const TCurve& ); | 140 bool initBounds(const TCurve& ); |
| 141 | 141 |
| 142 bool isBounded() const { | 142 bool isBounded() const { |
| 143 return fBounded != nullptr; | 143 return fBounded != nullptr; |
| 144 } | 144 } |
| 145 | 145 |
| 146 bool linearsIntersect(SkTSpan<OppCurve, TCurve>* span); | 146 bool linearsIntersect(SkTSpan<OppCurve, TCurve>* span); |
| 147 double linearT(const SkDPoint& ) const; | 147 double linearT(const SkDPoint& ) const; |
| 148 | 148 |
| 149 void markCoincident() { | 149 void markCoincident() { |
| 150 fCoinStart.markCoincident(); | 150 fCoinStart.markCoincident(); |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 void removeByPerpendicular(SkTSect<OppCurve, TCurve>* opp); | 310 void removeByPerpendicular(SkTSect<OppCurve, TCurve>* opp); |
| 311 void recoverCollapsed(); | 311 void recoverCollapsed(); |
| 312 void removeCoincident(SkTSpan<TCurve, OppCurve>* span, bool isBetween); | 312 void removeCoincident(SkTSpan<TCurve, OppCurve>* span, bool isBetween); |
| 313 void removeAllBut(const SkTSpan<OppCurve, TCurve>* keep, SkTSpan<TCurve, Opp
Curve>* span, | 313 void removeAllBut(const SkTSpan<OppCurve, TCurve>* keep, SkTSpan<TCurve, Opp
Curve>* span, |
| 314 SkTSect<OppCurve, TCurve>* opp); | 314 SkTSect<OppCurve, TCurve>* opp); |
| 315 bool removeSpan(SkTSpan<TCurve, OppCurve>* span); | 315 bool removeSpan(SkTSpan<TCurve, OppCurve>* span); |
| 316 void removeSpanRange(SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCu
rve>* last); | 316 void removeSpanRange(SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCu
rve>* last); |
| 317 void removeSpans(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>*
opp); | 317 void removeSpans(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>*
opp); |
| 318 SkTSpan<TCurve, OppCurve>* spanAtT(double t, SkTSpan<TCurve, OppCurve>** pri
orSpan); | 318 SkTSpan<TCurve, OppCurve>* spanAtT(double t, SkTSpan<TCurve, OppCurve>** pri
orSpan); |
| 319 SkTSpan<TCurve, OppCurve>* tail(); | 319 SkTSpan<TCurve, OppCurve>* tail(); |
| 320 void trim(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>* opp); | 320 bool trim(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>* opp); |
| 321 void unlinkSpan(SkTSpan<TCurve, OppCurve>* span); | 321 void unlinkSpan(SkTSpan<TCurve, OppCurve>* span); |
| 322 bool updateBounded(SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCurv
e>* last, | 322 bool updateBounded(SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCurv
e>* last, |
| 323 SkTSpan<OppCurve, TCurve>* oppFirst); | 323 SkTSpan<OppCurve, TCurve>* oppFirst); |
| 324 void validate() const; | 324 void validate() const; |
| 325 void validateBounded() const; | 325 void validateBounded() const; |
| 326 | 326 |
| 327 const TCurve& fCurve; | 327 const TCurve& fCurve; |
| 328 SkChunkAlloc fHeap; | 328 SkChunkAlloc fHeap; |
| 329 SkTSpan<TCurve, OppCurve>* fHead; | 329 SkTSpan<TCurve, OppCurve>* fHead; |
| 330 SkTSpan<TCurve, OppCurve>* fCoincident; | 330 SkTSpan<TCurve, OppCurve>* fCoincident; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 344 friend class SkTSect<OppCurve, TCurve>; | 344 friend class SkTSect<OppCurve, TCurve>; |
| 345 }; | 345 }; |
| 346 | 346 |
| 347 #define COINCIDENT_SPAN_COUNT 9 | 347 #define COINCIDENT_SPAN_COUNT 9 |
| 348 | 348 |
| 349 template<typename TCurve, typename OppCurve> | 349 template<typename TCurve, typename OppCurve> |
| 350 void SkTCoincident<TCurve, OppCurve>::setPerp(const TCurve& c1, double t, | 350 void SkTCoincident<TCurve, OppCurve>::setPerp(const TCurve& c1, double t, |
| 351 const SkDPoint& cPt, const OppCurve& c2) { | 351 const SkDPoint& cPt, const OppCurve& c2) { |
| 352 SkDVector dxdy = c1.dxdyAtT(t); | 352 SkDVector dxdy = c1.dxdyAtT(t); |
| 353 SkDLine perp = {{ cPt, {cPt.fX + dxdy.fY, cPt.fY - dxdy.fX} }}; | 353 SkDLine perp = {{ cPt, {cPt.fX + dxdy.fY, cPt.fY - dxdy.fX} }}; |
| 354 SkIntersections i; | 354 SkIntersections i SkDEBUGCODE((c1.globalState())); |
| 355 int used = i.intersectRay(c2, perp); | 355 int used = i.intersectRay(c2, perp); |
| 356 // only keep closest | 356 // only keep closest |
| 357 if (used == 0 || used == 3) { | 357 if (used == 0 || used == 3) { |
| 358 this->init(); | 358 this->init(); |
| 359 return; | 359 return; |
| 360 } | 360 } |
| 361 fPerpT = i[0][0]; | 361 fPerpT = i[0][0]; |
| 362 fPerpPt = i.pt(0); | 362 fPerpPt = i.pt(0); |
| 363 SkASSERT(used <= 2); | 363 SkASSERT(used <= 2); |
| 364 if (used == 2) { | 364 if (used == 2) { |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 template<typename TCurve, typename OppCurve> | 558 template<typename TCurve, typename OppCurve> |
| 559 void SkTSpan<TCurve, OppCurve>::init(const TCurve& c) { | 559 void SkTSpan<TCurve, OppCurve>::init(const TCurve& c) { |
| 560 fPrev = fNext = nullptr; | 560 fPrev = fNext = nullptr; |
| 561 fStartT = 0; | 561 fStartT = 0; |
| 562 fEndT = 1; | 562 fEndT = 1; |
| 563 fBounded = nullptr; | 563 fBounded = nullptr; |
| 564 resetBounds(c); | 564 resetBounds(c); |
| 565 } | 565 } |
| 566 | 566 |
| 567 template<typename TCurve, typename OppCurve> | 567 template<typename TCurve, typename OppCurve> |
| 568 void SkTSpan<TCurve, OppCurve>::initBounds(const TCurve& c) { | 568 bool SkTSpan<TCurve, OppCurve>::initBounds(const TCurve& c) { |
| 569 fPart = c.subDivide(fStartT, fEndT); | 569 fPart = c.subDivide(fStartT, fEndT); |
| 570 fBounds.setBounds(fPart); | 570 fBounds.setBounds(fPart); |
| 571 fCoinStart.init(); | 571 fCoinStart.init(); |
| 572 fCoinEnd.init(); | 572 fCoinEnd.init(); |
| 573 fBoundsMax = SkTMax(fBounds.width(), fBounds.height()); | 573 fBoundsMax = SkTMax(fBounds.width(), fBounds.height()); |
| 574 fCollapsed = fPart.collapsed(); | 574 fCollapsed = fPart.collapsed(); |
| 575 fHasPerp = false; | 575 fHasPerp = false; |
| 576 fDeleted = false; | 576 fDeleted = false; |
| 577 #if DEBUG_T_SECT | 577 #if DEBUG_T_SECT |
| 578 if (fCollapsed) { | 578 if (fCollapsed) { |
| 579 SkDebugf(""); // for convenient breakpoints | 579 SkDebugf(""); // for convenient breakpoints |
| 580 } | 580 } |
| 581 #endif | 581 #endif |
| 582 return fBounds.valid(); |
| 582 } | 583 } |
| 583 | 584 |
| 584 template<typename TCurve, typename OppCurve> | 585 template<typename TCurve, typename OppCurve> |
| 585 bool SkTSpan<TCurve, OppCurve>::linearsIntersect(SkTSpan<OppCurve, TCurve>* span
) { | 586 bool SkTSpan<TCurve, OppCurve>::linearsIntersect(SkTSpan<OppCurve, TCurve>* span
) { |
| 586 int result = this->linearIntersects(span->fPart); | 587 int result = this->linearIntersects(span->fPart); |
| 587 if (result <= 1) { | 588 if (result <= 1) { |
| 588 return SkToBool(result); | 589 return SkToBool(result); |
| 589 } | 590 } |
| 590 SkASSERT(span->fIsLinear); | 591 SkASSERT(span->fIsLinear); |
| 591 result = span->linearIntersects(this->fPart); | 592 result = span->linearIntersects(this->fPart); |
| (...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1199 oppFirst->fCoinEnd.markCoincident(); | 1200 oppFirst->fCoinEnd.markCoincident(); |
| 1200 oppHalf->markCoincident(); | 1201 oppHalf->markCoincident(); |
| 1201 oppFirst = oppHalf; | 1202 oppFirst = oppHalf; |
| 1202 } else { | 1203 } else { |
| 1203 oppFirst->markCoincident(); | 1204 oppFirst->markCoincident(); |
| 1204 oppHalf->fCoinStart.markCoincident(); | 1205 oppHalf->fCoinStart.markCoincident(); |
| 1205 } | 1206 } |
| 1206 } | 1207 } |
| 1207 } else { | 1208 } else { |
| 1208 SkDEBUGCODE(coinStart = first->fStartT); | 1209 SkDEBUGCODE(coinStart = first->fStartT); |
| 1210 FAIL_IF(!oppFirst); |
| 1209 SkDEBUGCODE(oppStartT = oppMatched ? oppFirst->fStartT : oppFirst->fEndT
); | 1211 SkDEBUGCODE(oppStartT = oppMatched ? oppFirst->fStartT : oppFirst->fEndT
); |
| 1210 } | 1212 } |
| 1211 // FIXME: incomplete : if we're not at the end, find end of coin | 1213 // FIXME: incomplete : if we're not at the end, find end of coin |
| 1212 SkTSpan<OppCurve, TCurve>* oppLast; | 1214 SkTSpan<OppCurve, TCurve>* oppLast; |
| 1213 SkOPASSERT(last->fCoinEnd.isMatch()); | 1215 SkOPASSERT(last->fCoinEnd.isMatch()); |
| 1214 oppLast = last->findOppT(last->fCoinEnd.perpT()); | 1216 oppLast = last->findOppT(last->fCoinEnd.perpT()); |
| 1215 SkDEBUGCODE(coinEnd = last->fEndT); | 1217 SkDEBUGCODE(coinEnd = last->fEndT); |
| 1216 #ifdef SK_DEBUG | 1218 #ifdef SK_DEBUG |
| 1217 if (!this->globalState() || !this->globalState()->debugSkipAssert()) { | 1219 if (!this->globalState() || !this->globalState()->debugSkipAssert()) { |
| 1218 oppEndT = oppMatched ? oppLast->fEndT : oppLast->fStartT; | 1220 oppEndT = oppMatched ? oppLast->fEndT : oppLast->fStartT; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1279 SkTSpan<TCurve, OppCurve>* work = first; | 1281 SkTSpan<TCurve, OppCurve>* work = first; |
| 1280 SkTSpan<TCurve, OppCurve>* lastCandidate = nullptr; | 1282 SkTSpan<TCurve, OppCurve>* lastCandidate = nullptr; |
| 1281 first = nullptr; | 1283 first = nullptr; |
| 1282 // find the first fully coincident span | 1284 // find the first fully coincident span |
| 1283 do { | 1285 do { |
| 1284 if (work->fCoinStart.isMatch()) { | 1286 if (work->fCoinStart.isMatch()) { |
| 1285 #if DEBUG_T_SECT | 1287 #if DEBUG_T_SECT |
| 1286 work->validatePerpT(work->fCoinStart.perpT()); | 1288 work->validatePerpT(work->fCoinStart.perpT()); |
| 1287 work->validatePerpPt(work->fCoinStart.perpT(), work->fCoinStart.perp
Pt()); | 1289 work->validatePerpPt(work->fCoinStart.perpT(), work->fCoinStart.perp
Pt()); |
| 1288 #endif | 1290 #endif |
| 1289 SkASSERT(work->hasOppT(work->fCoinStart.perpT())); | 1291 SkOPASSERT(work->hasOppT(work->fCoinStart.perpT())); |
| 1290 if (!work->fCoinEnd.isMatch()) { | 1292 if (!work->fCoinEnd.isMatch()) { |
| 1291 break; | 1293 break; |
| 1292 } | 1294 } |
| 1293 lastCandidate = work; | 1295 lastCandidate = work; |
| 1294 if (!first) { | 1296 if (!first) { |
| 1295 first = work; | 1297 first = work; |
| 1296 } | 1298 } |
| 1297 } else if (first && work->fCollapsed) { | 1299 } else if (first && work->fCollapsed) { |
| 1298 *lastPtr = lastCandidate; | 1300 *lastPtr = lastCandidate; |
| 1299 return first; | 1301 return first; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1393 return finds >= 2; | 1395 return finds >= 2; |
| 1394 } | 1396 } |
| 1395 | 1397 |
| 1396 // while the intersection points are sufficiently far apart: | 1398 // while the intersection points are sufficiently far apart: |
| 1397 // construct the tangent lines from the intersections | 1399 // construct the tangent lines from the intersections |
| 1398 // find the point where the tangent line intersects the opposite curve | 1400 // find the point where the tangent line intersects the opposite curve |
| 1399 template<typename TCurve, typename OppCurve> | 1401 template<typename TCurve, typename OppCurve> |
| 1400 int SkTSect<TCurve, OppCurve>::linesIntersect(SkTSpan<TCurve, OppCurve>* span, | 1402 int SkTSect<TCurve, OppCurve>::linesIntersect(SkTSpan<TCurve, OppCurve>* span, |
| 1401 SkTSect<OppCurve, TCurve>* opp, | 1403 SkTSect<OppCurve, TCurve>* opp, |
| 1402 SkTSpan<OppCurve, TCurve>* oppSpan, SkIntersections* i) { | 1404 SkTSpan<OppCurve, TCurve>* oppSpan, SkIntersections* i) { |
| 1403 SkIntersections thisRayI, oppRayI; | 1405 SkIntersections thisRayI SkDEBUGCODE((span->fDebugGlobalState)); |
| 1406 SkIntersections oppRayI SkDEBUGCODE((span->fDebugGlobalState)); |
| 1404 SkDLine thisLine = {{ span->fPart[0], span->fPart[TCurve::kPointLast] }}; | 1407 SkDLine thisLine = {{ span->fPart[0], span->fPart[TCurve::kPointLast] }}; |
| 1405 SkDLine oppLine = {{ oppSpan->fPart[0], oppSpan->fPart[OppCurve::kPointLast]
}}; | 1408 SkDLine oppLine = {{ oppSpan->fPart[0], oppSpan->fPart[OppCurve::kPointLast]
}}; |
| 1406 int loopCount = 0; | 1409 int loopCount = 0; |
| 1407 double bestDistSq = DBL_MAX; | 1410 double bestDistSq = DBL_MAX; |
| 1408 if (!thisRayI.intersectRay(opp->fCurve, thisLine)) { | 1411 if (!thisRayI.intersectRay(opp->fCurve, thisLine)) { |
| 1409 return 0; | 1412 return 0; |
| 1410 } | 1413 } |
| 1411 if (!oppRayI.intersectRay(this->fCurve, oppLine)) { | 1414 if (!oppRayI.intersectRay(this->fCurve, oppLine)) { |
| 1412 return 0; | 1415 return 0; |
| 1413 } | 1416 } |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1803 if (next->fEndT > result->fEndT) { | 1806 if (next->fEndT > result->fEndT) { |
| 1804 result = next; | 1807 result = next; |
| 1805 } | 1808 } |
| 1806 } | 1809 } |
| 1807 return result; | 1810 return result; |
| 1808 } | 1811 } |
| 1809 | 1812 |
| 1810 /* Each span has a range of opposite spans it intersects. After the span is spli
t in two, | 1813 /* Each span has a range of opposite spans it intersects. After the span is spli
t in two, |
| 1811 adjust the range to its new size */ | 1814 adjust the range to its new size */ |
| 1812 template<typename TCurve, typename OppCurve> | 1815 template<typename TCurve, typename OppCurve> |
| 1813 void SkTSect<TCurve, OppCurve>::trim(SkTSpan<TCurve, OppCurve>* span, | 1816 bool SkTSect<TCurve, OppCurve>::trim(SkTSpan<TCurve, OppCurve>* span, |
| 1814 SkTSect<OppCurve, TCurve>* opp) { | 1817 SkTSect<OppCurve, TCurve>* opp) { |
| 1815 span->initBounds(fCurve); | 1818 FAIL_IF(!span->initBounds(fCurve)); |
| 1816 const SkTSpanBounded<OppCurve, TCurve>* testBounded = span->fBounded; | 1819 const SkTSpanBounded<OppCurve, TCurve>* testBounded = span->fBounded; |
| 1817 while (testBounded) { | 1820 while (testBounded) { |
| 1818 SkTSpan<OppCurve, TCurve>* test = testBounded->fBounded; | 1821 SkTSpan<OppCurve, TCurve>* test = testBounded->fBounded; |
| 1819 const SkTSpanBounded<OppCurve, TCurve>* next = testBounded->fNext; | 1822 const SkTSpanBounded<OppCurve, TCurve>* next = testBounded->fNext; |
| 1820 int oppSects, sects = this->intersects(span, opp, test, &oppSects); | 1823 int oppSects, sects = this->intersects(span, opp, test, &oppSects); |
| 1821 if (sects >= 1) { | 1824 if (sects >= 1) { |
| 1822 if (oppSects == 2) { | 1825 if (oppSects == 2) { |
| 1823 test->initBounds(opp->fCurve); | 1826 test->initBounds(opp->fCurve); |
| 1824 opp->removeAllBut(span, test, this); | 1827 opp->removeAllBut(span, test, this); |
| 1825 } | 1828 } |
| 1826 if (sects == 2) { | 1829 if (sects == 2) { |
| 1827 span->initBounds(fCurve); | 1830 span->initBounds(fCurve); |
| 1828 this->removeAllBut(test, span, opp); | 1831 this->removeAllBut(test, span, opp); |
| 1829 return; | 1832 return true; |
| 1830 } | 1833 } |
| 1831 } else { | 1834 } else { |
| 1832 if (span->removeBounded(test)) { | 1835 if (span->removeBounded(test)) { |
| 1833 this->removeSpan(span); | 1836 this->removeSpan(span); |
| 1834 } | 1837 } |
| 1835 if (test->removeBounded(span)) { | 1838 if (test->removeBounded(span)) { |
| 1836 opp->removeSpan(test); | 1839 opp->removeSpan(test); |
| 1837 } | 1840 } |
| 1838 } | 1841 } |
| 1839 testBounded = next; | 1842 testBounded = next; |
| 1840 } | 1843 } |
| 1844 return true; |
| 1841 } | 1845 } |
| 1842 | 1846 |
| 1843 template<typename TCurve, typename OppCurve> | 1847 template<typename TCurve, typename OppCurve> |
| 1844 void SkTSect<TCurve, OppCurve>::unlinkSpan(SkTSpan<TCurve, OppCurve>* span) { | 1848 void SkTSect<TCurve, OppCurve>::unlinkSpan(SkTSpan<TCurve, OppCurve>* span) { |
| 1845 SkTSpan<TCurve, OppCurve>* prev = span->fPrev; | 1849 SkTSpan<TCurve, OppCurve>* prev = span->fPrev; |
| 1846 SkTSpan<TCurve, OppCurve>* next = span->fNext; | 1850 SkTSpan<TCurve, OppCurve>* next = span->fNext; |
| 1847 if (prev) { | 1851 if (prev) { |
| 1848 prev->fNext = next; | 1852 prev->fNext = next; |
| 1849 if (next) { | 1853 if (next) { |
| 1850 next->fPrev = prev; | 1854 next->fPrev = prev; |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2105 // returns true if the rect is too small to consider | 2109 // returns true if the rect is too small to consider |
| 2106 template<typename TCurve, typename OppCurve> | 2110 template<typename TCurve, typename OppCurve> |
| 2107 void SkTSect<TCurve, OppCurve>::BinarySearch(SkTSect<TCurve, OppCurve>* sect1, | 2111 void SkTSect<TCurve, OppCurve>::BinarySearch(SkTSect<TCurve, OppCurve>* sect1, |
| 2108 SkTSect<OppCurve, TCurve>* sect2, SkIntersections* intersections) { | 2112 SkTSect<OppCurve, TCurve>* sect2, SkIntersections* intersections) { |
| 2109 #if DEBUG_T_SECT_DUMP > 1 | 2113 #if DEBUG_T_SECT_DUMP > 1 |
| 2110 gDumpTSectNum = 0; | 2114 gDumpTSectNum = 0; |
| 2111 #endif | 2115 #endif |
| 2112 SkDEBUGCODE(sect1->fOppSect = sect2); | 2116 SkDEBUGCODE(sect1->fOppSect = sect2); |
| 2113 SkDEBUGCODE(sect2->fOppSect = sect1); | 2117 SkDEBUGCODE(sect2->fOppSect = sect1); |
| 2114 intersections->reset(); | 2118 intersections->reset(); |
| 2115 intersections->setMax(TCurve::kMaxIntersections + 3); // give extra for slo
p | 2119 intersections->setMax(TCurve::kMaxIntersections + 4); // give extra for slo
p |
| 2116 SkTSpan<TCurve, OppCurve>* span1 = sect1->fHead; | 2120 SkTSpan<TCurve, OppCurve>* span1 = sect1->fHead; |
| 2117 SkTSpan<OppCurve, TCurve>* span2 = sect2->fHead; | 2121 SkTSpan<OppCurve, TCurve>* span2 = sect2->fHead; |
| 2118 int oppSect, sect = sect1->intersects(span1, sect2, span2, &oppSect); | 2122 int oppSect, sect = sect1->intersects(span1, sect2, span2, &oppSect); |
| 2119 // SkASSERT(between(0, sect, 2)); | 2123 // SkASSERT(between(0, sect, 2)); |
| 2120 if (!sect) { | 2124 if (!sect) { |
| 2121 return; | 2125 return; |
| 2122 } | 2126 } |
| 2123 if (sect == 2 && oppSect == 2) { | 2127 if (sect == 2 && oppSect == 2) { |
| 2124 (void) EndsEqual(sect1, sect2, intersections); | 2128 (void) EndsEqual(sect1, sect2, intersections); |
| 2125 return; | 2129 return; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2144 || (!largest1->fCollapsed && largest2->fCollapsed)))) { | 2148 || (!largest1->fCollapsed && largest2->fCollapsed)))) { |
| 2145 if (largest1->fCollapsed) { | 2149 if (largest1->fCollapsed) { |
| 2146 break; | 2150 break; |
| 2147 } | 2151 } |
| 2148 // trim parts that don't intersect the opposite | 2152 // trim parts that don't intersect the opposite |
| 2149 SkTSpan<TCurve, OppCurve>* half1 = sect1->addOne(); | 2153 SkTSpan<TCurve, OppCurve>* half1 = sect1->addOne(); |
| 2150 SkDEBUGCODE(half1->debugSetGlobalState(sect1->globalState())); | 2154 SkDEBUGCODE(half1->debugSetGlobalState(sect1->globalState())); |
| 2151 if (!half1->split(largest1, §1->fHeap)) { | 2155 if (!half1->split(largest1, §1->fHeap)) { |
| 2152 break; | 2156 break; |
| 2153 } | 2157 } |
| 2154 sect1->trim(largest1, sect2); | 2158 if (!sect1->trim(largest1, sect2)) { |
| 2155 sect1->trim(half1, sect2); | 2159 SkOPOBJASSERT(intersections, 0); |
| 2160 return; |
| 2161 } |
| 2162 if (!sect1->trim(half1, sect2)) { |
| 2163 SkOPOBJASSERT(intersections, 0); |
| 2164 return; |
| 2165 } |
| 2156 } else { | 2166 } else { |
| 2157 if (largest2->fCollapsed) { | 2167 if (largest2->fCollapsed) { |
| 2158 break; | 2168 break; |
| 2159 } | 2169 } |
| 2160 // trim parts that don't intersect the opposite | 2170 // trim parts that don't intersect the opposite |
| 2161 SkTSpan<OppCurve, TCurve>* half2 = sect2->addOne(); | 2171 SkTSpan<OppCurve, TCurve>* half2 = sect2->addOne(); |
| 2162 SkDEBUGCODE(half2->debugSetGlobalState(sect2->globalState())); | 2172 SkDEBUGCODE(half2->debugSetGlobalState(sect2->globalState())); |
| 2163 if (!half2->split(largest2, §2->fHeap)) { | 2173 if (!half2->split(largest2, §2->fHeap)) { |
| 2164 break; | 2174 break; |
| 2165 } | 2175 } |
| 2166 sect2->trim(largest2, sect1); | 2176 if (!sect2->trim(largest2, sect1)) { |
| 2167 sect2->trim(half2, sect1); | 2177 SkOPOBJASSERT(intersections, 0); |
| 2178 return; |
| 2179 } |
| 2180 if (!sect2->trim(half2, sect1)) { |
| 2181 SkOPOBJASSERT(intersections, 0); |
| 2182 return; |
| 2183 } |
| 2168 } | 2184 } |
| 2169 sect1->validate(); | 2185 sect1->validate(); |
| 2170 sect2->validate(); | 2186 sect2->validate(); |
| 2171 #if DEBUG_T_SECT_LOOP_COUNT | 2187 #if DEBUG_T_SECT_LOOP_COUNT |
| 2172 intersections->debugBumpLoopCount(SkIntersections::kIterations_DebugLoop
); | 2188 intersections->debugBumpLoopCount(SkIntersections::kIterations_DebugLoop
); |
| 2173 #endif | 2189 #endif |
| 2174 // if there are 9 or more continuous spans on both sects, suspect coinci
dence | 2190 // if there are 9 or more continuous spans on both sects, suspect coinci
dence |
| 2175 if (sect1->fActiveCount >= COINCIDENT_SPAN_COUNT | 2191 if (sect1->fActiveCount >= COINCIDENT_SPAN_COUNT |
| 2176 && sect2->fActiveCount >= COINCIDENT_SPAN_COUNT) { | 2192 && sect2->fActiveCount >= COINCIDENT_SPAN_COUNT) { |
| 2177 if (coinLoopCount == kMaxCoinLoopCount) { | 2193 if (coinLoopCount == kMaxCoinLoopCount) { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2243 coincident->fPart[TCurve::kPointLast]) < 0) && index >= 0) { | 2259 coincident->fPart[TCurve::kPointLast]) < 0) && index >= 0) { |
| 2244 intersections->clearCoincidence(index); | 2260 intersections->clearCoincidence(index); |
| 2245 } | 2261 } |
| 2246 } while ((coincident = coincident->fNext)); | 2262 } while ((coincident = coincident->fNext)); |
| 2247 } | 2263 } |
| 2248 int zeroOneSet = EndsEqual(sect1, sect2, intersections); | 2264 int zeroOneSet = EndsEqual(sect1, sect2, intersections); |
| 2249 if (!sect1->fHead || !sect2->fHead) { | 2265 if (!sect1->fHead || !sect2->fHead) { |
| 2250 // if the final iteration contains an end (0 or 1), | 2266 // if the final iteration contains an end (0 or 1), |
| 2251 if (sect1->fRemovedStartT && !(zeroOneSet & kZeroS1Set)) { | 2267 if (sect1->fRemovedStartT && !(zeroOneSet & kZeroS1Set)) { |
| 2252 SkTCoincident<TCurve, OppCurve> perp; // intersect perpendicular w
ith opposite curve | 2268 SkTCoincident<TCurve, OppCurve> perp; // intersect perpendicular w
ith opposite curve |
| 2253 perp.setPerp(sect1->fCurve, 0, sect1->fCurve.fPts[0], sect2->fCurve)
; | 2269 perp.setPerp(sect1->fCurve, 0, sect1->fCurve[0], sect2->fCurve); |
| 2254 if (perp.isMatch()) { | 2270 if (perp.isMatch()) { |
| 2255 intersections->insert(0, perp.perpT(), perp.perpPt()); | 2271 intersections->insert(0, perp.perpT(), perp.perpPt()); |
| 2256 } | 2272 } |
| 2257 } | 2273 } |
| 2258 if (sect1->fRemovedEndT && !(zeroOneSet & kOneS1Set)) { | 2274 if (sect1->fRemovedEndT && !(zeroOneSet & kOneS1Set)) { |
| 2259 SkTCoincident<TCurve, OppCurve> perp; | 2275 SkTCoincident<TCurve, OppCurve> perp; |
| 2260 perp.setPerp(sect1->fCurve, 1, sect1->fCurve.fPts[TCurve::kPointLast
], sect2->fCurve); | 2276 perp.setPerp(sect1->fCurve, 1, sect1->fCurve[TCurve::kPointLast], se
ct2->fCurve); |
| 2261 if (perp.isMatch()) { | 2277 if (perp.isMatch()) { |
| 2262 intersections->insert(1, perp.perpT(), perp.perpPt()); | 2278 intersections->insert(1, perp.perpT(), perp.perpPt()); |
| 2263 } | 2279 } |
| 2264 } | 2280 } |
| 2265 if (sect2->fRemovedStartT && !(zeroOneSet & kZeroS2Set)) { | 2281 if (sect2->fRemovedStartT && !(zeroOneSet & kZeroS2Set)) { |
| 2266 SkTCoincident<OppCurve, TCurve> perp; | 2282 SkTCoincident<OppCurve, TCurve> perp; |
| 2267 perp.setPerp(sect2->fCurve, 0, sect2->fCurve.fPts[0], sect1->fCurve)
; | 2283 perp.setPerp(sect2->fCurve, 0, sect2->fCurve[0], sect1->fCurve); |
| 2268 if (perp.isMatch()) { | 2284 if (perp.isMatch()) { |
| 2269 intersections->insert(perp.perpT(), 0, perp.perpPt()); | 2285 intersections->insert(perp.perpT(), 0, perp.perpPt()); |
| 2270 } | 2286 } |
| 2271 } | 2287 } |
| 2272 if (sect2->fRemovedEndT && !(zeroOneSet & kOneS2Set)) { | 2288 if (sect2->fRemovedEndT && !(zeroOneSet & kOneS2Set)) { |
| 2273 SkTCoincident<OppCurve, TCurve> perp; | 2289 SkTCoincident<OppCurve, TCurve> perp; |
| 2274 perp.setPerp(sect2->fCurve, 1, sect2->fCurve.fPts[OppCurve::kPointLa
st], sect1->fCurve); | 2290 perp.setPerp(sect2->fCurve, 1, sect2->fCurve[OppCurve::kPointLast],
sect1->fCurve); |
| 2275 if (perp.isMatch()) { | 2291 if (perp.isMatch()) { |
| 2276 intersections->insert(perp.perpT(), 1, perp.perpPt()); | 2292 intersections->insert(perp.perpT(), 1, perp.perpPt()); |
| 2277 } | 2293 } |
| 2278 } | 2294 } |
| 2279 return; | 2295 return; |
| 2280 } | 2296 } |
| 2281 sect1->recoverCollapsed(); | 2297 sect1->recoverCollapsed(); |
| 2282 sect2->recoverCollapsed(); | 2298 sect2->recoverCollapsed(); |
| 2283 SkTSpan<TCurve, OppCurve>* result1 = sect1->fHead; | 2299 SkTSpan<TCurve, OppCurve>* result1 = sect1->fHead; |
| 2284 // check heads and tails for zero and ones and insert them if we haven't alr
eady done so | 2300 // check heads and tails for zero and ones and insert them if we haven't alr
eady done so |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2358 intersections->removeOne(index); | 2374 intersections->removeOne(index); |
| 2359 --last; | 2375 --last; |
| 2360 } else if (intersections->isCoincident(index + 1)) { | 2376 } else if (intersections->isCoincident(index + 1)) { |
| 2361 intersections->removeOne(index + 1); | 2377 intersections->removeOne(index + 1); |
| 2362 --last; | 2378 --last; |
| 2363 } else { | 2379 } else { |
| 2364 intersections->setCoincident(index++); | 2380 intersections->setCoincident(index++); |
| 2365 } | 2381 } |
| 2366 intersections->setCoincident(index); | 2382 intersections->setCoincident(index); |
| 2367 } | 2383 } |
| 2368 SkASSERT(intersections->used() <= TCurve::kMaxIntersections); | 2384 SkOPOBJASSERT(intersections, intersections->used() <= TCurve::kMaxIntersecti
ons); |
| 2369 } | 2385 } |
| 2370 | 2386 |
| 2371 #endif | 2387 #endif |
| OLD | NEW |