145fa447460f70ec21d22cf4e1531490acfd3c578caryclark/*
245fa447460f70ec21d22cf4e1531490acfd3c578caryclark * Copyright 2013 Google Inc.
345fa447460f70ec21d22cf4e1531490acfd3c578caryclark *
445fa447460f70ec21d22cf4e1531490acfd3c578caryclark * Use of this source code is governed by a BSD-style license that can be
545fa447460f70ec21d22cf4e1531490acfd3c578caryclark * found in the LICENSE file.
645fa447460f70ec21d22cf4e1531490acfd3c578caryclark */
745fa447460f70ec21d22cf4e1531490acfd3c578caryclark#ifndef SkOpCoincidence_DEFINED
845fa447460f70ec21d22cf4e1531490acfd3c578caryclark#define SkOpCoincidence_DEFINED
945fa447460f70ec21d22cf4e1531490acfd3c578caryclark
1055888e44171ffd48b591d19256884a969fe4da17caryclark#include "SkTDArray.h"
1145fa447460f70ec21d22cf4e1531490acfd3c578caryclark#include "SkOpTAllocator.h"
1245fa447460f70ec21d22cf4e1531490acfd3c578caryclark#include "SkOpSpan.h"
1327c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark#include "SkPathOpsTypes.h"
1445fa447460f70ec21d22cf4e1531490acfd3c578caryclark
1545fa447460f70ec21d22cf4e1531490acfd3c578caryclarkclass SkOpPtT;
1655888e44171ffd48b591d19256884a969fe4da17caryclarkclass SkOpSpanBase;
1745fa447460f70ec21d22cf4e1531490acfd3c578caryclark
1855888e44171ffd48b591d19256884a969fe4da17caryclarkclass SkCoincidentSpans {
1955888e44171ffd48b591d19256884a969fe4da17caryclarkpublic:
20db8f44f497f2b67b2500bbfc7b11ce7a510c5e5cCary Clark    const SkOpPtT* coinPtTEnd() const;
21db8f44f497f2b67b2500bbfc7b11ce7a510c5e5cCary Clark    const SkOpPtT* coinPtTStart() const;
2255888e44171ffd48b591d19256884a969fe4da17caryclark
2355888e44171ffd48b591d19256884a969fe4da17caryclark    // These return non-const pointers so that, as copies, they can be added
2455888e44171ffd48b591d19256884a969fe4da17caryclark    // to a new span pair
2555888e44171ffd48b591d19256884a969fe4da17caryclark    SkOpPtT* coinPtTEndWritable() const { return const_cast<SkOpPtT*>(fCoinPtTEnd); }
2655888e44171ffd48b591d19256884a969fe4da17caryclark    SkOpPtT* coinPtTStartWritable() const { return const_cast<SkOpPtT*>(fCoinPtTStart); }
2755888e44171ffd48b591d19256884a969fe4da17caryclark
2855888e44171ffd48b591d19256884a969fe4da17caryclark    bool collapsed(const SkOpPtT* ) const;
2955888e44171ffd48b591d19256884a969fe4da17caryclark    bool contains(const SkOpPtT* s, const SkOpPtT* e) const;
3055888e44171ffd48b591d19256884a969fe4da17caryclark    void correctEnds();
3155888e44171ffd48b591d19256884a969fe4da17caryclark    void correctOneEnd(const SkOpPtT* (SkCoincidentSpans::* getEnd)() const,
3255888e44171ffd48b591d19256884a969fe4da17caryclark                       void (SkCoincidentSpans::* setEnd)(const SkOpPtT* ptT) );
3355888e44171ffd48b591d19256884a969fe4da17caryclark
34ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark#if DEBUG_COIN
35ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    void debugCorrectEnds(SkPathOpsDebug::GlitchLog* log) const;
36ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    void debugCorrectOneEnd(SkPathOpsDebug::GlitchLog* log,
37ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark                            const SkOpPtT* (SkCoincidentSpans::* getEnd)() const,
38ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark                            void (SkCoincidentSpans::* setEnd)(const SkOpPtT* ptT) const) const;
39ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    bool debugExpand(SkPathOpsDebug::GlitchLog* log) const;
4055888e44171ffd48b591d19256884a969fe4da17caryclark#endif
4126ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark
42ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    const char* debugID() const {
43ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark#if DEBUG_COIN
44ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark        return fGlobalState->debugCoinDictEntry().fFunctionName;
45ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark#else
46ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark        return nullptr;
47ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark#endif
4826ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    }
4954359294a7c9dc54802d512a5d891a35c1663392caryclark
5055888e44171ffd48b591d19256884a969fe4da17caryclark    void debugShow() const;
5155888e44171ffd48b591d19256884a969fe4da17caryclark#ifdef SK_DEBUG
5255888e44171ffd48b591d19256884a969fe4da17caryclark    void debugStartCheck(const SkOpSpanBase* outer, const SkOpSpanBase* over,
5355888e44171ffd48b591d19256884a969fe4da17caryclark            const SkOpGlobalState* debugState) const;
5455888e44171ffd48b591d19256884a969fe4da17caryclark#endif
5554359294a7c9dc54802d512a5d891a35c1663392caryclark    void dump() const;
5655888e44171ffd48b591d19256884a969fe4da17caryclark    bool expand();
5755888e44171ffd48b591d19256884a969fe4da17caryclark    bool extend(const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd,
5855888e44171ffd48b591d19256884a969fe4da17caryclark                const SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd);
5955888e44171ffd48b591d19256884a969fe4da17caryclark    bool flipped() const { return fOppPtTStart->fT > fOppPtTEnd->fT; }
60fc560e09b3f777bb32dccb9f52d715383a10a620caryclark    SkDEBUGCODE(SkOpGlobalState* globalState() { return fGlobalState; })
61fc560e09b3f777bb32dccb9f52d715383a10a620caryclark
62fc560e09b3f777bb32dccb9f52d715383a10a620caryclark    void init(SkDEBUGCODE(SkOpGlobalState* globalState)) {
63fc560e09b3f777bb32dccb9f52d715383a10a620caryclark        sk_bzero(this, sizeof(*this));
64fc560e09b3f777bb32dccb9f52d715383a10a620caryclark        SkDEBUGCODE(fGlobalState = globalState);
65fc560e09b3f777bb32dccb9f52d715383a10a620caryclark    }
66fc560e09b3f777bb32dccb9f52d715383a10a620caryclark
6781a478ca6c36aac3e53ce0373a281ac8940f4780caryclark    SkCoincidentSpans* next() { return fNext; }
6881a478ca6c36aac3e53ce0373a281ac8940f4780caryclark    const SkCoincidentSpans* next() const { return fNext; }
6981a478ca6c36aac3e53ce0373a281ac8940f4780caryclark    SkCoincidentSpans** nextPtr() { return &fNext; }
70db8f44f497f2b67b2500bbfc7b11ce7a510c5e5cCary Clark    const SkOpPtT* oppPtTStart() const;
71db8f44f497f2b67b2500bbfc7b11ce7a510c5e5cCary Clark    const SkOpPtT* oppPtTEnd() const;
7255888e44171ffd48b591d19256884a969fe4da17caryclark    // These return non-const pointers so that, as copies, they can be added
7355888e44171ffd48b591d19256884a969fe4da17caryclark    // to a new span pair
7455888e44171ffd48b591d19256884a969fe4da17caryclark    SkOpPtT* oppPtTStartWritable() const { return const_cast<SkOpPtT*>(fOppPtTStart); }
7555888e44171ffd48b591d19256884a969fe4da17caryclark    SkOpPtT* oppPtTEndWritable() const { return const_cast<SkOpPtT*>(fOppPtTEnd); }
76a35ab3e6e024d0b548ded26a2e3b8ecd838ead93caryclark    bool ordered(bool* result) const;
7755888e44171ffd48b591d19256884a969fe4da17caryclark
7855888e44171ffd48b591d19256884a969fe4da17caryclark    void set(SkCoincidentSpans* next, const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd,
79ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark            const SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd);
8055888e44171ffd48b591d19256884a969fe4da17caryclark
8155888e44171ffd48b591d19256884a969fe4da17caryclark    void setCoinPtTEnd(const SkOpPtT* ptT) {
82d6562000efca50bc2bfddae8dcb69dce6b8c0950caryclark        SkOPASSERT(ptT == ptT->span()->ptT());
8396dc1c9efaab4636e30f90aa377f25863f9bf3bacaryclark        SkOPASSERT(!fCoinPtTStart || ptT->fT != fCoinPtTStart->fT);
8455888e44171ffd48b591d19256884a969fe4da17caryclark        SkASSERT(!fCoinPtTStart || fCoinPtTStart->segment() == ptT->segment());
8555888e44171ffd48b591d19256884a969fe4da17caryclark        fCoinPtTEnd = ptT;
8655888e44171ffd48b591d19256884a969fe4da17caryclark        ptT->setCoincident();
8755888e44171ffd48b591d19256884a969fe4da17caryclark    }
8855888e44171ffd48b591d19256884a969fe4da17caryclark
8955888e44171ffd48b591d19256884a969fe4da17caryclark    void setCoinPtTStart(const SkOpPtT* ptT) {
904c76c41c981dd7ea95062a1895a6e3415b70bce1Cary Clark        SkOPASSERT(ptT == ptT->span()->ptT());
91429428660b247bb3ccb3195aa8b3abe3194d4d5bcaryclark        SkOPASSERT(!fCoinPtTEnd || ptT->fT != fCoinPtTEnd->fT);
9255888e44171ffd48b591d19256884a969fe4da17caryclark        SkASSERT(!fCoinPtTEnd || fCoinPtTEnd->segment() == ptT->segment());
9355888e44171ffd48b591d19256884a969fe4da17caryclark        fCoinPtTStart = ptT;
9455888e44171ffd48b591d19256884a969fe4da17caryclark        ptT->setCoincident();
9555888e44171ffd48b591d19256884a969fe4da17caryclark    }
9655888e44171ffd48b591d19256884a969fe4da17caryclark
9755888e44171ffd48b591d19256884a969fe4da17caryclark    void setEnds(const SkOpPtT* coinPtTEnd, const SkOpPtT* oppPtTEnd) {
9855888e44171ffd48b591d19256884a969fe4da17caryclark        this->setCoinPtTEnd(coinPtTEnd);
9955888e44171ffd48b591d19256884a969fe4da17caryclark        this->setOppPtTEnd(oppPtTEnd);
10055888e44171ffd48b591d19256884a969fe4da17caryclark    }
10155888e44171ffd48b591d19256884a969fe4da17caryclark
10255888e44171ffd48b591d19256884a969fe4da17caryclark    void setOppPtTEnd(const SkOpPtT* ptT) {
103d6562000efca50bc2bfddae8dcb69dce6b8c0950caryclark        SkOPASSERT(ptT == ptT->span()->ptT());
104e7bb5b226662f01c91574b29f435acae71c76c46caryclark        SkOPASSERT(!fOppPtTStart || ptT->fT != fOppPtTStart->fT);
10555888e44171ffd48b591d19256884a969fe4da17caryclark        SkASSERT(!fOppPtTStart || fOppPtTStart->segment() == ptT->segment());
10655888e44171ffd48b591d19256884a969fe4da17caryclark        fOppPtTEnd = ptT;
10755888e44171ffd48b591d19256884a969fe4da17caryclark        ptT->setCoincident();
10855888e44171ffd48b591d19256884a969fe4da17caryclark    }
10955888e44171ffd48b591d19256884a969fe4da17caryclark
11055888e44171ffd48b591d19256884a969fe4da17caryclark    void setOppPtTStart(const SkOpPtT* ptT) {
111a35ab3e6e024d0b548ded26a2e3b8ecd838ead93caryclark        SkOPASSERT(ptT == ptT->span()->ptT());
112087140153861f4c2a003ce6b22a612acc9cc3cf9caryclark        SkOPASSERT(!fOppPtTEnd || ptT->fT != fOppPtTEnd->fT);
11355888e44171ffd48b591d19256884a969fe4da17caryclark        SkASSERT(!fOppPtTEnd || fOppPtTEnd->segment() == ptT->segment());
11455888e44171ffd48b591d19256884a969fe4da17caryclark        fOppPtTStart = ptT;
11555888e44171ffd48b591d19256884a969fe4da17caryclark        ptT->setCoincident();
11655888e44171ffd48b591d19256884a969fe4da17caryclark    }
11755888e44171ffd48b591d19256884a969fe4da17caryclark
11855888e44171ffd48b591d19256884a969fe4da17caryclark    void setStarts(const SkOpPtT* coinPtTStart, const SkOpPtT* oppPtTStart) {
11955888e44171ffd48b591d19256884a969fe4da17caryclark        this->setCoinPtTStart(coinPtTStart);
12055888e44171ffd48b591d19256884a969fe4da17caryclark        this->setOppPtTStart(oppPtTStart);
12155888e44171ffd48b591d19256884a969fe4da17caryclark    }
12255888e44171ffd48b591d19256884a969fe4da17caryclark
12355888e44171ffd48b591d19256884a969fe4da17caryclark    void setNext(SkCoincidentSpans* next) { fNext = next; }
12455888e44171ffd48b591d19256884a969fe4da17caryclark
12555888e44171ffd48b591d19256884a969fe4da17caryclarkprivate:
12655888e44171ffd48b591d19256884a969fe4da17caryclark    SkCoincidentSpans* fNext;
12755888e44171ffd48b591d19256884a969fe4da17caryclark    const SkOpPtT* fCoinPtTStart;
12855888e44171ffd48b591d19256884a969fe4da17caryclark    const SkOpPtT* fCoinPtTEnd;
12955888e44171ffd48b591d19256884a969fe4da17caryclark    const SkOpPtT* fOppPtTStart;
13055888e44171ffd48b591d19256884a969fe4da17caryclark    const SkOpPtT* fOppPtTEnd;
131fc560e09b3f777bb32dccb9f52d715383a10a620caryclark    SkDEBUGCODE(SkOpGlobalState* fGlobalState);
13245fa447460f70ec21d22cf4e1531490acfd3c578caryclark};
13345fa447460f70ec21d22cf4e1531490acfd3c578caryclark
13445fa447460f70ec21d22cf4e1531490acfd3c578caryclarkclass SkOpCoincidence {
13545fa447460f70ec21d22cf4e1531490acfd3c578caryclarkpublic:
13655888e44171ffd48b591d19256884a969fe4da17caryclark    SkOpCoincidence(SkOpGlobalState* globalState)
13796fcdcc219d2a0d3579719b84b28bede76efba64halcanary        : fHead(nullptr)
13896fcdcc219d2a0d3579719b84b28bede76efba64halcanary        , fTop(nullptr)
13955888e44171ffd48b591d19256884a969fe4da17caryclark        , fGlobalState(globalState)
14055888e44171ffd48b591d19256884a969fe4da17caryclark        , fContinue(false)
14155888e44171ffd48b591d19256884a969fe4da17caryclark        , fSpanDeleted(false)
14255888e44171ffd48b591d19256884a969fe4da17caryclark        , fPtAllocated(false)
14355888e44171ffd48b591d19256884a969fe4da17caryclark        , fCoinExtended(false)
14455888e44171ffd48b591d19256884a969fe4da17caryclark        , fSpanMerged(false) {
14555888e44171ffd48b591d19256884a969fe4da17caryclark        globalState->setCoincidence(this);
14645fa447460f70ec21d22cf4e1531490acfd3c578caryclark    }
14745fa447460f70ec21d22cf4e1531490acfd3c578caryclark
14845fa447460f70ec21d22cf4e1531490acfd3c578caryclark    void add(SkOpPtT* coinPtTStart, SkOpPtT* coinPtTEnd, SkOpPtT* oppPtTStart,
14955888e44171ffd48b591d19256884a969fe4da17caryclark             SkOpPtT* oppPtTEnd);
150ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    bool addEndMovedSpans(DEBUG_COIN_DECLARE_ONLY_PARAMS());
151ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    bool addExpanded(DEBUG_COIN_DECLARE_ONLY_PARAMS());
152ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    bool addMissing(bool* added  DEBUG_COIN_DECLARE_PARAMS());
153a35ab3e6e024d0b548ded26a2e3b8ecd838ead93caryclark    bool apply(DEBUG_COIN_DECLARE_ONLY_PARAMS());
15426ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    bool contains(const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd,
15555888e44171ffd48b591d19256884a969fe4da17caryclark                  const SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd) const;
156ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    void correctEnds(DEBUG_COIN_DECLARE_ONLY_PARAMS());
15726ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark
158ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark#if DEBUG_COIN
159ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    void debugAddEndMovedSpans(SkPathOpsDebug::GlitchLog* log) const;
160ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    void debugAddExpanded(SkPathOpsDebug::GlitchLog* ) const;
161ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    void debugAddMissing(SkPathOpsDebug::GlitchLog* , bool* added) const;
162ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    void debugAddOrOverlap(SkPathOpsDebug::GlitchLog* log,
16330b9fdd6a1d607bde20c793af65b5e2e8a1737cacaryclark                           const SkOpSegment* coinSeg, const SkOpSegment* oppSeg,
16481a478ca6c36aac3e53ce0373a281ac8940f4780caryclark                           double coinTs, double coinTe, double oppTs, double oppTe,
16581a478ca6c36aac3e53ce0373a281ac8940f4780caryclark                           bool* added) const;
16655888e44171ffd48b591d19256884a969fe4da17caryclark#endif
16727c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark
16827c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark    const SkOpAngle* debugAngle(int id) const {
16955888e44171ffd48b591d19256884a969fe4da17caryclark        return SkDEBUGRELEASE(fGlobalState->debugAngle(id), nullptr);
17027c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark    }
17127c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark
1726c3b9cdcb047afe963c7bcf34834ba2ecccacc33caryclark    void debugCheckBetween() const;
1736c3b9cdcb047afe963c7bcf34834ba2ecccacc33caryclark
174ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark#if DEBUG_COIN
175ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    void debugCheckValid(SkPathOpsDebug::GlitchLog* log) const;
17655888e44171ffd48b591d19256884a969fe4da17caryclark#endif
17755888e44171ffd48b591d19256884a969fe4da17caryclark
17830b9fdd6a1d607bde20c793af65b5e2e8a1737cacaryclark    SkOpContour* debugContour(int id) const {
17955888e44171ffd48b591d19256884a969fe4da17caryclark        return SkDEBUGRELEASE(fGlobalState->debugContour(id), nullptr);
18027c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark    }
18127c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark
182ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark#if DEBUG_COIN
183ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    void debugCorrectEnds(SkPathOpsDebug::GlitchLog* log) const;
184ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    bool debugExpand(SkPathOpsDebug::GlitchLog* ) const;
185ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    void debugMark(SkPathOpsDebug::GlitchLog* ) const;
186ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    void debugMarkCollapsed(SkPathOpsDebug::GlitchLog* ,
18755888e44171ffd48b591d19256884a969fe4da17caryclark                            const SkCoincidentSpans* coin, const SkOpPtT* test) const;
188ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    void debugMarkCollapsed(SkPathOpsDebug::GlitchLog* , const SkOpPtT* test) const;
18955888e44171ffd48b591d19256884a969fe4da17caryclark#endif
19026ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark
19127c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark    const SkOpPtT* debugPtT(int id) const {
19255888e44171ffd48b591d19256884a969fe4da17caryclark        return SkDEBUGRELEASE(fGlobalState->debugPtT(id), nullptr);
19327c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark    }
19427c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark
19527c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark    const SkOpSegment* debugSegment(int id) const {
19655888e44171ffd48b591d19256884a969fe4da17caryclark        return SkDEBUGRELEASE(fGlobalState->debugSegment(id), nullptr);
19727c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark    }
19827c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark
199ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark#if DEBUG_COIN
200ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    void debugRelease(SkPathOpsDebug::GlitchLog* , const SkCoincidentSpans* ,
20130b9fdd6a1d607bde20c793af65b5e2e8a1737cacaryclark                      const SkCoincidentSpans* ) const;
202ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    void debugRelease(SkPathOpsDebug::GlitchLog* , const SkOpSegment* ) const;
20355888e44171ffd48b591d19256884a969fe4da17caryclark#endif
204624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark    void debugShowCoincidence() const;
20527c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark
20627c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark    const SkOpSpanBase* debugSpan(int id) const {
20755888e44171ffd48b591d19256884a969fe4da17caryclark        return SkDEBUGRELEASE(fGlobalState->debugSpan(id), nullptr);
20827c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark    }
20927c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark
21055888e44171ffd48b591d19256884a969fe4da17caryclark    void debugValidate() const;
21145fa447460f70ec21d22cf4e1531490acfd3c578caryclark    void dump() const;
212ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    bool expand(DEBUG_COIN_DECLARE_ONLY_PARAMS());
21355888e44171ffd48b591d19256884a969fe4da17caryclark    bool extend(const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, const SkOpPtT* oppPtTStart,
21455888e44171ffd48b591d19256884a969fe4da17caryclark                const SkOpPtT* oppPtTEnd);
21540f23780e7ca36818660add0faf783fda81bf0b1Cary Clark    bool findOverlaps(SkOpCoincidence*  DEBUG_COIN_DECLARE_PARAMS()) const;
21655888e44171ffd48b591d19256884a969fe4da17caryclark    void fixUp(SkOpPtT* deleted, const SkOpPtT* kept);
21755888e44171ffd48b591d19256884a969fe4da17caryclark
21855888e44171ffd48b591d19256884a969fe4da17caryclark    SkOpGlobalState* globalState() {
21955888e44171ffd48b591d19256884a969fe4da17caryclark        return fGlobalState;
22055888e44171ffd48b591d19256884a969fe4da17caryclark    }
22127c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark
22281a478ca6c36aac3e53ce0373a281ac8940f4780caryclark    const SkOpGlobalState* globalState() const {
22381a478ca6c36aac3e53ce0373a281ac8940f4780caryclark        return fGlobalState;
22481a478ca6c36aac3e53ce0373a281ac8940f4780caryclark    }
22581a478ca6c36aac3e53ce0373a281ac8940f4780caryclark
22627c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark    bool isEmpty() const {
22755888e44171ffd48b591d19256884a969fe4da17caryclark        return !fHead && !fTop;
22827c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark    }
22927c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark
230e6522ea38fa3bcfdf2d718ea5ad898b3b3d46e00caryclark    bool mark(DEBUG_COIN_DECLARE_ONLY_PARAMS());
23155888e44171ffd48b591d19256884a969fe4da17caryclark    void markCollapsed(SkOpPtT* );
23255888e44171ffd48b591d19256884a969fe4da17caryclark
23355888e44171ffd48b591d19256884a969fe4da17caryclark    static bool Ordered(const SkOpPtT* coinPtTStart, const SkOpPtT* oppPtTStart) {
23455888e44171ffd48b591d19256884a969fe4da17caryclark      return Ordered(coinPtTStart->segment(), oppPtTStart->segment());
23555888e44171ffd48b591d19256884a969fe4da17caryclark    }
23655888e44171ffd48b591d19256884a969fe4da17caryclark
23755888e44171ffd48b591d19256884a969fe4da17caryclark    static bool Ordered(const SkOpSegment* coin, const SkOpSegment* opp);
23855888e44171ffd48b591d19256884a969fe4da17caryclark    void release(const SkOpSegment* );
23930b9fdd6a1d607bde20c793af65b5e2e8a1737cacaryclark    void releaseDeleted();
24045fa447460f70ec21d22cf4e1531490acfd3c578caryclark
24154359294a7c9dc54802d512a5d891a35c1663392caryclarkprivate:
24255888e44171ffd48b591d19256884a969fe4da17caryclark    void add(const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, const SkOpPtT* oppPtTStart,
24355888e44171ffd48b591d19256884a969fe4da17caryclark             const SkOpPtT* oppPtTEnd) {
24455888e44171ffd48b591d19256884a969fe4da17caryclark        this->add(const_cast<SkOpPtT*>(coinPtTStart), const_cast<SkOpPtT*>(coinPtTEnd),
24555888e44171ffd48b591d19256884a969fe4da17caryclark            const_cast<SkOpPtT*>(oppPtTStart), const_cast<SkOpPtT*>(oppPtTEnd));
24655888e44171ffd48b591d19256884a969fe4da17caryclark    }
24755888e44171ffd48b591d19256884a969fe4da17caryclark
2481597628fa38d24f23ad505bfb40e70e7c8617457caryclark    bool addEndMovedSpans(const SkOpSpan* base, const SkOpSpanBase* testSpan);
24955888e44171ffd48b591d19256884a969fe4da17caryclark    bool addEndMovedSpans(const SkOpPtT* ptT);
25055888e44171ffd48b591d19256884a969fe4da17caryclark
2518016b264ceec2b11d2acbeb77a9fbe66e48368b9caryclark    bool addIfMissing(const SkOpPtT* over1s, const SkOpPtT* over2s,
25281a478ca6c36aac3e53ce0373a281ac8940f4780caryclark                      double tStart, double tEnd, SkOpSegment* coinSeg, SkOpSegment* oppSeg,
25381a478ca6c36aac3e53ce0373a281ac8940f4780caryclark                      bool* added
2548016b264ceec2b11d2acbeb77a9fbe66e48368b9caryclark                      SkDEBUGPARAMS(const SkOpPtT* over1e) SkDEBUGPARAMS(const SkOpPtT* over2e));
25555888e44171ffd48b591d19256884a969fe4da17caryclark    bool addOrOverlap(SkOpSegment* coinSeg, SkOpSegment* oppSeg,
25681a478ca6c36aac3e53ce0373a281ac8940f4780caryclark                      double coinTs, double coinTe, double oppTs, double oppTe, bool* added);
25755888e44171ffd48b591d19256884a969fe4da17caryclark    bool addOverlap(const SkOpSegment* seg1, const SkOpSegment* seg1o,
25855888e44171ffd48b591d19256884a969fe4da17caryclark                    const SkOpSegment* seg2, const SkOpSegment* seg2o,
25955888e44171ffd48b591d19256884a969fe4da17caryclark                    const SkOpPtT* overS, const SkOpPtT* overE);
26055888e44171ffd48b591d19256884a969fe4da17caryclark    bool checkOverlap(SkCoincidentSpans* check,
26155888e44171ffd48b591d19256884a969fe4da17caryclark                      const SkOpSegment* coinSeg, const SkOpSegment* oppSeg,
26255888e44171ffd48b591d19256884a969fe4da17caryclark                      double coinTs, double coinTe, double oppTs, double oppTe,
26355888e44171ffd48b591d19256884a969fe4da17caryclark                      SkTDArray<SkCoincidentSpans*>* overlaps) const;
26455888e44171ffd48b591d19256884a969fe4da17caryclark    bool contains(const SkOpSegment* seg, const SkOpSegment* opp, double oppT) const;
26555888e44171ffd48b591d19256884a969fe4da17caryclark    bool contains(const SkCoincidentSpans* coin, const SkOpSegment* seg,
26655888e44171ffd48b591d19256884a969fe4da17caryclark                  const SkOpSegment* opp, double oppT) const;
267ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark#if DEBUG_COIN
268ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    void debugAddIfMissing(SkPathOpsDebug::GlitchLog* ,
2698016b264ceec2b11d2acbeb77a9fbe66e48368b9caryclark                           const SkCoincidentSpans* outer, const SkOpPtT* over1s,
2708016b264ceec2b11d2acbeb77a9fbe66e48368b9caryclark                           const SkOpPtT* over1e) const;
271ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    void debugAddIfMissing(SkPathOpsDebug::GlitchLog* ,
2728016b264ceec2b11d2acbeb77a9fbe66e48368b9caryclark                           const SkOpPtT* over1s, const SkOpPtT* over2s,
27326ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark                           double tStart, double tEnd,
27481a478ca6c36aac3e53ce0373a281ac8940f4780caryclark                           const SkOpSegment* coinSeg, const SkOpSegment* oppSeg, bool* added,
2758016b264ceec2b11d2acbeb77a9fbe66e48368b9caryclark                           const SkOpPtT* over1e, const SkOpPtT* over2e) const;
276ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    void debugAddEndMovedSpans(SkPathOpsDebug::GlitchLog* ,
277ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark                               const SkOpSpan* base, const SkOpSpanBase* testSpan) const;
278ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark    void debugAddEndMovedSpans(SkPathOpsDebug::GlitchLog* ,
279ab87d7abf1df007c90bef2e916294ca325d81c81Cary Clark                               const SkOpPtT* ptT) const;
28055888e44171ffd48b591d19256884a969fe4da17caryclark#endif
28155888e44171ffd48b591d19256884a969fe4da17caryclark    void fixUp(SkCoincidentSpans* coin, SkOpPtT* deleted, const SkOpPtT* kept);
28255888e44171ffd48b591d19256884a969fe4da17caryclark    void markCollapsed(SkCoincidentSpans* head, SkOpPtT* test);
28354359294a7c9dc54802d512a5d891a35c1663392caryclark    bool overlap(const SkOpPtT* coinStart1, const SkOpPtT* coinEnd1,
28454359294a7c9dc54802d512a5d891a35c1663392caryclark                 const SkOpPtT* coinStart2, const SkOpPtT* coinEnd2,
28554359294a7c9dc54802d512a5d891a35c1663392caryclark                 double* overS, double* overE) const;
28655888e44171ffd48b591d19256884a969fe4da17caryclark    bool release(SkCoincidentSpans* coin, SkCoincidentSpans* );
28730b9fdd6a1d607bde20c793af65b5e2e8a1737cacaryclark    void releaseDeleted(SkCoincidentSpans* );
28855888e44171ffd48b591d19256884a969fe4da17caryclark    void restoreHead();
2898016b264ceec2b11d2acbeb77a9fbe66e48368b9caryclark    // return coinPtT->segment()->t mapped from overS->fT <= t <= overE->fT
2908016b264ceec2b11d2acbeb77a9fbe66e48368b9caryclark    static double TRange(const SkOpPtT* overS, double t, const SkOpSegment* coinPtT
2918016b264ceec2b11d2acbeb77a9fbe66e48368b9caryclark                         SkDEBUGPARAMS(const SkOpPtT* overE));
29255888e44171ffd48b591d19256884a969fe4da17caryclark
29345fa447460f70ec21d22cf4e1531490acfd3c578caryclark    SkCoincidentSpans* fHead;
29427c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark    SkCoincidentSpans* fTop;
29555888e44171ffd48b591d19256884a969fe4da17caryclark    SkOpGlobalState* fGlobalState;
29655888e44171ffd48b591d19256884a969fe4da17caryclark    bool fContinue;
29755888e44171ffd48b591d19256884a969fe4da17caryclark    bool fSpanDeleted;
29855888e44171ffd48b591d19256884a969fe4da17caryclark    bool fPtAllocated;
29955888e44171ffd48b591d19256884a969fe4da17caryclark    bool fCoinExtended;
30055888e44171ffd48b591d19256884a969fe4da17caryclark    bool fSpanMerged;
30145fa447460f70ec21d22cf4e1531490acfd3c578caryclark};
30245fa447460f70ec21d22cf4e1531490acfd3c578caryclark
30345fa447460f70ec21d22cf4e1531490acfd3c578caryclark#endif
304