| 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 |