| 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 |