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 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 double SkOpCoincidence::TRange(const SkOpPtT* overS, double t, | 544 double SkOpCoincidence::TRange(const SkOpPtT* overS, double t, |
545 const SkOpSegment* coinSeg SkDEBUGPARAMS(const SkOpPtT* overE)) { | 545 const SkOpSegment* coinSeg SkDEBUGPARAMS(const SkOpPtT* overE)) { |
546 const SkOpSpanBase* work = overS->span(); | 546 const SkOpSpanBase* work = overS->span(); |
547 const SkOpPtT* foundStart = nullptr; | 547 const SkOpPtT* foundStart = nullptr; |
548 const SkOpPtT* foundEnd = nullptr; | 548 const SkOpPtT* foundEnd = nullptr; |
549 const SkOpPtT* coinStart = nullptr; | 549 const SkOpPtT* coinStart = nullptr; |
550 const SkOpPtT* coinEnd = nullptr; | 550 const SkOpPtT* coinEnd = nullptr; |
551 do { | 551 do { |
552 const SkOpPtT* contained = work->contains(coinSeg); | 552 const SkOpPtT* contained = work->contains(coinSeg); |
553 if (!contained) { | 553 if (!contained) { |
| 554 if (work->t() >= t) { |
| 555 return 1; |
| 556 } |
554 continue; | 557 continue; |
555 } | 558 } |
556 if (work->t() <= t) { | 559 if (work->t() <= t) { |
557 coinStart = contained; | 560 coinStart = contained; |
558 foundStart = work->ptT(); | 561 foundStart = work->ptT(); |
559 } | 562 } |
560 if (work->t() >= t) { | 563 if (work->t() >= t) { |
561 coinEnd = contained; | 564 coinEnd = contained; |
562 foundEnd = work->ptT(); | 565 foundEnd = work->ptT(); |
563 break; | 566 break; |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 fHead = nullptr; | 791 fHead = nullptr; |
789 do { | 792 do { |
790 // addifmissing can modify the list that this is walking | 793 // addifmissing can modify the list that this is walking |
791 // save head so that walker can iterate over old data unperturbed | 794 // save head so that walker can iterate over old data unperturbed |
792 // addifmissing adds to head freely then add saved head in the end | 795 // addifmissing adds to head freely then add saved head in the end |
793 const SkOpPtT* ocs = outer->coinPtTStart(); | 796 const SkOpPtT* ocs = outer->coinPtTStart(); |
794 SkASSERT(!ocs->deleted()); | 797 SkASSERT(!ocs->deleted()); |
795 const SkOpSegment* outerCoin = ocs->segment(); | 798 const SkOpSegment* outerCoin = ocs->segment(); |
796 SkASSERT(!outerCoin->done()); // if it's done, should have already been
removed from list | 799 SkASSERT(!outerCoin->done()); // if it's done, should have already been
removed from list |
797 const SkOpPtT* oos = outer->oppPtTStart(); | 800 const SkOpPtT* oos = outer->oppPtTStart(); |
798 SkASSERT(!oos->deleted()); | 801 if (oos->deleted()) { |
| 802 return false; |
| 803 } |
799 const SkOpSegment* outerOpp = oos->segment(); | 804 const SkOpSegment* outerOpp = oos->segment(); |
800 SkASSERT(!outerOpp->done()); | 805 SkASSERT(!outerOpp->done()); |
801 SkOpSegment* outerCoinWritable = const_cast<SkOpSegment*>(outerCoin); | 806 SkOpSegment* outerCoinWritable = const_cast<SkOpSegment*>(outerCoin); |
802 SkOpSegment* outerOppWritable = const_cast<SkOpSegment*>(outerOpp); | 807 SkOpSegment* outerOppWritable = const_cast<SkOpSegment*>(outerOpp); |
803 SkCoincidentSpans* inner = outer; | 808 SkCoincidentSpans* inner = outer; |
804 while ((inner = inner->next())) { | 809 while ((inner = inner->next())) { |
805 this->debugValidate(); | 810 this->debugValidate(); |
806 double overS, overE; | 811 double overS, overE; |
807 const SkOpPtT* ics = inner->coinPtTStart(); | 812 const SkOpPtT* ics = inner->coinPtTStart(); |
808 SkASSERT(!ics->deleted()); | 813 SkASSERT(!ics->deleted()); |
809 const SkOpSegment* innerCoin = ics->segment(); | 814 const SkOpSegment* innerCoin = ics->segment(); |
810 SkASSERT(!innerCoin->done()); | 815 SkASSERT(!innerCoin->done()); |
811 const SkOpPtT* ios = inner->oppPtTStart(); | 816 const SkOpPtT* ios = inner->oppPtTStart(); |
812 SkASSERT(!ios->deleted()); | 817 SkASSERT(!ios->deleted()); |
813 const SkOpSegment* innerOpp = ios->segment(); | 818 const SkOpSegment* innerOpp = ios->segment(); |
814 SkASSERT(!innerOpp->done()); | 819 SkASSERT(!innerOpp->done()); |
815 SkOpSegment* innerCoinWritable = const_cast<SkOpSegment*>(innerCoin)
; | 820 SkOpSegment* innerCoinWritable = const_cast<SkOpSegment*>(innerCoin)
; |
816 SkOpSegment* innerOppWritable = const_cast<SkOpSegment*>(innerOpp); | 821 SkOpSegment* innerOppWritable = const_cast<SkOpSegment*>(innerOpp); |
817 if (outerCoin == innerCoin) { | 822 if (outerCoin == innerCoin) { |
818 const SkOpPtT* oce = outer->coinPtTEnd(); | 823 const SkOpPtT* oce = outer->coinPtTEnd(); |
819 SkASSERT(!oce->deleted()); | 824 if (oce->deleted()) { |
| 825 return false; |
| 826 } |
820 const SkOpPtT* ice = inner->coinPtTEnd(); | 827 const SkOpPtT* ice = inner->coinPtTEnd(); |
821 SkASSERT(!ice->deleted()); | 828 SkASSERT(!ice->deleted()); |
822 if (outerOpp != innerOpp && this->overlap(ocs, oce, ics, ice, &o
verS, &overE)) { | 829 if (outerOpp != innerOpp && this->overlap(ocs, oce, ics, ice, &o
verS, &overE)) { |
823 added |= this->addIfMissing(ocs->starter(oce), ics->starter(
ice), | 830 added |= this->addIfMissing(ocs->starter(oce), ics->starter(
ice), |
824 overS, overE, outerOppWritable, innerOppWritable | 831 overS, overE, outerOppWritable, innerOppWritable |
825 SkDEBUGPARAMS(ocs->debugEnder(oce)) | 832 SkDEBUGPARAMS(ocs->debugEnder(oce)) |
826 SkDEBUGPARAMS(ics->debugEnder(ice))); | 833 SkDEBUGPARAMS(ics->debugEnder(ice))); |
827 } | 834 } |
828 } else if (outerCoin == innerOpp) { | 835 } else if (outerCoin == innerOpp) { |
829 const SkOpPtT* oce = outer->coinPtTEnd(); | 836 const SkOpPtT* oce = outer->coinPtTEnd(); |
(...skipping 15 matching lines...) Expand all Loading... |
845 if (this->overlap(oos, ooe, ics, ice, &overS, &overE)) { | 852 if (this->overlap(oos, ooe, ics, ice, &overS, &overE)) { |
846 added |= this->addIfMissing(oos->starter(ooe), ics->starter(
ice), | 853 added |= this->addIfMissing(oos->starter(ooe), ics->starter(
ice), |
847 overS, overE, outerCoinWritable, innerOppWritable | 854 overS, overE, outerCoinWritable, innerOppWritable |
848 SkDEBUGPARAMS(oos->debugEnder(ooe)) | 855 SkDEBUGPARAMS(oos->debugEnder(ooe)) |
849 SkDEBUGPARAMS(ics->debugEnder(ice))); | 856 SkDEBUGPARAMS(ics->debugEnder(ice))); |
850 } | 857 } |
851 } else if (outerOpp == innerOpp) { | 858 } else if (outerOpp == innerOpp) { |
852 const SkOpPtT* ooe = outer->oppPtTEnd(); | 859 const SkOpPtT* ooe = outer->oppPtTEnd(); |
853 SkASSERT(!ooe->deleted()); | 860 SkASSERT(!ooe->deleted()); |
854 const SkOpPtT* ioe = inner->oppPtTEnd(); | 861 const SkOpPtT* ioe = inner->oppPtTEnd(); |
855 SkASSERT(!ioe->deleted()); | 862 if (ioe->deleted()) { |
| 863 return false; |
| 864 } |
856 SkASSERT(outerCoin != innerCoin); | 865 SkASSERT(outerCoin != innerCoin); |
857 if (this->overlap(oos, ooe, ios, ioe, &overS, &overE)) { | 866 if (this->overlap(oos, ooe, ios, ioe, &overS, &overE)) { |
858 added |= this->addIfMissing(oos->starter(ooe), ios->starter(
ioe), | 867 added |= this->addIfMissing(oos->starter(ooe), ios->starter(
ioe), |
859 overS, overE, outerCoinWritable, innerCoinWritable | 868 overS, overE, outerCoinWritable, innerCoinWritable |
860 SkDEBUGPARAMS(oos->debugEnder(ooe)) | 869 SkDEBUGPARAMS(oos->debugEnder(ooe)) |
861 SkDEBUGPARAMS(ios->debugEnder(ioe))); | 870 SkDEBUGPARAMS(ios->debugEnder(ioe))); |
862 } | 871 } |
863 } | 872 } |
864 this->debugValidate(); | 873 this->debugValidate(); |
865 } | 874 } |
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1387 if (coin->oppPtTStart()->collapsed(coin->oppPtTEnd())) { | 1396 if (coin->oppPtTStart()->collapsed(coin->oppPtTEnd())) { |
1388 *priorPtr = coin->next(); | 1397 *priorPtr = coin->next(); |
1389 continue; | 1398 continue; |
1390 } | 1399 } |
1391 priorPtr = coin->nextPtr(); | 1400 priorPtr = coin->nextPtr(); |
1392 } while ((coin = coin->next())); | 1401 } while ((coin = coin->next())); |
1393 return true; | 1402 return true; |
1394 } | 1403 } |
1395 | 1404 |
1396 void SkOpCoincidence::fixUp(SkOpPtT* deleted, const SkOpPtT* kept) { | 1405 void SkOpCoincidence::fixUp(SkOpPtT* deleted, const SkOpPtT* kept) { |
1397 SkASSERT(deleted != kept); | 1406 SkOPASSERT(deleted != kept); |
1398 if (fHead) { | 1407 if (fHead) { |
1399 this->fixUp(fHead, deleted, kept); | 1408 this->fixUp(fHead, deleted, kept); |
1400 } | 1409 } |
1401 if (fTop) { | 1410 if (fTop) { |
1402 this->fixUp(fTop, deleted, kept); | 1411 this->fixUp(fTop, deleted, kept); |
1403 } | 1412 } |
1404 } | 1413 } |
1405 | 1414 |
1406 void SkOpCoincidence::fixUp(SkCoincidentSpans* coin, SkOpPtT* deleted, const SkO
pPtT* kept) { | 1415 void SkOpCoincidence::fixUp(SkCoincidentSpans* coin, SkOpPtT* deleted, const SkO
pPtT* kept) { |
1407 SkCoincidentSpans* head = coin; | 1416 SkCoincidentSpans* head = coin; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1446 } | 1455 } |
1447 do { | 1456 do { |
1448 if (!coin->coinPtTStartWritable()->span()->upCastable()) { | 1457 if (!coin->coinPtTStartWritable()->span()->upCastable()) { |
1449 return false; | 1458 return false; |
1450 } | 1459 } |
1451 SkOpSpan* start = coin->coinPtTStartWritable()->span()->upCast(); | 1460 SkOpSpan* start = coin->coinPtTStartWritable()->span()->upCast(); |
1452 SkASSERT(!start->deleted()); | 1461 SkASSERT(!start->deleted()); |
1453 SkOpSpanBase* end = coin->coinPtTEndWritable()->span(); | 1462 SkOpSpanBase* end = coin->coinPtTEndWritable()->span(); |
1454 SkASSERT(!end->deleted()); | 1463 SkASSERT(!end->deleted()); |
1455 SkOpSpanBase* oStart = coin->oppPtTStartWritable()->span(); | 1464 SkOpSpanBase* oStart = coin->oppPtTStartWritable()->span(); |
1456 SkASSERT(!oStart->deleted()); | 1465 if (oStart->deleted()) { |
| 1466 return false; |
| 1467 } |
1457 SkOpSpanBase* oEnd = coin->oppPtTEndWritable()->span(); | 1468 SkOpSpanBase* oEnd = coin->oppPtTEndWritable()->span(); |
1458 SkASSERT(!oEnd->deleted()); | 1469 SkASSERT(!oEnd->deleted()); |
1459 bool flipped = coin->flipped(); | 1470 bool flipped = coin->flipped(); |
1460 if (flipped) { | 1471 if (flipped) { |
1461 SkTSwap(oStart, oEnd); | 1472 SkTSwap(oStart, oEnd); |
1462 } | 1473 } |
1463 /* coin and opp spans may not match up. Mark the ends, and then let the
interior | 1474 /* coin and opp spans may not match up. Mark the ends, and then let the
interior |
1464 get marked as many times as the spans allow */ | 1475 get marked as many times as the spans allow */ |
1465 start->insertCoincidence(oStart->upCast()); | 1476 start->insertCoincidence(oStart->upCast()); |
1466 end->insertCoinEnd(oEnd); | 1477 end->insertCoinEnd(oEnd); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1556 this->release(fHead, coin); | 1567 this->release(fHead, coin); |
1557 } | 1568 } |
1558 } while ((coin = coin->next())); | 1569 } while ((coin = coin->next())); |
1559 } | 1570 } |
1560 | 1571 |
1561 bool SkOpCoincidence::testForCoincidence(const SkCoincidentSpans* outer, const S
kOpPtT* testS, | 1572 bool SkOpCoincidence::testForCoincidence(const SkCoincidentSpans* outer, const S
kOpPtT* testS, |
1562 const SkOpPtT* testE) const { | 1573 const SkOpPtT* testE) const { |
1563 return testS->segment()->testForCoincidence(testS, testE, testS->span(), | 1574 return testS->segment()->testForCoincidence(testS, testE, testS->span(), |
1564 testE->span(), outer->coinPtTStart()->segment()); | 1575 testE->span(), outer->coinPtTStart()->segment()); |
1565 } | 1576 } |
OLD | NEW |