| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 #include "SkOpCoincidence.h" | 7 #include "SkOpCoincidence.h" |
| 8 #include "SkOpSegment.h" | 8 #include "SkOpSegment.h" |
| 9 #include "SkPathOpsTSect.h" | 9 #include "SkPathOpsTSect.h" |
| 10 | 10 |
| 11 void SkOpCoincidence::add(SkOpPtT* coinPtTStart, SkOpPtT* coinPtTEnd, SkOpPtT* o
ppPtTStart, | 11 void SkOpCoincidence::add(SkOpPtT* coinPtTStart, SkOpPtT* coinPtTEnd, SkOpPtT* o
ppPtTStart, |
| 12 SkOpPtT* oppPtTEnd, SkChunkAlloc* allocator) { | 12 SkOpPtT* oppPtTEnd, SkChunkAlloc* allocator) { |
| 13 SkASSERT(coinPtTStart->fT < coinPtTEnd->fT); | 13 SkASSERT(coinPtTStart->fT < coinPtTEnd->fT); |
| 14 bool flipped = oppPtTStart->fT > oppPtTEnd->fT; | 14 bool flipped = oppPtTStart->fT > oppPtTEnd->fT; |
| 15 SkCoincidentSpans* coinRec = SkOpTAllocator<SkCoincidentSpans>::Allocate(all
ocator); | 15 SkCoincidentSpans* coinRec = SkOpTAllocator<SkCoincidentSpans>::Allocate(all
ocator); |
| 16 coinRec->fNext = this->fHead; | 16 coinRec->fNext = this->fHead; |
| 17 coinRec->fCoinPtTStart = coinPtTStart; | 17 coinRec->fCoinPtTStart = coinPtTStart; |
| 18 coinRec->fCoinPtTEnd = coinPtTEnd; | 18 coinRec->fCoinPtTEnd = coinPtTEnd; |
| 19 coinRec->fOppPtTStart = oppPtTStart; | 19 coinRec->fOppPtTStart = oppPtTStart; |
| 20 coinRec->fOppPtTEnd = oppPtTEnd; | 20 coinRec->fOppPtTEnd = oppPtTEnd; |
| 21 coinRec->fFlipped = flipped; | 21 coinRec->fFlipped = flipped; |
| 22 this->fHead = coinRec; | 22 this->fHead = coinRec; |
| 23 } | 23 } |
| 24 | 24 |
| 25 static void tRange(const SkOpPtT* overS, const SkOpPtT* overE, double tStart, do
uble tEnd, | 25 static void t_range(const SkOpPtT* overS, const SkOpPtT* overE, double tStart, d
ouble tEnd, |
| 26 const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, double* coinTs,
double* coinTe) { | 26 const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, double* coinTs,
double* coinTe) { |
| 27 double denom = overE->fT - overS->fT; | 27 double denom = overE->fT - overS->fT; |
| 28 double start = 0 < denom ? tStart : tEnd; | 28 double start = 0 < denom ? tStart : tEnd; |
| 29 double end = 0 < denom ? tEnd : tStart; | 29 double end = 0 < denom ? tEnd : tStart; |
| 30 double sRatio = (start - overS->fT) / denom; | 30 double sRatio = (start - overS->fT) / denom; |
| 31 double eRatio = (end - overS->fT) / denom; | 31 double eRatio = (end - overS->fT) / denom; |
| 32 *coinTs = coinPtTStart->fT + (coinPtTEnd->fT - coinPtTStart->fT) * sRatio; | 32 *coinTs = coinPtTStart->fT + (coinPtTEnd->fT - coinPtTStart->fT) * sRatio; |
| 33 *coinTe = coinPtTStart->fT + (coinPtTEnd->fT - coinPtTStart->fT) * eRatio; | 33 *coinTe = coinPtTStart->fT + (coinPtTEnd->fT - coinPtTStart->fT) * eRatio; |
| 34 } | 34 } |
| 35 | 35 |
| 36 bool SkOpCoincidence::addIfMissing(const SkOpPtT* over1s, const SkOpPtT* over1e, | 36 bool SkOpCoincidence::addIfMissing(const SkOpPtT* over1s, const SkOpPtT* over1e, |
| 37 const SkOpPtT* over2s, const SkOpPtT* over2e, double tStar
t, double tEnd, | 37 const SkOpPtT* over2s, const SkOpPtT* over2e, double tStar
t, double tEnd, |
| 38 SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, | 38 SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, |
| 39 SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd, SkChunkAlloc* allocator)
{ | 39 SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd, SkChunkAlloc* allocator)
{ |
| 40 double coinTs, coinTe, oppTs, oppTe; | 40 double coinTs, coinTe, oppTs, oppTe; |
| 41 tRange(over1s, over1e, tStart, tEnd, coinPtTStart, coinPtTEnd, &coinTs, &coi
nTe); | 41 t_range(over1s, over1e, tStart, tEnd, coinPtTStart, coinPtTEnd, &coinTs, &co
inTe); |
| 42 tRange(over2s, over2e, tStart, tEnd, oppPtTStart, oppPtTEnd, &oppTs, &oppTe)
; | 42 t_range(over2s, over2e, tStart, tEnd, oppPtTStart, oppPtTEnd, &oppTs, &oppTe
); |
| 43 SkOpSegment* coinSeg = coinPtTStart->segment(); | 43 SkOpSegment* coinSeg = coinPtTStart->segment(); |
| 44 SkOpSegment* oppSeg = oppPtTStart->segment(); | 44 SkOpSegment* oppSeg = oppPtTStart->segment(); |
| 45 SkASSERT(coinSeg != oppSeg); | 45 SkASSERT(coinSeg != oppSeg); |
| 46 SkCoincidentSpans* check = this->fHead; | 46 SkCoincidentSpans* check = this->fHead; |
| 47 do { | 47 do { |
| 48 const SkOpSegment* checkCoinSeg = check->fCoinPtTStart->segment(); | 48 const SkOpSegment* checkCoinSeg = check->fCoinPtTStart->segment(); |
| 49 if (checkCoinSeg != coinSeg && checkCoinSeg != oppSeg) { | 49 if (checkCoinSeg != coinSeg && checkCoinSeg != oppSeg) { |
| 50 continue; | 50 continue; |
| 51 } | 51 } |
| 52 const SkOpSegment* checkOppSeg = check->fOppPtTStart->segment(); | 52 const SkOpSegment* checkOppSeg = check->fOppPtTStart->segment(); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 SkCoincidentSpans* outer = this->fHead; | 96 SkCoincidentSpans* outer = this->fHead; |
| 97 if (!outer) { | 97 if (!outer) { |
| 98 return true; | 98 return true; |
| 99 } | 99 } |
| 100 do { | 100 do { |
| 101 SkCoincidentSpans* inner = outer; | 101 SkCoincidentSpans* inner = outer; |
| 102 while ((inner = inner->fNext)) { | 102 while ((inner = inner->fNext)) { |
| 103 double overS, overE; | 103 double overS, overE; |
| 104 if (this->overlap(outer->fCoinPtTStart, outer->fCoinPtTEnd, | 104 if (this->overlap(outer->fCoinPtTStart, outer->fCoinPtTEnd, |
| 105 inner->fCoinPtTStart, inner->fCoinPtTEnd, &overS, &overE)) { | 105 inner->fCoinPtTStart, inner->fCoinPtTEnd, &overS, &overE)) { |
| 106 if (!addIfMissing(outer->fCoinPtTStart, outer->fCoinPtTEnd, | 106 if (!this->addIfMissing(outer->fCoinPtTStart, outer->fCoinPtTEnd
, |
| 107 inner->fCoinPtTStart, inner->fCoinPtTEnd, overS, overE, | 107 inner->fCoinPtTStart, inner->fCoinPtTEnd, overS, overE, |
| 108 outer->fOppPtTStart, outer->fOppPtTEnd, | 108 outer->fOppPtTStart, outer->fOppPtTEnd, |
| 109 inner->fOppPtTStart, inner->fOppPtTEnd, allocator)) { | 109 inner->fOppPtTStart, inner->fOppPtTEnd, allocator)) { |
| 110 return false; | 110 return false; |
| 111 } | 111 } |
| 112 } else if (this->overlap(outer->fCoinPtTStart, outer->fCoinPtTEnd, | 112 } else if (this->overlap(outer->fCoinPtTStart, outer->fCoinPtTEnd, |
| 113 inner->fOppPtTStart, inner->fOppPtTEnd, &overS, &overE)) { | 113 inner->fOppPtTStart, inner->fOppPtTEnd, &overS, &overE)) { |
| 114 if (!addIfMissing(outer->fCoinPtTStart, outer->fCoinPtTEnd, | 114 if (!this->addIfMissing(outer->fCoinPtTStart, outer->fCoinPtTEnd
, |
| 115 inner->fOppPtTStart, inner->fOppPtTEnd, overS, overE, | 115 inner->fOppPtTStart, inner->fOppPtTEnd, overS, overE, |
| 116 outer->fOppPtTStart, outer->fOppPtTEnd, | 116 outer->fOppPtTStart, outer->fOppPtTEnd, |
| 117 inner->fCoinPtTStart, inner->fCoinPtTEnd, allocator)) { | 117 inner->fCoinPtTStart, inner->fCoinPtTEnd, allocator)) { |
| 118 return false; | 118 return false; |
| 119 } | 119 } |
| 120 } else if (this->overlap(outer->fOppPtTStart, outer->fOppPtTEnd, | 120 } else if (this->overlap(outer->fOppPtTStart, outer->fOppPtTEnd, |
| 121 inner->fCoinPtTStart, inner->fCoinPtTEnd, &overS, &overE)) { | 121 inner->fCoinPtTStart, inner->fCoinPtTEnd, &overS, &overE)) { |
| 122 if (!addIfMissing(outer->fOppPtTStart, outer->fOppPtTEnd, | 122 if (!this->addIfMissing(outer->fOppPtTStart, outer->fOppPtTEnd, |
| 123 inner->fCoinPtTStart, inner->fCoinPtTEnd, overS, overE, | 123 inner->fCoinPtTStart, inner->fCoinPtTEnd, overS, overE, |
| 124 outer->fCoinPtTStart, outer->fCoinPtTEnd, | 124 outer->fCoinPtTStart, outer->fCoinPtTEnd, |
| 125 inner->fOppPtTStart, inner->fOppPtTEnd, allocator)) { | 125 inner->fOppPtTStart, inner->fOppPtTEnd, allocator)) { |
| 126 return false; | 126 return false; |
| 127 } | 127 } |
| 128 } else if (this->overlap(outer->fOppPtTStart, outer->fOppPtTEnd, | 128 } else if (this->overlap(outer->fOppPtTStart, outer->fOppPtTEnd, |
| 129 inner->fOppPtTStart, inner->fOppPtTEnd, &overS, &overE)) { | 129 inner->fOppPtTStart, inner->fOppPtTEnd, &overS, &overE)) { |
| 130 if (!addIfMissing(outer->fOppPtTStart, outer->fOppPtTEnd, | 130 if (!this->addIfMissing(outer->fOppPtTStart, outer->fOppPtTEnd, |
| 131 inner->fOppPtTStart, inner->fOppPtTEnd, overS, overE, | 131 inner->fOppPtTStart, inner->fOppPtTEnd, overS, overE, |
| 132 outer->fCoinPtTStart, outer->fCoinPtTEnd, | 132 outer->fCoinPtTStart, outer->fCoinPtTEnd, |
| 133 inner->fCoinPtTStart, inner->fCoinPtTEnd, allocator)) { | 133 inner->fCoinPtTStart, inner->fCoinPtTEnd, allocator)) { |
| 134 return false; | 134 return false; |
| 135 } | 135 } |
| 136 } | 136 } |
| 137 } | 137 } |
| 138 | 138 |
| 139 } while ((outer = outer->fNext)); | 139 } while ((outer = outer->fNext)); |
| 140 return true; | 140 return true; |
| 141 } | 141 } |
| 142 | 142 |
| 143 | |
| 144 bool SkOpCoincidence::contains(SkOpPtT* coinPtTStart, SkOpPtT* coinPtTEnd, SkOpP
tT* oppPtTStart, | 143 bool SkOpCoincidence::contains(SkOpPtT* coinPtTStart, SkOpPtT* coinPtTEnd, SkOpP
tT* oppPtTStart, |
| 145 SkOpPtT* oppPtTEnd, bool flipped) { | 144 SkOpPtT* oppPtTEnd, bool flipped) { |
| 146 SkCoincidentSpans* coin = fHead; | 145 SkCoincidentSpans* coin = fHead; |
| 147 if (!coin) { | 146 if (!coin) { |
| 148 return false; | 147 return false; |
| 149 } | 148 } |
| 150 do { | 149 do { |
| 151 if (coin->fCoinPtTStart == coinPtTStart && coin->fCoinPtTEnd == coinPtT
End | 150 if (coin->fCoinPtTStart == coinPtTStart && coin->fCoinPtTEnd == coinPtT
End |
| 152 && coin->fOppPtTStart == oppPtTStart && coin->fOppPtTEnd == oppP
tTEnd | 151 && coin->fOppPtTStart == oppPtTStart && coin->fOppPtTEnd == oppP
tTEnd |
| 153 && coin->fFlipped == flipped) { | 152 && coin->fFlipped == flipped) { |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 } | 237 } |
| 239 if (!oWindValue && !oOppValue) { | 238 if (!oWindValue && !oOppValue) { |
| 240 oSegment->markDone(oStart); | 239 oSegment->markDone(oStart); |
| 241 } | 240 } |
| 242 SkOpSpanBase* next = start->next(); | 241 SkOpSpanBase* next = start->next(); |
| 243 SkOpSpanBase* oNext = flipped ? oStart->prev() : oStart->next(); | 242 SkOpSpanBase* oNext = flipped ? oStart->prev() : oStart->next(); |
| 244 if (next == end) { | 243 if (next == end) { |
| 245 break; | 244 break; |
| 246 } | 245 } |
| 247 start = next->upCast(); | 246 start = next->upCast(); |
| 248 if (!oNext) { | 247 // if the opposite ran out too soon, just reuse the last span |
| 249 return false; | 248 if (!oNext || !oNext->upCastable()) { |
| 250 } | 249 oNext = oStart; |
| 251 if (!oNext->upCastable()) { | |
| 252 return false; | |
| 253 } | 250 } |
| 254 oStart = oNext->upCast(); | 251 oStart = oNext->upCast(); |
| 255 } while (true); | 252 } while (true); |
| 256 } while ((coin = coin->fNext)); | 253 } while ((coin = coin->fNext)); |
| 257 return true; | 254 return true; |
| 258 } | 255 } |
| 259 | 256 |
| 260 void SkOpCoincidence::detach(SkCoincidentSpans* remove) { | 257 void SkOpCoincidence::detach(SkCoincidentSpans* remove) { |
| 261 SkCoincidentSpans* coin = fHead; | 258 SkCoincidentSpans* coin = fHead; |
| 262 SkCoincidentSpans* prev = NULL; | 259 SkCoincidentSpans* prev = NULL; |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 | 376 |
| 380 bool SkOpCoincidence::overlap(const SkOpPtT* coin1s, const SkOpPtT* coin1e, | 377 bool SkOpCoincidence::overlap(const SkOpPtT* coin1s, const SkOpPtT* coin1e, |
| 381 const SkOpPtT* coin2s, const SkOpPtT* coin2e, double* overS, double* ove
rE) const { | 378 const SkOpPtT* coin2s, const SkOpPtT* coin2e, double* overS, double* ove
rE) const { |
| 382 if (coin1s->segment() != coin2s->segment()) { | 379 if (coin1s->segment() != coin2s->segment()) { |
| 383 return false; | 380 return false; |
| 384 } | 381 } |
| 385 *overS = SkTMax(SkTMin(coin1s->fT, coin1e->fT), SkTMin(coin2s->fT, coin2e->f
T)); | 382 *overS = SkTMax(SkTMin(coin1s->fT, coin1e->fT), SkTMin(coin2s->fT, coin2e->f
T)); |
| 386 *overE = SkTMin(SkTMax(coin1s->fT, coin1e->fT), SkTMax(coin2s->fT, coin2e->f
T)); | 383 *overE = SkTMin(SkTMax(coin1s->fT, coin1e->fT), SkTMax(coin2s->fT, coin2e->f
T)); |
| 387 return *overS < *overE; | 384 return *overS < *overE; |
| 388 } | 385 } |
| OLD | NEW |