| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 #include "SkOpCoincidence.h" | 7 #include "SkOpCoincidence.h" |
| 8 #include "SkOpSegment.h" | 8 #include "SkOpSegment.h" |
| 9 #include "SkPathOpsTSect.h" | 9 #include "SkPathOpsTSect.h" |
| 10 | 10 |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 DebugCheckAdd(fTop, coinPtTStart, coinPtTEnd, oppPtTStart, oppPtTEnd); | 261 DebugCheckAdd(fTop, coinPtTStart, coinPtTEnd, oppPtTStart, oppPtTEnd); |
| 262 SkCoincidentSpans* coinRec = SkOpTAllocator<SkCoincidentSpans>::Allocate( | 262 SkCoincidentSpans* coinRec = SkOpTAllocator<SkCoincidentSpans>::Allocate( |
| 263 this->globalState()->allocator()); | 263 this->globalState()->allocator()); |
| 264 coinRec->init(); | 264 coinRec->init(); |
| 265 coinRec->set(this->fHead, coinPtTStart, coinPtTEnd, oppPtTStart, oppPtTEnd | 265 coinRec->set(this->fHead, coinPtTStart, coinPtTEnd, oppPtTStart, oppPtTEnd |
| 266 SkDEBUGPARAMS(fGlobalState->nextCoinID())); | 266 SkDEBUGPARAMS(fGlobalState->nextCoinID())); |
| 267 fHead = coinRec; | 267 fHead = coinRec; |
| 268 } | 268 } |
| 269 | 269 |
| 270 // description below | 270 // description below |
| 271 void SkOpCoincidence::addEndMovedSpans(const SkOpSpan* base, const SkOpSpanBase*
testSpan) { | 271 bool SkOpCoincidence::addEndMovedSpans(const SkOpSpan* base, const SkOpSpanBase*
testSpan) { |
| 272 const SkOpPtT* testPtT = testSpan->ptT(); | 272 const SkOpPtT* testPtT = testSpan->ptT(); |
| 273 const SkOpPtT* stopPtT = testPtT; | 273 const SkOpPtT* stopPtT = testPtT; |
| 274 const SkOpSegment* baseSeg = base->segment(); | 274 const SkOpSegment* baseSeg = base->segment(); |
| 275 while ((testPtT = testPtT->next()) != stopPtT) { | 275 while ((testPtT = testPtT->next()) != stopPtT) { |
| 276 const SkOpSegment* testSeg = testPtT->segment(); | 276 const SkOpSegment* testSeg = testPtT->segment(); |
| 277 if (testPtT->deleted()) { | 277 if (testPtT->deleted()) { |
| 278 continue; | 278 continue; |
| 279 } | 279 } |
| 280 if (testSeg == baseSeg) { | 280 if (testSeg == baseSeg) { |
| 281 continue; | 281 continue; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 SkTSwap(coinSeg, oppSeg); | 317 SkTSwap(coinSeg, oppSeg); |
| 318 coinTs = oppStart->fT; | 318 coinTs = oppStart->fT; |
| 319 coinTe = testPtT->fT; | 319 coinTe = testPtT->fT; |
| 320 oppTs = base->t(); | 320 oppTs = base->t(); |
| 321 oppTe = testSpan->t(); | 321 oppTe = testSpan->t(); |
| 322 } | 322 } |
| 323 if (coinTs > coinTe) { | 323 if (coinTs > coinTe) { |
| 324 SkTSwap(coinTs, coinTe); | 324 SkTSwap(coinTs, coinTe); |
| 325 SkTSwap(oppTs, oppTe); | 325 SkTSwap(oppTs, oppTe); |
| 326 } | 326 } |
| 327 (void) this->addOrOverlap(coinSeg, oppSeg, coinTs, coinTe, oppTs, op
pTe); | 327 if (!this->addOrOverlap(coinSeg, oppSeg, coinTs, coinTe, oppTs, oppT
e)) { |
| 328 return false; |
| 329 } |
| 328 } | 330 } |
| 329 } | 331 } |
| 332 return true; |
| 330 } | 333 } |
| 331 | 334 |
| 332 // description below | 335 // description below |
| 333 bool SkOpCoincidence::addEndMovedSpans(const SkOpPtT* ptT) { | 336 bool SkOpCoincidence::addEndMovedSpans(const SkOpPtT* ptT) { |
| 334 const SkOpSpan* base = ptT->span()->upCast(); | 337 const SkOpSpan* base = ptT->span()->upCast(); |
| 335 const SkOpSpan* prev = base->prev(); | 338 const SkOpSpan* prev = base->prev(); |
| 336 if (!prev) { | 339 if (!prev) { |
| 337 return false; | 340 return false; |
| 338 } | 341 } |
| 339 if (!prev->isCanceled()) { | 342 if (!prev->isCanceled()) { |
| 340 this->addEndMovedSpans(base, base->prev()); | 343 if (!this->addEndMovedSpans(base, base->prev())) { |
| 344 return false; |
| 345 } |
| 341 } | 346 } |
| 342 if (!base->isCanceled()) { | 347 if (!base->isCanceled()) { |
| 343 this->addEndMovedSpans(base, base->next()); | 348 if (!this->addEndMovedSpans(base, base->next())) { |
| 349 return false; |
| 350 } |
| 344 } | 351 } |
| 345 return true; | 352 return true; |
| 346 } | 353 } |
| 347 | 354 |
| 348 /* If A is coincident with B and B includes an endpoint, and A's matching point | 355 /* If A is coincident with B and B includes an endpoint, and A's matching point |
| 349 is not the endpoint (i.e., there's an implied line connecting B-end and A) | 356 is not the endpoint (i.e., there's an implied line connecting B-end and A) |
| 350 then assume that the same implied line may intersect another curve close to
B. | 357 then assume that the same implied line may intersect another curve close to
B. |
| 351 Since we only care about coincidence that was undetected, look at the | 358 Since we only care about coincidence that was undetected, look at the |
| 352 ptT list on B-segment adjacent to the B-end/A ptT loop (not in the loop, but | 359 ptT list on B-segment adjacent to the B-end/A ptT loop (not in the loop, but |
| 353 next door) and see if the A matching point is close enough to form another | 360 next door) and see if the A matching point is close enough to form another |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 624 } | 631 } |
| 625 if (!fHead || !this->release(fHead, test)) { | 632 if (!fHead || !this->release(fHead, test)) { |
| 626 SkAssertResult(this->release(fTop, test)); | 633 SkAssertResult(this->release(fTop, test)); |
| 627 } | 634 } |
| 628 } | 635 } |
| 629 const SkOpPtT* cs = coinSeg->existing(coinTs, oppSeg); | 636 const SkOpPtT* cs = coinSeg->existing(coinTs, oppSeg); |
| 630 const SkOpPtT* ce = coinSeg->existing(coinTe, oppSeg); | 637 const SkOpPtT* ce = coinSeg->existing(coinTe, oppSeg); |
| 631 if (overlap && cs && ce && overlap->contains(cs, ce)) { | 638 if (overlap && cs && ce && overlap->contains(cs, ce)) { |
| 632 return false; | 639 return false; |
| 633 } | 640 } |
| 634 SkASSERT(cs != ce || !cs); | 641 if (cs == ce && cs) { |
| 642 return false; |
| 643 } |
| 635 const SkOpPtT* os = oppSeg->existing(oppTs, coinSeg); | 644 const SkOpPtT* os = oppSeg->existing(oppTs, coinSeg); |
| 636 const SkOpPtT* oe = oppSeg->existing(oppTe, coinSeg); | 645 const SkOpPtT* oe = oppSeg->existing(oppTe, coinSeg); |
| 637 if (overlap && os && oe && overlap->contains(os, oe)) { | 646 if (overlap && os && oe && overlap->contains(os, oe)) { |
| 638 return false; | 647 return false; |
| 639 } | 648 } |
| 640 SkASSERT(!cs || !cs->deleted()); | 649 SkASSERT(!cs || !cs->deleted()); |
| 641 SkASSERT(!os || !os->deleted()); | 650 SkASSERT(!os || !os->deleted()); |
| 642 SkASSERT(!ce || !ce->deleted()); | 651 SkASSERT(!ce || !ce->deleted()); |
| 643 SkASSERT(!oe || !oe->deleted()); | 652 SkASSERT(!oe || !oe->deleted()); |
| 644 const SkOpPtT* csExisting = !cs ? coinSeg->existing(coinTs, nullptr) : nullp
tr; | 653 const SkOpPtT* csExisting = !cs ? coinSeg->existing(coinTs, nullptr) : nullp
tr; |
| (...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1439 this->release(fHead, coin); | 1448 this->release(fHead, coin); |
| 1440 } | 1449 } |
| 1441 } while ((coin = coin->next())); | 1450 } while ((coin = coin->next())); |
| 1442 } | 1451 } |
| 1443 | 1452 |
| 1444 bool SkOpCoincidence::testForCoincidence(const SkCoincidentSpans* outer, const S
kOpPtT* testS, | 1453 bool SkOpCoincidence::testForCoincidence(const SkCoincidentSpans* outer, const S
kOpPtT* testS, |
| 1445 const SkOpPtT* testE) const { | 1454 const SkOpPtT* testE) const { |
| 1446 return testS->segment()->testForCoincidence(testS, testE, testS->span(), | 1455 return testS->segment()->testForCoincidence(testS, testE, testS->span(), |
| 1447 testE->span(), outer->coinPtTStart()->segment()); | 1456 testE->span(), outer->coinPtTStart()->segment()); |
| 1448 } | 1457 } |
| OLD | NEW |