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 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 SkOpSegment* writableSeg = const_cast<SkOpSegment*>(testSeg); | 301 SkOpSegment* writableSeg = const_cast<SkOpSegment*>(testSeg); |
302 SkOpPtT* oppStart = writableSeg->addT(t); | 302 SkOpPtT* oppStart = writableSeg->addT(t); |
303 SkOpSpan* writableBase = const_cast<SkOpSpan*>(base); | 303 SkOpSpan* writableBase = const_cast<SkOpSpan*>(base); |
304 oppStart->span()->addOpp(writableBase); | 304 oppStart->span()->addOpp(writableBase); |
305 if (oppStart->deleted()) { | 305 if (oppStart->deleted()) { |
306 continue; | 306 continue; |
307 } | 307 } |
308 SkOpSegment* coinSeg = base->segment(); | 308 SkOpSegment* coinSeg = base->segment(); |
309 SkOpSegment* oppSeg = oppStart->segment(); | 309 SkOpSegment* oppSeg = oppStart->segment(); |
310 double coinTs, coinTe, oppTs, oppTe; | 310 double coinTs, coinTe, oppTs, oppTe; |
311 if (coinSeg < oppSeg) { | 311 if (Ordered(coinSeg, oppSeg)) { |
312 coinTs = base->t(); | 312 coinTs = base->t(); |
313 coinTe = testSpan->t(); | 313 coinTe = testSpan->t(); |
314 oppTs = oppStart->fT; | 314 oppTs = oppStart->fT; |
315 oppTe = testPtT->fT; | 315 oppTe = testPtT->fT; |
316 } else { | 316 } else { |
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(); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 // for each coincident pair, match the spans | 409 // for each coincident pair, match the spans |
410 // if the spans don't match, add the missing pt to the segment and loop it in th
e opposite span | 410 // if the spans don't match, add the missing pt to the segment and loop it in th
e opposite span |
411 bool SkOpCoincidence::addExpanded() { | 411 bool SkOpCoincidence::addExpanded() { |
412 SkCoincidentSpans* coin = this->fHead; | 412 SkCoincidentSpans* coin = this->fHead; |
413 if (!coin) { | 413 if (!coin) { |
414 return true; | 414 return true; |
415 } | 415 } |
416 do { | 416 do { |
417 const SkOpPtT* startPtT = coin->coinPtTStart(); | 417 const SkOpPtT* startPtT = coin->coinPtTStart(); |
418 const SkOpPtT* oStartPtT = coin->oppPtTStart(); | 418 const SkOpPtT* oStartPtT = coin->oppPtTStart(); |
| 419 double priorT = startPtT->fT; |
| 420 double oPriorT = oStartPtT->fT; |
419 SkASSERT(startPtT->contains(oStartPtT)); | 421 SkASSERT(startPtT->contains(oStartPtT)); |
420 SkOPASSERT(coin->coinPtTEnd()->contains(coin->oppPtTEnd())); | 422 SkOPASSERT(coin->coinPtTEnd()->contains(coin->oppPtTEnd())); |
421 const SkOpSpanBase* start = startPtT->span(); | 423 const SkOpSpanBase* start = startPtT->span(); |
422 const SkOpSpanBase* oStart = oStartPtT->span(); | 424 const SkOpSpanBase* oStart = oStartPtT->span(); |
423 const SkOpSpanBase* end = coin->coinPtTEnd()->span(); | 425 const SkOpSpanBase* end = coin->coinPtTEnd()->span(); |
424 const SkOpSpanBase* oEnd = coin->oppPtTEnd()->span(); | 426 const SkOpSpanBase* oEnd = coin->oppPtTEnd()->span(); |
425 FAIL_IF(oEnd->deleted()); | 427 FAIL_IF(oEnd->deleted()); |
426 FAIL_IF(!start->upCastable()); | 428 FAIL_IF(!start->upCastable()); |
427 const SkOpSpanBase* test = start->upCast()->next(); | 429 const SkOpSpanBase* test = start->upCast()->next(); |
428 const SkOpSpanBase* oTest = coin->flipped() ? oStart->prev() : oStart->u
pCast()->next(); | 430 const SkOpSpanBase* oTest = coin->flipped() ? oStart->prev() : oStart->u
pCast()->next(); |
429 FAIL_IF(!oTest); | 431 FAIL_IF(!oTest); |
| 432 SkOpSegment* seg = start->segment(); |
| 433 SkOpSegment* oSeg = oStart->segment(); |
430 while (test != end || oTest != oEnd) { | 434 while (test != end || oTest != oEnd) { |
431 if (!test->ptT()->contains(oStart->segment()) | 435 const SkOpPtT* containedOpp = test->ptT()->contains(oSeg); |
432 || !oTest->ptT()->contains(start->segment())) { | 436 const SkOpPtT* containedThis = oTest->ptT()->contains(seg); |
| 437 if (!containedOpp || !containedThis) { |
| 438 // choose the ends, or the first common pt-t list shared by both |
| 439 double nextT, oNextT; |
| 440 if (containedOpp) { |
| 441 nextT = test->t(); |
| 442 oNextT = containedOpp->fT; |
| 443 } else if (containedThis) { |
| 444 nextT = containedThis->fT; |
| 445 oNextT = oTest->t(); |
| 446 } else { |
| 447 // iterate through until a pt-t list found that contains the
other |
| 448 const SkOpSpanBase* walk = test; |
| 449 const SkOpPtT* walkOpp; |
| 450 do { |
| 451 FAIL_IF(!walk->upCastable()); |
| 452 walk = walk->upCast()->next(); |
| 453 } while (!(walkOpp = walk->ptT()->contains(oSeg)) |
| 454 && walk != coin->coinPtTEnd()->span()); |
| 455 nextT = walk->t(); |
| 456 oNextT = walkOpp->fT; |
| 457 } |
433 // use t ranges to guess which one is missing | 458 // use t ranges to guess which one is missing |
434 double startRange = coin->coinPtTEnd()->fT - startPtT->fT; | 459 double startRange = nextT - priorT; |
435 FAIL_IF(!startRange); | 460 FAIL_IF(!startRange); |
436 double startPart = (test->t() - startPtT->fT) / startRange; | 461 double startPart = (test->t() - priorT) / startRange; |
437 double oStartRange = coin->oppPtTEnd()->fT - oStartPtT->fT; | 462 double oStartRange = oNextT - oPriorT; |
438 FAIL_IF(!oStartRange); | 463 FAIL_IF(!oStartRange); |
439 double oStartPart = (oTest->t() - oStartPtT->fT) / oStartRange; | 464 double oStartPart = (oTest->t() - oPriorT) / oStartRange; |
440 FAIL_IF(startPart == oStartPart); | 465 FAIL_IF(startPart == oStartPart); |
| 466 bool addToOpp = !containedOpp && !containedThis ? startPart < oS
tartPart |
| 467 : !!containedThis; |
441 bool startOver = false; | 468 bool startOver = false; |
442 bool success = startPart < oStartPart | 469 bool success = addToOpp ? oSeg->addExpanded( |
443 ? oStart->segment()->addExpanded( | 470 oPriorT + oStartRange * startPart, test, &startOver) |
444 oStartPtT->fT + oStartRange * startPart, test, &
startOver) | 471 : seg->addExpanded( |
445 : start->segment()->addExpanded( | 472 priorT + startRange * oStartPart, oTest, &startOver); |
446 startPtT->fT + startRange * oStartPart, oTest, &
startOver); | |
447 FAIL_IF(!success); | 473 FAIL_IF(!success); |
448 if (startOver) { | 474 if (startOver) { |
449 test = start; | 475 test = start; |
450 oTest = oStart; | 476 oTest = oStart; |
451 } | 477 } |
452 end = coin->coinPtTEnd()->span(); | 478 end = coin->coinPtTEnd()->span(); |
453 oEnd = coin->oppPtTEnd()->span(); | 479 oEnd = coin->oppPtTEnd()->span(); |
454 } | 480 } |
455 if (test != end) { | 481 if (test != end) { |
456 FAIL_IF(!test->upCastable()); | 482 FAIL_IF(!test->upCastable()); |
| 483 priorT = test->t(); |
457 test = test->upCast()->next(); | 484 test = test->upCast()->next(); |
458 } | 485 } |
459 if (oTest != oEnd) { | 486 if (oTest != oEnd) { |
| 487 oPriorT = oTest->t(); |
460 oTest = coin->flipped() ? oTest->prev() : oTest->upCast()->next(
); | 488 oTest = coin->flipped() ? oTest->prev() : oTest->upCast()->next(
); |
461 FAIL_IF(!oTest); | 489 FAIL_IF(!oTest); |
462 } | 490 } |
| 491 |
463 } | 492 } |
464 } while ((coin = coin->next())); | 493 } while ((coin = coin->next())); |
465 return true; | 494 return true; |
466 } | 495 } |
467 | 496 |
468 // checks to see if coincidence has already been found | 497 // checks to see if coincidence has already been found |
469 bool SkOpCoincidence::alreadyAdded(const SkCoincidentSpans* check, const SkCoinc
identSpans* outer, | 498 bool SkOpCoincidence::alreadyAdded(const SkCoincidentSpans* check, const SkCoinc
identSpans* outer, |
470 const SkOpPtT* over1s, const SkOpPtT* over1e) const { | 499 const SkOpPtT* over1s, const SkOpPtT* over1e) const { |
471 do { | 500 do { |
472 if (check->oppPtTStart() == outer->coinPtTStart() && check->coinPtTStart
() == over1s | 501 if (check->oppPtTStart() == outer->coinPtTStart() && check->coinPtTStart
() == over1s |
(...skipping 27 matching lines...) Expand all Loading... |
500 } | 529 } |
501 if (fHead && this->alreadyAdded(fHead, outer, over1s, over1e)) { | 530 if (fHead && this->alreadyAdded(fHead, outer, over1s, over1e)) { |
502 return false; | 531 return false; |
503 } | 532 } |
504 this->add(outer->coinPtTStart(), outer->coinPtTEnd(), over1s, over1e); | 533 this->add(outer->coinPtTStart(), outer->coinPtTEnd(), over1s, over1e); |
505 this->debugValidate(); | 534 this->debugValidate(); |
506 return true; | 535 return true; |
507 } | 536 } |
508 | 537 |
509 // given a t span, map the same range on the coincident span | 538 // given a t span, map the same range on the coincident span |
510 void SkOpCoincidence::TRange(const SkOpPtT* overS, const SkOpPtT* overE, double
tStart, | 539 /* |
511 double tEnd, const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, dou
ble* coinTs, | 540 the curves may not scale linearly, so interpolation may only happen within known
points |
512 double* coinTe) { | 541 remap over1s, over1e, cointPtTStart, coinPtTEnd to smallest range that captures
over1s |
513 double denom = overE->fT - overS->fT; | 542 then repeat to capture over1e |
514 double start = 0 < denom ? tStart : tEnd; | 543 */ |
515 double end = 0 < denom ? tEnd : tStart; | 544 double SkOpCoincidence::TRange(const SkOpPtT* overS, double t, |
516 double sRatio = (start - overS->fT) / denom; | 545 const SkOpSegment* coinSeg SkDEBUGPARAMS(const SkOpPtT* overE)) { |
517 double eRatio = (end - overS->fT) / denom; | 546 const SkOpSpanBase* work = overS->span(); |
518 *coinTs = coinPtTStart->fT + (coinPtTEnd->fT - coinPtTStart->fT) * sRatio; | 547 const SkOpPtT* foundStart = nullptr; |
519 *coinTe = coinPtTStart->fT + (coinPtTEnd->fT - coinPtTStart->fT) * eRatio; | 548 const SkOpPtT* foundEnd = nullptr; |
| 549 const SkOpPtT* coinStart = nullptr; |
| 550 const SkOpPtT* coinEnd = nullptr; |
| 551 do { |
| 552 const SkOpPtT* contained = work->contains(coinSeg); |
| 553 if (!contained) { |
| 554 continue; |
| 555 } |
| 556 if (work->t() <= t) { |
| 557 coinStart = contained; |
| 558 foundStart = work->ptT(); |
| 559 } |
| 560 if (work->t() >= t) { |
| 561 coinEnd = contained; |
| 562 foundEnd = work->ptT(); |
| 563 break; |
| 564 } |
| 565 SkASSERT(work->ptT() != overE); |
| 566 } while ((work = work->upCast()->next())); |
| 567 SkASSERT(coinStart); |
| 568 SkASSERT(coinEnd); |
| 569 // while overS->fT <=t and overS contains coinSeg |
| 570 double denom = foundEnd->fT - foundStart->fT; |
| 571 double sRatio = denom ? (t - foundStart->fT) / denom : 1; |
| 572 return coinStart->fT + (coinEnd->fT - coinStart->fT) * sRatio; |
520 } | 573 } |
521 | 574 |
522 // return true if span overlaps existing and needs to adjust the coincident list | 575 // return true if span overlaps existing and needs to adjust the coincident list |
523 bool SkOpCoincidence::checkOverlap(SkCoincidentSpans* check, | 576 bool SkOpCoincidence::checkOverlap(SkCoincidentSpans* check, |
524 const SkOpSegment* coinSeg, const SkOpSegment* oppSeg, | 577 const SkOpSegment* coinSeg, const SkOpSegment* oppSeg, |
525 double coinTs, double coinTe, double oppTs, double oppTe, | 578 double coinTs, double coinTe, double oppTs, double oppTe, |
526 SkTDArray<SkCoincidentSpans*>* overlaps) const { | 579 SkTDArray<SkCoincidentSpans*>* overlaps) const { |
527 if (!Ordered(coinSeg, oppSeg)) { | 580 if (!Ordered(coinSeg, oppSeg)) { |
528 if (oppTs < oppTe) { | 581 if (oppTs < oppTe) { |
529 return this->checkOverlap(check, oppSeg, coinSeg, oppTs, oppTe, coin
Ts, coinTe, | 582 return this->checkOverlap(check, oppSeg, coinSeg, oppTs, oppTe, coin
Ts, coinTe, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
561 bool oppInside = oppTe <= oCheckTe && oppTs >= oCheckTs; | 614 bool oppInside = oppTe <= oCheckTe && oppTs >= oCheckTs; |
562 if (coinInside && oppInside) { | 615 if (coinInside && oppInside) { |
563 return false; // complete overlap, already included, do nothing | 616 return false; // complete overlap, already included, do nothing |
564 } | 617 } |
565 *overlaps->append() = check; // partial overlap, extend existing entry | 618 *overlaps->append() = check; // partial overlap, extend existing entry |
566 } while ((check = check->next())); | 619 } while ((check = check->next())); |
567 return true; | 620 return true; |
568 } | 621 } |
569 | 622 |
570 /* Please keep this in sync with debugAddIfMissing() */ | 623 /* Please keep this in sync with debugAddIfMissing() */ |
571 bool SkOpCoincidence::addIfMissing(const SkOpPtT* over1s, const SkOpPtT* over1e, | 624 // note that over1s, over1e, over2s, over2e are ordered |
572 const SkOpPtT* over2s, const SkOpPtT* over2e, double tStart, double tEnd
, | 625 bool SkOpCoincidence::addIfMissing(const SkOpPtT* over1s, const SkOpPtT* over2s, |
573 SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, | 626 double tStart, double tEnd, SkOpSegment* coinSeg, SkOpSegment* oppSeg |
574 SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd) { | 627 SkDEBUGPARAMS(const SkOpPtT* over1e) SkDEBUGPARAMS(const SkOpPtT* over2e
)) { |
575 SkOpSegment* coinSeg = coinPtTStart->segment(); | 628 SkASSERT(tStart < tEnd); |
576 SkOpSegment* oppSeg = oppPtTStart->segment(); | 629 SkASSERT(over1s->fT < over1e->fT); |
577 if (coinSeg == oppSeg) { | 630 SkASSERT(between(over1s->fT, tStart, over1e->fT)); |
578 return false; | 631 SkASSERT(between(over1s->fT, tEnd, over1e->fT)); |
579 } | 632 SkASSERT(over2s->fT < over2e->fT); |
| 633 SkASSERT(between(over2s->fT, tStart, over2e->fT)); |
| 634 SkASSERT(between(over2s->fT, tEnd, over2e->fT)); |
| 635 SkASSERT(over1s->segment() == over1e->segment()); |
| 636 SkASSERT(over2s->segment() == over2e->segment()); |
| 637 SkASSERT(over1s->segment() == over2s->segment()); |
| 638 SkASSERT(over1s->segment() != coinSeg); |
| 639 SkASSERT(over1s->segment() != oppSeg); |
| 640 SkASSERT(coinSeg != oppSeg); |
580 double coinTs, coinTe, oppTs, oppTe; | 641 double coinTs, coinTe, oppTs, oppTe; |
581 TRange(over1s, over1e, tStart, tEnd, coinPtTStart, coinPtTEnd, &coinTs, &coi
nTe); | 642 coinTs = TRange(over1s, tStart, coinSeg SkDEBUGPARAMS(over1e)); |
| 643 coinTe = TRange(over1s, tEnd, coinSeg SkDEBUGPARAMS(over1e)); |
582 if (coinSeg->collapsed(coinTs, coinTe)) { | 644 if (coinSeg->collapsed(coinTs, coinTe)) { |
583 return false; | 645 return false; |
584 } | 646 } |
585 TRange(over2s, over2e, tStart, tEnd, oppPtTStart, oppPtTEnd, &oppTs, &oppTe)
; | 647 oppTs = TRange(over2s, tStart, oppSeg SkDEBUGPARAMS(over2e)); |
| 648 oppTe = TRange(over2s, tEnd, oppSeg SkDEBUGPARAMS(over2e)); |
586 if (oppSeg->collapsed(oppTs, oppTe)) { | 649 if (oppSeg->collapsed(oppTs, oppTe)) { |
587 return false; | 650 return false; |
588 } | 651 } |
589 bool swap = coinTs > coinTe; | 652 if (coinTs > coinTe) { |
590 if (swap) { | |
591 SkTSwap(coinTs, coinTe); | 653 SkTSwap(coinTs, coinTe); |
592 } | |
593 if ((over1s->fT < over1e->fT) != (over2s->fT < over2e->fT)) { | |
594 SkTSwap(oppTs, oppTe); | |
595 } | |
596 if (swap) { | |
597 SkTSwap(oppTs, oppTe); | 654 SkTSwap(oppTs, oppTe); |
598 } | 655 } |
599 return this->addOrOverlap(coinSeg, oppSeg, coinTs, coinTe, oppTs, oppTe | 656 return this->addOrOverlap(coinSeg, oppSeg, coinTs, coinTe, oppTs, oppTe |
600 SkDEBUGPARAMS(false) /* don't assert if addOrOverlap fails */ ); | 657 SkDEBUGPARAMS(false) /* don't assert if addOrOverlap fails */ ); |
601 } | 658 } |
602 | 659 |
603 /* Please keep this in sync with debugAddOrOverlap() */ | 660 /* Please keep this in sync with debugAddOrOverlap() */ |
604 // If this is called by addEndMovedSpans(), a returned false propogates out to a
n abort. | 661 // If this is called by addEndMovedSpans(), a returned false propogates out to a
n abort. |
605 // If this is called by AddIfMissing(), a returned false indicates there was not
hing to add | 662 // If this is called by AddIfMissing(), a returned false indicates there was not
hing to add |
606 bool SkOpCoincidence::addOrOverlap(SkOpSegment* coinSeg, SkOpSegment* oppSeg, | 663 bool SkOpCoincidence::addOrOverlap(SkOpSegment* coinSeg, SkOpSegment* oppSeg, |
607 double coinTs, double coinTe, double oppTs, double oppTe | 664 double coinTs, double coinTe, double oppTs, double oppTe |
608 SkDEBUGPARAMS(bool callerAborts)) { | 665 SkDEBUGPARAMS(bool callerAborts)) { |
609 SkTDArray<SkCoincidentSpans*> overlaps; | 666 SkTDArray<SkCoincidentSpans*> overlaps; |
610 RETURN_FALSE_IF(callerAborts, !fTop); | 667 RETURN_FALSE_IF(callerAborts, !fTop); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 if (!outer) { | 783 if (!outer) { |
727 return false; | 784 return false; |
728 } | 785 } |
729 bool added = false; | 786 bool added = false; |
730 fTop = outer; | 787 fTop = outer; |
731 fHead = nullptr; | 788 fHead = nullptr; |
732 do { | 789 do { |
733 // addifmissing can modify the list that this is walking | 790 // addifmissing can modify the list that this is walking |
734 // save head so that walker can iterate over old data unperturbed | 791 // save head so that walker can iterate over old data unperturbed |
735 // addifmissing adds to head freely then add saved head in the end | 792 // addifmissing adds to head freely then add saved head in the end |
736 const SkOpSegment* outerCoin = outer->coinPtTStart()->segment(); | 793 const SkOpPtT* ocs = outer->coinPtTStart(); |
737 const SkOpSegment* outerOpp = outer->oppPtTStart()->segment(); | 794 SkASSERT(!ocs->deleted()); |
738 if (outerCoin->done() || outerOpp->done()) { | 795 const SkOpSegment* outerCoin = ocs->segment(); |
739 continue; | 796 SkASSERT(!outerCoin->done()); // if it's done, should have already been
removed from list |
740 } | 797 const SkOpPtT* oos = outer->oppPtTStart(); |
| 798 SkASSERT(!oos->deleted()); |
| 799 const SkOpSegment* outerOpp = oos->segment(); |
| 800 SkASSERT(!outerOpp->done()); |
| 801 SkOpSegment* outerCoinWritable = const_cast<SkOpSegment*>(outerCoin); |
| 802 SkOpSegment* outerOppWritable = const_cast<SkOpSegment*>(outerOpp); |
741 SkCoincidentSpans* inner = outer; | 803 SkCoincidentSpans* inner = outer; |
742 while ((inner = inner->next())) { | 804 while ((inner = inner->next())) { |
743 this->debugValidate(); | 805 this->debugValidate(); |
744 double overS, overE; | 806 double overS, overE; |
745 const SkOpSegment* innerCoin = inner->coinPtTStart()->segment(); | 807 const SkOpPtT* ics = inner->coinPtTStart(); |
746 const SkOpSegment* innerOpp = inner->oppPtTStart()->segment(); | 808 SkASSERT(!ics->deleted()); |
747 if (innerCoin->done() || innerOpp->done()) { | 809 const SkOpSegment* innerCoin = ics->segment(); |
748 continue; | 810 SkASSERT(!innerCoin->done()); |
749 } | 811 const SkOpPtT* ios = inner->oppPtTStart(); |
| 812 SkASSERT(!ios->deleted()); |
| 813 const SkOpSegment* innerOpp = ios->segment(); |
| 814 SkASSERT(!innerOpp->done()); |
| 815 SkOpSegment* innerCoinWritable = const_cast<SkOpSegment*>(innerCoin)
; |
| 816 SkOpSegment* innerOppWritable = const_cast<SkOpSegment*>(innerOpp); |
750 if (outerCoin == innerCoin) { | 817 if (outerCoin == innerCoin) { |
751 if (outerOpp != innerOpp | 818 const SkOpPtT* oce = outer->coinPtTEnd(); |
752 && this->overlap(outer->coinPtTStart(), outer->coinPtTEn
d(), | 819 SkASSERT(!oce->deleted()); |
753 inner->coinPtTStart(), inner->coinPtTEnd(), &overS, &ove
rE)) { | 820 const SkOpPtT* ice = inner->coinPtTEnd(); |
754 added |= this->addIfMissing(outer->coinPtTStart(), outer->co
inPtTEnd(), | 821 SkASSERT(!ice->deleted()); |
755 inner->coinPtTStart(), inner->coinPtTEnd(), overS, o
verE, | 822 if (outerOpp != innerOpp && this->overlap(ocs, oce, ics, ice, &o
verS, &overE)) { |
756 outer->oppPtTStart(), outer->oppPtTEnd(), | 823 added |= this->addIfMissing(ocs->starter(oce), ics->starter(
ice), |
757 inner->oppPtTStart(), inner->oppPtTEnd()); | 824 overS, overE, outerOppWritable, innerOppWritable |
| 825 SkDEBUGPARAMS(ocs->debugEnder(oce)) |
| 826 SkDEBUGPARAMS(ics->debugEnder(ice))); |
758 } | 827 } |
759 } else if (outerCoin == innerOpp) { | 828 } else if (outerCoin == innerOpp) { |
760 if (outerOpp != innerCoin | 829 const SkOpPtT* oce = outer->coinPtTEnd(); |
761 && this->overlap(outer->coinPtTStart(), outer->coinPtTEn
d(), | 830 SkASSERT(!oce->deleted()); |
762 inner->oppPtTStart(), inner->oppPtTEnd(), &overS, &overE
)) { | 831 const SkOpPtT* ioe = inner->oppPtTEnd(); |
763 added |= this->addIfMissing(outer->coinPtTStart(), outer->co
inPtTEnd(), | 832 SkASSERT(!ioe->deleted()); |
764 inner->oppPtTStart(), inner->oppPtTEnd(), overS, ove
rE, | 833 if (outerOpp != innerCoin && this->overlap(ocs, oce, ios, ioe, &
overS, &overE)) { |
765 outer->oppPtTStart(), outer->oppPtTEnd(), | 834 added |= this->addIfMissing(ocs->starter(oce), ios->starter(
ioe), |
766 inner->coinPtTStart(), inner->coinPtTEnd()); | 835 overS, overE, outerOppWritable, innerCoinWritable |
| 836 SkDEBUGPARAMS(ocs->debugEnder(oce)) |
| 837 SkDEBUGPARAMS(ios->debugEnder(ioe))); |
767 } | 838 } |
768 } else if (outerOpp == innerCoin) { | 839 } else if (outerOpp == innerCoin) { |
| 840 const SkOpPtT* ooe = outer->oppPtTEnd(); |
| 841 SkASSERT(!ooe->deleted()); |
| 842 const SkOpPtT* ice = inner->coinPtTEnd(); |
| 843 SkASSERT(!ice->deleted()); |
769 SkASSERT(outerCoin != innerOpp); | 844 SkASSERT(outerCoin != innerOpp); |
770 if (this->overlap(outer->oppPtTStart(), outer->oppPtTEnd(), | 845 if (this->overlap(oos, ooe, ics, ice, &overS, &overE)) { |
771 inner->coinPtTStart(), inner->coinPtTEnd(), &overS, &ove
rE)) { | 846 added |= this->addIfMissing(oos->starter(ooe), ics->starter(
ice), |
772 added |= this->addIfMissing(outer->oppPtTStart(), outer->opp
PtTEnd(), | 847 overS, overE, outerCoinWritable, innerOppWritable |
773 inner->coinPtTStart(), inner->coinPtTEnd(), overS, o
verE, | 848 SkDEBUGPARAMS(oos->debugEnder(ooe)) |
774 outer->coinPtTStart(), outer->coinPtTEnd(), | 849 SkDEBUGPARAMS(ics->debugEnder(ice))); |
775 inner->oppPtTStart(), inner->oppPtTEnd()); | |
776 } | 850 } |
777 } else if (outerOpp == innerOpp) { | 851 } else if (outerOpp == innerOpp) { |
| 852 const SkOpPtT* ooe = outer->oppPtTEnd(); |
| 853 SkASSERT(!ooe->deleted()); |
| 854 const SkOpPtT* ioe = inner->oppPtTEnd(); |
| 855 SkASSERT(!ioe->deleted()); |
778 SkASSERT(outerCoin != innerCoin); | 856 SkASSERT(outerCoin != innerCoin); |
779 if (this->overlap(outer->oppPtTStart(), outer->oppPtTEnd(), | 857 if (this->overlap(oos, ooe, ios, ioe, &overS, &overE)) { |
780 inner->oppPtTStart(), inner->oppPtTEnd(), &overS, &overE
)) { | 858 added |= this->addIfMissing(oos->starter(ooe), ios->starter(
ioe), |
781 added |= this->addIfMissing(outer->oppPtTStart(), outer->opp
PtTEnd(), | 859 overS, overE, outerCoinWritable, innerCoinWritable |
782 inner->oppPtTStart(), inner->oppPtTEnd(), overS, ove
rE, | 860 SkDEBUGPARAMS(oos->debugEnder(ooe)) |
783 outer->coinPtTStart(), outer->coinPtTEnd(), | 861 SkDEBUGPARAMS(ios->debugEnder(ioe))); |
784 inner->coinPtTStart(), inner->coinPtTEnd()); | |
785 } | 862 } |
786 } | 863 } |
787 this->debugValidate(); | 864 this->debugValidate(); |
788 } | 865 } |
789 } while ((outer = outer->next())); | 866 } while ((outer = outer->next())); |
790 this->restoreHead(); | 867 this->restoreHead(); |
791 return added; | 868 return added; |
792 } | 869 } |
793 | 870 |
794 bool SkOpCoincidence::addOverlap(const SkOpSegment* seg1, const SkOpSegment* seg
1o, | 871 bool SkOpCoincidence::addOverlap(const SkOpSegment* seg1, const SkOpSegment* seg
1o, |
(...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1479 this->release(fHead, coin); | 1556 this->release(fHead, coin); |
1480 } | 1557 } |
1481 } while ((coin = coin->next())); | 1558 } while ((coin = coin->next())); |
1482 } | 1559 } |
1483 | 1560 |
1484 bool SkOpCoincidence::testForCoincidence(const SkCoincidentSpans* outer, const S
kOpPtT* testS, | 1561 bool SkOpCoincidence::testForCoincidence(const SkCoincidentSpans* outer, const S
kOpPtT* testS, |
1485 const SkOpPtT* testE) const { | 1562 const SkOpPtT* testE) const { |
1486 return testS->segment()->testForCoincidence(testS, testE, testS->span(), | 1563 return testS->segment()->testForCoincidence(testS, testE, testS->span(), |
1487 testE->span(), outer->coinPtTStart()->segment()); | 1564 testE->span(), outer->coinPtTStart()->segment()); |
1488 } | 1565 } |
OLD | NEW |