| Index: src/pathops/SkOpCoincidence.cpp
|
| diff --git a/src/pathops/SkOpCoincidence.cpp b/src/pathops/SkOpCoincidence.cpp
|
| index 45eee0a38ecc77e2986a21f3af4f3ade1956b0ce..4251d9fcd8153fcb545eedb20d6044883fa76855 100755
|
| --- a/src/pathops/SkOpCoincidence.cpp
|
| +++ b/src/pathops/SkOpCoincidence.cpp
|
| @@ -22,7 +22,7 @@ void SkOpCoincidence::add(SkOpPtT* coinPtTStart, SkOpPtT* coinPtTEnd, SkOpPtT* o
|
| this->fHead = coinRec;
|
| }
|
|
|
| -static void tRange(const SkOpPtT* overS, const SkOpPtT* overE, double tStart, double tEnd,
|
| +static void t_range(const SkOpPtT* overS, const SkOpPtT* overE, double tStart, double tEnd,
|
| const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, double* coinTs, double* coinTe) {
|
| double denom = overE->fT - overS->fT;
|
| double start = 0 < denom ? tStart : tEnd;
|
| @@ -38,8 +38,8 @@ bool SkOpCoincidence::addIfMissing(const SkOpPtT* over1s, const SkOpPtT* over1e,
|
| SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd,
|
| SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd, SkChunkAlloc* allocator) {
|
| double coinTs, coinTe, oppTs, oppTe;
|
| - tRange(over1s, over1e, tStart, tEnd, coinPtTStart, coinPtTEnd, &coinTs, &coinTe);
|
| - tRange(over2s, over2e, tStart, tEnd, oppPtTStart, oppPtTEnd, &oppTs, &oppTe);
|
| + t_range(over1s, over1e, tStart, tEnd, coinPtTStart, coinPtTEnd, &coinTs, &coinTe);
|
| + t_range(over2s, over2e, tStart, tEnd, oppPtTStart, oppPtTEnd, &oppTs, &oppTe);
|
| SkOpSegment* coinSeg = coinPtTStart->segment();
|
| SkOpSegment* oppSeg = oppPtTStart->segment();
|
| SkASSERT(coinSeg != oppSeg);
|
| @@ -103,7 +103,7 @@ bool SkOpCoincidence::addMissing(SkChunkAlloc* allocator) {
|
| double overS, overE;
|
| if (this->overlap(outer->fCoinPtTStart, outer->fCoinPtTEnd,
|
| inner->fCoinPtTStart, inner->fCoinPtTEnd, &overS, &overE)) {
|
| - if (!addIfMissing(outer->fCoinPtTStart, outer->fCoinPtTEnd,
|
| + if (!this->addIfMissing(outer->fCoinPtTStart, outer->fCoinPtTEnd,
|
| inner->fCoinPtTStart, inner->fCoinPtTEnd, overS, overE,
|
| outer->fOppPtTStart, outer->fOppPtTEnd,
|
| inner->fOppPtTStart, inner->fOppPtTEnd, allocator)) {
|
| @@ -111,7 +111,7 @@ bool SkOpCoincidence::addMissing(SkChunkAlloc* allocator) {
|
| }
|
| } else if (this->overlap(outer->fCoinPtTStart, outer->fCoinPtTEnd,
|
| inner->fOppPtTStart, inner->fOppPtTEnd, &overS, &overE)) {
|
| - if (!addIfMissing(outer->fCoinPtTStart, outer->fCoinPtTEnd,
|
| + if (!this->addIfMissing(outer->fCoinPtTStart, outer->fCoinPtTEnd,
|
| inner->fOppPtTStart, inner->fOppPtTEnd, overS, overE,
|
| outer->fOppPtTStart, outer->fOppPtTEnd,
|
| inner->fCoinPtTStart, inner->fCoinPtTEnd, allocator)) {
|
| @@ -119,7 +119,7 @@ bool SkOpCoincidence::addMissing(SkChunkAlloc* allocator) {
|
| }
|
| } else if (this->overlap(outer->fOppPtTStart, outer->fOppPtTEnd,
|
| inner->fCoinPtTStart, inner->fCoinPtTEnd, &overS, &overE)) {
|
| - if (!addIfMissing(outer->fOppPtTStart, outer->fOppPtTEnd,
|
| + if (!this->addIfMissing(outer->fOppPtTStart, outer->fOppPtTEnd,
|
| inner->fCoinPtTStart, inner->fCoinPtTEnd, overS, overE,
|
| outer->fCoinPtTStart, outer->fCoinPtTEnd,
|
| inner->fOppPtTStart, inner->fOppPtTEnd, allocator)) {
|
| @@ -127,7 +127,7 @@ bool SkOpCoincidence::addMissing(SkChunkAlloc* allocator) {
|
| }
|
| } else if (this->overlap(outer->fOppPtTStart, outer->fOppPtTEnd,
|
| inner->fOppPtTStart, inner->fOppPtTEnd, &overS, &overE)) {
|
| - if (!addIfMissing(outer->fOppPtTStart, outer->fOppPtTEnd,
|
| + if (!this->addIfMissing(outer->fOppPtTStart, outer->fOppPtTEnd,
|
| inner->fOppPtTStart, inner->fOppPtTEnd, overS, overE,
|
| outer->fCoinPtTStart, outer->fCoinPtTEnd,
|
| inner->fCoinPtTStart, inner->fCoinPtTEnd, allocator)) {
|
| @@ -140,7 +140,6 @@ bool SkOpCoincidence::addMissing(SkChunkAlloc* allocator) {
|
| return true;
|
| }
|
|
|
| -
|
| bool SkOpCoincidence::contains(SkOpPtT* coinPtTStart, SkOpPtT* coinPtTEnd, SkOpPtT* oppPtTStart,
|
| SkOpPtT* oppPtTEnd, bool flipped) {
|
| SkCoincidentSpans* coin = fHead;
|
| @@ -183,16 +182,21 @@ bool SkOpCoincidence::apply() {
|
| oStart = oNext->upCast();
|
| } while (true);
|
| }
|
| - bool isXor = segment->isXor();
|
| - bool oppXor = oSegment->isXor();
|
| do {
|
| int windValue = start->windValue();
|
| - int oWindValue = oStart->windValue();
|
| int oppValue = start->oppValue();
|
| + int oWindValue = oStart->windValue();
|
| int oOppValue = oStart->oppValue();
|
| // winding values are added or subtracted depending on direction and wind type
|
| // same or opposite values are summed depending on the operand value
|
| - if (windValue >= oWindValue) {
|
| + int windDiff = operandSwap ? oOppValue : oWindValue;
|
| + int oWindDiff = operandSwap ? oppValue : windValue;
|
| + if (!flipped) {
|
| + windDiff = -windDiff;
|
| + oWindDiff = -oWindDiff;
|
| + }
|
| + if (windValue && (windValue > windDiff || (windValue == windDiff
|
| + && oWindValue <= oWindDiff))) {
|
| if (operandSwap) {
|
| SkTSwap(oWindValue, oOppValue);
|
| }
|
| @@ -203,10 +207,10 @@ bool SkOpCoincidence::apply() {
|
| windValue += oWindValue;
|
| oppValue += oOppValue;
|
| }
|
| - if (isXor) {
|
| + if (segment->isXor()) {
|
| windValue &= 1;
|
| }
|
| - if (oppXor) {
|
| + if (segment->oppXor()) {
|
| oppValue &= 1;
|
| }
|
| oWindValue = oOppValue = 0;
|
| @@ -221,12 +225,12 @@ bool SkOpCoincidence::apply() {
|
| oWindValue += windValue;
|
| oOppValue += oppValue;
|
| }
|
| - if (isXor) {
|
| - oOppValue &= 1;
|
| - }
|
| - if (oppXor) {
|
| + if (oSegment->isXor()) {
|
| oWindValue &= 1;
|
| }
|
| + if (oSegment->oppXor()) {
|
| + oOppValue &= 1;
|
| + }
|
| windValue = oppValue = 0;
|
| }
|
| start->setWindValue(windValue);
|
| @@ -245,11 +249,9 @@ bool SkOpCoincidence::apply() {
|
| break;
|
| }
|
| start = next->upCast();
|
| - if (!oNext) {
|
| - return false;
|
| - }
|
| - if (!oNext->upCastable()) {
|
| - return false;
|
| + // if the opposite ran out too soon, just reuse the last span
|
| + if (!oNext || !oNext->upCastable()) {
|
| + oNext = oStart;
|
| }
|
| oStart = oNext->upCast();
|
| } while (true);
|
|
|