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 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 SkDEBUGCODE(result->debugSetGlobalState(this->globalState())); | 267 SkDEBUGCODE(result->debugSetGlobalState(this->globalState())); |
268 result->splitAt(span, t, &fHeap); | 268 result->splitAt(span, t, &fHeap); |
269 result->initBounds(fCurve); | 269 result->initBounds(fCurve); |
270 span->initBounds(fCurve); | 270 span->initBounds(fCurve); |
271 return result; | 271 return result; |
272 } | 272 } |
273 | 273 |
274 bool binarySearchCoin(SkTSect<OppCurve, TCurve>* , double tStart, double tSt
ep, double* t, | 274 bool binarySearchCoin(SkTSect<OppCurve, TCurve>* , double tStart, double tSt
ep, double* t, |
275 double* oppT); | 275 double* oppT); |
276 SkTSpan<TCurve, OppCurve>* boundsMax() const; | 276 SkTSpan<TCurve, OppCurve>* boundsMax() const; |
277 void coincidentCheck(SkTSect<OppCurve, TCurve>* sect2); | 277 bool coincidentCheck(SkTSect<OppCurve, TCurve>* sect2); |
278 void coincidentForce(SkTSect<OppCurve, TCurve>* sect2, double start1s, doubl
e start1e); | 278 void coincidentForce(SkTSect<OppCurve, TCurve>* sect2, double start1s, doubl
e start1e); |
279 bool coincidentHasT(double t); | 279 bool coincidentHasT(double t); |
280 int collapsed() const; | 280 int collapsed() const; |
281 void computePerpendiculars(SkTSect<OppCurve, TCurve>* sect2, SkTSpan<TCurve,
OppCurve>* first, | 281 void computePerpendiculars(SkTSect<OppCurve, TCurve>* sect2, SkTSpan<TCurve,
OppCurve>* first, |
282 SkTSpan<TCurve, OppCurve>* last); | 282 SkTSpan<TCurve, OppCurve>* last); |
283 int countConsecutiveSpans(SkTSpan<TCurve, OppCurve>* first, | 283 int countConsecutiveSpans(SkTSpan<TCurve, OppCurve>* first, |
284 SkTSpan<TCurve, OppCurve>** last) const; | 284 SkTSpan<TCurve, OppCurve>** last) const; |
285 | 285 |
286 int debugID() const { | 286 int debugID() const { |
287 return PATH_OPS_DEBUG_T_SECT_RELEASE(fID, -1); | 287 return PATH_OPS_DEBUG_T_SECT_RELEASE(fID, -1); |
288 } | 288 } |
289 | 289 |
290 void deleteEmptySpans(); | 290 bool deleteEmptySpans(); |
291 void dumpCommon(const SkTSpan<TCurve, OppCurve>* ) const; | 291 void dumpCommon(const SkTSpan<TCurve, OppCurve>* ) const; |
292 void dumpCommonCurves(const SkTSpan<TCurve, OppCurve>* ) const; | 292 void dumpCommonCurves(const SkTSpan<TCurve, OppCurve>* ) const; |
293 static int EndsEqual(const SkTSect* sect1, const SkTSect<OppCurve, TCurve>*
sect2, | 293 static int EndsEqual(const SkTSect* sect1, const SkTSect<OppCurve, TCurve>*
sect2, |
294 SkIntersections* ); | 294 SkIntersections* ); |
295 SkTSpan<TCurve, OppCurve>* extractCoincident(SkTSect<OppCurve, TCurve>* sect
2, | 295 bool extractCoincident(SkTSect<OppCurve, TCurve>* sect2, SkTSpan<TCurve, Opp
Curve>* first, |
296 SkTSpan<TCurve, OppCurve>* fir
st, | 296 SkTSpan<TCurve, OppCurve>* last, SkTSpan<TCurve, OppC
urve>** result); |
297 SkTSpan<TCurve, OppCurve>* las
t); | |
298 SkTSpan<TCurve, OppCurve>* findCoincidentRun(SkTSpan<TCurve, OppCurve>* firs
t, | 297 SkTSpan<TCurve, OppCurve>* findCoincidentRun(SkTSpan<TCurve, OppCurve>* firs
t, |
299 SkTSpan<TCurve, OppCurve>** la
stPtr); | 298 SkTSpan<TCurve, OppCurve>** la
stPtr); |
300 int intersects(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>* o
pp, | 299 int intersects(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>* o
pp, |
301 SkTSpan<OppCurve, TCurve>* oppSpan, int* oppResult); | 300 SkTSpan<OppCurve, TCurve>* oppSpan, int* oppResult); |
302 bool isParallel(const SkDLine& thisLine, const SkTSect<OppCurve, TCurve>* op
p) const; | 301 bool isParallel(const SkDLine& thisLine, const SkTSect<OppCurve, TCurve>* op
p) const; |
303 int linesIntersect(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve
>* opp, | 302 int linesIntersect(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve
>* opp, |
304 SkTSpan<OppCurve, TCurve>* oppSpan, SkIntersections* ); | 303 SkTSpan<OppCurve, TCurve>* oppSpan, SkIntersections* ); |
305 void markSpanGone(SkTSpan<TCurve, OppCurve>* span); | 304 bool markSpanGone(SkTSpan<TCurve, OppCurve>* span); |
306 bool matchedDirection(double t, const SkTSect<OppCurve, TCurve>* sect2, doub
le t2) const; | 305 bool matchedDirection(double t, const SkTSect<OppCurve, TCurve>* sect2, doub
le t2) const; |
307 void matchedDirCheck(double t, const SkTSect<OppCurve, TCurve>* sect2, doubl
e t2, | 306 void matchedDirCheck(double t, const SkTSect<OppCurve, TCurve>* sect2, doubl
e t2, |
308 bool* calcMatched, bool* oppMatched) const; | 307 bool* calcMatched, bool* oppMatched) const; |
309 void mergeCoincidence(SkTSect<OppCurve, TCurve>* sect2); | 308 void mergeCoincidence(SkTSect<OppCurve, TCurve>* sect2); |
310 SkTSpan<TCurve, OppCurve>* prev(SkTSpan<TCurve, OppCurve>* ) const; | 309 SkTSpan<TCurve, OppCurve>* prev(SkTSpan<TCurve, OppCurve>* ) const; |
311 void removeByPerpendicular(SkTSect<OppCurve, TCurve>* opp); | 310 void removeByPerpendicular(SkTSect<OppCurve, TCurve>* opp); |
312 void recoverCollapsed(); | 311 void recoverCollapsed(); |
313 void removeCoincident(SkTSpan<TCurve, OppCurve>* span, bool isBetween); | 312 void removeCoincident(SkTSpan<TCurve, OppCurve>* span, bool isBetween); |
314 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, |
315 SkTSect<OppCurve, TCurve>* opp); | 314 SkTSect<OppCurve, TCurve>* opp); |
316 void removeSpan(SkTSpan<TCurve, OppCurve>* span); | 315 bool removeSpan(SkTSpan<TCurve, OppCurve>* span); |
317 void removeSpanRange(SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCu
rve>* last); | 316 void removeSpanRange(SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCu
rve>* last); |
318 void removeSpans(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>*
opp); | 317 void removeSpans(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>*
opp); |
319 SkTSpan<TCurve, OppCurve>* spanAtT(double t, SkTSpan<TCurve, OppCurve>** pri
orSpan); | 318 SkTSpan<TCurve, OppCurve>* spanAtT(double t, SkTSpan<TCurve, OppCurve>** pri
orSpan); |
320 SkTSpan<TCurve, OppCurve>* tail(); | 319 SkTSpan<TCurve, OppCurve>* tail(); |
321 void trim(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>* opp); | 320 void trim(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>* opp); |
322 void unlinkSpan(SkTSpan<TCurve, OppCurve>* span); | 321 void unlinkSpan(SkTSpan<TCurve, OppCurve>* span); |
323 bool updateBounded(SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCurv
e>* last, | 322 bool updateBounded(SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCurv
e>* last, |
324 SkTSpan<OppCurve, TCurve>* oppFirst); | 323 SkTSpan<OppCurve, TCurve>* oppFirst); |
325 void validate() const; | 324 void validate() const; |
326 void validateBounded() const; | 325 void validateBounded() const; |
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
974 if ((lCollapsed && !tCollapsed) || (lCollapsed == tCollapsed && | 973 if ((lCollapsed && !tCollapsed) || (lCollapsed == tCollapsed && |
975 largest->fBoundsMax < test->fBoundsMax)) { | 974 largest->fBoundsMax < test->fBoundsMax)) { |
976 largest = test; | 975 largest = test; |
977 lCollapsed = test->fCollapsed; | 976 lCollapsed = test->fCollapsed; |
978 } | 977 } |
979 } | 978 } |
980 return largest; | 979 return largest; |
981 } | 980 } |
982 | 981 |
983 template<typename TCurve, typename OppCurve> | 982 template<typename TCurve, typename OppCurve> |
984 void SkTSect<TCurve, OppCurve>::coincidentCheck(SkTSect<OppCurve, TCurve>* sect2
) { | 983 bool SkTSect<TCurve, OppCurve>::coincidentCheck(SkTSect<OppCurve, TCurve>* sect2
) { |
985 SkTSpan<TCurve, OppCurve>* first = fHead; | 984 SkTSpan<TCurve, OppCurve>* first = fHead; |
986 SkTSpan<TCurve, OppCurve>* last, * next; | 985 SkTSpan<TCurve, OppCurve>* last, * next; |
987 do { | 986 do { |
988 int consecutive = this->countConsecutiveSpans(first, &last); | 987 int consecutive = this->countConsecutiveSpans(first, &last); |
989 next = last->fNext; | 988 next = last->fNext; |
990 if (consecutive < COINCIDENT_SPAN_COUNT) { | 989 if (consecutive < COINCIDENT_SPAN_COUNT) { |
991 continue; | 990 continue; |
992 } | 991 } |
993 this->validate(); | 992 this->validate(); |
994 sect2->validate(); | 993 sect2->validate(); |
995 this->computePerpendiculars(sect2, first, last); | 994 this->computePerpendiculars(sect2, first, last); |
996 this->validate(); | 995 this->validate(); |
997 sect2->validate(); | 996 sect2->validate(); |
998 // check to see if a range of points are on the curve | 997 // check to see if a range of points are on the curve |
999 SkTSpan<TCurve, OppCurve>* coinStart = first; | 998 SkTSpan<TCurve, OppCurve>* coinStart = first; |
1000 do { | 999 do { |
1001 coinStart = this->extractCoincident(sect2, coinStart, last); | 1000 bool success = this->extractCoincident(sect2, coinStart, last, &coin
Start); |
| 1001 if (!success) { |
| 1002 return false; |
| 1003 } |
1002 } while (coinStart && !last->fDeleted); | 1004 } while (coinStart && !last->fDeleted); |
1003 if (!fHead || !sect2->fHead) { | 1005 if (!fHead || !sect2->fHead) { |
1004 break; | 1006 break; |
1005 } | 1007 } |
1006 if (!next || next->fDeleted) { | 1008 if (!next || next->fDeleted) { |
1007 break; | 1009 break; |
1008 } | 1010 } |
1009 } while ((first = next)); | 1011 } while ((first = next)); |
| 1012 return true; |
1010 } | 1013 } |
1011 | 1014 |
1012 template<typename TCurve, typename OppCurve> | 1015 template<typename TCurve, typename OppCurve> |
1013 void SkTSect<TCurve, OppCurve>::coincidentForce(SkTSect<OppCurve, TCurve>* sect2
, | 1016 void SkTSect<TCurve, OppCurve>::coincidentForce(SkTSect<OppCurve, TCurve>* sect2
, |
1014 double start1s, double start1e) { | 1017 double start1s, double start1e) { |
1015 SkTSpan<TCurve, OppCurve>* first = fHead; | 1018 SkTSpan<TCurve, OppCurve>* first = fHead; |
1016 SkTSpan<TCurve, OppCurve>* last = this->tail(); | 1019 SkTSpan<TCurve, OppCurve>* last = this->tail(); |
1017 SkTSpan<OppCurve, TCurve>* oppFirst = sect2->fHead; | 1020 SkTSpan<OppCurve, TCurve>* oppFirst = sect2->fHead; |
1018 SkTSpan<OppCurve, TCurve>* oppLast = sect2->tail(); | 1021 SkTSpan<OppCurve, TCurve>* oppLast = sect2->tail(); |
1019 bool deleteEmptySpans = this->updateBounded(first, last, oppFirst); | 1022 bool deleteEmptySpans = this->updateBounded(first, last, oppFirst); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1136 } | 1139 } |
1137 do { | 1140 do { |
1138 if (test->findOppSpan(span)) { | 1141 if (test->findOppSpan(span)) { |
1139 return true; | 1142 return true; |
1140 } | 1143 } |
1141 } while ((test = test->next())); | 1144 } while ((test = test->next())); |
1142 return false; | 1145 return false; |
1143 } | 1146 } |
1144 | 1147 |
1145 template<typename TCurve, typename OppCurve> | 1148 template<typename TCurve, typename OppCurve> |
1146 void SkTSect<TCurve, OppCurve>::deleteEmptySpans() { | 1149 bool SkTSect<TCurve, OppCurve>::deleteEmptySpans() { |
1147 SkTSpan<TCurve, OppCurve>* test; | 1150 SkTSpan<TCurve, OppCurve>* test; |
1148 SkTSpan<TCurve, OppCurve>* next = fHead; | 1151 SkTSpan<TCurve, OppCurve>* next = fHead; |
1149 while ((test = next)) { | 1152 while ((test = next)) { |
1150 next = test->fNext; | 1153 next = test->fNext; |
1151 if (!test->fBounded) { | 1154 if (!test->fBounded) { |
1152 this->removeSpan(test); | 1155 if (!this->removeSpan(test)) { |
| 1156 return false; |
| 1157 } |
1153 } | 1158 } |
1154 } | 1159 } |
| 1160 return true; |
1155 } | 1161 } |
1156 | 1162 |
1157 template<typename TCurve, typename OppCurve> | 1163 template<typename TCurve, typename OppCurve> |
1158 SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::extractCoincident( | 1164 bool SkTSect<TCurve, OppCurve>::extractCoincident( |
1159 SkTSect<OppCurve, TCurve>* sect2, | 1165 SkTSect<OppCurve, TCurve>* sect2, |
1160 SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCurve>* last) { | 1166 SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCurve>* last, |
| 1167 SkTSpan<TCurve, OppCurve>** result) { |
1161 first = findCoincidentRun(first, &last); | 1168 first = findCoincidentRun(first, &last); |
1162 if (!first || !last) { | 1169 if (!first || !last) { |
1163 return nullptr; | 1170 *result = nullptr; |
| 1171 return true; |
1164 } | 1172 } |
1165 // march outwards to find limit of coincidence from here to previous and nex
t spans | 1173 // march outwards to find limit of coincidence from here to previous and nex
t spans |
1166 double startT = first->fStartT; | 1174 double startT = first->fStartT; |
1167 double oppStartT SK_INIT_TO_AVOID_WARNING; | 1175 double oppStartT SK_INIT_TO_AVOID_WARNING; |
1168 double oppEndT SK_INIT_TO_AVOID_WARNING; | 1176 double oppEndT SK_INIT_TO_AVOID_WARNING; |
1169 SkTSpan<TCurve, OppCurve>* prev = first->fPrev; | 1177 SkTSpan<TCurve, OppCurve>* prev = first->fPrev; |
1170 SkASSERT(first->fCoinStart.isCoincident()); | 1178 SkASSERT(first->fCoinStart.isCoincident()); |
1171 SkTSpan<OppCurve, TCurve>* oppFirst = first->findOppT(first->fCoinStart.perp
T()); | 1179 SkTSpan<OppCurve, TCurve>* oppFirst = first->findOppT(first->fCoinStart.perp
T()); |
1172 SkOPASSERT(last->fCoinEnd.isCoincident()); | 1180 SkOPASSERT(last->fCoinEnd.isCoincident()); |
1173 bool oppMatched = first->fCoinStart.perpT() < first->fCoinEnd.perpT(); | 1181 bool oppMatched = first->fCoinStart.perpT() < first->fCoinEnd.perpT(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1211 if (!oppMatched) { | 1219 if (!oppMatched) { |
1212 SkTSwap(oppFirst, oppLast); | 1220 SkTSwap(oppFirst, oppLast); |
1213 SkTSwap(oppStartT, oppEndT); | 1221 SkTSwap(oppStartT, oppEndT); |
1214 } | 1222 } |
1215 SkOPASSERT(oppStartT < oppEndT); | 1223 SkOPASSERT(oppStartT < oppEndT); |
1216 SkASSERT(coinStart == first->fStartT); | 1224 SkASSERT(coinStart == first->fStartT); |
1217 SkASSERT(coinEnd == last->fEndT); | 1225 SkASSERT(coinEnd == last->fEndT); |
1218 SkOPASSERT(oppStartT == oppFirst->fStartT); | 1226 SkOPASSERT(oppStartT == oppFirst->fStartT); |
1219 SkOPASSERT(oppEndT == oppLast->fEndT); | 1227 SkOPASSERT(oppEndT == oppLast->fEndT); |
1220 if (!oppFirst) { | 1228 if (!oppFirst) { |
1221 return nullptr; | 1229 *result = nullptr; |
| 1230 return true; |
1222 } | 1231 } |
1223 if (!oppLast) { | 1232 if (!oppLast) { |
1224 return nullptr; | 1233 *result = nullptr; |
| 1234 return true; |
1225 } | 1235 } |
1226 // reduce coincident runs to single entries | 1236 // reduce coincident runs to single entries |
1227 this->validate(); | 1237 this->validate(); |
1228 sect2->validate(); | 1238 sect2->validate(); |
1229 bool deleteEmptySpans = this->updateBounded(first, last, oppFirst); | 1239 bool deleteEmptySpans = this->updateBounded(first, last, oppFirst); |
1230 deleteEmptySpans |= sect2->updateBounded(oppFirst, oppLast, first); | 1240 deleteEmptySpans |= sect2->updateBounded(oppFirst, oppLast, first); |
1231 this->removeSpanRange(first, last); | 1241 this->removeSpanRange(first, last); |
1232 sect2->removeSpanRange(oppFirst, oppLast); | 1242 sect2->removeSpanRange(oppFirst, oppLast); |
1233 first->fEndT = last->fEndT; | 1243 first->fEndT = last->fEndT; |
1234 first->resetBounds(this->fCurve); | 1244 first->resetBounds(this->fCurve); |
1235 first->fCoinStart.setPerp(fCurve, first->fStartT, first->fPart[0], sect2->fC
urve); | 1245 first->fCoinStart.setPerp(fCurve, first->fStartT, first->fPart[0], sect2->fC
urve); |
1236 first->fCoinEnd.setPerp(fCurve, first->fEndT, first->fPart[TCurve::kPointLas
t], sect2->fCurve); | 1246 first->fCoinEnd.setPerp(fCurve, first->fEndT, first->fPart[TCurve::kPointLas
t], sect2->fCurve); |
1237 oppStartT = first->fCoinStart.perpT(); | 1247 oppStartT = first->fCoinStart.perpT(); |
1238 oppEndT = first->fCoinEnd.perpT(); | 1248 oppEndT = first->fCoinEnd.perpT(); |
1239 if (between(0, oppStartT, 1) && between(0, oppEndT, 1)) { | 1249 if (between(0, oppStartT, 1) && between(0, oppEndT, 1)) { |
1240 if (!oppMatched) { | 1250 if (!oppMatched) { |
1241 SkTSwap(oppStartT, oppEndT); | 1251 SkTSwap(oppStartT, oppEndT); |
1242 } | 1252 } |
1243 oppFirst->fStartT = oppStartT; | 1253 oppFirst->fStartT = oppStartT; |
1244 oppFirst->fEndT = oppEndT; | 1254 oppFirst->fEndT = oppEndT; |
1245 oppFirst->resetBounds(sect2->fCurve); | 1255 oppFirst->resetBounds(sect2->fCurve); |
1246 } | 1256 } |
1247 this->validateBounded(); | 1257 this->validateBounded(); |
1248 sect2->validateBounded(); | 1258 sect2->validateBounded(); |
1249 last = first->fNext; | 1259 last = first->fNext; |
1250 this->removeCoincident(first, false); | 1260 this->removeCoincident(first, false); |
1251 sect2->removeCoincident(oppFirst, true); | 1261 sect2->removeCoincident(oppFirst, true); |
1252 if (deleteEmptySpans) { | 1262 if (deleteEmptySpans) { |
1253 this->deleteEmptySpans(); | 1263 if (!this->deleteEmptySpans() || !sect2->deleteEmptySpans()) { |
1254 sect2->deleteEmptySpans(); | 1264 *result = nullptr; |
| 1265 return false; |
| 1266 } |
1255 } | 1267 } |
1256 this->validate(); | 1268 this->validate(); |
1257 sect2->validate(); | 1269 sect2->validate(); |
1258 return last && !last->fDeleted && fHead && sect2->fHead ? last : nullptr; | 1270 *result = last && !last->fDeleted && fHead && sect2->fHead ? last : nullptr; |
| 1271 return true; |
1259 } | 1272 } |
1260 | 1273 |
1261 template<typename TCurve, typename OppCurve> | 1274 template<typename TCurve, typename OppCurve> |
1262 SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::findCoincidentRun( | 1275 SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::findCoincidentRun( |
1263 SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCurve>** lastPtr) { | 1276 SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCurve>** lastPtr) { |
1264 SkTSpan<TCurve, OppCurve>* work = first; | 1277 SkTSpan<TCurve, OppCurve>* work = first; |
1265 SkTSpan<TCurve, OppCurve>* lastCandidate = nullptr; | 1278 SkTSpan<TCurve, OppCurve>* lastCandidate = nullptr; |
1266 first = nullptr; | 1279 first = nullptr; |
1267 // find the first fully coincident span | 1280 // find the first fully coincident span |
1268 do { | 1281 do { |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1533 if (!opp->fHead->contains(oppTTest)) { | 1546 if (!opp->fHead->contains(oppTTest)) { |
1534 return 0; | 1547 return 0; |
1535 } | 1548 } |
1536 i->setMax(1); | 1549 i->setMax(1); |
1537 i->insert(workT, oppTTest, workPt); | 1550 i->insert(workT, oppTTest, workPt); |
1538 return 1; | 1551 return 1; |
1539 } | 1552 } |
1540 | 1553 |
1541 | 1554 |
1542 template<typename TCurve, typename OppCurve> | 1555 template<typename TCurve, typename OppCurve> |
1543 void SkTSect<TCurve, OppCurve>::markSpanGone(SkTSpan<TCurve, OppCurve>* span) { | 1556 bool SkTSect<TCurve, OppCurve>::markSpanGone(SkTSpan<TCurve, OppCurve>* span) { |
1544 --fActiveCount; | 1557 if (--fActiveCount < 0) { |
| 1558 return false; |
| 1559 } |
1545 span->fNext = fDeleted; | 1560 span->fNext = fDeleted; |
1546 fDeleted = span; | 1561 fDeleted = span; |
1547 SkOPASSERT(!span->fDeleted); | 1562 SkOPASSERT(!span->fDeleted); |
1548 span->fDeleted = true; | 1563 span->fDeleted = true; |
| 1564 return true; |
1549 } | 1565 } |
1550 | 1566 |
1551 template<typename TCurve, typename OppCurve> | 1567 template<typename TCurve, typename OppCurve> |
1552 bool SkTSect<TCurve, OppCurve>::matchedDirection(double t, const SkTSect<OppCurv
e, TCurve>* sect2, | 1568 bool SkTSect<TCurve, OppCurve>::matchedDirection(double t, const SkTSect<OppCurv
e, TCurve>* sect2, |
1553 double t2) const { | 1569 double t2) const { |
1554 SkDVector dxdy = this->fCurve.dxdyAtT(t); | 1570 SkDVector dxdy = this->fCurve.dxdyAtT(t); |
1555 SkDVector dxdy2 = sect2->fCurve.dxdyAtT(t2); | 1571 SkDVector dxdy2 = sect2->fCurve.dxdyAtT(t2); |
1556 return dxdy.dot(dxdy2) >= 0; | 1572 return dxdy.dot(dxdy2) >= 0; |
1557 } | 1573 } |
1558 | 1574 |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1703 if (isBetween || between(0, span->fCoinStart.perpT(), 1)) { | 1719 if (isBetween || between(0, span->fCoinStart.perpT(), 1)) { |
1704 --fActiveCount; | 1720 --fActiveCount; |
1705 span->fNext = fCoincident; | 1721 span->fNext = fCoincident; |
1706 fCoincident = span; | 1722 fCoincident = span; |
1707 } else { | 1723 } else { |
1708 this->markSpanGone(span); | 1724 this->markSpanGone(span); |
1709 } | 1725 } |
1710 } | 1726 } |
1711 | 1727 |
1712 template<typename TCurve, typename OppCurve> | 1728 template<typename TCurve, typename OppCurve> |
1713 void SkTSect<TCurve, OppCurve>::removeSpan(SkTSpan<TCurve, OppCurve>* span) { | 1729 bool SkTSect<TCurve, OppCurve>::removeSpan(SkTSpan<TCurve, OppCurve>* span) { |
1714 this->unlinkSpan(span); | 1730 this->unlinkSpan(span); |
1715 this->markSpanGone(span); | 1731 return this->markSpanGone(span); |
1716 } | 1732 } |
1717 | 1733 |
1718 template<typename TCurve, typename OppCurve> | 1734 template<typename TCurve, typename OppCurve> |
1719 void SkTSect<TCurve, OppCurve>::removeSpanRange(SkTSpan<TCurve, OppCurve>* first
, | 1735 void SkTSect<TCurve, OppCurve>::removeSpanRange(SkTSpan<TCurve, OppCurve>* first
, |
1720 SkTSpan<TCurve, OppCurve>* last) { | 1736 SkTSpan<TCurve, OppCurve>* last) { |
1721 if (first == last) { | 1737 if (first == last) { |
1722 return; | 1738 return; |
1723 } | 1739 } |
1724 SkTSpan<TCurve, OppCurve>* span = first; | 1740 SkTSpan<TCurve, OppCurve>* span = first; |
1725 SkASSERT(span); | 1741 SkASSERT(span); |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2141 #if DEBUG_T_SECT_LOOP_COUNT | 2157 #if DEBUG_T_SECT_LOOP_COUNT |
2142 intersections->debugBumpLoopCount(SkIntersections::kIterations_DebugLoop
); | 2158 intersections->debugBumpLoopCount(SkIntersections::kIterations_DebugLoop
); |
2143 #endif | 2159 #endif |
2144 // if there are 9 or more continuous spans on both sects, suspect coinci
dence | 2160 // if there are 9 or more continuous spans on both sects, suspect coinci
dence |
2145 if (sect1->fActiveCount >= COINCIDENT_SPAN_COUNT | 2161 if (sect1->fActiveCount >= COINCIDENT_SPAN_COUNT |
2146 && sect2->fActiveCount >= COINCIDENT_SPAN_COUNT) { | 2162 && sect2->fActiveCount >= COINCIDENT_SPAN_COUNT) { |
2147 if (coinLoopCount == kMaxCoinLoopCount) { | 2163 if (coinLoopCount == kMaxCoinLoopCount) { |
2148 start1s = sect1->fHead->fStartT; | 2164 start1s = sect1->fHead->fStartT; |
2149 start1e = sect1->tail()->fEndT; | 2165 start1e = sect1->tail()->fEndT; |
2150 } | 2166 } |
2151 sect1->coincidentCheck(sect2); | 2167 if (!sect1->coincidentCheck(sect2)) { |
| 2168 return; |
| 2169 } |
2152 sect1->validate(); | 2170 sect1->validate(); |
2153 sect2->validate(); | 2171 sect2->validate(); |
2154 #if DEBUG_T_SECT_LOOP_COUNT | 2172 #if DEBUG_T_SECT_LOOP_COUNT |
2155 intersections->debugBumpLoopCount(SkIntersections::kCoinCheck_DebugL
oop); | 2173 intersections->debugBumpLoopCount(SkIntersections::kCoinCheck_DebugL
oop); |
2156 #endif | 2174 #endif |
2157 if (!--coinLoopCount && sect1->fHead && sect2->fHead) { | 2175 if (!--coinLoopCount && sect1->fHead && sect2->fHead) { |
2158 /* All known working cases resolve in two tries. Sadly, cubicCon
icTests[0] | 2176 /* All known working cases resolve in two tries. Sadly, cubicCon
icTests[0] |
2159 gets stuck in a loop. It adds an extension to allow a coincid
ent end | 2177 gets stuck in a loop. It adds an extension to allow a coincid
ent end |
2160 perpendicular to track its intersection in the opposite curve
. However, | 2178 perpendicular to track its intersection in the opposite curve
. However, |
2161 the bounding box of the extension does not intersect the orig
inal curve, | 2179 the bounding box of the extension does not intersect the orig
inal curve, |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2298 --last; | 2316 --last; |
2299 } else { | 2317 } else { |
2300 intersections->setCoincident(index++); | 2318 intersections->setCoincident(index++); |
2301 } | 2319 } |
2302 intersections->setCoincident(index); | 2320 intersections->setCoincident(index); |
2303 } | 2321 } |
2304 SkASSERT(intersections->used() <= TCurve::kMaxIntersections); | 2322 SkASSERT(intersections->used() <= TCurve::kMaxIntersections); |
2305 } | 2323 } |
2306 | 2324 |
2307 #endif | 2325 #endif |
OLD | NEW |