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" |
(...skipping 10 matching lines...) Expand all Loading... |
21 struct SkPathOpsBounds; | 21 struct SkPathOpsBounds; |
22 | 22 |
23 // 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) |
24 class SkOpPtT { | 24 class SkOpPtT { |
25 public: | 25 public: |
26 enum { | 26 enum { |
27 kIsAlias = 1, | 27 kIsAlias = 1, |
28 kIsDuplicate = 1 | 28 kIsDuplicate = 1 |
29 }; | 29 }; |
30 | 30 |
| 31 const SkOpPtT* active() const; |
| 32 |
31 // please keep in sync with debugAddOpp() | 33 // please keep in sync with debugAddOpp() |
32 void addOpp(SkOpPtT* opp, SkOpPtT* oppPrev) { | 34 void addOpp(SkOpPtT* opp, SkOpPtT* oppPrev) { |
33 SkOpPtT* oldNext = this->fNext; | 35 SkOpPtT* oldNext = this->fNext; |
34 SkASSERT(this != opp); | 36 SkASSERT(this != opp); |
35 this->fNext = opp; | 37 this->fNext = opp; |
36 SkASSERT(oppPrev != oldNext); | 38 SkASSERT(oppPrev != oldNext); |
37 oppPrev->fNext = oldNext; | 39 oppPrev->fNext = oldNext; |
38 } | 40 } |
39 | 41 |
40 bool alias() const; | 42 bool alias() const; |
41 bool coincident() const { return fCoincident; } | 43 bool coincident() const { return fCoincident; } |
42 bool collapsed(const SkOpPtT* ) const; | 44 bool collapsed(const SkOpPtT* ) const; |
43 bool contains(const SkOpPtT* ) const; | 45 bool contains(const SkOpPtT* ) const; |
44 bool contains(const SkOpSegment*, const SkPoint& ) const; | 46 bool contains(const SkOpSegment*, const SkPoint& ) const; |
45 bool contains(const SkOpSegment*, double t) const; | 47 bool contains(const SkOpSegment*, double t) const; |
46 const SkOpPtT* contains(const SkOpSegment* ) const; | 48 const SkOpPtT* contains(const SkOpSegment* ) const; |
47 SkOpContour* contour() const; | 49 SkOpContour* contour() const; |
48 | 50 |
49 int debugID() const { | 51 int debugID() const { |
50 return SkDEBUGRELEASE(fID, -1); | 52 return SkDEBUGRELEASE(fID, -1); |
51 } | 53 } |
52 | 54 |
53 void debugAddOpp(const SkOpPtT* opp, const SkOpPtT* oppPrev) const; | 55 void debugAddOpp(const SkOpPtT* opp, const SkOpPtT* oppPrev) const; |
54 const SkOpAngle* debugAngle(int id) const; | 56 const SkOpAngle* debugAngle(int id) const; |
55 const SkOpCoincidence* debugCoincidence() const; | 57 const SkOpCoincidence* debugCoincidence() const; |
56 bool debugContains(const SkOpPtT* ) const; | 58 bool debugContains(const SkOpPtT* ) const; |
57 const SkOpPtT* debugContains(const SkOpSegment* check) const; | 59 const SkOpPtT* debugContains(const SkOpSegment* check) const; |
58 SkOpContour* debugContour(int id); | 60 SkOpContour* debugContour(int id) const; |
59 int debugLoopLimit(bool report) const; | 61 int debugLoopLimit(bool report) const; |
60 bool debugMatchID(int id) const; | 62 bool debugMatchID(int id) const; |
61 const SkOpPtT* debugOppPrev(const SkOpPtT* opp) const; | 63 const SkOpPtT* debugOppPrev(const SkOpPtT* opp) const; |
62 const SkOpPtT* debugPtT(int id) const; | 64 const SkOpPtT* debugPtT(int id) const; |
63 void debugResetCoinT() const; | 65 void debugResetCoinT() const; |
64 const SkOpSegment* debugSegment(int id) const; | 66 const SkOpSegment* debugSegment(int id) const; |
65 void debugSetCoinT(int ) const; | 67 void debugSetCoinT(int ) const; |
66 const SkOpSpanBase* debugSpan(int id) const; | 68 const SkOpSpanBase* debugSpan(int id) const; |
67 void debugValidate() const; | 69 void debugValidate() const; |
68 | 70 |
(...skipping 22 matching lines...) Expand all Loading... |
91 const SkOpPtT* next() const { | 93 const SkOpPtT* next() const { |
92 return fNext; | 94 return fNext; |
93 } | 95 } |
94 | 96 |
95 SkOpPtT* next() { | 97 SkOpPtT* next() { |
96 return fNext; | 98 return fNext; |
97 } | 99 } |
98 | 100 |
99 bool onEnd() const; | 101 bool onEnd() const; |
100 | 102 |
101 SkOpPtT* oppPrev(SkOpPtT* opp) const { | 103 // returns nullptr if this is already in the opp ptT loop |
| 104 SkOpPtT* oppPrev(const SkOpPtT* opp) const { |
102 // find the fOpp ptr to opp | 105 // find the fOpp ptr to opp |
103 SkOpPtT* oppPrev = opp->fNext; | 106 SkOpPtT* oppPrev = opp->fNext; |
104 if (oppPrev == this) { | 107 if (oppPrev == this) { |
105 return nullptr; | 108 return nullptr; |
106 } | 109 } |
107 while (oppPrev->fNext != opp) { | 110 while (oppPrev->fNext != opp) { |
108 oppPrev = oppPrev->fNext; | 111 oppPrev = oppPrev->fNext; |
109 if (oppPrev == this) { | 112 if (oppPrev == this) { |
110 return nullptr; | 113 return nullptr; |
111 } | 114 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 SkOpPtT* fNext; // intersection on opposite curve or alias on this curve | 172 SkOpPtT* fNext; // intersection on opposite curve or alias on this curve |
170 bool fDeleted; // set if removed from span list | 173 bool fDeleted; // set if removed from span list |
171 bool fDuplicatePt; // set if identical pt is somewhere in the next loop | 174 bool fDuplicatePt; // set if identical pt is somewhere in the next loop |
172 // below mutable since referrer is otherwise always const | 175 // below mutable since referrer is otherwise always const |
173 mutable bool fCoincident; // set if at some point a coincident span pointed
here | 176 mutable bool fCoincident; // set if at some point a coincident span pointed
here |
174 SkDEBUGCODE(int fID); | 177 SkDEBUGCODE(int fID); |
175 }; | 178 }; |
176 | 179 |
177 class SkOpSpanBase { | 180 class SkOpSpanBase { |
178 public: | 181 public: |
179 void addOppAndMerge(SkOpSpanBase* ); | 182 SkOpSpanBase* active(); |
| 183 void addOpp(SkOpSpanBase* opp); |
180 | 184 |
181 void bumpSpanAdds() { | 185 void bumpSpanAdds() { |
182 ++fSpanAdds; | 186 ++fSpanAdds; |
183 } | 187 } |
184 | 188 |
185 bool chased() const { | 189 bool chased() const { |
186 return fChased; | 190 return fChased; |
187 } | 191 } |
188 | 192 |
189 void checkForCollapsedCoincidence(); | 193 void checkForCollapsedCoincidence(); |
190 | 194 |
191 const SkOpSpanBase* coinEnd() const { | 195 const SkOpSpanBase* coinEnd() const { |
192 return fCoinEnd; | 196 return fCoinEnd; |
193 } | 197 } |
194 | 198 |
| 199 bool collapsed(double s, double e) const; |
195 bool contains(const SkOpSpanBase* ) const; | 200 bool contains(const SkOpSpanBase* ) const; |
196 const SkOpPtT* contains(const SkOpSegment* ) const; | 201 const SkOpPtT* contains(const SkOpSegment* ) const; |
197 | 202 |
198 bool containsCoinEnd(const SkOpSpanBase* coin) const { | 203 bool containsCoinEnd(const SkOpSpanBase* coin) const { |
199 SkASSERT(this != coin); | 204 SkASSERT(this != coin); |
200 const SkOpSpanBase* next = this; | 205 const SkOpSpanBase* next = this; |
201 while ((next = next->fCoinEnd) != this) { | 206 while ((next = next->fCoinEnd) != this) { |
202 if (next == coin) { | 207 if (next == coin) { |
203 return true; | 208 return true; |
204 } | 209 } |
205 } | 210 } |
206 return false; | 211 return false; |
207 } | 212 } |
208 | 213 |
209 bool containsCoinEnd(const SkOpSegment* ) const; | 214 bool containsCoinEnd(const SkOpSegment* ) const; |
210 SkOpContour* contour() const; | 215 SkOpContour* contour() const; |
211 | 216 |
212 #if DEBUG_COINCIDENCE_VERBOSE | |
213 void debugAddOppAndMerge(const char* id, SkPathOpsDebug::GlitchLog* , const
SkOpSpanBase* , | |
214 bool* del1, bool* del2) const; | |
215 #endif | |
216 | |
217 int debugBumpCount() { | 217 int debugBumpCount() { |
218 return SkDEBUGRELEASE(++fCount, -1); | 218 return SkDEBUGRELEASE(++fCount, -1); |
219 } | 219 } |
220 | 220 |
221 int debugID() const { | 221 int debugID() const { |
222 return SkDEBUGRELEASE(fID, -1); | 222 return SkDEBUGRELEASE(fID, -1); |
223 } | 223 } |
224 | 224 |
| 225 #if DEBUG_COINCIDENCE_VERBOSE |
| 226 void debugAddOpp(const char* id, SkPathOpsDebug::GlitchLog* , const SkOpSpan
Base* opp) const; |
| 227 #endif |
225 bool debugAlignedEnd(double t, const SkPoint& pt) const; | 228 bool debugAlignedEnd(double t, const SkPoint& pt) const; |
226 bool debugAlignedInner() const; | 229 bool debugAlignedInner() const; |
227 const SkOpAngle* debugAngle(int id) const; | 230 const SkOpAngle* debugAngle(int id) const; |
228 #if DEBUG_COINCIDENCE_VERBOSE | 231 #if DEBUG_COINCIDENCE_VERBOSE |
229 void debugCheckForCollapsedCoincidence(const char* id, SkPathOpsDebug::Glitc
hLog* ) const; | 232 void debugCheckForCollapsedCoincidence(const char* id, SkPathOpsDebug::Glitc
hLog* ) const; |
230 #endif | 233 #endif |
231 const SkOpCoincidence* debugCoincidence() const; | 234 const SkOpCoincidence* debugCoincidence() const; |
232 bool debugCoinEndLoopCheck() const; | 235 bool debugCoinEndLoopCheck() const; |
233 SkOpContour* debugContour(int id); | 236 SkOpContour* debugContour(int id) const; |
234 #ifdef SK_DEBUG | 237 #ifdef SK_DEBUG |
235 bool debugDeleted() const { return fDeleted; } | 238 bool debugDeleted() const { return fDebugDeleted; } |
236 #endif | 239 #endif |
237 #if DEBUG_COINCIDENCE_VERBOSE | 240 #if DEBUG_COINCIDENCE_VERBOSE |
238 void debugInsertCoinEnd(const char* id, SkPathOpsDebug::GlitchLog* , | 241 void debugInsertCoinEnd(const char* id, SkPathOpsDebug::GlitchLog* , |
239 const SkOpSpanBase* ) const; | 242 const SkOpSpanBase* ) const; |
240 void debugMergeContained(const char* id, SkPathOpsDebug::GlitchLog* , | 243 void debugMergeContained(const char* id, SkPathOpsDebug::GlitchLog* , |
241 const SkPathOpsBounds& bounds, bool* deleted) const
; | 244 const SkPathOpsBounds& bounds, bool* deleted) const
; |
| 245 void debugMergeMatches(const char* id, SkPathOpsDebug::GlitchLog* log, |
| 246 const SkOpSpanBase* opp) const; |
242 #endif | 247 #endif |
243 const SkOpPtT* debugPtT(int id) const; | 248 const SkOpPtT* debugPtT(int id) const; |
244 void debugResetCoinT() const; | 249 void debugResetCoinT() const; |
245 const SkOpSegment* debugSegment(int id) const; | 250 const SkOpSegment* debugSegment(int id) const; |
246 void debugSetCoinT(int ) const; | 251 void debugSetCoinT(int ) const; |
| 252 #ifdef SK_DEBUG |
| 253 void debugSetDeleted() { fDebugDeleted = true; } |
| 254 #endif |
247 const SkOpSpanBase* debugSpan(int id) const; | 255 const SkOpSpanBase* debugSpan(int id) const; |
248 const SkOpSpan* debugStarter(SkOpSpanBase const** endPtr) const; | 256 const SkOpSpan* debugStarter(SkOpSpanBase const** endPtr) const; |
249 SkOpGlobalState* globalState() const; | 257 SkOpGlobalState* globalState() const; |
250 void debugValidate() const; | 258 void debugValidate() const; |
251 | 259 |
252 bool deleted() const { | 260 bool deleted() const { |
253 return fPtT.deleted(); | 261 return fPtT.deleted(); |
254 } | 262 } |
255 | 263 |
256 void dump() const; // available to testing only | 264 void dump() const; // available to testing only |
(...skipping 21 matching lines...) Expand all Loading... |
278 debugValidate(); | 286 debugValidate(); |
279 SkASSERT(this != coin); | 287 SkASSERT(this != coin); |
280 SkOpSpanBase* coinNext = coin->fCoinEnd; | 288 SkOpSpanBase* coinNext = coin->fCoinEnd; |
281 coin->fCoinEnd = this->fCoinEnd; | 289 coin->fCoinEnd = this->fCoinEnd; |
282 this->fCoinEnd = coinNext; | 290 this->fCoinEnd = coinNext; |
283 debugValidate(); | 291 debugValidate(); |
284 } | 292 } |
285 | 293 |
286 void merge(SkOpSpan* span); | 294 void merge(SkOpSpan* span); |
287 void mergeContained(const SkPathOpsBounds& bounds); | 295 void mergeContained(const SkPathOpsBounds& bounds); |
| 296 void mergeMatches(SkOpSpanBase* opp); |
288 | 297 |
289 const SkOpSpan* prev() const { | 298 const SkOpSpan* prev() const { |
290 return fPrev; | 299 return fPrev; |
291 } | 300 } |
292 | 301 |
293 SkOpSpan* prev() { | 302 SkOpSpan* prev() { |
294 return fPrev; | 303 return fPrev; |
295 } | 304 } |
296 | 305 |
297 const SkPoint& pt() const { | 306 const SkPoint& pt() const { |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 SkOpPtT fPtT; // list of points and t values associated with the start of t
his span | 405 SkOpPtT fPtT; // list of points and t values associated with the start of t
his span |
397 SkOpSegment* fSegment; // segment that contains this span | 406 SkOpSegment* fSegment; // segment that contains this span |
398 SkOpSpanBase* fCoinEnd; // linked list of coincident spans that end here (m
ay point to itself) | 407 SkOpSpanBase* fCoinEnd; // linked list of coincident spans that end here (m
ay point to itself) |
399 SkOpAngle* fFromAngle; // points to next angle from span start to end | 408 SkOpAngle* fFromAngle; // points to next angle from span start to end |
400 SkOpSpan* fPrev; // previous intersection point | 409 SkOpSpan* fPrev; // previous intersection point |
401 int fSpanAdds; // number of times intersections have been added to span | 410 int fSpanAdds; // number of times intersections have been added to span |
402 bool fAligned; | 411 bool fAligned; |
403 bool fChased; // set after span has been added to chase array | 412 bool fChased; // set after span has been added to chase array |
404 SkDEBUGCODE(int fCount); // number of pt/t pairs added | 413 SkDEBUGCODE(int fCount); // number of pt/t pairs added |
405 SkDEBUGCODE(int fID); | 414 SkDEBUGCODE(int fID); |
406 SkDEBUGCODE(bool fDeleted); // set when span was merged with another span | 415 SkDEBUGCODE(bool fDebugDeleted); // set when span was merged with another s
pan |
407 }; | 416 }; |
408 | 417 |
409 class SkOpSpan : public SkOpSpanBase { | 418 class SkOpSpan : public SkOpSpanBase { |
410 public: | 419 public: |
411 bool alreadyAdded() const { | 420 bool alreadyAdded() const { |
412 if (fAlreadyAdded) { | 421 if (fAlreadyAdded) { |
413 return true; | 422 return true; |
414 } | 423 } |
415 fAlreadyAdded = true; | 424 fAlreadyAdded = true; |
416 return false; | 425 return false; |
(...skipping 21 matching lines...) Expand all Loading... |
438 } | 447 } |
439 return false; | 448 return false; |
440 } | 449 } |
441 | 450 |
442 bool debugCoinLoopCheck() const; | 451 bool debugCoinLoopCheck() const; |
443 #if DEBUG_COINCIDENCE_VERBOSE | 452 #if DEBUG_COINCIDENCE_VERBOSE |
444 void debugInsertCoincidence(const char* , SkPathOpsDebug::GlitchLog* , const
SkOpSpan* ) const; | 453 void debugInsertCoincidence(const char* , SkPathOpsDebug::GlitchLog* , const
SkOpSpan* ) const; |
445 void debugInsertCoincidence(const char* , SkPathOpsDebug::GlitchLog* , | 454 void debugInsertCoincidence(const char* , SkPathOpsDebug::GlitchLog* , |
446 const SkOpSegment* , bool flipped) const; | 455 const SkOpSegment* , bool flipped) const; |
447 #endif | 456 #endif |
448 void release(const SkOpPtT* ); | 457 void dumpCoin() const; |
| 458 bool dumpSpan() const; |
449 | 459 |
450 bool done() const { | 460 bool done() const { |
451 SkASSERT(!final()); | 461 SkASSERT(!final()); |
452 return fDone; | 462 return fDone; |
453 } | 463 } |
454 | 464 |
455 void dumpCoin() const; | |
456 bool dumpSpan() const; | |
457 void init(SkOpSegment* parent, SkOpSpan* prev, double t, const SkPoint& pt); | 465 void init(SkOpSegment* parent, SkOpSpan* prev, double t, const SkPoint& pt); |
458 bool insertCoincidence(const SkOpSegment* , bool flipped); | 466 bool insertCoincidence(const SkOpSegment* , bool flipped); |
459 | 467 |
460 // Please keep this in sync with debugInsertCoincidence() | 468 // Please keep this in sync with debugInsertCoincidence() |
461 void insertCoincidence(SkOpSpan* coin) { | 469 void insertCoincidence(SkOpSpan* coin) { |
462 if (containsCoincidence(coin)) { | 470 if (containsCoincidence(coin)) { |
463 SkASSERT(coin->containsCoincidence(this)); | 471 SkASSERT(coin->containsCoincidence(this)); |
464 return; | 472 return; |
465 } | 473 } |
466 debugValidate(); | 474 debugValidate(); |
(...skipping 22 matching lines...) Expand all Loading... |
489 int oppSum() const { | 497 int oppSum() const { |
490 SkASSERT(!final()); | 498 SkASSERT(!final()); |
491 return fOppSum; | 499 return fOppSum; |
492 } | 500 } |
493 | 501 |
494 int oppValue() const { | 502 int oppValue() const { |
495 SkASSERT(!final()); | 503 SkASSERT(!final()); |
496 return fOppValue; | 504 return fOppValue; |
497 } | 505 } |
498 | 506 |
| 507 void release(const SkOpPtT* ); |
| 508 |
499 SkOpPtT* setCoinStart(SkOpSpan* oldCoinStart, SkOpSegment* oppSegment); | 509 SkOpPtT* setCoinStart(SkOpSpan* oldCoinStart, SkOpSegment* oppSegment); |
500 | 510 |
501 void setDone(bool done) { | 511 void setDone(bool done) { |
502 SkASSERT(!final()); | 512 SkASSERT(!final()); |
503 fDone = done; | 513 fDone = done; |
504 } | 514 } |
505 | 515 |
506 void setNext(SkOpSpanBase* nextT) { | 516 void setNext(SkOpSpanBase* nextT) { |
507 SkASSERT(!final()); | 517 SkASSERT(!final()); |
508 fNext = nextT; | 518 fNext = nextT; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
556 int fWindSum; // accumulated from contours surrounding this one. | 566 int fWindSum; // accumulated from contours surrounding this one. |
557 int fOppSum; // for binary operators: the opposite winding sum | 567 int fOppSum; // for binary operators: the opposite winding sum |
558 int fWindValue; // 0 == canceled; 1 == normal; >1 == coincident | 568 int fWindValue; // 0 == canceled; 1 == normal; >1 == coincident |
559 int fOppValue; // normally 0 -- when binary coincident edges combine, opp v
alue goes here | 569 int fOppValue; // normally 0 -- when binary coincident edges combine, opp v
alue goes here |
560 int fTopTTry; // specifies direction and t value to try next | 570 int fTopTTry; // specifies direction and t value to try next |
561 bool fDone; // if set, this span to next higher T has been processed | 571 bool fDone; // if set, this span to next higher T has been processed |
562 mutable bool fAlreadyAdded; | 572 mutable bool fAlreadyAdded; |
563 }; | 573 }; |
564 | 574 |
565 #endif | 575 #endif |
OLD | NEW |