xref: /aosp_15_r20/external/skia/src/pathops/SkOpCoincidence.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2013 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker #ifndef SkOpCoincidence_DEFINED
8*c8dee2aaSAndroid Build Coastguard Worker #define SkOpCoincidence_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkDebug.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkMalloc.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/pathops/SkOpSpan.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/pathops/SkPathOpsTypes.h"
15*c8dee2aaSAndroid Build Coastguard Worker 
16*c8dee2aaSAndroid Build Coastguard Worker class SkOpAngle;
17*c8dee2aaSAndroid Build Coastguard Worker class SkOpContour;
18*c8dee2aaSAndroid Build Coastguard Worker class SkOpSegment;
19*c8dee2aaSAndroid Build Coastguard Worker 
20*c8dee2aaSAndroid Build Coastguard Worker template <typename T> class SkTDArray;
21*c8dee2aaSAndroid Build Coastguard Worker 
22*c8dee2aaSAndroid Build Coastguard Worker class SkCoincidentSpans {
23*c8dee2aaSAndroid Build Coastguard Worker public:
24*c8dee2aaSAndroid Build Coastguard Worker     const SkOpPtT* coinPtTEnd() const;
25*c8dee2aaSAndroid Build Coastguard Worker     const SkOpPtT* coinPtTStart() const;
26*c8dee2aaSAndroid Build Coastguard Worker 
27*c8dee2aaSAndroid Build Coastguard Worker     // These return non-const pointers so that, as copies, they can be added
28*c8dee2aaSAndroid Build Coastguard Worker     // to a new span pair
coinPtTEndWritable()29*c8dee2aaSAndroid Build Coastguard Worker     SkOpPtT* coinPtTEndWritable() const { return const_cast<SkOpPtT*>(fCoinPtTEnd); }
coinPtTStartWritable()30*c8dee2aaSAndroid Build Coastguard Worker     SkOpPtT* coinPtTStartWritable() const { return const_cast<SkOpPtT*>(fCoinPtTStart); }
31*c8dee2aaSAndroid Build Coastguard Worker 
32*c8dee2aaSAndroid Build Coastguard Worker     bool collapsed(const SkOpPtT* ) const;
33*c8dee2aaSAndroid Build Coastguard Worker     bool contains(const SkOpPtT* s, const SkOpPtT* e) const;
34*c8dee2aaSAndroid Build Coastguard Worker     void correctEnds();
35*c8dee2aaSAndroid Build Coastguard Worker     void correctOneEnd(const SkOpPtT* (SkCoincidentSpans::* getEnd)() const,
36*c8dee2aaSAndroid Build Coastguard Worker                        void (SkCoincidentSpans::* setEnd)(const SkOpPtT* ptT) );
37*c8dee2aaSAndroid Build Coastguard Worker 
38*c8dee2aaSAndroid Build Coastguard Worker #if DEBUG_COIN
39*c8dee2aaSAndroid Build Coastguard Worker     void debugCorrectEnds(SkPathOpsDebug::GlitchLog* log) const;
40*c8dee2aaSAndroid Build Coastguard Worker     void debugCorrectOneEnd(SkPathOpsDebug::GlitchLog* log,
41*c8dee2aaSAndroid Build Coastguard Worker                             const SkOpPtT* (SkCoincidentSpans::* getEnd)() const,
42*c8dee2aaSAndroid Build Coastguard Worker                             void (SkCoincidentSpans::* setEnd)(const SkOpPtT* ptT) const) const;
43*c8dee2aaSAndroid Build Coastguard Worker     bool debugExpand(SkPathOpsDebug::GlitchLog* log) const;
44*c8dee2aaSAndroid Build Coastguard Worker #endif
45*c8dee2aaSAndroid Build Coastguard Worker 
debugID()46*c8dee2aaSAndroid Build Coastguard Worker     const char* debugID() const {
47*c8dee2aaSAndroid Build Coastguard Worker #if DEBUG_COIN
48*c8dee2aaSAndroid Build Coastguard Worker         return fGlobalState->debugCoinDictEntry().fFunctionName;
49*c8dee2aaSAndroid Build Coastguard Worker #else
50*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
51*c8dee2aaSAndroid Build Coastguard Worker #endif
52*c8dee2aaSAndroid Build Coastguard Worker     }
53*c8dee2aaSAndroid Build Coastguard Worker 
54*c8dee2aaSAndroid Build Coastguard Worker     void debugShow() const;
55*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
56*c8dee2aaSAndroid Build Coastguard Worker     void debugStartCheck(const SkOpSpanBase* outer, const SkOpSpanBase* over,
57*c8dee2aaSAndroid Build Coastguard Worker             const SkOpGlobalState* debugState) const;
58*c8dee2aaSAndroid Build Coastguard Worker #endif
59*c8dee2aaSAndroid Build Coastguard Worker     void dump() const;
60*c8dee2aaSAndroid Build Coastguard Worker     bool expand();
61*c8dee2aaSAndroid Build Coastguard Worker     bool extend(const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd,
62*c8dee2aaSAndroid Build Coastguard Worker                 const SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd);
flipped()63*c8dee2aaSAndroid Build Coastguard Worker     bool flipped() const { return fOppPtTStart->fT > fOppPtTEnd->fT; }
SkDEBUGCODE(SkOpGlobalState * globalState (){ return fGlobalState; })64*c8dee2aaSAndroid Build Coastguard Worker     SkDEBUGCODE(SkOpGlobalState* globalState() { return fGlobalState; })
65*c8dee2aaSAndroid Build Coastguard Worker 
66*c8dee2aaSAndroid Build Coastguard Worker     void init(SkDEBUGCODE(SkOpGlobalState* globalState)) {
67*c8dee2aaSAndroid Build Coastguard Worker         sk_bzero(this, sizeof(*this));
68*c8dee2aaSAndroid Build Coastguard Worker         SkDEBUGCODE(fGlobalState = globalState);
69*c8dee2aaSAndroid Build Coastguard Worker     }
70*c8dee2aaSAndroid Build Coastguard Worker 
next()71*c8dee2aaSAndroid Build Coastguard Worker     SkCoincidentSpans* next() { return fNext; }
next()72*c8dee2aaSAndroid Build Coastguard Worker     const SkCoincidentSpans* next() const { return fNext; }
nextPtr()73*c8dee2aaSAndroid Build Coastguard Worker     SkCoincidentSpans** nextPtr() { return &fNext; }
74*c8dee2aaSAndroid Build Coastguard Worker     const SkOpPtT* oppPtTStart() const;
75*c8dee2aaSAndroid Build Coastguard Worker     const SkOpPtT* oppPtTEnd() const;
76*c8dee2aaSAndroid Build Coastguard Worker     // These return non-const pointers so that, as copies, they can be added
77*c8dee2aaSAndroid Build Coastguard Worker     // to a new span pair
oppPtTStartWritable()78*c8dee2aaSAndroid Build Coastguard Worker     SkOpPtT* oppPtTStartWritable() const { return const_cast<SkOpPtT*>(fOppPtTStart); }
oppPtTEndWritable()79*c8dee2aaSAndroid Build Coastguard Worker     SkOpPtT* oppPtTEndWritable() const { return const_cast<SkOpPtT*>(fOppPtTEnd); }
80*c8dee2aaSAndroid Build Coastguard Worker     bool ordered(bool* result) const;
81*c8dee2aaSAndroid Build Coastguard Worker 
82*c8dee2aaSAndroid Build Coastguard Worker     void set(SkCoincidentSpans* next, const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd,
83*c8dee2aaSAndroid Build Coastguard Worker             const SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd);
84*c8dee2aaSAndroid Build Coastguard Worker 
setCoinPtTEnd(const SkOpPtT * ptT)85*c8dee2aaSAndroid Build Coastguard Worker     void setCoinPtTEnd(const SkOpPtT* ptT) {
86*c8dee2aaSAndroid Build Coastguard Worker         SkOPASSERT(ptT == ptT->span()->ptT());
87*c8dee2aaSAndroid Build Coastguard Worker         SkOPASSERT(!fCoinPtTStart || ptT->fT != fCoinPtTStart->fT);
88*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!fCoinPtTStart || fCoinPtTStart->segment() == ptT->segment());
89*c8dee2aaSAndroid Build Coastguard Worker         fCoinPtTEnd = ptT;
90*c8dee2aaSAndroid Build Coastguard Worker         ptT->setCoincident();
91*c8dee2aaSAndroid Build Coastguard Worker     }
92*c8dee2aaSAndroid Build Coastguard Worker 
setCoinPtTStart(const SkOpPtT * ptT)93*c8dee2aaSAndroid Build Coastguard Worker     void setCoinPtTStart(const SkOpPtT* ptT) {
94*c8dee2aaSAndroid Build Coastguard Worker         SkOPASSERT(ptT == ptT->span()->ptT());
95*c8dee2aaSAndroid Build Coastguard Worker         SkOPASSERT(!fCoinPtTEnd || ptT->fT != fCoinPtTEnd->fT);
96*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!fCoinPtTEnd || fCoinPtTEnd->segment() == ptT->segment());
97*c8dee2aaSAndroid Build Coastguard Worker         fCoinPtTStart = ptT;
98*c8dee2aaSAndroid Build Coastguard Worker         ptT->setCoincident();
99*c8dee2aaSAndroid Build Coastguard Worker     }
100*c8dee2aaSAndroid Build Coastguard Worker 
setEnds(const SkOpPtT * coinPtTEnd,const SkOpPtT * oppPtTEnd)101*c8dee2aaSAndroid Build Coastguard Worker     void setEnds(const SkOpPtT* coinPtTEnd, const SkOpPtT* oppPtTEnd) {
102*c8dee2aaSAndroid Build Coastguard Worker         this->setCoinPtTEnd(coinPtTEnd);
103*c8dee2aaSAndroid Build Coastguard Worker         this->setOppPtTEnd(oppPtTEnd);
104*c8dee2aaSAndroid Build Coastguard Worker     }
105*c8dee2aaSAndroid Build Coastguard Worker 
setOppPtTEnd(const SkOpPtT * ptT)106*c8dee2aaSAndroid Build Coastguard Worker     void setOppPtTEnd(const SkOpPtT* ptT) {
107*c8dee2aaSAndroid Build Coastguard Worker         SkOPASSERT(ptT == ptT->span()->ptT());
108*c8dee2aaSAndroid Build Coastguard Worker         SkOPASSERT(!fOppPtTStart || ptT->fT != fOppPtTStart->fT);
109*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!fOppPtTStart || fOppPtTStart->segment() == ptT->segment());
110*c8dee2aaSAndroid Build Coastguard Worker         fOppPtTEnd = ptT;
111*c8dee2aaSAndroid Build Coastguard Worker         ptT->setCoincident();
112*c8dee2aaSAndroid Build Coastguard Worker     }
113*c8dee2aaSAndroid Build Coastguard Worker 
setOppPtTStart(const SkOpPtT * ptT)114*c8dee2aaSAndroid Build Coastguard Worker     void setOppPtTStart(const SkOpPtT* ptT) {
115*c8dee2aaSAndroid Build Coastguard Worker         SkOPASSERT(ptT == ptT->span()->ptT());
116*c8dee2aaSAndroid Build Coastguard Worker         SkOPASSERT(!fOppPtTEnd || ptT->fT != fOppPtTEnd->fT);
117*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!fOppPtTEnd || fOppPtTEnd->segment() == ptT->segment());
118*c8dee2aaSAndroid Build Coastguard Worker         fOppPtTStart = ptT;
119*c8dee2aaSAndroid Build Coastguard Worker         ptT->setCoincident();
120*c8dee2aaSAndroid Build Coastguard Worker     }
121*c8dee2aaSAndroid Build Coastguard Worker 
setStarts(const SkOpPtT * coinPtTStart,const SkOpPtT * oppPtTStart)122*c8dee2aaSAndroid Build Coastguard Worker     void setStarts(const SkOpPtT* coinPtTStart, const SkOpPtT* oppPtTStart) {
123*c8dee2aaSAndroid Build Coastguard Worker         this->setCoinPtTStart(coinPtTStart);
124*c8dee2aaSAndroid Build Coastguard Worker         this->setOppPtTStart(oppPtTStart);
125*c8dee2aaSAndroid Build Coastguard Worker     }
126*c8dee2aaSAndroid Build Coastguard Worker 
setNext(SkCoincidentSpans * next)127*c8dee2aaSAndroid Build Coastguard Worker     void setNext(SkCoincidentSpans* next) { fNext = next; }
128*c8dee2aaSAndroid Build Coastguard Worker 
129*c8dee2aaSAndroid Build Coastguard Worker private:
130*c8dee2aaSAndroid Build Coastguard Worker     SkCoincidentSpans* fNext;
131*c8dee2aaSAndroid Build Coastguard Worker     const SkOpPtT* fCoinPtTStart;
132*c8dee2aaSAndroid Build Coastguard Worker     const SkOpPtT* fCoinPtTEnd;
133*c8dee2aaSAndroid Build Coastguard Worker     const SkOpPtT* fOppPtTStart;
134*c8dee2aaSAndroid Build Coastguard Worker     const SkOpPtT* fOppPtTEnd;
135*c8dee2aaSAndroid Build Coastguard Worker     SkDEBUGCODE(SkOpGlobalState* fGlobalState;)
136*c8dee2aaSAndroid Build Coastguard Worker };
137*c8dee2aaSAndroid Build Coastguard Worker 
138*c8dee2aaSAndroid Build Coastguard Worker class SkOpCoincidence {
139*c8dee2aaSAndroid Build Coastguard Worker public:
SkOpCoincidence(SkOpGlobalState * globalState)140*c8dee2aaSAndroid Build Coastguard Worker     SkOpCoincidence(SkOpGlobalState* globalState)
141*c8dee2aaSAndroid Build Coastguard Worker         : fHead(nullptr)
142*c8dee2aaSAndroid Build Coastguard Worker         , fTop(nullptr)
143*c8dee2aaSAndroid Build Coastguard Worker         , fGlobalState(globalState)
144*c8dee2aaSAndroid Build Coastguard Worker         , fContinue(false)
145*c8dee2aaSAndroid Build Coastguard Worker         , fSpanDeleted(false)
146*c8dee2aaSAndroid Build Coastguard Worker         , fPtAllocated(false)
147*c8dee2aaSAndroid Build Coastguard Worker         , fCoinExtended(false)
148*c8dee2aaSAndroid Build Coastguard Worker         , fSpanMerged(false) {
149*c8dee2aaSAndroid Build Coastguard Worker         globalState->setCoincidence(this);
150*c8dee2aaSAndroid Build Coastguard Worker     }
151*c8dee2aaSAndroid Build Coastguard Worker 
152*c8dee2aaSAndroid Build Coastguard Worker     void add(SkOpPtT* coinPtTStart, SkOpPtT* coinPtTEnd, SkOpPtT* oppPtTStart,
153*c8dee2aaSAndroid Build Coastguard Worker              SkOpPtT* oppPtTEnd);
154*c8dee2aaSAndroid Build Coastguard Worker     bool addEndMovedSpans(DEBUG_COIN_DECLARE_ONLY_PARAMS());
155*c8dee2aaSAndroid Build Coastguard Worker     bool addExpanded(DEBUG_COIN_DECLARE_ONLY_PARAMS());
156*c8dee2aaSAndroid Build Coastguard Worker     bool addMissing(bool* added  DEBUG_COIN_DECLARE_PARAMS());
157*c8dee2aaSAndroid Build Coastguard Worker     bool apply(DEBUG_COIN_DECLARE_ONLY_PARAMS());
158*c8dee2aaSAndroid Build Coastguard Worker     bool contains(const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd,
159*c8dee2aaSAndroid Build Coastguard Worker                   const SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd) const;
160*c8dee2aaSAndroid Build Coastguard Worker     void correctEnds(DEBUG_COIN_DECLARE_ONLY_PARAMS());
161*c8dee2aaSAndroid Build Coastguard Worker 
162*c8dee2aaSAndroid Build Coastguard Worker #if DEBUG_COIN
163*c8dee2aaSAndroid Build Coastguard Worker     void debugAddEndMovedSpans(SkPathOpsDebug::GlitchLog* log) const;
164*c8dee2aaSAndroid Build Coastguard Worker     void debugAddExpanded(SkPathOpsDebug::GlitchLog* ) const;
165*c8dee2aaSAndroid Build Coastguard Worker     void debugAddMissing(SkPathOpsDebug::GlitchLog* , bool* added) const;
166*c8dee2aaSAndroid Build Coastguard Worker     void debugAddOrOverlap(SkPathOpsDebug::GlitchLog* log,
167*c8dee2aaSAndroid Build Coastguard Worker                            const SkOpSegment* coinSeg, const SkOpSegment* oppSeg,
168*c8dee2aaSAndroid Build Coastguard Worker                            double coinTs, double coinTe, double oppTs, double oppTe,
169*c8dee2aaSAndroid Build Coastguard Worker                            bool* added) const;
170*c8dee2aaSAndroid Build Coastguard Worker #endif
171*c8dee2aaSAndroid Build Coastguard Worker 
debugAngle(int id)172*c8dee2aaSAndroid Build Coastguard Worker     const SkOpAngle* debugAngle(int id) const {
173*c8dee2aaSAndroid Build Coastguard Worker         return SkDEBUGRELEASE(fGlobalState->debugAngle(id), nullptr);
174*c8dee2aaSAndroid Build Coastguard Worker     }
175*c8dee2aaSAndroid Build Coastguard Worker 
176*c8dee2aaSAndroid Build Coastguard Worker     void debugCheckBetween() const;
177*c8dee2aaSAndroid Build Coastguard Worker 
178*c8dee2aaSAndroid Build Coastguard Worker #if DEBUG_COIN
179*c8dee2aaSAndroid Build Coastguard Worker     void debugCheckValid(SkPathOpsDebug::GlitchLog* log) const;
180*c8dee2aaSAndroid Build Coastguard Worker #endif
181*c8dee2aaSAndroid Build Coastguard Worker 
debugContour(int id)182*c8dee2aaSAndroid Build Coastguard Worker     SkOpContour* debugContour(int id) const {
183*c8dee2aaSAndroid Build Coastguard Worker         return SkDEBUGRELEASE(fGlobalState->debugContour(id), nullptr);
184*c8dee2aaSAndroid Build Coastguard Worker     }
185*c8dee2aaSAndroid Build Coastguard Worker 
186*c8dee2aaSAndroid Build Coastguard Worker #if DEBUG_COIN
187*c8dee2aaSAndroid Build Coastguard Worker     void debugCorrectEnds(SkPathOpsDebug::GlitchLog* log) const;
188*c8dee2aaSAndroid Build Coastguard Worker     bool debugExpand(SkPathOpsDebug::GlitchLog* ) const;
189*c8dee2aaSAndroid Build Coastguard Worker     void debugMark(SkPathOpsDebug::GlitchLog* ) const;
190*c8dee2aaSAndroid Build Coastguard Worker     void debugMarkCollapsed(SkPathOpsDebug::GlitchLog* ,
191*c8dee2aaSAndroid Build Coastguard Worker                             const SkCoincidentSpans* coin, const SkOpPtT* test) const;
192*c8dee2aaSAndroid Build Coastguard Worker     void debugMarkCollapsed(SkPathOpsDebug::GlitchLog* , const SkOpPtT* test) const;
193*c8dee2aaSAndroid Build Coastguard Worker #endif
194*c8dee2aaSAndroid Build Coastguard Worker 
debugPtT(int id)195*c8dee2aaSAndroid Build Coastguard Worker     const SkOpPtT* debugPtT(int id) const {
196*c8dee2aaSAndroid Build Coastguard Worker         return SkDEBUGRELEASE(fGlobalState->debugPtT(id), nullptr);
197*c8dee2aaSAndroid Build Coastguard Worker     }
198*c8dee2aaSAndroid Build Coastguard Worker 
debugSegment(int id)199*c8dee2aaSAndroid Build Coastguard Worker     const SkOpSegment* debugSegment(int id) const {
200*c8dee2aaSAndroid Build Coastguard Worker         return SkDEBUGRELEASE(fGlobalState->debugSegment(id), nullptr);
201*c8dee2aaSAndroid Build Coastguard Worker     }
202*c8dee2aaSAndroid Build Coastguard Worker 
203*c8dee2aaSAndroid Build Coastguard Worker #if DEBUG_COIN
204*c8dee2aaSAndroid Build Coastguard Worker     void debugRelease(SkPathOpsDebug::GlitchLog* , const SkCoincidentSpans* ,
205*c8dee2aaSAndroid Build Coastguard Worker                       const SkCoincidentSpans* ) const;
206*c8dee2aaSAndroid Build Coastguard Worker     void debugRelease(SkPathOpsDebug::GlitchLog* , const SkOpSegment* ) const;
207*c8dee2aaSAndroid Build Coastguard Worker #endif
208*c8dee2aaSAndroid Build Coastguard Worker     void debugShowCoincidence() const;
209*c8dee2aaSAndroid Build Coastguard Worker 
debugSpan(int id)210*c8dee2aaSAndroid Build Coastguard Worker     const SkOpSpanBase* debugSpan(int id) const {
211*c8dee2aaSAndroid Build Coastguard Worker         return SkDEBUGRELEASE(fGlobalState->debugSpan(id), nullptr);
212*c8dee2aaSAndroid Build Coastguard Worker     }
213*c8dee2aaSAndroid Build Coastguard Worker 
214*c8dee2aaSAndroid Build Coastguard Worker     void debugValidate() const;
215*c8dee2aaSAndroid Build Coastguard Worker     void dump() const;
216*c8dee2aaSAndroid Build Coastguard Worker     bool expand(DEBUG_COIN_DECLARE_ONLY_PARAMS());
217*c8dee2aaSAndroid Build Coastguard Worker     bool extend(const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, const SkOpPtT* oppPtTStart,
218*c8dee2aaSAndroid Build Coastguard Worker                 const SkOpPtT* oppPtTEnd);
219*c8dee2aaSAndroid Build Coastguard Worker     bool findOverlaps(SkOpCoincidence*  DEBUG_COIN_DECLARE_PARAMS()) const;
220*c8dee2aaSAndroid Build Coastguard Worker     void fixUp(SkOpPtT* deleted, const SkOpPtT* kept);
221*c8dee2aaSAndroid Build Coastguard Worker 
globalState()222*c8dee2aaSAndroid Build Coastguard Worker     SkOpGlobalState* globalState() {
223*c8dee2aaSAndroid Build Coastguard Worker         return fGlobalState;
224*c8dee2aaSAndroid Build Coastguard Worker     }
225*c8dee2aaSAndroid Build Coastguard Worker 
globalState()226*c8dee2aaSAndroid Build Coastguard Worker     const SkOpGlobalState* globalState() const {
227*c8dee2aaSAndroid Build Coastguard Worker         return fGlobalState;
228*c8dee2aaSAndroid Build Coastguard Worker     }
229*c8dee2aaSAndroid Build Coastguard Worker 
isEmpty()230*c8dee2aaSAndroid Build Coastguard Worker     bool isEmpty() const {
231*c8dee2aaSAndroid Build Coastguard Worker         return !fHead && !fTop;
232*c8dee2aaSAndroid Build Coastguard Worker     }
233*c8dee2aaSAndroid Build Coastguard Worker 
234*c8dee2aaSAndroid Build Coastguard Worker     bool mark(DEBUG_COIN_DECLARE_ONLY_PARAMS());
235*c8dee2aaSAndroid Build Coastguard Worker     void markCollapsed(SkOpPtT* );
236*c8dee2aaSAndroid Build Coastguard Worker 
Ordered(const SkOpPtT * coinPtTStart,const SkOpPtT * oppPtTStart)237*c8dee2aaSAndroid Build Coastguard Worker     static bool Ordered(const SkOpPtT* coinPtTStart, const SkOpPtT* oppPtTStart) {
238*c8dee2aaSAndroid Build Coastguard Worker       return Ordered(coinPtTStart->segment(), oppPtTStart->segment());
239*c8dee2aaSAndroid Build Coastguard Worker     }
240*c8dee2aaSAndroid Build Coastguard Worker 
241*c8dee2aaSAndroid Build Coastguard Worker     static bool Ordered(const SkOpSegment* coin, const SkOpSegment* opp);
242*c8dee2aaSAndroid Build Coastguard Worker     void release(const SkOpSegment* );
243*c8dee2aaSAndroid Build Coastguard Worker     void releaseDeleted();
244*c8dee2aaSAndroid Build Coastguard Worker 
245*c8dee2aaSAndroid Build Coastguard Worker private:
add(const SkOpPtT * coinPtTStart,const SkOpPtT * coinPtTEnd,const SkOpPtT * oppPtTStart,const SkOpPtT * oppPtTEnd)246*c8dee2aaSAndroid Build Coastguard Worker     void add(const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, const SkOpPtT* oppPtTStart,
247*c8dee2aaSAndroid Build Coastguard Worker              const SkOpPtT* oppPtTEnd) {
248*c8dee2aaSAndroid Build Coastguard Worker         this->add(const_cast<SkOpPtT*>(coinPtTStart), const_cast<SkOpPtT*>(coinPtTEnd),
249*c8dee2aaSAndroid Build Coastguard Worker             const_cast<SkOpPtT*>(oppPtTStart), const_cast<SkOpPtT*>(oppPtTEnd));
250*c8dee2aaSAndroid Build Coastguard Worker     }
251*c8dee2aaSAndroid Build Coastguard Worker 
252*c8dee2aaSAndroid Build Coastguard Worker     bool addEndMovedSpans(const SkOpSpan* base, const SkOpSpanBase* testSpan);
253*c8dee2aaSAndroid Build Coastguard Worker     bool addEndMovedSpans(const SkOpPtT* ptT);
254*c8dee2aaSAndroid Build Coastguard Worker 
255*c8dee2aaSAndroid Build Coastguard Worker     bool addIfMissing(const SkOpPtT* over1s, const SkOpPtT* over2s,
256*c8dee2aaSAndroid Build Coastguard Worker                       double tStart, double tEnd, SkOpSegment* coinSeg, SkOpSegment* oppSeg,
257*c8dee2aaSAndroid Build Coastguard Worker                       bool* added
258*c8dee2aaSAndroid Build Coastguard Worker                       SkDEBUGPARAMS(const SkOpPtT* over1e) SkDEBUGPARAMS(const SkOpPtT* over2e));
259*c8dee2aaSAndroid Build Coastguard Worker     bool addOrOverlap(SkOpSegment* coinSeg, SkOpSegment* oppSeg,
260*c8dee2aaSAndroid Build Coastguard Worker                       double coinTs, double coinTe, double oppTs, double oppTe, bool* added);
261*c8dee2aaSAndroid Build Coastguard Worker     bool addOverlap(const SkOpSegment* seg1, const SkOpSegment* seg1o,
262*c8dee2aaSAndroid Build Coastguard Worker                     const SkOpSegment* seg2, const SkOpSegment* seg2o,
263*c8dee2aaSAndroid Build Coastguard Worker                     const SkOpPtT* overS, const SkOpPtT* overE);
264*c8dee2aaSAndroid Build Coastguard Worker     bool checkOverlap(SkCoincidentSpans* check,
265*c8dee2aaSAndroid Build Coastguard Worker                       const SkOpSegment* coinSeg, const SkOpSegment* oppSeg,
266*c8dee2aaSAndroid Build Coastguard Worker                       double coinTs, double coinTe, double oppTs, double oppTe,
267*c8dee2aaSAndroid Build Coastguard Worker                       SkTDArray<SkCoincidentSpans*>* overlaps) const;
268*c8dee2aaSAndroid Build Coastguard Worker     bool contains(const SkOpSegment* seg, const SkOpSegment* opp, double oppT) const;
269*c8dee2aaSAndroid Build Coastguard Worker     bool contains(const SkCoincidentSpans* coin, const SkOpSegment* seg,
270*c8dee2aaSAndroid Build Coastguard Worker                   const SkOpSegment* opp, double oppT) const;
271*c8dee2aaSAndroid Build Coastguard Worker #if DEBUG_COIN
272*c8dee2aaSAndroid Build Coastguard Worker     void debugAddIfMissing(SkPathOpsDebug::GlitchLog* ,
273*c8dee2aaSAndroid Build Coastguard Worker                            const SkCoincidentSpans* outer, const SkOpPtT* over1s,
274*c8dee2aaSAndroid Build Coastguard Worker                            const SkOpPtT* over1e) const;
275*c8dee2aaSAndroid Build Coastguard Worker     void debugAddIfMissing(SkPathOpsDebug::GlitchLog* ,
276*c8dee2aaSAndroid Build Coastguard Worker                            const SkOpPtT* over1s, const SkOpPtT* over2s,
277*c8dee2aaSAndroid Build Coastguard Worker                            double tStart, double tEnd,
278*c8dee2aaSAndroid Build Coastguard Worker                            const SkOpSegment* coinSeg, const SkOpSegment* oppSeg, bool* added,
279*c8dee2aaSAndroid Build Coastguard Worker                            const SkOpPtT* over1e, const SkOpPtT* over2e) const;
280*c8dee2aaSAndroid Build Coastguard Worker     void debugAddEndMovedSpans(SkPathOpsDebug::GlitchLog* ,
281*c8dee2aaSAndroid Build Coastguard Worker                                const SkOpSpan* base, const SkOpSpanBase* testSpan) const;
282*c8dee2aaSAndroid Build Coastguard Worker     void debugAddEndMovedSpans(SkPathOpsDebug::GlitchLog* ,
283*c8dee2aaSAndroid Build Coastguard Worker                                const SkOpPtT* ptT) const;
284*c8dee2aaSAndroid Build Coastguard Worker #endif
285*c8dee2aaSAndroid Build Coastguard Worker     void fixUp(SkCoincidentSpans* coin, SkOpPtT* deleted, const SkOpPtT* kept);
286*c8dee2aaSAndroid Build Coastguard Worker     void markCollapsed(SkCoincidentSpans* head, SkOpPtT* test);
287*c8dee2aaSAndroid Build Coastguard Worker     bool overlap(const SkOpPtT* coinStart1, const SkOpPtT* coinEnd1,
288*c8dee2aaSAndroid Build Coastguard Worker                  const SkOpPtT* coinStart2, const SkOpPtT* coinEnd2,
289*c8dee2aaSAndroid Build Coastguard Worker                  double* overS, double* overE) const;
290*c8dee2aaSAndroid Build Coastguard Worker     bool release(SkCoincidentSpans* coin, SkCoincidentSpans* );
291*c8dee2aaSAndroid Build Coastguard Worker     void releaseDeleted(SkCoincidentSpans* );
292*c8dee2aaSAndroid Build Coastguard Worker     void restoreHead();
293*c8dee2aaSAndroid Build Coastguard Worker     // return coinPtT->segment()->t mapped from overS->fT <= t <= overE->fT
294*c8dee2aaSAndroid Build Coastguard Worker     static double TRange(const SkOpPtT* overS, double t, const SkOpSegment* coinPtT
295*c8dee2aaSAndroid Build Coastguard Worker                          SkDEBUGPARAMS(const SkOpPtT* overE));
296*c8dee2aaSAndroid Build Coastguard Worker 
297*c8dee2aaSAndroid Build Coastguard Worker     SkCoincidentSpans* fHead;
298*c8dee2aaSAndroid Build Coastguard Worker     SkCoincidentSpans* fTop;
299*c8dee2aaSAndroid Build Coastguard Worker     SkOpGlobalState* fGlobalState;
300*c8dee2aaSAndroid Build Coastguard Worker     bool fContinue;
301*c8dee2aaSAndroid Build Coastguard Worker     bool fSpanDeleted;
302*c8dee2aaSAndroid Build Coastguard Worker     bool fPtAllocated;
303*c8dee2aaSAndroid Build Coastguard Worker     bool fCoinExtended;
304*c8dee2aaSAndroid Build Coastguard Worker     bool fSpanMerged;
305*c8dee2aaSAndroid Build Coastguard Worker };
306*c8dee2aaSAndroid Build Coastguard Worker 
307*c8dee2aaSAndroid Build Coastguard Worker #endif
308