| 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 |