Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: src/pathops/SkPathOpsTSect.h

Issue 2310113002: provide safe exit for runaway intersections (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tests/PathOpsOpTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | tests/PathOpsOpTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698