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

Side by Side Diff: src/pathops/SkOpSpan.h

Issue 2128633003: pathops coincidence and security rewrite (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: require resulting t to be between 0 and 1 Created 4 years, 5 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 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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698