Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(346)

Side by Side Diff: src/pathops/SkOpCoincidence.cpp

Issue 1037953004: add conics to path ops (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix linux build Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698