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 #ifndef SkOpSpan_DEFINED | 7 #ifndef SkOpSpan_DEFINED |
8 #define SkOpSpan_DEFINED | 8 #define SkOpSpan_DEFINED |
9 | 9 |
10 #include "SkPathOpsDebug.h" | 10 #include "SkPathOpsDebug.h" |
11 #include "SkPathOpsTypes.h" | 11 #include "SkPathOpsTypes.h" |
12 #include "SkPoint.h" | 12 #include "SkPoint.h" |
13 | 13 |
14 class SkChunkAlloc; | 14 class SkChunkAlloc; |
15 struct SkOpAngle; | 15 class SkOpAngle; |
16 class SkOpContour; | 16 class SkOpContour; |
17 class SkOpGlobalState; | 17 class SkOpGlobalState; |
18 class SkOpSegment; | 18 class SkOpSegment; |
19 class SkOpSpanBase; | 19 class SkOpSpanBase; |
20 class SkOpSpan; | 20 class SkOpSpan; |
| 21 struct SkPathOpsBounds; |
21 | 22 |
22 // subset of op span used by terminal span (when t is equal to one) | 23 // subset of op span used by terminal span (when t is equal to one) |
23 class SkOpPtT { | 24 class SkOpPtT { |
24 public: | 25 public: |
25 enum { | 26 enum { |
26 kIsAlias = 1, | 27 kIsAlias = 1, |
27 kIsDuplicate = 1 | 28 kIsDuplicate = 1 |
28 }; | 29 }; |
29 | 30 |
30 void addOpp(SkOpPtT* opp) { | 31 // please keep in sync with debugAddOpp() |
| 32 bool addOpp(SkOpPtT* opp) { |
31 // find the fOpp ptr to opp | 33 // find the fOpp ptr to opp |
32 SkOpPtT* oppPrev = opp->fNext; | 34 SkOpPtT* oppPrev = opp->fNext; |
33 if (oppPrev == this) { | 35 if (oppPrev == this) { |
34 return; | 36 return false; |
35 } | 37 } |
36 while (oppPrev->fNext != opp) { | 38 while (oppPrev->fNext != opp) { |
37 oppPrev = oppPrev->fNext; | 39 oppPrev = oppPrev->fNext; |
38 if (oppPrev == this) { | 40 if (oppPrev == this) { |
39 return; | 41 return false; |
40 } | 42 } |
41 } | 43 } |
42 | |
43 SkOpPtT* oldNext = this->fNext; | 44 SkOpPtT* oldNext = this->fNext; |
44 SkASSERT(this != opp); | 45 SkASSERT(this != opp); |
45 this->fNext = opp; | 46 this->fNext = opp; |
46 SkASSERT(oppPrev != oldNext); | 47 SkASSERT(oppPrev != oldNext); |
47 oppPrev->fNext = oldNext; | 48 oppPrev->fNext = oldNext; |
| 49 return true; |
48 } | 50 } |
49 | 51 |
50 bool alias() const; | 52 bool alias() const; |
| 53 bool coincident() const { return fCoincident; } |
51 bool collapsed(const SkOpPtT* ) const; | 54 bool collapsed(const SkOpPtT* ) const; |
52 bool contains(const SkOpPtT* ) const; | 55 bool contains(const SkOpPtT* ) const; |
53 SkOpPtT* contains(const SkOpSegment* ); | 56 bool contains(const SkOpSegment*, const SkPoint& ) const; |
| 57 bool contains(const SkOpSegment*, double t) const; |
| 58 const SkOpPtT* contains(const SkOpSegment* ) const; |
54 SkOpContour* contour() const; | 59 SkOpContour* contour() const; |
55 | 60 |
56 int debugID() const { | 61 int debugID() const { |
57 return SkDEBUGRELEASE(fID, -1); | 62 return SkDEBUGRELEASE(fID, -1); |
58 } | 63 } |
59 | 64 |
| 65 bool debugAddOpp(const SkOpPtT* opp) const; |
60 const SkOpAngle* debugAngle(int id) const; | 66 const SkOpAngle* debugAngle(int id) const; |
| 67 const SkOpCoincidence* debugCoincidence() const; |
61 bool debugContains(const SkOpPtT* ) const; | 68 bool debugContains(const SkOpPtT* ) const; |
62 const SkOpPtT* debugContains(const SkOpSegment* check) const; | 69 const SkOpPtT* debugContains(const SkOpSegment* check) const; |
63 SkOpContour* debugContour(int id); | 70 SkOpContour* debugContour(int id); |
64 int debugLoopLimit(bool report) const; | 71 int debugLoopLimit(bool report) const; |
65 bool debugMatchID(int id) const; | 72 bool debugMatchID(int id) const; |
66 const SkOpPtT* debugPtT(int id) const; | 73 const SkOpPtT* debugPtT(int id) const; |
67 const SkOpSegment* debugSegment(int id) const; | 74 const SkOpSegment* debugSegment(int id) const; |
68 const SkOpSpanBase* debugSpan(int id) const; | 75 const SkOpSpanBase* debugSpan(int id) const; |
69 void debugValidate() const; | 76 void debugValidate() const; |
70 | 77 |
71 bool deleted() const { | 78 bool deleted() const { |
72 return fDeleted; | 79 return fDeleted; |
73 } | 80 } |
74 | 81 |
75 SkOpPtT* doppelganger(); | |
76 | |
77 bool duplicate() const { | 82 bool duplicate() const { |
78 return fDuplicatePt; | 83 return fDuplicatePt; |
79 } | 84 } |
80 | 85 |
81 void dump() const; // available to testing only | 86 void dump() const; // available to testing only |
82 void dumpAll() const; | 87 void dumpAll() const; |
83 void dumpBase() const; | 88 void dumpBase() const; |
84 | 89 |
85 SkOpPtT* find(SkOpSegment* ); | 90 const SkOpPtT* find(const SkOpSegment* ) const; |
86 SkOpGlobalState* globalState() const; | 91 SkOpGlobalState* globalState() const; |
87 void init(SkOpSpanBase* , double t, const SkPoint& , bool dup); | 92 void init(SkOpSpanBase* , double t, const SkPoint& , bool dup); |
88 | 93 |
89 void insert(SkOpPtT* span) { | 94 void insert(SkOpPtT* span) { |
90 SkASSERT(span != this); | 95 SkASSERT(span != this); |
91 span->fNext = fNext; | 96 span->fNext = fNext; |
92 fNext = span; | 97 fNext = span; |
93 } | 98 } |
94 | 99 |
95 const SkOpPtT* next() const { | 100 const SkOpPtT* next() const { |
96 return fNext; | 101 return fNext; |
97 } | 102 } |
98 | 103 |
99 SkOpPtT* next() { | 104 SkOpPtT* next() { |
100 return fNext; | 105 return fNext; |
101 } | 106 } |
102 | 107 |
103 bool onEnd() const; | 108 bool onEnd() const; |
104 | 109 |
105 static bool Overlaps(SkOpPtT* s1, SkOpPtT* e1, SkOpPtT* s2, SkOpPtT* e2, | 110 static bool Overlaps(const SkOpPtT* s1, const SkOpPtT* e1, const SkOpPtT* s2
, |
106 SkOpPtT** sOut, SkOpPtT** eOut) { | 111 const SkOpPtT* e2, const SkOpPtT** sOut, const SkOpPtT** eOut) { |
107 SkOpPtT* start1 = s1->fT < e1->fT ? s1 : e1; | 112 const SkOpPtT* start1 = s1->fT < e1->fT ? s1 : e1; |
108 SkOpPtT* start2 = s2->fT < e2->fT ? s2 : e2; | 113 const SkOpPtT* start2 = s2->fT < e2->fT ? s2 : e2; |
109 *sOut = between(s1->fT, start2->fT, e1->fT) ? start2 | 114 *sOut = between(s1->fT, start2->fT, e1->fT) ? start2 |
110 : between(s2->fT, start1->fT, e2->fT) ? start1 : nullptr; | 115 : between(s2->fT, start1->fT, e2->fT) ? start1 : nullptr; |
111 SkOpPtT* end1 = s1->fT < e1->fT ? e1 : s1; | 116 const SkOpPtT* end1 = s1->fT < e1->fT ? e1 : s1; |
112 SkOpPtT* end2 = s2->fT < e2->fT ? e2 : s2; | 117 const SkOpPtT* end2 = s2->fT < e2->fT ? e2 : s2; |
113 *eOut = between(s1->fT, end2->fT, e1->fT) ? end2 | 118 *eOut = between(s1->fT, end2->fT, e1->fT) ? end2 |
114 : between(s2->fT, end1->fT, e2->fT) ? end1 : nullptr; | 119 : between(s2->fT, end1->fT, e2->fT) ? end1 : nullptr; |
115 if (*sOut == *eOut) { | 120 if (*sOut == *eOut) { |
116 SkASSERT(start1->fT >= end2->fT || start2->fT >= end1->fT); | 121 SkASSERT(start1->fT >= end2->fT || start2->fT >= end1->fT); |
117 return false; | 122 return false; |
118 } | 123 } |
119 SkASSERT(!*sOut || *sOut != *eOut); | 124 SkASSERT(!*sOut || *sOut != *eOut); |
120 return *sOut && *eOut; | 125 return *sOut && *eOut; |
121 } | 126 } |
122 | 127 |
| 128 bool ptAlreadySeen(const SkOpPtT* head) const; |
123 SkOpPtT* prev(); | 129 SkOpPtT* prev(); |
124 SkOpPtT* remove(); | 130 SkOpPtT* remove(const SkOpPtT* kept); |
125 void removeNext(SkOpPtT* kept); | 131 void removeNext(const SkOpPtT* kept); |
126 | 132 |
127 const SkOpSegment* segment() const; | 133 const SkOpSegment* segment() const; |
128 SkOpSegment* segment(); | 134 SkOpSegment* segment(); |
129 | 135 |
130 void setDeleted() { | 136 void setCoincident() const { |
131 SkASSERT(!fDeleted); | 137 SkASSERT(!fDeleted); |
132 fDeleted = true; | 138 fCoincident = true; |
| 139 } |
| 140 |
| 141 void setDeleted(); |
| 142 |
| 143 void setSpan(const SkOpSpanBase* span) { |
| 144 fSpan = const_cast<SkOpSpanBase*>(span); |
133 } | 145 } |
134 | 146 |
135 const SkOpSpanBase* span() const { | 147 const SkOpSpanBase* span() const { |
136 return fSpan; | 148 return fSpan; |
137 } | 149 } |
138 | 150 |
139 SkOpSpanBase* span() { | 151 SkOpSpanBase* span() { |
140 return fSpan; | 152 return fSpan; |
141 } | 153 } |
142 | 154 |
143 const SkOpPtT* starter(const SkOpPtT* end) const { | 155 const SkOpPtT* starter(const SkOpPtT* end) const { |
144 return fT < end->fT ? this : end; | 156 return fT < end->fT ? this : end; |
145 } | 157 } |
146 | 158 |
147 double fT; | 159 double fT; |
148 SkPoint fPt; // cache of point value at this t | 160 SkPoint fPt; // cache of point value at this t |
149 protected: | 161 protected: |
150 SkOpSpanBase* fSpan; // contains winding data | 162 SkOpSpanBase* fSpan; // contains winding data |
151 SkOpPtT* fNext; // intersection on opposite curve or alias on this curve | 163 SkOpPtT* fNext; // intersection on opposite curve or alias on this curve |
152 bool fDeleted; // set if removed from span list | 164 bool fDeleted; // set if removed from span list |
153 bool fDuplicatePt; // set if identical pt is somewhere in the next loop | 165 bool fDuplicatePt; // set if identical pt is somewhere in the next loop |
| 166 // below mutable since referrer is otherwise always const |
| 167 mutable bool fCoincident; // set if at some point a coincident span pointed
here |
154 SkDEBUGCODE(int fID); | 168 SkDEBUGCODE(int fID); |
155 }; | 169 }; |
156 | 170 |
157 class SkOpSpanBase { | 171 class SkOpSpanBase { |
158 public: | 172 public: |
159 void align(); | 173 void addOppAndMerge(SkOpSpanBase* ); |
160 | |
161 bool aligned() const { | |
162 return fAligned; | |
163 } | |
164 | |
165 void alignEnd(double t, const SkPoint& pt); | |
166 | 174 |
167 void bumpSpanAdds() { | 175 void bumpSpanAdds() { |
168 ++fSpanAdds; | 176 ++fSpanAdds; |
169 } | 177 } |
170 | 178 |
171 bool chased() const { | 179 bool chased() const { |
172 return fChased; | 180 return fChased; |
173 } | 181 } |
174 | 182 |
175 void clearCoinEnd() { | 183 void checkForCollapsedCoincidence(); |
176 SkASSERT(fCoinEnd != this); | |
177 fCoinEnd = this; | |
178 } | |
179 | 184 |
180 const SkOpSpanBase* coinEnd() const { | 185 const SkOpSpanBase* coinEnd() const { |
181 return fCoinEnd; | 186 return fCoinEnd; |
182 } | 187 } |
183 | 188 |
184 bool contains(const SkOpSpanBase* ) const; | 189 bool contains(const SkOpSpanBase* ) const; |
185 SkOpPtT* contains(const SkOpSegment* ); | 190 const SkOpPtT* contains(const SkOpSegment* ) const; |
186 | 191 |
187 bool containsCoinEnd(const SkOpSpanBase* coin) const { | 192 bool containsCoinEnd(const SkOpSpanBase* coin) const { |
188 SkASSERT(this != coin); | 193 SkASSERT(this != coin); |
189 const SkOpSpanBase* next = this; | 194 const SkOpSpanBase* next = this; |
190 while ((next = next->fCoinEnd) != this) { | 195 while ((next = next->fCoinEnd) != this) { |
191 if (next == coin) { | 196 if (next == coin) { |
192 return true; | 197 return true; |
193 } | 198 } |
194 } | 199 } |
195 return false; | 200 return false; |
196 } | 201 } |
197 | 202 |
198 bool containsCoinEnd(const SkOpSegment* ) const; | 203 bool containsCoinEnd(const SkOpSegment* ) const; |
199 SkOpContour* contour() const; | 204 SkOpContour* contour() const; |
200 | 205 |
| 206 #if DEBUG_COINCIDENCE_VERBOSE |
| 207 void debugAddOppAndMerge(const char* id, SkPathOpsDebug::GlitchLog* , const
SkOpSpanBase* , |
| 208 bool* del1, bool* del2) const; |
| 209 #endif |
| 210 |
201 int debugBumpCount() { | 211 int debugBumpCount() { |
202 return SkDEBUGRELEASE(++fCount, -1); | 212 return SkDEBUGRELEASE(++fCount, -1); |
203 } | 213 } |
204 | 214 |
205 int debugID() const { | 215 int debugID() const { |
206 return SkDEBUGRELEASE(fID, -1); | 216 return SkDEBUGRELEASE(fID, -1); |
207 } | 217 } |
208 | 218 |
209 bool debugAlignedEnd(double t, const SkPoint& pt) const; | 219 bool debugAlignedEnd(double t, const SkPoint& pt) const; |
210 bool debugAlignedInner() const; | 220 bool debugAlignedInner() const; |
211 const SkOpAngle* debugAngle(int id) const; | 221 const SkOpAngle* debugAngle(int id) const; |
| 222 #if DEBUG_COINCIDENCE_VERBOSE |
| 223 void debugCheckForCollapsedCoincidence(const char* id, SkPathOpsDebug::Glitc
hLog* ) const; |
| 224 #endif |
| 225 const SkOpCoincidence* debugCoincidence() const; |
212 bool debugCoinEndLoopCheck() const; | 226 bool debugCoinEndLoopCheck() const; |
213 bool debugContains(const SkOpSegment* ) const; | |
214 SkOpContour* debugContour(int id); | 227 SkOpContour* debugContour(int id); |
| 228 #ifdef SK_DEBUG |
| 229 bool debugDeleted() const { return fDeleted; } |
| 230 #endif |
| 231 #if DEBUG_COINCIDENCE_VERBOSE |
| 232 void debugInsertCoinEnd(const char* id, SkPathOpsDebug::GlitchLog* , |
| 233 const SkOpSpanBase* ) const; |
| 234 void debugMergeContained(const char* id, SkPathOpsDebug::GlitchLog* , |
| 235 const SkPathOpsBounds& bounds, bool* deleted) const
; |
| 236 #endif |
215 const SkOpPtT* debugPtT(int id) const; | 237 const SkOpPtT* debugPtT(int id) const; |
216 const SkOpSegment* debugSegment(int id) const; | 238 const SkOpSegment* debugSegment(int id) const; |
217 const SkOpSpanBase* debugSpan(int id) const; | 239 const SkOpSpanBase* debugSpan(int id) const; |
218 const SkOpSpan* debugStarter(SkOpSpanBase const** endPtr) const; | 240 const SkOpSpan* debugStarter(SkOpSpanBase const** endPtr) const; |
219 SkOpGlobalState* globalState() const; | 241 SkOpGlobalState* globalState() const; |
220 void debugValidate() const; | 242 void debugValidate() const; |
221 | 243 |
222 bool deleted() const { | 244 bool deleted() const { |
223 return fPtT.deleted(); | 245 return fPtT.deleted(); |
224 } | 246 } |
225 | 247 |
226 void dump() const; // available to testing only | 248 void dump() const; // available to testing only |
227 void dumpCoin() const; | 249 void dumpCoin() const; |
228 void dumpAll() const; | 250 void dumpAll() const; |
229 void dumpBase() const; | 251 void dumpBase() const; |
| 252 void dumpHead() const; |
230 | 253 |
231 bool final() const { | 254 bool final() const { |
232 return fPtT.fT == 1; | 255 return fPtT.fT == 1; |
233 } | 256 } |
234 | 257 |
235 SkOpAngle* fromAngle() const { | 258 SkOpAngle* fromAngle() const { |
236 return fFromAngle; | 259 return fFromAngle; |
237 } | 260 } |
238 | 261 |
239 void initBase(SkOpSegment* parent, SkOpSpan* prev, double t, const SkPoint&
pt); | 262 void initBase(SkOpSegment* parent, SkOpSpan* prev, double t, const SkPoint&
pt); |
240 | 263 |
| 264 // Please keep this in sync with debugInsertCoinEnd() |
241 void insertCoinEnd(SkOpSpanBase* coin) { | 265 void insertCoinEnd(SkOpSpanBase* coin) { |
242 if (containsCoinEnd(coin)) { | 266 if (containsCoinEnd(coin)) { |
243 SkASSERT(coin->containsCoinEnd(this)); | 267 SkASSERT(coin->containsCoinEnd(this)); |
244 return; | 268 return; |
245 } | 269 } |
246 debugValidate(); | 270 debugValidate(); |
247 SkASSERT(this != coin); | 271 SkASSERT(this != coin); |
248 SkOpSpanBase* coinNext = coin->fCoinEnd; | 272 SkOpSpanBase* coinNext = coin->fCoinEnd; |
249 coin->fCoinEnd = this->fCoinEnd; | 273 coin->fCoinEnd = this->fCoinEnd; |
250 this->fCoinEnd = coinNext; | 274 this->fCoinEnd = coinNext; |
251 debugValidate(); | 275 debugValidate(); |
252 } | 276 } |
253 | 277 |
254 void merge(SkOpSpan* span); | 278 void merge(SkOpSpan* span); |
| 279 void mergeContained(const SkPathOpsBounds& bounds); |
255 | 280 |
256 SkOpSpan* prev() const { | 281 const SkOpSpan* prev() const { |
257 return fPrev; | 282 return fPrev; |
258 } | 283 } |
259 | 284 |
| 285 SkOpSpan* prev() { |
| 286 return fPrev; |
| 287 } |
| 288 |
260 const SkPoint& pt() const { | 289 const SkPoint& pt() const { |
261 return fPtT.fPt; | 290 return fPtT.fPt; |
262 } | 291 } |
263 | 292 |
264 const SkOpPtT* ptT() const { | 293 const SkOpPtT* ptT() const { |
265 return &fPtT; | 294 return &fPtT; |
266 } | 295 } |
267 | 296 |
268 SkOpPtT* ptT() { | 297 SkOpPtT* ptT() { |
269 return &fPtT; | 298 return &fPtT; |
270 } | 299 } |
271 | 300 |
272 SkOpSegment* segment() const { | 301 SkOpSegment* segment() const { |
273 return fSegment; | 302 return fSegment; |
274 } | 303 } |
275 | 304 |
276 void setAligned() { | 305 void setAligned() { |
277 fAligned = true; | 306 fAligned = true; |
278 } | 307 } |
279 | 308 |
280 void setChased(bool chased) { | 309 void setChased(bool chased) { |
281 fChased = chased; | 310 fChased = chased; |
282 } | 311 } |
283 | 312 |
284 SkOpPtT* setCoinEnd(SkOpSpanBase* oldCoinEnd, SkOpSegment* oppSegment); | |
285 | |
286 void setFromAngle(SkOpAngle* angle) { | 313 void setFromAngle(SkOpAngle* angle) { |
287 fFromAngle = angle; | 314 fFromAngle = angle; |
288 } | 315 } |
289 | 316 |
290 void setPrev(SkOpSpan* prev) { | 317 void setPrev(SkOpSpan* prev) { |
291 fPrev = prev; | 318 fPrev = prev; |
292 } | 319 } |
293 | 320 |
294 bool simple() const { | 321 bool simple() const { |
295 fPtT.debugValidate(); | 322 fPtT.debugValidate(); |
296 return fPtT.next()->next() == &fPtT; | 323 return fPtT.next()->next() == &fPtT; |
297 } | 324 } |
298 | 325 |
299 int spanAddsCount() const { | 326 int spanAddsCount() const { |
300 return fSpanAdds; | 327 return fSpanAdds; |
301 } | 328 } |
302 | 329 |
303 const SkOpSpan* starter(const SkOpSpanBase* end) const { | 330 const SkOpSpan* starter(const SkOpSpanBase* end) const { |
304 const SkOpSpanBase* result = t() < end->t() ? this : end; | 331 const SkOpSpanBase* result = t() < end->t() ? this : end; |
305 return result->upCast(); | 332 return result->upCast(); |
306 } | 333 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 SkOpPtT fPtT; // list of points and t values associated with the start of t
his span | 388 SkOpPtT fPtT; // list of points and t values associated with the start of t
his span |
362 SkOpSegment* fSegment; // segment that contains this span | 389 SkOpSegment* fSegment; // segment that contains this span |
363 SkOpSpanBase* fCoinEnd; // linked list of coincident spans that end here (m
ay point to itself) | 390 SkOpSpanBase* fCoinEnd; // linked list of coincident spans that end here (m
ay point to itself) |
364 SkOpAngle* fFromAngle; // points to next angle from span start to end | 391 SkOpAngle* fFromAngle; // points to next angle from span start to end |
365 SkOpSpan* fPrev; // previous intersection point | 392 SkOpSpan* fPrev; // previous intersection point |
366 int fSpanAdds; // number of times intersections have been added to span | 393 int fSpanAdds; // number of times intersections have been added to span |
367 bool fAligned; | 394 bool fAligned; |
368 bool fChased; // set after span has been added to chase array | 395 bool fChased; // set after span has been added to chase array |
369 SkDEBUGCODE(int fCount); // number of pt/t pairs added | 396 SkDEBUGCODE(int fCount); // number of pt/t pairs added |
370 SkDEBUGCODE(int fID); | 397 SkDEBUGCODE(int fID); |
| 398 SkDEBUGCODE(bool fDeleted); // set when span was merged with another span |
371 }; | 399 }; |
372 | 400 |
373 class SkOpSpan : public SkOpSpanBase { | 401 class SkOpSpan : public SkOpSpanBase { |
374 public: | 402 public: |
375 bool alreadyAdded() const { | 403 bool alreadyAdded() const { |
376 if (fAlreadyAdded) { | 404 if (fAlreadyAdded) { |
377 return true; | 405 return true; |
378 } | 406 } |
379 fAlreadyAdded = true; | 407 fAlreadyAdded = true; |
380 return false; | 408 return false; |
(...skipping 16 matching lines...) Expand all Loading... |
397 const SkOpSpan* next = this; | 425 const SkOpSpan* next = this; |
398 while ((next = next->fCoincident) != this) { | 426 while ((next = next->fCoincident) != this) { |
399 if (next == coin) { | 427 if (next == coin) { |
400 return true; | 428 return true; |
401 } | 429 } |
402 } | 430 } |
403 return false; | 431 return false; |
404 } | 432 } |
405 | 433 |
406 bool debugCoinLoopCheck() const; | 434 bool debugCoinLoopCheck() const; |
407 void release(SkOpPtT* ); | 435 #if DEBUG_COINCIDENCE_VERBOSE |
| 436 void debugInsertCoincidence(const char* , SkPathOpsDebug::GlitchLog* , const
SkOpSpan* ) const; |
| 437 void debugInsertCoincidence(const char* , SkPathOpsDebug::GlitchLog* , |
| 438 const SkOpSegment* , bool flipped) const; |
| 439 #endif |
| 440 void release(const SkOpPtT* ); |
408 | 441 |
409 bool done() const { | 442 bool done() const { |
410 SkASSERT(!final()); | 443 SkASSERT(!final()); |
411 return fDone; | 444 return fDone; |
412 } | 445 } |
413 | 446 |
414 void dumpCoin() const; | 447 void dumpCoin() const; |
415 bool dumpSpan() const; | 448 bool dumpSpan() const; |
416 void init(SkOpSegment* parent, SkOpSpan* prev, double t, const SkPoint& pt); | 449 void init(SkOpSegment* parent, SkOpSpan* prev, double t, const SkPoint& pt); |
| 450 bool insertCoincidence(const SkOpSegment* , bool flipped); |
417 | 451 |
| 452 // Please keep this in sync with debugInsertCoincidence() |
418 void insertCoincidence(SkOpSpan* coin) { | 453 void insertCoincidence(SkOpSpan* coin) { |
419 if (containsCoincidence(coin)) { | 454 if (containsCoincidence(coin)) { |
420 SkASSERT(coin->containsCoincidence(this)); | 455 SkASSERT(coin->containsCoincidence(this)); |
421 return; | 456 return; |
422 } | 457 } |
423 debugValidate(); | 458 debugValidate(); |
424 SkASSERT(this != coin); | 459 SkASSERT(this != coin); |
425 SkOpSpan* coinNext = coin->fCoincident; | 460 SkOpSpan* coinNext = coin->fCoincident; |
426 coin->fCoincident = this->fCoincident; | 461 coin->fCoincident = this->fCoincident; |
427 this->fCoincident = coinNext; | 462 this->fCoincident = coinNext; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 void setNext(SkOpSpanBase* nextT) { | 498 void setNext(SkOpSpanBase* nextT) { |
464 SkASSERT(!final()); | 499 SkASSERT(!final()); |
465 fNext = nextT; | 500 fNext = nextT; |
466 } | 501 } |
467 | 502 |
468 void setOppSum(int oppSum); | 503 void setOppSum(int oppSum); |
469 | 504 |
470 void setOppValue(int oppValue) { | 505 void setOppValue(int oppValue) { |
471 SkASSERT(!final()); | 506 SkASSERT(!final()); |
472 SkASSERT(fOppSum == SK_MinS32); | 507 SkASSERT(fOppSum == SK_MinS32); |
| 508 SkASSERT(!oppValue || !fDone); |
473 fOppValue = oppValue; | 509 fOppValue = oppValue; |
474 } | 510 } |
475 | 511 |
476 void setToAngle(SkOpAngle* angle) { | 512 void setToAngle(SkOpAngle* angle) { |
477 SkASSERT(!final()); | 513 SkASSERT(!final()); |
478 fToAngle = angle; | 514 fToAngle = angle; |
479 } | 515 } |
480 | 516 |
481 void setWindSum(int windSum); | 517 void setWindSum(int windSum); |
482 | 518 |
483 void setWindValue(int windValue) { | 519 void setWindValue(int windValue) { |
484 SkASSERT(!final()); | 520 SkASSERT(!final()); |
485 SkASSERT(windValue >= 0); | 521 SkASSERT(windValue >= 0); |
486 SkASSERT(fWindSum == SK_MinS32); | 522 SkASSERT(fWindSum == SK_MinS32); |
| 523 SkASSERT(!windValue || !fDone); |
487 fWindValue = windValue; | 524 fWindValue = windValue; |
488 } | 525 } |
489 | 526 |
490 bool sortableTop(SkOpContour* ); | 527 bool sortableTop(SkOpContour* ); |
491 | 528 |
492 SkOpAngle* toAngle() const { | 529 SkOpAngle* toAngle() const { |
493 SkASSERT(!final()); | 530 SkASSERT(!final()); |
494 return fToAngle; | 531 return fToAngle; |
495 } | 532 } |
496 | 533 |
(...skipping 14 matching lines...) Expand all Loading... |
511 int fWindSum; // accumulated from contours surrounding this one. | 548 int fWindSum; // accumulated from contours surrounding this one. |
512 int fOppSum; // for binary operators: the opposite winding sum | 549 int fOppSum; // for binary operators: the opposite winding sum |
513 int fWindValue; // 0 == canceled; 1 == normal; >1 == coincident | 550 int fWindValue; // 0 == canceled; 1 == normal; >1 == coincident |
514 int fOppValue; // normally 0 -- when binary coincident edges combine, opp v
alue goes here | 551 int fOppValue; // normally 0 -- when binary coincident edges combine, opp v
alue goes here |
515 int fTopTTry; // specifies direction and t value to try next | 552 int fTopTTry; // specifies direction and t value to try next |
516 bool fDone; // if set, this span to next higher T has been processed | 553 bool fDone; // if set, this span to next higher T has been processed |
517 mutable bool fAlreadyAdded; | 554 mutable bool fAlreadyAdded; |
518 }; | 555 }; |
519 | 556 |
520 #endif | 557 #endif |
OLD | NEW |