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