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 |