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 |