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 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 void mergeCoincidence(SkTSect<OppCurve, TCurve>* sect2); | 308 void mergeCoincidence(SkTSect<OppCurve, TCurve>* sect2); |
309 SkTSpan<TCurve, OppCurve>* prev(SkTSpan<TCurve, OppCurve>* ) const; | 309 SkTSpan<TCurve, OppCurve>* prev(SkTSpan<TCurve, OppCurve>* ) const; |
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 void removedEndCheck(SkTSpan<TCurve, OppCurve>* span); |
| 319 |
| 320 void resetRemovedEnds() { |
| 321 fRemovedStartT = fRemovedEndT = false; |
| 322 } |
| 323 |
318 SkTSpan<TCurve, OppCurve>* spanAtT(double t, SkTSpan<TCurve, OppCurve>** pri
orSpan); | 324 SkTSpan<TCurve, OppCurve>* spanAtT(double t, SkTSpan<TCurve, OppCurve>** pri
orSpan); |
319 SkTSpan<TCurve, OppCurve>* tail(); | 325 SkTSpan<TCurve, OppCurve>* tail(); |
320 bool trim(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>* opp); | 326 bool trim(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>* opp); |
321 void unlinkSpan(SkTSpan<TCurve, OppCurve>* span); | 327 void unlinkSpan(SkTSpan<TCurve, OppCurve>* span); |
322 bool updateBounded(SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCurv
e>* last, | 328 bool updateBounded(SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCurv
e>* last, |
323 SkTSpan<OppCurve, TCurve>* oppFirst); | 329 SkTSpan<OppCurve, TCurve>* oppFirst); |
324 void validate() const; | 330 void validate() const; |
325 void validateBounded() const; | 331 void validateBounded() const; |
326 | 332 |
327 const TCurve& fCurve; | 333 const TCurve& fCurve; |
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
858 : fCurve(c) | 864 : fCurve(c) |
859 , fHeap(sizeof(SkTSpan<TCurve, OppCurve>) * 4) | 865 , fHeap(sizeof(SkTSpan<TCurve, OppCurve>) * 4) |
860 , fCoincident(nullptr) | 866 , fCoincident(nullptr) |
861 , fDeleted(nullptr) | 867 , fDeleted(nullptr) |
862 , fActiveCount(0) | 868 , fActiveCount(0) |
863 SkDEBUGPARAMS(fDebugGlobalState(debugGlobalState)) | 869 SkDEBUGPARAMS(fDebugGlobalState(debugGlobalState)) |
864 PATH_OPS_DEBUG_T_SECT_PARAMS(fID(id)) | 870 PATH_OPS_DEBUG_T_SECT_PARAMS(fID(id)) |
865 PATH_OPS_DEBUG_T_SECT_PARAMS(fDebugCount(0)) | 871 PATH_OPS_DEBUG_T_SECT_PARAMS(fDebugCount(0)) |
866 PATH_OPS_DEBUG_T_SECT_PARAMS(fDebugAllocatedCount(0)) | 872 PATH_OPS_DEBUG_T_SECT_PARAMS(fDebugAllocatedCount(0)) |
867 { | 873 { |
868 fHead = addOne(); | 874 this->resetRemovedEnds(); |
| 875 fHead = this->addOne(); |
869 SkDEBUGCODE(fHead->debugSetGlobalState(debugGlobalState)); | 876 SkDEBUGCODE(fHead->debugSetGlobalState(debugGlobalState)); |
870 fHead->init(c); | 877 fHead->init(c); |
871 } | 878 } |
872 | 879 |
873 template<typename TCurve, typename OppCurve> | 880 template<typename TCurve, typename OppCurve> |
874 SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::addOne() { | 881 SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::addOne() { |
875 SkTSpan<TCurve, OppCurve>* result; | 882 SkTSpan<TCurve, OppCurve>* result; |
876 if (fDeleted) { | 883 if (fDeleted) { |
877 result = fDeleted; | 884 result = fDeleted; |
878 fDeleted = result->fNext; | 885 fDeleted = result->fNext; |
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1353 } | 1360 } |
1354 if (span->fIsLine && oppSpan->fIsLine) { | 1361 if (span->fIsLine && oppSpan->fIsLine) { |
1355 SkIntersections i; | 1362 SkIntersections i; |
1356 int sects = this->linesIntersect(span, opp, oppSpan, &i); | 1363 int sects = this->linesIntersect(span, opp, oppSpan, &i); |
1357 if (sects == 2) { | 1364 if (sects == 2) { |
1358 return *oppResult = 1; | 1365 return *oppResult = 1; |
1359 } | 1366 } |
1360 if (!sects) { | 1367 if (!sects) { |
1361 return -1; | 1368 return -1; |
1362 } | 1369 } |
| 1370 this->removedEndCheck(span); |
1363 span->fStartT = span->fEndT = i[0][0]; | 1371 span->fStartT = span->fEndT = i[0][0]; |
| 1372 opp->removedEndCheck(oppSpan); |
1364 oppSpan->fStartT = oppSpan->fEndT = i[1][0]; | 1373 oppSpan->fStartT = oppSpan->fEndT = i[1][0]; |
1365 return *oppResult = 2; | 1374 return *oppResult = 2; |
1366 } | 1375 } |
1367 if (span->fIsLinear || oppSpan->fIsLinear) { | 1376 if (span->fIsLinear || oppSpan->fIsLinear) { |
1368 return *oppResult = (int) span->linearsIntersect(oppSpan); | 1377 return *oppResult = (int) span->linearsIntersect(oppSpan); |
1369 } | 1378 } |
1370 return *oppResult = 1; | 1379 return *oppResult = 1; |
1371 } | 1380 } |
1372 | 1381 |
1373 template<typename TCurve> | 1382 template<typename TCurve> |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1728 if (isBetween || between(0, span->fCoinStart.perpT(), 1)) { | 1737 if (isBetween || between(0, span->fCoinStart.perpT(), 1)) { |
1729 --fActiveCount; | 1738 --fActiveCount; |
1730 span->fNext = fCoincident; | 1739 span->fNext = fCoincident; |
1731 fCoincident = span; | 1740 fCoincident = span; |
1732 } else { | 1741 } else { |
1733 this->markSpanGone(span); | 1742 this->markSpanGone(span); |
1734 } | 1743 } |
1735 } | 1744 } |
1736 | 1745 |
1737 template<typename TCurve, typename OppCurve> | 1746 template<typename TCurve, typename OppCurve> |
1738 bool SkTSect<TCurve, OppCurve>::removeSpan(SkTSpan<TCurve, OppCurve>* span) { | 1747 void SkTSect<TCurve, OppCurve>::removedEndCheck(SkTSpan<TCurve, OppCurve>* span)
{ |
1739 if (!span->fStartT) { | 1748 if (!span->fStartT) { |
1740 fRemovedStartT = true; | 1749 fRemovedStartT = true; |
1741 } | 1750 } |
1742 if (1 == span->fEndT) { | 1751 if (1 == span->fEndT) { |
1743 fRemovedEndT = true; | 1752 fRemovedEndT = true; |
1744 } | 1753 } |
| 1754 } |
| 1755 |
| 1756 template<typename TCurve, typename OppCurve> |
| 1757 bool SkTSect<TCurve, OppCurve>::removeSpan(SkTSpan<TCurve, OppCurve>* span) {\ |
| 1758 this->removedEndCheck(span); |
1745 this->unlinkSpan(span); | 1759 this->unlinkSpan(span); |
1746 return this->markSpanGone(span); | 1760 return this->markSpanGone(span); |
1747 } | 1761 } |
1748 | 1762 |
1749 template<typename TCurve, typename OppCurve> | 1763 template<typename TCurve, typename OppCurve> |
1750 void SkTSect<TCurve, OppCurve>::removeSpanRange(SkTSpan<TCurve, OppCurve>* first
, | 1764 void SkTSect<TCurve, OppCurve>::removeSpanRange(SkTSpan<TCurve, OppCurve>* first
, |
1751 SkTSpan<TCurve, OppCurve>* last) { | 1765 SkTSpan<TCurve, OppCurve>* last) { |
1752 if (first == last) { | 1766 if (first == last) { |
1753 return; | 1767 return; |
1754 } | 1768 } |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2134 int coinLoopCount = kMaxCoinLoopCount; | 2148 int coinLoopCount = kMaxCoinLoopCount; |
2135 double start1s SK_INIT_TO_AVOID_WARNING; | 2149 double start1s SK_INIT_TO_AVOID_WARNING; |
2136 double start1e SK_INIT_TO_AVOID_WARNING; | 2150 double start1e SK_INIT_TO_AVOID_WARNING; |
2137 do { | 2151 do { |
2138 // find the largest bounds | 2152 // find the largest bounds |
2139 SkTSpan<TCurve, OppCurve>* largest1 = sect1->boundsMax(); | 2153 SkTSpan<TCurve, OppCurve>* largest1 = sect1->boundsMax(); |
2140 if (!largest1) { | 2154 if (!largest1) { |
2141 break; | 2155 break; |
2142 } | 2156 } |
2143 SkTSpan<OppCurve, TCurve>* largest2 = sect2->boundsMax(); | 2157 SkTSpan<OppCurve, TCurve>* largest2 = sect2->boundsMax(); |
2144 sect1->fRemovedStartT = sect1->fRemovedEndT = false; | |
2145 sect2->fRemovedStartT = sect2->fRemovedEndT = false; | |
2146 // split it | 2158 // split it |
2147 if (!largest2 || (largest1 && (largest1->fBoundsMax > largest2->fBoundsM
ax | 2159 if (!largest2 || (largest1 && (largest1->fBoundsMax > largest2->fBoundsM
ax |
2148 || (!largest1->fCollapsed && largest2->fCollapsed)))) { | 2160 || (!largest1->fCollapsed && largest2->fCollapsed)))) { |
2149 if (largest1->fCollapsed) { | 2161 if (largest1->fCollapsed) { |
2150 break; | 2162 break; |
2151 } | 2163 } |
| 2164 sect1->resetRemovedEnds(); |
| 2165 sect2->resetRemovedEnds(); |
2152 // trim parts that don't intersect the opposite | 2166 // trim parts that don't intersect the opposite |
2153 SkTSpan<TCurve, OppCurve>* half1 = sect1->addOne(); | 2167 SkTSpan<TCurve, OppCurve>* half1 = sect1->addOne(); |
2154 SkDEBUGCODE(half1->debugSetGlobalState(sect1->globalState())); | 2168 SkDEBUGCODE(half1->debugSetGlobalState(sect1->globalState())); |
2155 if (!half1->split(largest1, §1->fHeap)) { | 2169 if (!half1->split(largest1, §1->fHeap)) { |
2156 break; | 2170 break; |
2157 } | 2171 } |
2158 if (!sect1->trim(largest1, sect2)) { | 2172 if (!sect1->trim(largest1, sect2)) { |
2159 SkOPOBJASSERT(intersections, 0); | 2173 SkOPOBJASSERT(intersections, 0); |
2160 return; | 2174 return; |
2161 } | 2175 } |
2162 if (!sect1->trim(half1, sect2)) { | 2176 if (!sect1->trim(half1, sect2)) { |
2163 SkOPOBJASSERT(intersections, 0); | 2177 SkOPOBJASSERT(intersections, 0); |
2164 return; | 2178 return; |
2165 } | 2179 } |
2166 } else { | 2180 } else { |
2167 if (largest2->fCollapsed) { | 2181 if (largest2->fCollapsed) { |
2168 break; | 2182 break; |
2169 } | 2183 } |
| 2184 sect1->resetRemovedEnds(); |
| 2185 sect2->resetRemovedEnds(); |
2170 // trim parts that don't intersect the opposite | 2186 // trim parts that don't intersect the opposite |
2171 SkTSpan<OppCurve, TCurve>* half2 = sect2->addOne(); | 2187 SkTSpan<OppCurve, TCurve>* half2 = sect2->addOne(); |
2172 SkDEBUGCODE(half2->debugSetGlobalState(sect2->globalState())); | 2188 SkDEBUGCODE(half2->debugSetGlobalState(sect2->globalState())); |
2173 if (!half2->split(largest2, §2->fHeap)) { | 2189 if (!half2->split(largest2, §2->fHeap)) { |
2174 break; | 2190 break; |
2175 } | 2191 } |
2176 if (!sect2->trim(largest2, sect1)) { | 2192 if (!sect2->trim(largest2, sect1)) { |
2177 SkOPOBJASSERT(intersections, 0); | 2193 SkOPOBJASSERT(intersections, 0); |
2178 return; | 2194 return; |
2179 } | 2195 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2255 int index = intersections->insertCoincident(coincident->fStartT, | 2271 int index = intersections->insertCoincident(coincident->fStartT, |
2256 coincident->fCoinStart.perpT(), coincident->fPart[0]); | 2272 coincident->fCoinStart.perpT(), coincident->fPart[0]); |
2257 if ((intersections->insertCoincident(coincident->fEndT, | 2273 if ((intersections->insertCoincident(coincident->fEndT, |
2258 coincident->fCoinEnd.perpT(), | 2274 coincident->fCoinEnd.perpT(), |
2259 coincident->fPart[TCurve::kPointLast]) < 0) && index >= 0) { | 2275 coincident->fPart[TCurve::kPointLast]) < 0) && index >= 0) { |
2260 intersections->clearCoincidence(index); | 2276 intersections->clearCoincidence(index); |
2261 } | 2277 } |
2262 } while ((coincident = coincident->fNext)); | 2278 } while ((coincident = coincident->fNext)); |
2263 } | 2279 } |
2264 int zeroOneSet = EndsEqual(sect1, sect2, intersections); | 2280 int zeroOneSet = EndsEqual(sect1, sect2, intersections); |
2265 if (!sect1->fHead || !sect2->fHead) { | 2281 // if (!sect1->fHead || !sect2->fHead) { |
2266 // if the final iteration contains an end (0 or 1), | 2282 // if the final iteration contains an end (0 or 1), |
2267 if (sect1->fRemovedStartT && !(zeroOneSet & kZeroS1Set)) { | 2283 if (sect1->fRemovedStartT && !(zeroOneSet & kZeroS1Set)) { |
2268 SkTCoincident<TCurve, OppCurve> perp; // intersect perpendicular w
ith opposite curve | 2284 SkTCoincident<TCurve, OppCurve> perp; // intersect perpendicular w
ith opposite curve |
2269 perp.setPerp(sect1->fCurve, 0, sect1->fCurve[0], sect2->fCurve); | 2285 perp.setPerp(sect1->fCurve, 0, sect1->fCurve[0], sect2->fCurve); |
2270 if (perp.isMatch()) { | 2286 if (perp.isMatch()) { |
2271 intersections->insert(0, perp.perpT(), perp.perpPt()); | 2287 intersections->insert(0, perp.perpT(), perp.perpPt()); |
2272 } | 2288 } |
2273 } | 2289 } |
2274 if (sect1->fRemovedEndT && !(zeroOneSet & kOneS1Set)) { | 2290 if (sect1->fRemovedEndT && !(zeroOneSet & kOneS1Set)) { |
2275 SkTCoincident<TCurve, OppCurve> perp; | 2291 SkTCoincident<TCurve, OppCurve> perp; |
2276 perp.setPerp(sect1->fCurve, 1, sect1->fCurve[TCurve::kPointLast], se
ct2->fCurve); | 2292 perp.setPerp(sect1->fCurve, 1, sect1->fCurve[TCurve::kPointLast], se
ct2->fCurve); |
2277 if (perp.isMatch()) { | 2293 if (perp.isMatch()) { |
2278 intersections->insert(1, perp.perpT(), perp.perpPt()); | 2294 intersections->insert(1, perp.perpT(), perp.perpPt()); |
2279 } | 2295 } |
2280 } | 2296 } |
2281 if (sect2->fRemovedStartT && !(zeroOneSet & kZeroS2Set)) { | 2297 if (sect2->fRemovedStartT && !(zeroOneSet & kZeroS2Set)) { |
2282 SkTCoincident<OppCurve, TCurve> perp; | 2298 SkTCoincident<OppCurve, TCurve> perp; |
2283 perp.setPerp(sect2->fCurve, 0, sect2->fCurve[0], sect1->fCurve); | 2299 perp.setPerp(sect2->fCurve, 0, sect2->fCurve[0], sect1->fCurve); |
2284 if (perp.isMatch()) { | 2300 if (perp.isMatch()) { |
2285 intersections->insert(perp.perpT(), 0, perp.perpPt()); | 2301 intersections->insert(perp.perpT(), 0, perp.perpPt()); |
2286 } | 2302 } |
2287 } | 2303 } |
2288 if (sect2->fRemovedEndT && !(zeroOneSet & kOneS2Set)) { | 2304 if (sect2->fRemovedEndT && !(zeroOneSet & kOneS2Set)) { |
2289 SkTCoincident<OppCurve, TCurve> perp; | 2305 SkTCoincident<OppCurve, TCurve> perp; |
2290 perp.setPerp(sect2->fCurve, 1, sect2->fCurve[OppCurve::kPointLast],
sect1->fCurve); | 2306 perp.setPerp(sect2->fCurve, 1, sect2->fCurve[OppCurve::kPointLast],
sect1->fCurve); |
2291 if (perp.isMatch()) { | 2307 if (perp.isMatch()) { |
2292 intersections->insert(perp.perpT(), 1, perp.perpPt()); | 2308 intersections->insert(perp.perpT(), 1, perp.perpPt()); |
2293 } | 2309 } |
2294 } | 2310 } |
| 2311 // } |
| 2312 if (!sect1->fHead || !sect2->fHead) { |
2295 return; | 2313 return; |
2296 } | 2314 } |
2297 sect1->recoverCollapsed(); | 2315 sect1->recoverCollapsed(); |
2298 sect2->recoverCollapsed(); | 2316 sect2->recoverCollapsed(); |
2299 SkTSpan<TCurve, OppCurve>* result1 = sect1->fHead; | 2317 SkTSpan<TCurve, OppCurve>* result1 = sect1->fHead; |
2300 // check heads and tails for zero and ones and insert them if we haven't alr
eady done so | 2318 // check heads and tails for zero and ones and insert them if we haven't alr
eady done so |
2301 const SkTSpan<TCurve, OppCurve>* head1 = result1; | 2319 const SkTSpan<TCurve, OppCurve>* head1 = result1; |
2302 if (!(zeroOneSet & kZeroS1Set) && approximately_less_than_zero(head1->fStart
T)) { | 2320 if (!(zeroOneSet & kZeroS1Set) && approximately_less_than_zero(head1->fStart
T)) { |
2303 const SkDPoint& start1 = sect1->fCurve[0]; | 2321 const SkDPoint& start1 = sect1->fCurve[0]; |
2304 if (head1->isBounded()) { | 2322 if (head1->isBounded()) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2378 --last; | 2396 --last; |
2379 } else { | 2397 } else { |
2380 intersections->setCoincident(index++); | 2398 intersections->setCoincident(index++); |
2381 } | 2399 } |
2382 intersections->setCoincident(index); | 2400 intersections->setCoincident(index); |
2383 } | 2401 } |
2384 SkOPOBJASSERT(intersections, intersections->used() <= TCurve::kMaxIntersecti
ons); | 2402 SkOPOBJASSERT(intersections, intersections->used() <= TCurve::kMaxIntersecti
ons); |
2385 } | 2403 } |
2386 | 2404 |
2387 #endif | 2405 #endif |
OLD | NEW |