OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 "SkOpContour.h" | 8 #include "SkOpContour.h" |
9 #include "SkOpSegment.h" | 9 #include "SkOpSegment.h" |
10 #include "SkPathWriter.h" | 10 #include "SkPathWriter.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 #undef T | 43 #undef T |
44 | 44 |
45 SkOpAngle* SkOpSegment::activeAngle(SkOpSpanBase* start, SkOpSpanBase** startPtr
, | 45 SkOpAngle* SkOpSegment::activeAngle(SkOpSpanBase* start, SkOpSpanBase** startPtr
, |
46 SkOpSpanBase** endPtr, bool* done) { | 46 SkOpSpanBase** endPtr, bool* done) { |
47 if (SkOpAngle* result = activeAngleInner(start, startPtr, endPtr, done)) { | 47 if (SkOpAngle* result = activeAngleInner(start, startPtr, endPtr, done)) { |
48 return result; | 48 return result; |
49 } | 49 } |
50 if (SkOpAngle* result = activeAngleOther(start, startPtr, endPtr, done)) { | 50 if (SkOpAngle* result = activeAngleOther(start, startPtr, endPtr, done)) { |
51 return result; | 51 return result; |
52 } | 52 } |
53 return NULL; | 53 return nullptr; |
54 } | 54 } |
55 | 55 |
56 SkOpAngle* SkOpSegment::activeAngleInner(SkOpSpanBase* start, SkOpSpanBase** sta
rtPtr, | 56 SkOpAngle* SkOpSegment::activeAngleInner(SkOpSpanBase* start, SkOpSpanBase** sta
rtPtr, |
57 SkOpSpanBase** endPtr, bool* done) { | 57 SkOpSpanBase** endPtr, bool* done) { |
58 SkOpSpan* upSpan = start->upCastable(); | 58 SkOpSpan* upSpan = start->upCastable(); |
59 if (upSpan) { | 59 if (upSpan) { |
60 if (upSpan->windValue() || upSpan->oppValue()) { | 60 if (upSpan->windValue() || upSpan->oppValue()) { |
61 SkOpSpanBase* next = upSpan->next(); | 61 SkOpSpanBase* next = upSpan->next(); |
62 if (!*endPtr) { | 62 if (!*endPtr) { |
63 *startPtr = start; | 63 *startPtr = start; |
(...skipping 20 matching lines...) Expand all Loading... |
84 if (!downSpan->done()) { | 84 if (!downSpan->done()) { |
85 if (downSpan->windSum() != SK_MinS32) { | 85 if (downSpan->windSum() != SK_MinS32) { |
86 return spanToAngle(start, downSpan); | 86 return spanToAngle(start, downSpan); |
87 } | 87 } |
88 *done = false; | 88 *done = false; |
89 } | 89 } |
90 } else { | 90 } else { |
91 SkASSERT(downSpan->done()); | 91 SkASSERT(downSpan->done()); |
92 } | 92 } |
93 } | 93 } |
94 return NULL; | 94 return nullptr; |
95 } | 95 } |
96 | 96 |
97 SkOpAngle* SkOpSegment::activeAngleOther(SkOpSpanBase* start, SkOpSpanBase** sta
rtPtr, | 97 SkOpAngle* SkOpSegment::activeAngleOther(SkOpSpanBase* start, SkOpSpanBase** sta
rtPtr, |
98 SkOpSpanBase** endPtr, bool* done) { | 98 SkOpSpanBase** endPtr, bool* done) { |
99 SkOpPtT* oPtT = start->ptT()->next(); | 99 SkOpPtT* oPtT = start->ptT()->next(); |
100 SkOpSegment* other = oPtT->segment(); | 100 SkOpSegment* other = oPtT->segment(); |
101 SkOpSpanBase* oSpan = oPtT->span(); | 101 SkOpSpanBase* oSpan = oPtT->span(); |
102 return other->activeAngleInner(oSpan, startPtr, endPtr, done); | 102 return other->activeAngleInner(oSpan, startPtr, endPtr, done); |
103 } | 103 } |
104 | 104 |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 path->cubicTo(ePtr[1], ePtr[2], ePtr[3]); | 290 path->cubicTo(ePtr[1], ePtr[2], ePtr[3]); |
291 break; | 291 break; |
292 default: | 292 default: |
293 SkASSERT(0); | 293 SkASSERT(0); |
294 } | 294 } |
295 } | 295 } |
296 } | 296 } |
297 } | 297 } |
298 | 298 |
299 SkOpPtT* SkOpSegment::addMissing(double t, SkOpSegment* opp, SkChunkAlloc* alloc
ator) { | 299 SkOpPtT* SkOpSegment::addMissing(double t, SkOpSegment* opp, SkChunkAlloc* alloc
ator) { |
300 SkOpSpanBase* existing = NULL; | 300 SkOpSpanBase* existing = nullptr; |
301 SkOpSpanBase* test = &fHead; | 301 SkOpSpanBase* test = &fHead; |
302 double testT; | 302 double testT; |
303 do { | 303 do { |
304 if ((testT = test->ptT()->fT) >= t) { | 304 if ((testT = test->ptT()->fT) >= t) { |
305 if (testT == t) { | 305 if (testT == t) { |
306 existing = test; | 306 existing = test; |
307 } | 307 } |
308 break; | 308 break; |
309 } | 309 } |
310 } while ((test = test->upCast()->next())); | 310 } while ((test = test->upCast()->next())); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 #if DEBUG_ADD_T | 366 #if DEBUG_ADD_T |
367 SkDebugf("%s insert t=%1.9g segID=%d spanID=%d\n", __FUNCTION__, t, | 367 SkDebugf("%s insert t=%1.9g segID=%d spanID=%d\n", __FUNCTION__, t, |
368 span->segment()->debugID(), span->debugID()); | 368 span->segment()->debugID(), span->debugID()); |
369 #endif | 369 #endif |
370 span->bumpSpanAdds(); | 370 span->bumpSpanAdds(); |
371 return span->ptT(); | 371 return span->ptT(); |
372 } | 372 } |
373 SkASSERT(span != &fTail); | 373 SkASSERT(span != &fTail); |
374 } while ((span = span->upCast()->next())); | 374 } while ((span = span->upCast()->next())); |
375 SkASSERT(0); | 375 SkASSERT(0); |
376 return NULL; | 376 return nullptr; |
377 } | 377 } |
378 | 378 |
379 // choose a solitary t and pt value; remove aliases; align the opposite ends | 379 // choose a solitary t and pt value; remove aliases; align the opposite ends |
380 void SkOpSegment::align() { | 380 void SkOpSegment::align() { |
381 debugValidate(); | 381 debugValidate(); |
382 SkOpSpanBase* span = &fHead; | 382 SkOpSpanBase* span = &fHead; |
383 if (!span->aligned()) { | 383 if (!span->aligned()) { |
384 span->alignEnd(0, fPts[0]); | 384 span->alignEnd(0, fPts[0]); |
385 } | 385 } |
386 while ((span = span->upCast()->next())) { | 386 while ((span = span->upCast()->next())) { |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 last = nextSegment->markAngle(maxWinding, sumWinding, nextAngle); | 512 last = nextSegment->markAngle(maxWinding, sumWinding, nextAngle); |
513 } | 513 } |
514 nextAngle->setLastMarked(last); | 514 nextAngle->setLastMarked(last); |
515 } | 515 } |
516 | 516 |
517 // at this point, the span is already ordered, or unorderable | 517 // at this point, the span is already ordered, or unorderable |
518 int SkOpSegment::computeSum(SkOpSpanBase* start, SkOpSpanBase* end, | 518 int SkOpSegment::computeSum(SkOpSpanBase* start, SkOpSpanBase* end, |
519 SkOpAngle::IncludeType includeType) { | 519 SkOpAngle::IncludeType includeType) { |
520 SkASSERT(includeType != SkOpAngle::kUnaryXor); | 520 SkASSERT(includeType != SkOpAngle::kUnaryXor); |
521 SkOpAngle* firstAngle = this->spanToAngle(end, start); | 521 SkOpAngle* firstAngle = this->spanToAngle(end, start); |
522 if (NULL == firstAngle || NULL == firstAngle->next()) { | 522 if (nullptr == firstAngle || nullptr == firstAngle->next()) { |
523 return SK_NaN32; | 523 return SK_NaN32; |
524 } | 524 } |
525 // if all angles have a computed winding, | 525 // if all angles have a computed winding, |
526 // or if no adjacent angles are orderable, | 526 // or if no adjacent angles are orderable, |
527 // or if adjacent orderable angles have no computed winding, | 527 // or if adjacent orderable angles have no computed winding, |
528 // there's nothing to do | 528 // there's nothing to do |
529 // if two orderable angles are adjacent, and both are next to orderable angl
es, | 529 // if two orderable angles are adjacent, and both are next to orderable angl
es, |
530 // and one has winding computed, transfer to the other | 530 // and one has winding computed, transfer to the other |
531 SkOpAngle* baseAngle = NULL; | 531 SkOpAngle* baseAngle = nullptr; |
532 bool tryReverse = false; | 532 bool tryReverse = false; |
533 // look for counterclockwise transfers | 533 // look for counterclockwise transfers |
534 SkOpAngle* angle = firstAngle->previous(); | 534 SkOpAngle* angle = firstAngle->previous(); |
535 SkOpAngle* next = angle->next(); | 535 SkOpAngle* next = angle->next(); |
536 firstAngle = next; | 536 firstAngle = next; |
537 do { | 537 do { |
538 SkOpAngle* prior = angle; | 538 SkOpAngle* prior = angle; |
539 angle = next; | 539 angle = next; |
540 next = angle->next(); | 540 next = angle->next(); |
541 SkASSERT(prior->next() == angle); | 541 SkASSERT(prior->next() == angle); |
542 SkASSERT(angle->next() == next); | 542 SkASSERT(angle->next() == next); |
543 if (prior->unorderable() || angle->unorderable() || next->unorderable())
{ | 543 if (prior->unorderable() || angle->unorderable() || next->unorderable())
{ |
544 baseAngle = NULL; | 544 baseAngle = nullptr; |
545 continue; | 545 continue; |
546 } | 546 } |
547 int testWinding = angle->starter()->windSum(); | 547 int testWinding = angle->starter()->windSum(); |
548 if (SK_MinS32 != testWinding) { | 548 if (SK_MinS32 != testWinding) { |
549 baseAngle = angle; | 549 baseAngle = angle; |
550 tryReverse = true; | 550 tryReverse = true; |
551 continue; | 551 continue; |
552 } | 552 } |
553 if (baseAngle) { | 553 if (baseAngle) { |
554 ComputeOneSum(baseAngle, angle, includeType); | 554 ComputeOneSum(baseAngle, angle, includeType); |
555 baseAngle = SK_MinS32 != angle->starter()->windSum() ? angle : NULL; | 555 baseAngle = SK_MinS32 != angle->starter()->windSum() ? angle : nullp
tr; |
556 } | 556 } |
557 } while (next != firstAngle); | 557 } while (next != firstAngle); |
558 if (baseAngle && SK_MinS32 == firstAngle->starter()->windSum()) { | 558 if (baseAngle && SK_MinS32 == firstAngle->starter()->windSum()) { |
559 firstAngle = baseAngle; | 559 firstAngle = baseAngle; |
560 tryReverse = true; | 560 tryReverse = true; |
561 } | 561 } |
562 if (tryReverse) { | 562 if (tryReverse) { |
563 baseAngle = NULL; | 563 baseAngle = nullptr; |
564 SkOpAngle* prior = firstAngle; | 564 SkOpAngle* prior = firstAngle; |
565 do { | 565 do { |
566 angle = prior; | 566 angle = prior; |
567 prior = angle->previous(); | 567 prior = angle->previous(); |
568 SkASSERT(prior->next() == angle); | 568 SkASSERT(prior->next() == angle); |
569 next = angle->next(); | 569 next = angle->next(); |
570 if (prior->unorderable() || angle->unorderable() || next->unorderabl
e()) { | 570 if (prior->unorderable() || angle->unorderable() || next->unorderabl
e()) { |
571 baseAngle = NULL; | 571 baseAngle = nullptr; |
572 continue; | 572 continue; |
573 } | 573 } |
574 int testWinding = angle->starter()->windSum(); | 574 int testWinding = angle->starter()->windSum(); |
575 if (SK_MinS32 != testWinding) { | 575 if (SK_MinS32 != testWinding) { |
576 baseAngle = angle; | 576 baseAngle = angle; |
577 continue; | 577 continue; |
578 } | 578 } |
579 if (baseAngle) { | 579 if (baseAngle) { |
580 ComputeOneSumReverse(baseAngle, angle, includeType); | 580 ComputeOneSumReverse(baseAngle, angle, includeType); |
581 baseAngle = SK_MinS32 != angle->starter()->windSum() ? angle : N
ULL; | 581 baseAngle = SK_MinS32 != angle->starter()->windSum() ? angle : n
ullptr; |
582 } | 582 } |
583 } while (prior != firstAngle); | 583 } while (prior != firstAngle); |
584 } | 584 } |
585 return start->starter(end)->windSum(); | 585 return start->starter(end)->windSum(); |
586 } | 586 } |
587 | 587 |
588 void SkOpSegment::detach(const SkOpSpan* span) { | 588 void SkOpSegment::detach(const SkOpSpan* span) { |
589 if (span->done()) { | 589 if (span->done()) { |
590 --fDoneCount; | 590 --fDoneCount; |
591 } | 591 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
639 int step = start->step(end); | 639 int step = start->step(end); |
640 SkOpSegment* other = this->isSimple(nextStart, &step); // advances nextStar
t | 640 SkOpSegment* other = this->isSimple(nextStart, &step); // advances nextStar
t |
641 if (other) { | 641 if (other) { |
642 // mark the smaller of startIndex, endIndex done, and all adjacent | 642 // mark the smaller of startIndex, endIndex done, and all adjacent |
643 // spans with the same T value (but not 'other' spans) | 643 // spans with the same T value (but not 'other' spans) |
644 #if DEBUG_WINDING | 644 #if DEBUG_WINDING |
645 SkDebugf("%s simple\n", __FUNCTION__); | 645 SkDebugf("%s simple\n", __FUNCTION__); |
646 #endif | 646 #endif |
647 SkOpSpan* startSpan = start->starter(end); | 647 SkOpSpan* startSpan = start->starter(end); |
648 if (startSpan->done()) { | 648 if (startSpan->done()) { |
649 return NULL; | 649 return nullptr; |
650 } | 650 } |
651 markDone(startSpan); | 651 markDone(startSpan); |
652 *nextEnd = step > 0 ? (*nextStart)->upCast()->next() : (*nextStart)->pre
v(); | 652 *nextEnd = step > 0 ? (*nextStart)->upCast()->next() : (*nextStart)->pre
v(); |
653 return other; | 653 return other; |
654 } | 654 } |
655 SkOpSpanBase* endNear = step > 0 ? (*nextStart)->upCast()->next() : (*nextSt
art)->prev(); | 655 SkOpSpanBase* endNear = step > 0 ? (*nextStart)->upCast()->next() : (*nextSt
art)->prev(); |
656 SkASSERT(endNear == end); // is this ever not end? | 656 SkASSERT(endNear == end); // is this ever not end? |
657 SkASSERT(endNear); | 657 SkASSERT(endNear); |
658 SkASSERT(start != endNear); | 658 SkASSERT(start != endNear); |
659 SkASSERT((start->t() < endNear->t()) ^ (step < 0)); | 659 SkASSERT((start->t() < endNear->t()) ^ (step < 0)); |
660 // more than one viable candidate -- measure angles to find best | 660 // more than one viable candidate -- measure angles to find best |
661 int calcWinding = computeSum(start, endNear, SkOpAngle::kBinaryOpp); | 661 int calcWinding = computeSum(start, endNear, SkOpAngle::kBinaryOpp); |
662 bool sortable = calcWinding != SK_NaN32; | 662 bool sortable = calcWinding != SK_NaN32; |
663 if (!sortable) { | 663 if (!sortable) { |
664 *unsortable = true; | 664 *unsortable = true; |
665 markDone(start->starter(end)); | 665 markDone(start->starter(end)); |
666 return NULL; | 666 return nullptr; |
667 } | 667 } |
668 SkOpAngle* angle = this->spanToAngle(end, start); | 668 SkOpAngle* angle = this->spanToAngle(end, start); |
669 if (angle->unorderable()) { | 669 if (angle->unorderable()) { |
670 *unsortable = true; | 670 *unsortable = true; |
671 markDone(start->starter(end)); | 671 markDone(start->starter(end)); |
672 return NULL; | 672 return nullptr; |
673 } | 673 } |
674 #if DEBUG_SORT | 674 #if DEBUG_SORT |
675 SkDebugf("%s\n", __FUNCTION__); | 675 SkDebugf("%s\n", __FUNCTION__); |
676 angle->debugLoop(); | 676 angle->debugLoop(); |
677 #endif | 677 #endif |
678 int sumMiWinding = updateWinding(end, start); | 678 int sumMiWinding = updateWinding(end, start); |
679 if (sumMiWinding == SK_MinS32) { | 679 if (sumMiWinding == SK_MinS32) { |
680 *unsortable = true; | 680 *unsortable = true; |
681 markDone(start->starter(end)); | 681 markDone(start->starter(end)); |
682 return NULL; | 682 return nullptr; |
683 } | 683 } |
684 int sumSuWinding = updateOppWinding(end, start); | 684 int sumSuWinding = updateOppWinding(end, start); |
685 if (operand()) { | 685 if (operand()) { |
686 SkTSwap<int>(sumMiWinding, sumSuWinding); | 686 SkTSwap<int>(sumMiWinding, sumSuWinding); |
687 } | 687 } |
688 SkOpAngle* nextAngle = angle->next(); | 688 SkOpAngle* nextAngle = angle->next(); |
689 const SkOpAngle* foundAngle = NULL; | 689 const SkOpAngle* foundAngle = nullptr; |
690 bool foundDone = false; | 690 bool foundDone = false; |
691 // iterate through the angle, and compute everyone's winding | 691 // iterate through the angle, and compute everyone's winding |
692 SkOpSegment* nextSegment; | 692 SkOpSegment* nextSegment; |
693 int activeCount = 0; | 693 int activeCount = 0; |
694 do { | 694 do { |
695 nextSegment = nextAngle->segment(); | 695 nextSegment = nextAngle->segment(); |
696 bool activeAngle = nextSegment->activeOp(xorMiMask, xorSuMask, nextAngle
->start(), | 696 bool activeAngle = nextSegment->activeOp(xorMiMask, xorSuMask, nextAngle
->start(), |
697 nextAngle->end(), op, &sumMiWinding, &sumSuWinding); | 697 nextAngle->end(), op, &sumMiWinding, &sumSuWinding); |
698 if (activeAngle) { | 698 if (activeAngle) { |
699 ++activeCount; | 699 ++activeCount; |
(...skipping 17 matching lines...) Expand all Loading... |
717 last->segment()->debugID(), last->debugID()); | 717 last->segment()->debugID(), last->debugID()); |
718 if (!last->final()) { | 718 if (!last->final()) { |
719 SkDebugf(" windSum=%d", last->upCast()->windSum()); | 719 SkDebugf(" windSum=%d", last->upCast()->windSum()); |
720 } | 720 } |
721 SkDebugf("\n"); | 721 SkDebugf("\n"); |
722 #endif | 722 #endif |
723 } | 723 } |
724 } while ((nextAngle = nextAngle->next()) != angle); | 724 } while ((nextAngle = nextAngle->next()) != angle); |
725 start->segment()->markDone(start->starter(end)); | 725 start->segment()->markDone(start->starter(end)); |
726 if (!foundAngle) { | 726 if (!foundAngle) { |
727 return NULL; | 727 return nullptr; |
728 } | 728 } |
729 *nextStart = foundAngle->start(); | 729 *nextStart = foundAngle->start(); |
730 *nextEnd = foundAngle->end(); | 730 *nextEnd = foundAngle->end(); |
731 nextSegment = foundAngle->segment(); | 731 nextSegment = foundAngle->segment(); |
732 #if DEBUG_WINDING | 732 #if DEBUG_WINDING |
733 SkDebugf("%s from:[%d] to:[%d] start=%d end=%d\n", | 733 SkDebugf("%s from:[%d] to:[%d] start=%d end=%d\n", |
734 __FUNCTION__, debugID(), nextSegment->debugID(), *nextStart, *nextEn
d); | 734 __FUNCTION__, debugID(), nextSegment->debugID(), *nextStart, *nextEn
d); |
735 #endif | 735 #endif |
736 return nextSegment; | 736 return nextSegment; |
737 } | 737 } |
738 | 738 |
739 SkOpSegment* SkOpSegment::findNextWinding(SkTDArray<SkOpSpanBase*>* chase, | 739 SkOpSegment* SkOpSegment::findNextWinding(SkTDArray<SkOpSpanBase*>* chase, |
740 SkOpSpanBase** nextStart, SkOpSpanBase** nextEnd, bool* unsortable) { | 740 SkOpSpanBase** nextStart, SkOpSpanBase** nextEnd, bool* unsortable) { |
741 SkOpSpanBase* start = *nextStart; | 741 SkOpSpanBase* start = *nextStart; |
742 SkOpSpanBase* end = *nextEnd; | 742 SkOpSpanBase* end = *nextEnd; |
743 SkASSERT(start != end); | 743 SkASSERT(start != end); |
744 int step = start->step(end); | 744 int step = start->step(end); |
745 SkOpSegment* other = this->isSimple(nextStart, &step); // advances nextStar
t | 745 SkOpSegment* other = this->isSimple(nextStart, &step); // advances nextStar
t |
746 if (other) { | 746 if (other) { |
747 // mark the smaller of startIndex, endIndex done, and all adjacent | 747 // mark the smaller of startIndex, endIndex done, and all adjacent |
748 // spans with the same T value (but not 'other' spans) | 748 // spans with the same T value (but not 'other' spans) |
749 #if DEBUG_WINDING | 749 #if DEBUG_WINDING |
750 SkDebugf("%s simple\n", __FUNCTION__); | 750 SkDebugf("%s simple\n", __FUNCTION__); |
751 #endif | 751 #endif |
752 SkOpSpan* startSpan = start->starter(end); | 752 SkOpSpan* startSpan = start->starter(end); |
753 if (startSpan->done()) { | 753 if (startSpan->done()) { |
754 return NULL; | 754 return nullptr; |
755 } | 755 } |
756 markDone(startSpan); | 756 markDone(startSpan); |
757 *nextEnd = step > 0 ? (*nextStart)->upCast()->next() : (*nextStart)->pre
v(); | 757 *nextEnd = step > 0 ? (*nextStart)->upCast()->next() : (*nextStart)->pre
v(); |
758 return other; | 758 return other; |
759 } | 759 } |
760 SkOpSpanBase* endNear = step > 0 ? (*nextStart)->upCast()->next() : (*nextSt
art)->prev(); | 760 SkOpSpanBase* endNear = step > 0 ? (*nextStart)->upCast()->next() : (*nextSt
art)->prev(); |
761 SkASSERT(endNear == end); // is this ever not end? | 761 SkASSERT(endNear == end); // is this ever not end? |
762 SkASSERT(endNear); | 762 SkASSERT(endNear); |
763 SkASSERT(start != endNear); | 763 SkASSERT(start != endNear); |
764 SkASSERT((start->t() < endNear->t()) ^ (step < 0)); | 764 SkASSERT((start->t() < endNear->t()) ^ (step < 0)); |
765 // more than one viable candidate -- measure angles to find best | 765 // more than one viable candidate -- measure angles to find best |
766 int calcWinding = computeSum(start, endNear, SkOpAngle::kUnaryWinding); | 766 int calcWinding = computeSum(start, endNear, SkOpAngle::kUnaryWinding); |
767 bool sortable = calcWinding != SK_NaN32; | 767 bool sortable = calcWinding != SK_NaN32; |
768 if (!sortable) { | 768 if (!sortable) { |
769 *unsortable = true; | 769 *unsortable = true; |
770 markDone(start->starter(end)); | 770 markDone(start->starter(end)); |
771 return NULL; | 771 return nullptr; |
772 } | 772 } |
773 SkOpAngle* angle = this->spanToAngle(end, start); | 773 SkOpAngle* angle = this->spanToAngle(end, start); |
774 if (angle->unorderable()) { | 774 if (angle->unorderable()) { |
775 *unsortable = true; | 775 *unsortable = true; |
776 markDone(start->starter(end)); | 776 markDone(start->starter(end)); |
777 return NULL; | 777 return nullptr; |
778 } | 778 } |
779 #if DEBUG_SORT | 779 #if DEBUG_SORT |
780 SkDebugf("%s\n", __FUNCTION__); | 780 SkDebugf("%s\n", __FUNCTION__); |
781 angle->debugLoop(); | 781 angle->debugLoop(); |
782 #endif | 782 #endif |
783 int sumWinding = updateWinding(end, start); | 783 int sumWinding = updateWinding(end, start); |
784 SkOpAngle* nextAngle = angle->next(); | 784 SkOpAngle* nextAngle = angle->next(); |
785 const SkOpAngle* foundAngle = NULL; | 785 const SkOpAngle* foundAngle = nullptr; |
786 bool foundDone = false; | 786 bool foundDone = false; |
787 // iterate through the angle, and compute everyone's winding | 787 // iterate through the angle, and compute everyone's winding |
788 SkOpSegment* nextSegment; | 788 SkOpSegment* nextSegment; |
789 int activeCount = 0; | 789 int activeCount = 0; |
790 do { | 790 do { |
791 nextSegment = nextAngle->segment(); | 791 nextSegment = nextAngle->segment(); |
792 bool activeAngle = nextSegment->activeWinding(nextAngle->start(), nextAn
gle->end(), | 792 bool activeAngle = nextSegment->activeWinding(nextAngle->start(), nextAn
gle->end(), |
793 &sumWinding); | 793 &sumWinding); |
794 if (activeAngle) { | 794 if (activeAngle) { |
795 ++activeCount; | 795 ++activeCount; |
(...skipping 17 matching lines...) Expand all Loading... |
813 last->segment()->debugID(), last->debugID()); | 813 last->segment()->debugID(), last->debugID()); |
814 if (!last->final()) { | 814 if (!last->final()) { |
815 SkDebugf(" windSum=%d", last->upCast()->windSum()); | 815 SkDebugf(" windSum=%d", last->upCast()->windSum()); |
816 } | 816 } |
817 SkDebugf("\n"); | 817 SkDebugf("\n"); |
818 #endif | 818 #endif |
819 } | 819 } |
820 } while ((nextAngle = nextAngle->next()) != angle); | 820 } while ((nextAngle = nextAngle->next()) != angle); |
821 start->segment()->markDone(start->starter(end)); | 821 start->segment()->markDone(start->starter(end)); |
822 if (!foundAngle) { | 822 if (!foundAngle) { |
823 return NULL; | 823 return nullptr; |
824 } | 824 } |
825 *nextStart = foundAngle->start(); | 825 *nextStart = foundAngle->start(); |
826 *nextEnd = foundAngle->end(); | 826 *nextEnd = foundAngle->end(); |
827 nextSegment = foundAngle->segment(); | 827 nextSegment = foundAngle->segment(); |
828 #if DEBUG_WINDING | 828 #if DEBUG_WINDING |
829 SkDebugf("%s from:[%d] to:[%d] start=%d end=%d\n", | 829 SkDebugf("%s from:[%d] to:[%d] start=%d end=%d\n", |
830 __FUNCTION__, debugID(), nextSegment->debugID(), *nextStart, *nextEn
d); | 830 __FUNCTION__, debugID(), nextSegment->debugID(), *nextStart, *nextEn
d); |
831 #endif | 831 #endif |
832 return nextSegment; | 832 return nextSegment; |
833 } | 833 } |
834 | 834 |
835 SkOpSegment* SkOpSegment::findNextXor(SkOpSpanBase** nextStart, SkOpSpanBase** n
extEnd, | 835 SkOpSegment* SkOpSegment::findNextXor(SkOpSpanBase** nextStart, SkOpSpanBase** n
extEnd, |
836 bool* unsortable) { | 836 bool* unsortable) { |
837 SkOpSpanBase* start = *nextStart; | 837 SkOpSpanBase* start = *nextStart; |
838 SkOpSpanBase* end = *nextEnd; | 838 SkOpSpanBase* end = *nextEnd; |
839 SkASSERT(start != end); | 839 SkASSERT(start != end); |
840 int step = start->step(end); | 840 int step = start->step(end); |
841 SkOpSegment* other = this->isSimple(nextStart, &step); // advances nextStar
t | 841 SkOpSegment* other = this->isSimple(nextStart, &step); // advances nextStar
t |
842 if (other) { | 842 if (other) { |
843 // mark the smaller of startIndex, endIndex done, and all adjacent | 843 // mark the smaller of startIndex, endIndex done, and all adjacent |
844 // spans with the same T value (but not 'other' spans) | 844 // spans with the same T value (but not 'other' spans) |
845 #if DEBUG_WINDING | 845 #if DEBUG_WINDING |
846 SkDebugf("%s simple\n", __FUNCTION__); | 846 SkDebugf("%s simple\n", __FUNCTION__); |
847 #endif | 847 #endif |
848 SkOpSpan* startSpan = start->starter(end); | 848 SkOpSpan* startSpan = start->starter(end); |
849 if (startSpan->done()) { | 849 if (startSpan->done()) { |
850 return NULL; | 850 return nullptr; |
851 } | 851 } |
852 markDone(startSpan); | 852 markDone(startSpan); |
853 *nextEnd = step > 0 ? (*nextStart)->upCast()->next() : (*nextStart)->pre
v(); | 853 *nextEnd = step > 0 ? (*nextStart)->upCast()->next() : (*nextStart)->pre
v(); |
854 return other; | 854 return other; |
855 } | 855 } |
856 SkDEBUGCODE(SkOpSpanBase* endNear = step > 0 ? (*nextStart)->upCast()->next(
) \ | 856 SkDEBUGCODE(SkOpSpanBase* endNear = step > 0 ? (*nextStart)->upCast()->next(
) \ |
857 : (*nextStart)->prev()); | 857 : (*nextStart)->prev()); |
858 SkASSERT(endNear == end); // is this ever not end? | 858 SkASSERT(endNear == end); // is this ever not end? |
859 SkASSERT(endNear); | 859 SkASSERT(endNear); |
860 SkASSERT(start != endNear); | 860 SkASSERT(start != endNear); |
861 SkASSERT((start->t() < endNear->t()) ^ (step < 0)); | 861 SkASSERT((start->t() < endNear->t()) ^ (step < 0)); |
862 SkOpAngle* angle = this->spanToAngle(end, start); | 862 SkOpAngle* angle = this->spanToAngle(end, start); |
863 if (!angle || angle->unorderable()) { | 863 if (!angle || angle->unorderable()) { |
864 *unsortable = true; | 864 *unsortable = true; |
865 markDone(start->starter(end)); | 865 markDone(start->starter(end)); |
866 return NULL; | 866 return nullptr; |
867 } | 867 } |
868 #if DEBUG_SORT | 868 #if DEBUG_SORT |
869 SkDebugf("%s\n", __FUNCTION__); | 869 SkDebugf("%s\n", __FUNCTION__); |
870 angle->debugLoop(); | 870 angle->debugLoop(); |
871 #endif | 871 #endif |
872 SkOpAngle* nextAngle = angle->next(); | 872 SkOpAngle* nextAngle = angle->next(); |
873 const SkOpAngle* foundAngle = NULL; | 873 const SkOpAngle* foundAngle = nullptr; |
874 bool foundDone = false; | 874 bool foundDone = false; |
875 // iterate through the angle, and compute everyone's winding | 875 // iterate through the angle, and compute everyone's winding |
876 SkOpSegment* nextSegment; | 876 SkOpSegment* nextSegment; |
877 int activeCount = 0; | 877 int activeCount = 0; |
878 do { | 878 do { |
879 nextSegment = nextAngle->segment(); | 879 nextSegment = nextAngle->segment(); |
880 ++activeCount; | 880 ++activeCount; |
881 if (!foundAngle || (foundDone && activeCount & 1)) { | 881 if (!foundAngle || (foundDone && activeCount & 1)) { |
882 foundAngle = nextAngle; | 882 foundAngle = nextAngle; |
883 if (!(foundDone = nextSegment->done(nextAngle))) { | 883 if (!(foundDone = nextSegment->done(nextAngle))) { |
884 break; | 884 break; |
885 } | 885 } |
886 } | 886 } |
887 nextAngle = nextAngle->next(); | 887 nextAngle = nextAngle->next(); |
888 } while (nextAngle != angle); | 888 } while (nextAngle != angle); |
889 start->segment()->markDone(start->starter(end)); | 889 start->segment()->markDone(start->starter(end)); |
890 if (!foundAngle) { | 890 if (!foundAngle) { |
891 return NULL; | 891 return nullptr; |
892 } | 892 } |
893 *nextStart = foundAngle->start(); | 893 *nextStart = foundAngle->start(); |
894 *nextEnd = foundAngle->end(); | 894 *nextEnd = foundAngle->end(); |
895 nextSegment = foundAngle->segment(); | 895 nextSegment = foundAngle->segment(); |
896 #if DEBUG_WINDING | 896 #if DEBUG_WINDING |
897 SkDebugf("%s from:[%d] to:[%d] start=%d end=%d\n", | 897 SkDebugf("%s from:[%d] to:[%d] start=%d end=%d\n", |
898 __FUNCTION__, debugID(), nextSegment->debugID(), *nextStart, *nextEn
d); | 898 __FUNCTION__, debugID(), nextSegment->debugID(), *nextStart, *nextEn
d); |
899 #endif | 899 #endif |
900 return nextSegment; | 900 return nextSegment; |
901 } | 901 } |
902 | 902 |
903 SkOpGlobalState* SkOpSegment::globalState() const { | 903 SkOpGlobalState* SkOpSegment::globalState() const { |
904 return contour()->globalState(); | 904 return contour()->globalState(); |
905 } | 905 } |
906 | 906 |
907 void SkOpSegment::init(SkPoint pts[], SkScalar weight, SkOpContour* contour, SkP
ath::Verb verb) { | 907 void SkOpSegment::init(SkPoint pts[], SkScalar weight, SkOpContour* contour, SkP
ath::Verb verb) { |
908 fContour = contour; | 908 fContour = contour; |
909 fNext = NULL; | 909 fNext = nullptr; |
910 fOriginal[0] = pts[0]; | 910 fOriginal[0] = pts[0]; |
911 fOriginal[1] = pts[SkPathOpsVerbToPoints(verb)]; | 911 fOriginal[1] = pts[SkPathOpsVerbToPoints(verb)]; |
912 fPts = pts; | 912 fPts = pts; |
913 fWeight = weight; | 913 fWeight = weight; |
914 fVerb = verb; | 914 fVerb = verb; |
915 fCubicType = SkDCubic::kUnsplit_SkDCubicType; | 915 fCubicType = SkDCubic::kUnsplit_SkDCubicType; |
916 fCount = 0; | 916 fCount = 0; |
917 fDoneCount = 0; | 917 fDoneCount = 0; |
918 fTopsFound = false; | 918 fTopsFound = false; |
919 fVisited = false; | 919 fVisited = false; |
920 SkOpSpan* zeroSpan = &fHead; | 920 SkOpSpan* zeroSpan = &fHead; |
921 zeroSpan->init(this, NULL, 0, fPts[0]); | 921 zeroSpan->init(this, nullptr, 0, fPts[0]); |
922 SkOpSpanBase* oneSpan = &fTail; | 922 SkOpSpanBase* oneSpan = &fTail; |
923 zeroSpan->setNext(oneSpan); | 923 zeroSpan->setNext(oneSpan); |
924 oneSpan->initBase(this, zeroSpan, 1, fPts[SkPathOpsVerbToPoints(fVerb)]); | 924 oneSpan->initBase(this, zeroSpan, 1, fPts[SkPathOpsVerbToPoints(fVerb)]); |
925 SkDEBUGCODE(fID = globalState()->nextSegmentID()); | 925 SkDEBUGCODE(fID = globalState()->nextSegmentID()); |
926 } | 926 } |
927 | 927 |
928 bool SkOpSegment::isClose(double t, const SkOpSegment* opp) const { | 928 bool SkOpSegment::isClose(double t, const SkOpSegment* opp) const { |
929 SkDPoint cPt = this->dPtAtT(t); | 929 SkDPoint cPt = this->dPtAtT(t); |
930 SkDVector dxdy = (*CurveDSlopeAtT[this->verb()])(this->pts(), this->weight()
, t); | 930 SkDVector dxdy = (*CurveDSlopeAtT[this->verb()])(this->pts(), this->weight()
, t); |
931 SkDLine perp = {{ cPt, {cPt.fX + dxdy.fY, cPt.fY - dxdy.fX} }}; | 931 SkDLine perp = {{ cPt, {cPt.fX + dxdy.fY, cPt.fY - dxdy.fX} }}; |
(...skipping 16 matching lines...) Expand all Loading... |
948 SkOpSpan* span = this->head(); | 948 SkOpSpan* span = this->head(); |
949 do { | 949 do { |
950 this->markDone(span); | 950 this->markDone(span); |
951 } while ((span = span->next()->upCastable())); | 951 } while ((span = span->next()->upCastable())); |
952 } | 952 } |
953 | 953 |
954 SkOpSpanBase* SkOpSegment::markAndChaseDone(SkOpSpanBase* start, SkOpSpanBase* e
nd) { | 954 SkOpSpanBase* SkOpSegment::markAndChaseDone(SkOpSpanBase* start, SkOpSpanBase* e
nd) { |
955 int step = start->step(end); | 955 int step = start->step(end); |
956 SkOpSpan* minSpan = start->starter(end); | 956 SkOpSpan* minSpan = start->starter(end); |
957 markDone(minSpan); | 957 markDone(minSpan); |
958 SkOpSpanBase* last = NULL; | 958 SkOpSpanBase* last = nullptr; |
959 SkOpSegment* other = this; | 959 SkOpSegment* other = this; |
960 while ((other = other->nextChase(&start, &step, &minSpan, &last))) { | 960 while ((other = other->nextChase(&start, &step, &minSpan, &last))) { |
961 if (other->done()) { | 961 if (other->done()) { |
962 SkASSERT(!last); | 962 SkASSERT(!last); |
963 break; | 963 break; |
964 } | 964 } |
965 other->markDone(minSpan); | 965 other->markDone(minSpan); |
966 } | 966 } |
967 return last; | 967 return last; |
968 } | 968 } |
969 | 969 |
970 bool SkOpSegment::markAndChaseWinding(SkOpSpanBase* start, SkOpSpanBase* end, in
t winding, | 970 bool SkOpSegment::markAndChaseWinding(SkOpSpanBase* start, SkOpSpanBase* end, in
t winding, |
971 SkOpSpanBase** lastPtr) { | 971 SkOpSpanBase** lastPtr) { |
972 SkOpSpan* spanStart = start->starter(end); | 972 SkOpSpan* spanStart = start->starter(end); |
973 int step = start->step(end); | 973 int step = start->step(end); |
974 bool success = markWinding(spanStart, winding); | 974 bool success = markWinding(spanStart, winding); |
975 SkOpSpanBase* last = NULL; | 975 SkOpSpanBase* last = nullptr; |
976 SkOpSegment* other = this; | 976 SkOpSegment* other = this; |
977 while ((other = other->nextChase(&start, &step, &spanStart, &last))) { | 977 while ((other = other->nextChase(&start, &step, &spanStart, &last))) { |
978 if (spanStart->windSum() != SK_MinS32) { | 978 if (spanStart->windSum() != SK_MinS32) { |
979 SkASSERT(spanStart->windSum() == winding); | 979 SkASSERT(spanStart->windSum() == winding); |
980 SkASSERT(!last); | 980 SkASSERT(!last); |
981 break; | 981 break; |
982 } | 982 } |
983 (void) other->markWinding(spanStart, winding); | 983 (void) other->markWinding(spanStart, winding); |
984 } | 984 } |
985 if (lastPtr) { | 985 if (lastPtr) { |
986 *lastPtr = last; | 986 *lastPtr = last; |
987 } | 987 } |
988 return success; | 988 return success; |
989 } | 989 } |
990 | 990 |
991 bool SkOpSegment::markAndChaseWinding(SkOpSpanBase* start, SkOpSpanBase* end, | 991 bool SkOpSegment::markAndChaseWinding(SkOpSpanBase* start, SkOpSpanBase* end, |
992 int winding, int oppWinding, SkOpSpanBase** lastPtr) { | 992 int winding, int oppWinding, SkOpSpanBase** lastPtr) { |
993 SkOpSpan* spanStart = start->starter(end); | 993 SkOpSpan* spanStart = start->starter(end); |
994 int step = start->step(end); | 994 int step = start->step(end); |
995 bool success = markWinding(spanStart, winding, oppWinding); | 995 bool success = markWinding(spanStart, winding, oppWinding); |
996 SkOpSpanBase* last = NULL; | 996 SkOpSpanBase* last = nullptr; |
997 SkOpSegment* other = this; | 997 SkOpSegment* other = this; |
998 while ((other = other->nextChase(&start, &step, &spanStart, &last))) { | 998 while ((other = other->nextChase(&start, &step, &spanStart, &last))) { |
999 if (spanStart->windSum() != SK_MinS32) { | 999 if (spanStart->windSum() != SK_MinS32) { |
1000 if (this->operand() == other->operand()) { | 1000 if (this->operand() == other->operand()) { |
1001 if (spanStart->windSum() != winding || spanStart->oppSum() != op
pWinding) { | 1001 if (spanStart->windSum() != winding || spanStart->oppSum() != op
pWinding) { |
1002 this->globalState()->setWindingFailed(); | 1002 this->globalState()->setWindingFailed(); |
1003 return false; | 1003 return false; |
1004 } | 1004 } |
1005 } else { | 1005 } else { |
1006 SkASSERT(spanStart->windSum() == oppWinding); | 1006 SkASSERT(spanStart->windSum() == oppWinding); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1044 | 1044 |
1045 SkOpSpanBase* SkOpSegment::markAngle(int maxWinding, int sumWinding, int oppMaxW
inding, | 1045 SkOpSpanBase* SkOpSegment::markAngle(int maxWinding, int sumWinding, int oppMaxW
inding, |
1046 int oppSumWinding, const SkOpAngle* angle) { | 1046 int oppSumWinding, const SkOpAngle* angle) { |
1047 SkASSERT(angle->segment() == this); | 1047 SkASSERT(angle->segment() == this); |
1048 if (UseInnerWinding(maxWinding, sumWinding)) { | 1048 if (UseInnerWinding(maxWinding, sumWinding)) { |
1049 maxWinding = sumWinding; | 1049 maxWinding = sumWinding; |
1050 } | 1050 } |
1051 if (oppMaxWinding != oppSumWinding && UseInnerWinding(oppMaxWinding, oppSumW
inding)) { | 1051 if (oppMaxWinding != oppSumWinding && UseInnerWinding(oppMaxWinding, oppSumW
inding)) { |
1052 oppMaxWinding = oppSumWinding; | 1052 oppMaxWinding = oppSumWinding; |
1053 } | 1053 } |
1054 SkOpSpanBase* last = NULL; | 1054 SkOpSpanBase* last = nullptr; |
1055 // caller doesn't require that this marks anything | 1055 // caller doesn't require that this marks anything |
1056 (void) markAndChaseWinding(angle->start(), angle->end(), maxWinding, oppMaxW
inding, &last); | 1056 (void) markAndChaseWinding(angle->start(), angle->end(), maxWinding, oppMaxW
inding, &last); |
1057 #if DEBUG_WINDING | 1057 #if DEBUG_WINDING |
1058 if (last) { | 1058 if (last) { |
1059 SkDebugf("%s last segment=%d span=%d", __FUNCTION__, | 1059 SkDebugf("%s last segment=%d span=%d", __FUNCTION__, |
1060 last->segment()->debugID(), last->debugID()); | 1060 last->segment()->debugID(), last->debugID()); |
1061 if (!last->final()) { | 1061 if (!last->final()) { |
1062 SkDebugf(" windSum="); | 1062 SkDebugf(" windSum="); |
1063 SkPathOpsDebug::WindingPrintf(last->upCast()->windSum()); | 1063 SkPathOpsDebug::WindingPrintf(last->upCast()->windSum()); |
1064 } | 1064 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1119 if (!SkDPoint::ApproximatelyEqual(testPt, base->fPt)) { | 1119 if (!SkDPoint::ApproximatelyEqual(testPt, base->fPt)) { |
1120 return false; | 1120 return false; |
1121 } | 1121 } |
1122 return !this->ptsDisjoint(base->fT, base->fPt, testT, testPt); | 1122 return !this->ptsDisjoint(base->fT, base->fPt, testT, testPt); |
1123 } | 1123 } |
1124 | 1124 |
1125 static SkOpSegment* set_last(SkOpSpanBase** last, SkOpSpanBase* endSpan) { | 1125 static SkOpSegment* set_last(SkOpSpanBase** last, SkOpSpanBase* endSpan) { |
1126 if (last) { | 1126 if (last) { |
1127 *last = endSpan; | 1127 *last = endSpan; |
1128 } | 1128 } |
1129 return NULL; | 1129 return nullptr; |
1130 } | 1130 } |
1131 | 1131 |
1132 SkOpSegment* SkOpSegment::nextChase(SkOpSpanBase** startPtr, int* stepPtr, SkOpS
pan** minPtr, | 1132 SkOpSegment* SkOpSegment::nextChase(SkOpSpanBase** startPtr, int* stepPtr, SkOpS
pan** minPtr, |
1133 SkOpSpanBase** last) const { | 1133 SkOpSpanBase** last) const { |
1134 SkOpSpanBase* origStart = *startPtr; | 1134 SkOpSpanBase* origStart = *startPtr; |
1135 int step = *stepPtr; | 1135 int step = *stepPtr; |
1136 SkOpSpanBase* endSpan = step > 0 ? origStart->upCast()->next() : origStart->
prev(); | 1136 SkOpSpanBase* endSpan = step > 0 ? origStart->upCast()->next() : origStart->
prev(); |
1137 SkASSERT(endSpan); | 1137 SkASSERT(endSpan); |
1138 SkOpAngle* angle = step > 0 ? endSpan->fromAngle() : endSpan->upCast()->toAn
gle(); | 1138 SkOpAngle* angle = step > 0 ? endSpan->fromAngle() : endSpan->upCast()->toAn
gle(); |
1139 SkOpSpanBase* foundSpan; | 1139 SkOpSpanBase* foundSpan; |
1140 SkOpSpanBase* otherEnd; | 1140 SkOpSpanBase* otherEnd; |
1141 SkOpSegment* other; | 1141 SkOpSegment* other; |
1142 if (angle == NULL) { | 1142 if (angle == nullptr) { |
1143 if (endSpan->t() != 0 && endSpan->t() != 1) { | 1143 if (endSpan->t() != 0 && endSpan->t() != 1) { |
1144 return NULL; | 1144 return nullptr; |
1145 } | 1145 } |
1146 SkOpPtT* otherPtT = endSpan->ptT()->next(); | 1146 SkOpPtT* otherPtT = endSpan->ptT()->next(); |
1147 other = otherPtT->segment(); | 1147 other = otherPtT->segment(); |
1148 foundSpan = otherPtT->span(); | 1148 foundSpan = otherPtT->span(); |
1149 otherEnd = step > 0 ? foundSpan->upCast()->next() : foundSpan->prev(); | 1149 otherEnd = step > 0 ? foundSpan->upCast()->next() : foundSpan->prev(); |
1150 } else { | 1150 } else { |
1151 int loopCount = angle->loopCount(); | 1151 int loopCount = angle->loopCount(); |
1152 if (loopCount > 2) { | 1152 if (loopCount > 2) { |
1153 return set_last(last, endSpan); | 1153 return set_last(last, endSpan); |
1154 } | 1154 } |
1155 const SkOpAngle* next = angle->next(); | 1155 const SkOpAngle* next = angle->next(); |
1156 if (NULL == next) { | 1156 if (nullptr == next) { |
1157 return NULL; | 1157 return nullptr; |
1158 } | 1158 } |
1159 #if DEBUG_WINDING | 1159 #if DEBUG_WINDING |
1160 if (angle->debugSign() != next->debugSign() && !angle->segment()->contou
r()->isXor() | 1160 if (angle->debugSign() != next->debugSign() && !angle->segment()->contou
r()->isXor() |
1161 && !next->segment()->contour()->isXor()) { | 1161 && !next->segment()->contour()->isXor()) { |
1162 SkDebugf("%s mismatched signs\n", __FUNCTION__); | 1162 SkDebugf("%s mismatched signs\n", __FUNCTION__); |
1163 } | 1163 } |
1164 #endif | 1164 #endif |
1165 other = next->segment(); | 1165 other = next->segment(); |
1166 foundSpan = endSpan = next->start(); | 1166 foundSpan = endSpan = next->start(); |
1167 otherEnd = next->end(); | 1167 otherEnd = next->end(); |
1168 } | 1168 } |
1169 int foundStep = foundSpan->step(otherEnd); | 1169 int foundStep = foundSpan->step(otherEnd); |
1170 if (*stepPtr != foundStep) { | 1170 if (*stepPtr != foundStep) { |
1171 return set_last(last, endSpan); | 1171 return set_last(last, endSpan); |
1172 } | 1172 } |
1173 SkASSERT(*startPtr); | 1173 SkASSERT(*startPtr); |
1174 if (!otherEnd) { | 1174 if (!otherEnd) { |
1175 return NULL; | 1175 return nullptr; |
1176 } | 1176 } |
1177 // SkASSERT(otherEnd >= 0); | 1177 // SkASSERT(otherEnd >= 0); |
1178 SkOpSpan* origMin = step < 0 ? origStart->prev() : origStart->upCast(); | 1178 SkOpSpan* origMin = step < 0 ? origStart->prev() : origStart->upCast(); |
1179 SkOpSpan* foundMin = foundSpan->starter(otherEnd); | 1179 SkOpSpan* foundMin = foundSpan->starter(otherEnd); |
1180 if (foundMin->windValue() != origMin->windValue() | 1180 if (foundMin->windValue() != origMin->windValue() |
1181 || foundMin->oppValue() != origMin->oppValue()) { | 1181 || foundMin->oppValue() != origMin->oppValue()) { |
1182 return set_last(last, endSpan); | 1182 return set_last(last, endSpan); |
1183 } | 1183 } |
1184 *startPtr = foundSpan; | 1184 *startPtr = foundSpan; |
1185 *stepPtr = foundStep; | 1185 *stepPtr = foundStep; |
(...skipping 19 matching lines...) Expand all Loading... |
1205 // curve/curve intersection should now do a pretty good job of finding coinciden
t runs so | 1205 // curve/curve intersection should now do a pretty good job of finding coinciden
t runs so |
1206 // this may be only be necessary for line/curve pairs -- so skip unless this is
a line and the | 1206 // this may be only be necessary for line/curve pairs -- so skip unless this is
a line and the |
1207 // the opp is not a line | 1207 // the opp is not a line |
1208 bool SkOpSegment::missingCoincidence(SkOpCoincidence* coincidences, SkChunkAlloc
* allocator) { | 1208 bool SkOpSegment::missingCoincidence(SkOpCoincidence* coincidences, SkChunkAlloc
* allocator) { |
1209 if (this->verb() != SkPath::kLine_Verb) { | 1209 if (this->verb() != SkPath::kLine_Verb) { |
1210 return false; | 1210 return false; |
1211 } | 1211 } |
1212 if (this->done()) { | 1212 if (this->done()) { |
1213 return false; | 1213 return false; |
1214 } | 1214 } |
1215 SkOpSpan* prior = NULL; | 1215 SkOpSpan* prior = nullptr; |
1216 SkOpSpanBase* spanBase = &fHead; | 1216 SkOpSpanBase* spanBase = &fHead; |
1217 do { | 1217 do { |
1218 SkOpPtT* ptT = spanBase->ptT(), * spanStopPtT = ptT; | 1218 SkOpPtT* ptT = spanBase->ptT(), * spanStopPtT = ptT; |
1219 SkASSERT(ptT->span() == spanBase); | 1219 SkASSERT(ptT->span() == spanBase); |
1220 while ((ptT = ptT->next()) != spanStopPtT) { | 1220 while ((ptT = ptT->next()) != spanStopPtT) { |
1221 if (ptT->deleted()) { | 1221 if (ptT->deleted()) { |
1222 continue; | 1222 continue; |
1223 } | 1223 } |
1224 SkOpSegment* opp = ptT->span()->segment(); | 1224 SkOpSegment* opp = ptT->span()->segment(); |
1225 if (opp->verb() == SkPath::kLine_Verb) { | 1225 if (opp->verb() == SkPath::kLine_Verb) { |
(...skipping 11 matching lines...) Expand all Loading... |
1237 } | 1237 } |
1238 SkOpSpan* span = spanBase->upCastable(); | 1238 SkOpSpan* span = spanBase->upCastable(); |
1239 // FIXME?: this assumes that if the opposite segment is coincident t
hen no more | 1239 // FIXME?: this assumes that if the opposite segment is coincident t
hen no more |
1240 // coincidence needs to be detected. This may not be true. | 1240 // coincidence needs to be detected. This may not be true. |
1241 if (span && span->containsCoincidence(opp)) { | 1241 if (span && span->containsCoincidence(opp)) { |
1242 continue; | 1242 continue; |
1243 } | 1243 } |
1244 if (spanBase->containsCoinEnd(opp)) { | 1244 if (spanBase->containsCoinEnd(opp)) { |
1245 continue; | 1245 continue; |
1246 } | 1246 } |
1247 SkOpPtT* priorPtT = NULL, * priorStopPtT; | 1247 SkOpPtT* priorPtT = nullptr, * priorStopPtT; |
1248 // find prior span containing opp segment | 1248 // find prior span containing opp segment |
1249 SkOpSegment* priorOpp = NULL; | 1249 SkOpSegment* priorOpp = nullptr; |
1250 SkOpSpan* priorTest = spanBase->prev(); | 1250 SkOpSpan* priorTest = spanBase->prev(); |
1251 while (!priorOpp && priorTest) { | 1251 while (!priorOpp && priorTest) { |
1252 priorStopPtT = priorPtT = priorTest->ptT(); | 1252 priorStopPtT = priorPtT = priorTest->ptT(); |
1253 while ((priorPtT = priorPtT->next()) != priorStopPtT) { | 1253 while ((priorPtT = priorPtT->next()) != priorStopPtT) { |
1254 if (priorPtT->deleted()) { | 1254 if (priorPtT->deleted()) { |
1255 continue; | 1255 continue; |
1256 } | 1256 } |
1257 SkOpSegment* segment = priorPtT->span()->segment(); | 1257 SkOpSegment* segment = priorPtT->span()->segment(); |
1258 if (segment == opp) { | 1258 if (segment == opp) { |
1259 prior = priorTest; | 1259 prior = priorTest; |
(...skipping 26 matching lines...) Expand all Loading... |
1286 coincidences->add(priorPtT, ptT, oppStart, oppEnd, allocator
); | 1286 coincidences->add(priorPtT, ptT, oppStart, oppEnd, allocator
); |
1287 } | 1287 } |
1288 clear_visited(&fHead); | 1288 clear_visited(&fHead); |
1289 return true; | 1289 return true; |
1290 } | 1290 } |
1291 swapBack: | 1291 swapBack: |
1292 if (swapped) { | 1292 if (swapped) { |
1293 SkTSwap(priorPtT, ptT); | 1293 SkTSwap(priorPtT, ptT); |
1294 } | 1294 } |
1295 } | 1295 } |
1296 } while ((spanBase = spanBase->final() ? NULL : spanBase->upCast()->next()))
; | 1296 } while ((spanBase = spanBase->final() ? nullptr : spanBase->upCast()->next(
))); |
1297 clear_visited(&fHead); | 1297 clear_visited(&fHead); |
1298 return false; | 1298 return false; |
1299 } | 1299 } |
1300 | 1300 |
1301 // if a span has more than one intersection, merge the other segments' span as n
eeded | 1301 // if a span has more than one intersection, merge the other segments' span as n
eeded |
1302 void SkOpSegment::moveMultiples() { | 1302 void SkOpSegment::moveMultiples() { |
1303 debugValidate(); | 1303 debugValidate(); |
1304 SkOpSpanBase* test = &fHead; | 1304 SkOpSpanBase* test = &fHead; |
1305 do { | 1305 do { |
1306 int addCount = test->spanAddsCount(); | 1306 int addCount = test->spanAddsCount(); |
(...skipping 25 matching lines...) Expand all Loading... |
1332 if (oppPrev->spanAddsCount() == addCount) { | 1332 if (oppPrev->spanAddsCount() == addCount) { |
1333 continue; | 1333 continue; |
1334 } | 1334 } |
1335 if (oppPrev->deleted()) { | 1335 if (oppPrev->deleted()) { |
1336 continue; | 1336 continue; |
1337 } | 1337 } |
1338 oppFirst = oppPrev; | 1338 oppFirst = oppPrev; |
1339 } | 1339 } |
1340 SkOpSpanBase* oppNext = oppSpan; | 1340 SkOpSpanBase* oppNext = oppSpan; |
1341 SkOpSpanBase* oppLast = oppSpan; | 1341 SkOpSpanBase* oppLast = oppSpan; |
1342 while ((oppNext = oppNext->final() ? NULL : oppNext->upCast()->next(
))) { | 1342 while ((oppNext = oppNext->final() ? nullptr : oppNext->upCast()->ne
xt())) { |
1343 if (!roughly_equal(oppNext->t(), oppSpan->t())) { | 1343 if (!roughly_equal(oppNext->t(), oppSpan->t())) { |
1344 break; | 1344 break; |
1345 } | 1345 } |
1346 if (oppNext->spanAddsCount() == addCount) { | 1346 if (oppNext->spanAddsCount() == addCount) { |
1347 continue; | 1347 continue; |
1348 } | 1348 } |
1349 if (oppNext->deleted()) { | 1349 if (oppNext->deleted()) { |
1350 continue; | 1350 continue; |
1351 } | 1351 } |
1352 oppLast = oppNext; | 1352 oppLast = oppNext; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1386 } | 1386 } |
1387 oppSegment->debugValidate(); | 1387 oppSegment->debugValidate(); |
1388 goto checkNextSpan; | 1388 goto checkNextSpan; |
1389 } | 1389 } |
1390 tryNextSpan: | 1390 tryNextSpan: |
1391 ; | 1391 ; |
1392 } while (oppTest != oppLast && (oppTest = oppTest->upCast()->next())
); | 1392 } while (oppTest != oppLast && (oppTest = oppTest->upCast()->next())
); |
1393 } while ((testPtT = testPtT->next()) != startPtT); | 1393 } while ((testPtT = testPtT->next()) != startPtT); |
1394 checkNextSpan: | 1394 checkNextSpan: |
1395 ; | 1395 ; |
1396 } while ((test = test->final() ? NULL : test->upCast()->next())); | 1396 } while ((test = test->final() ? nullptr : test->upCast()->next())); |
1397 debugValidate(); | 1397 debugValidate(); |
1398 } | 1398 } |
1399 | 1399 |
1400 // Move nearby t values and pts so they all hang off the same span. Alignment ha
ppens later. | 1400 // Move nearby t values and pts so they all hang off the same span. Alignment ha
ppens later. |
1401 void SkOpSegment::moveNearby() { | 1401 void SkOpSegment::moveNearby() { |
1402 debugValidate(); | 1402 debugValidate(); |
1403 SkOpSpanBase* spanS = &fHead; | 1403 SkOpSpanBase* spanS = &fHead; |
1404 do { | 1404 do { |
1405 SkOpSpanBase* test = spanS->upCast()->next(); | 1405 SkOpSpanBase* test = spanS->upCast()->next(); |
1406 SkOpSpanBase* next; | 1406 SkOpSpanBase* next; |
1407 if (spanS->contains(test)) { | 1407 if (spanS->contains(test)) { |
1408 if (!test->final()) { | 1408 if (!test->final()) { |
1409 test->upCast()->detach(spanS->ptT()); | 1409 test->upCast()->detach(spanS->ptT()); |
1410 continue; | 1410 continue; |
1411 } else if (spanS != &fHead) { | 1411 } else if (spanS != &fHead) { |
1412 spanS->upCast()->detach(test->ptT()); | 1412 spanS->upCast()->detach(test->ptT()); |
1413 spanS = test; | 1413 spanS = test; |
1414 continue; | 1414 continue; |
1415 } | 1415 } |
1416 } | 1416 } |
1417 do { // iterate through all spans associated with start | 1417 do { // iterate through all spans associated with start |
1418 SkOpPtT* startBase = spanS->ptT(); | 1418 SkOpPtT* startBase = spanS->ptT(); |
1419 next = test->final() ? NULL : test->upCast()->next(); | 1419 next = test->final() ? nullptr : test->upCast()->next(); |
1420 do { | 1420 do { |
1421 SkOpPtT* testBase = test->ptT(); | 1421 SkOpPtT* testBase = test->ptT(); |
1422 do { | 1422 do { |
1423 if (startBase == testBase) { | 1423 if (startBase == testBase) { |
1424 goto checkNextSpan; | 1424 goto checkNextSpan; |
1425 } | 1425 } |
1426 if (testBase->duplicate()) { | 1426 if (testBase->duplicate()) { |
1427 continue; | 1427 continue; |
1428 } | 1428 } |
1429 if (this->match(startBase, testBase->segment(), testBase->fT
, testBase->fPt)) { | 1429 if (this->match(startBase, testBase->segment(), testBase->fT
, testBase->fPt)) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1499 *oppSumWinding = *sumSuWinding -= oppDeltaSum; | 1499 *oppSumWinding = *sumSuWinding -= oppDeltaSum; |
1500 } | 1500 } |
1501 SkASSERT(!DEBUG_LIMIT_WIND_SUM || SkTAbs(*sumWinding) <= DEBUG_LIMIT_WIND_SU
M); | 1501 SkASSERT(!DEBUG_LIMIT_WIND_SUM || SkTAbs(*sumWinding) <= DEBUG_LIMIT_WIND_SU
M); |
1502 SkASSERT(!DEBUG_LIMIT_WIND_SUM || SkTAbs(*oppSumWinding) <= DEBUG_LIMIT_WIND
_SUM); | 1502 SkASSERT(!DEBUG_LIMIT_WIND_SUM || SkTAbs(*oppSumWinding) <= DEBUG_LIMIT_WIND
_SUM); |
1503 } | 1503 } |
1504 | 1504 |
1505 void SkOpSegment::sortAngles() { | 1505 void SkOpSegment::sortAngles() { |
1506 SkOpSpanBase* span = &this->fHead; | 1506 SkOpSpanBase* span = &this->fHead; |
1507 do { | 1507 do { |
1508 SkOpAngle* fromAngle = span->fromAngle(); | 1508 SkOpAngle* fromAngle = span->fromAngle(); |
1509 SkOpAngle* toAngle = span->final() ? NULL : span->upCast()->toAngle(); | 1509 SkOpAngle* toAngle = span->final() ? nullptr : span->upCast()->toAngle()
; |
1510 if (!fromAngle && !toAngle) { | 1510 if (!fromAngle && !toAngle) { |
1511 continue; | 1511 continue; |
1512 } | 1512 } |
1513 #if DEBUG_ANGLE | 1513 #if DEBUG_ANGLE |
1514 bool wroteAfterHeader = false; | 1514 bool wroteAfterHeader = false; |
1515 #endif | 1515 #endif |
1516 SkOpAngle* baseAngle = fromAngle; | 1516 SkOpAngle* baseAngle = fromAngle; |
1517 if (fromAngle && toAngle) { | 1517 if (fromAngle && toAngle) { |
1518 #if DEBUG_ANGLE | 1518 #if DEBUG_ANGLE |
1519 SkDebugf("%s [%d] tStart=%1.9g [%d]\n", __FUNCTION__, debugID(), spa
n->t(), | 1519 SkDebugf("%s [%d] tStart=%1.9g [%d]\n", __FUNCTION__, debugID(), spa
n->t(), |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1553 wroteAfterHeader = true; | 1553 wroteAfterHeader = true; |
1554 } | 1554 } |
1555 #endif | 1555 #endif |
1556 if (!oAngle->loopContains(baseAngle)) { | 1556 if (!oAngle->loopContains(baseAngle)) { |
1557 baseAngle->insert(oAngle); | 1557 baseAngle->insert(oAngle); |
1558 } | 1558 } |
1559 } | 1559 } |
1560 } | 1560 } |
1561 } while ((ptT = ptT->next()) != stopPtT); | 1561 } while ((ptT = ptT->next()) != stopPtT); |
1562 if (baseAngle->loopCount() == 1) { | 1562 if (baseAngle->loopCount() == 1) { |
1563 span->setFromAngle(NULL); | 1563 span->setFromAngle(nullptr); |
1564 if (toAngle) { | 1564 if (toAngle) { |
1565 span->upCast()->setToAngle(NULL); | 1565 span->upCast()->setToAngle(nullptr); |
1566 } | 1566 } |
1567 baseAngle = NULL; | 1567 baseAngle = nullptr; |
1568 } | 1568 } |
1569 #if DEBUG_SORT | 1569 #if DEBUG_SORT |
1570 SkASSERT(!baseAngle || baseAngle->loopCount() > 1); | 1570 SkASSERT(!baseAngle || baseAngle->loopCount() > 1); |
1571 #endif | 1571 #endif |
1572 } while (!span->final() && (span = span->upCast()->next())); | 1572 } while (!span->final() && (span = span->upCast()->next())); |
1573 } | 1573 } |
1574 | 1574 |
1575 // return true if midpoints were computed | 1575 // return true if midpoints were computed |
1576 bool SkOpSegment::subDivide(const SkOpSpanBase* start, const SkOpSpanBase* end, | 1576 bool SkOpSegment::subDivide(const SkOpSpanBase* start, const SkOpSpanBase* end, |
1577 SkOpCurve* edge) const { | 1577 SkOpCurve* edge) const { |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1777 int absOut = SkTAbs(outerWinding); | 1777 int absOut = SkTAbs(outerWinding); |
1778 int absIn = SkTAbs(innerWinding); | 1778 int absIn = SkTAbs(innerWinding); |
1779 bool result = absOut == absIn ? outerWinding < 0 : absOut < absIn; | 1779 bool result = absOut == absIn ? outerWinding < 0 : absOut < absIn; |
1780 return result; | 1780 return result; |
1781 } | 1781 } |
1782 | 1782 |
1783 int SkOpSegment::windSum(const SkOpAngle* angle) const { | 1783 int SkOpSegment::windSum(const SkOpAngle* angle) const { |
1784 const SkOpSpan* minSpan = angle->start()->starter(angle->end()); | 1784 const SkOpSpan* minSpan = angle->start()->starter(angle->end()); |
1785 return minSpan->windSum(); | 1785 return minSpan->windSum(); |
1786 } | 1786 } |
OLD | NEW |