123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- /*
- * Copyright 2013 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #ifndef SkOpCoincidence_DEFINED
- #define SkOpCoincidence_DEFINED
- #include "include/private/SkTDArray.h"
- #include "src/core/SkArenaAlloc.h"
- #include "src/pathops/SkOpSpan.h"
- #include "src/pathops/SkPathOpsTypes.h"
- class SkOpPtT;
- class SkOpSpanBase;
- class SkCoincidentSpans {
- public:
- const SkOpPtT* coinPtTEnd() const;
- const SkOpPtT* coinPtTStart() const;
- // These return non-const pointers so that, as copies, they can be added
- // to a new span pair
- SkOpPtT* coinPtTEndWritable() const { return const_cast<SkOpPtT*>(fCoinPtTEnd); }
- SkOpPtT* coinPtTStartWritable() const { return const_cast<SkOpPtT*>(fCoinPtTStart); }
- bool collapsed(const SkOpPtT* ) const;
- bool contains(const SkOpPtT* s, const SkOpPtT* e) const;
- void correctEnds();
- void correctOneEnd(const SkOpPtT* (SkCoincidentSpans::* getEnd)() const,
- void (SkCoincidentSpans::* setEnd)(const SkOpPtT* ptT) );
- #if DEBUG_COIN
- void debugCorrectEnds(SkPathOpsDebug::GlitchLog* log) const;
- void debugCorrectOneEnd(SkPathOpsDebug::GlitchLog* log,
- const SkOpPtT* (SkCoincidentSpans::* getEnd)() const,
- void (SkCoincidentSpans::* setEnd)(const SkOpPtT* ptT) const) const;
- bool debugExpand(SkPathOpsDebug::GlitchLog* log) const;
- #endif
- const char* debugID() const {
- #if DEBUG_COIN
- return fGlobalState->debugCoinDictEntry().fFunctionName;
- #else
- return nullptr;
- #endif
- }
- void debugShow() const;
- #ifdef SK_DEBUG
- void debugStartCheck(const SkOpSpanBase* outer, const SkOpSpanBase* over,
- const SkOpGlobalState* debugState) const;
- #endif
- void dump() const;
- bool expand();
- bool extend(const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd,
- const SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd);
- bool flipped() const { return fOppPtTStart->fT > fOppPtTEnd->fT; }
- SkDEBUGCODE(SkOpGlobalState* globalState() { return fGlobalState; })
- void init(SkDEBUGCODE(SkOpGlobalState* globalState)) {
- sk_bzero(this, sizeof(*this));
- SkDEBUGCODE(fGlobalState = globalState);
- }
- SkCoincidentSpans* next() { return fNext; }
- const SkCoincidentSpans* next() const { return fNext; }
- SkCoincidentSpans** nextPtr() { return &fNext; }
- const SkOpPtT* oppPtTStart() const;
- const SkOpPtT* oppPtTEnd() const;
- // These return non-const pointers so that, as copies, they can be added
- // to a new span pair
- SkOpPtT* oppPtTStartWritable() const { return const_cast<SkOpPtT*>(fOppPtTStart); }
- SkOpPtT* oppPtTEndWritable() const { return const_cast<SkOpPtT*>(fOppPtTEnd); }
- bool ordered(bool* result) const;
- void set(SkCoincidentSpans* next, const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd,
- const SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd);
- void setCoinPtTEnd(const SkOpPtT* ptT) {
- SkOPASSERT(ptT == ptT->span()->ptT());
- SkOPASSERT(!fCoinPtTStart || ptT->fT != fCoinPtTStart->fT);
- SkASSERT(!fCoinPtTStart || fCoinPtTStart->segment() == ptT->segment());
- fCoinPtTEnd = ptT;
- ptT->setCoincident();
- }
- void setCoinPtTStart(const SkOpPtT* ptT) {
- SkOPASSERT(ptT == ptT->span()->ptT());
- SkOPASSERT(!fCoinPtTEnd || ptT->fT != fCoinPtTEnd->fT);
- SkASSERT(!fCoinPtTEnd || fCoinPtTEnd->segment() == ptT->segment());
- fCoinPtTStart = ptT;
- ptT->setCoincident();
- }
- void setEnds(const SkOpPtT* coinPtTEnd, const SkOpPtT* oppPtTEnd) {
- this->setCoinPtTEnd(coinPtTEnd);
- this->setOppPtTEnd(oppPtTEnd);
- }
- void setOppPtTEnd(const SkOpPtT* ptT) {
- SkOPASSERT(ptT == ptT->span()->ptT());
- SkOPASSERT(!fOppPtTStart || ptT->fT != fOppPtTStart->fT);
- SkASSERT(!fOppPtTStart || fOppPtTStart->segment() == ptT->segment());
- fOppPtTEnd = ptT;
- ptT->setCoincident();
- }
- void setOppPtTStart(const SkOpPtT* ptT) {
- SkOPASSERT(ptT == ptT->span()->ptT());
- SkOPASSERT(!fOppPtTEnd || ptT->fT != fOppPtTEnd->fT);
- SkASSERT(!fOppPtTEnd || fOppPtTEnd->segment() == ptT->segment());
- fOppPtTStart = ptT;
- ptT->setCoincident();
- }
- void setStarts(const SkOpPtT* coinPtTStart, const SkOpPtT* oppPtTStart) {
- this->setCoinPtTStart(coinPtTStart);
- this->setOppPtTStart(oppPtTStart);
- }
- void setNext(SkCoincidentSpans* next) { fNext = next; }
- private:
- SkCoincidentSpans* fNext;
- const SkOpPtT* fCoinPtTStart;
- const SkOpPtT* fCoinPtTEnd;
- const SkOpPtT* fOppPtTStart;
- const SkOpPtT* fOppPtTEnd;
- SkDEBUGCODE(SkOpGlobalState* fGlobalState);
- };
- class SkOpCoincidence {
- public:
- SkOpCoincidence(SkOpGlobalState* globalState)
- : fHead(nullptr)
- , fTop(nullptr)
- , fGlobalState(globalState)
- , fContinue(false)
- , fSpanDeleted(false)
- , fPtAllocated(false)
- , fCoinExtended(false)
- , fSpanMerged(false) {
- globalState->setCoincidence(this);
- }
- void add(SkOpPtT* coinPtTStart, SkOpPtT* coinPtTEnd, SkOpPtT* oppPtTStart,
- SkOpPtT* oppPtTEnd);
- bool addEndMovedSpans(DEBUG_COIN_DECLARE_ONLY_PARAMS());
- bool addExpanded(DEBUG_COIN_DECLARE_ONLY_PARAMS());
- bool addMissing(bool* added DEBUG_COIN_DECLARE_PARAMS());
- bool apply(DEBUG_COIN_DECLARE_ONLY_PARAMS());
- bool contains(const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd,
- const SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd) const;
- void correctEnds(DEBUG_COIN_DECLARE_ONLY_PARAMS());
- #if DEBUG_COIN
- void debugAddEndMovedSpans(SkPathOpsDebug::GlitchLog* log) const;
- void debugAddExpanded(SkPathOpsDebug::GlitchLog* ) const;
- void debugAddMissing(SkPathOpsDebug::GlitchLog* , bool* added) const;
- void debugAddOrOverlap(SkPathOpsDebug::GlitchLog* log,
- const SkOpSegment* coinSeg, const SkOpSegment* oppSeg,
- double coinTs, double coinTe, double oppTs, double oppTe,
- bool* added) const;
- #endif
- const SkOpAngle* debugAngle(int id) const {
- return SkDEBUGRELEASE(fGlobalState->debugAngle(id), nullptr);
- }
- void debugCheckBetween() const;
- #if DEBUG_COIN
- void debugCheckValid(SkPathOpsDebug::GlitchLog* log) const;
- #endif
- SkOpContour* debugContour(int id) const {
- return SkDEBUGRELEASE(fGlobalState->debugContour(id), nullptr);
- }
- #if DEBUG_COIN
- void debugCorrectEnds(SkPathOpsDebug::GlitchLog* log) const;
- bool debugExpand(SkPathOpsDebug::GlitchLog* ) const;
- void debugMark(SkPathOpsDebug::GlitchLog* ) const;
- void debugMarkCollapsed(SkPathOpsDebug::GlitchLog* ,
- const SkCoincidentSpans* coin, const SkOpPtT* test) const;
- void debugMarkCollapsed(SkPathOpsDebug::GlitchLog* , const SkOpPtT* test) const;
- #endif
- const SkOpPtT* debugPtT(int id) const {
- return SkDEBUGRELEASE(fGlobalState->debugPtT(id), nullptr);
- }
- const SkOpSegment* debugSegment(int id) const {
- return SkDEBUGRELEASE(fGlobalState->debugSegment(id), nullptr);
- }
- #if DEBUG_COIN
- void debugRelease(SkPathOpsDebug::GlitchLog* , const SkCoincidentSpans* ,
- const SkCoincidentSpans* ) const;
- void debugRelease(SkPathOpsDebug::GlitchLog* , const SkOpSegment* ) const;
- #endif
- void debugShowCoincidence() const;
- const SkOpSpanBase* debugSpan(int id) const {
- return SkDEBUGRELEASE(fGlobalState->debugSpan(id), nullptr);
- }
- void debugValidate() const;
- void dump() const;
- bool expand(DEBUG_COIN_DECLARE_ONLY_PARAMS());
- bool extend(const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, const SkOpPtT* oppPtTStart,
- const SkOpPtT* oppPtTEnd);
- bool findOverlaps(SkOpCoincidence* DEBUG_COIN_DECLARE_PARAMS()) const;
- void fixUp(SkOpPtT* deleted, const SkOpPtT* kept);
- SkOpGlobalState* globalState() {
- return fGlobalState;
- }
- const SkOpGlobalState* globalState() const {
- return fGlobalState;
- }
- bool isEmpty() const {
- return !fHead && !fTop;
- }
- bool mark(DEBUG_COIN_DECLARE_ONLY_PARAMS());
- void markCollapsed(SkOpPtT* );
- static bool Ordered(const SkOpPtT* coinPtTStart, const SkOpPtT* oppPtTStart) {
- return Ordered(coinPtTStart->segment(), oppPtTStart->segment());
- }
- static bool Ordered(const SkOpSegment* coin, const SkOpSegment* opp);
- void release(const SkOpSegment* );
- void releaseDeleted();
- private:
- void add(const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, const SkOpPtT* oppPtTStart,
- const SkOpPtT* oppPtTEnd) {
- this->add(const_cast<SkOpPtT*>(coinPtTStart), const_cast<SkOpPtT*>(coinPtTEnd),
- const_cast<SkOpPtT*>(oppPtTStart), const_cast<SkOpPtT*>(oppPtTEnd));
- }
- bool addEndMovedSpans(const SkOpSpan* base, const SkOpSpanBase* testSpan);
- bool addEndMovedSpans(const SkOpPtT* ptT);
- bool addIfMissing(const SkOpPtT* over1s, const SkOpPtT* over2s,
- double tStart, double tEnd, SkOpSegment* coinSeg, SkOpSegment* oppSeg,
- bool* added
- SkDEBUGPARAMS(const SkOpPtT* over1e) SkDEBUGPARAMS(const SkOpPtT* over2e));
- bool addOrOverlap(SkOpSegment* coinSeg, SkOpSegment* oppSeg,
- double coinTs, double coinTe, double oppTs, double oppTe, bool* added);
- bool addOverlap(const SkOpSegment* seg1, const SkOpSegment* seg1o,
- const SkOpSegment* seg2, const SkOpSegment* seg2o,
- const SkOpPtT* overS, const SkOpPtT* overE);
- bool checkOverlap(SkCoincidentSpans* check,
- const SkOpSegment* coinSeg, const SkOpSegment* oppSeg,
- double coinTs, double coinTe, double oppTs, double oppTe,
- SkTDArray<SkCoincidentSpans*>* overlaps) const;
- bool contains(const SkOpSegment* seg, const SkOpSegment* opp, double oppT) const;
- bool contains(const SkCoincidentSpans* coin, const SkOpSegment* seg,
- const SkOpSegment* opp, double oppT) const;
- #if DEBUG_COIN
- void debugAddIfMissing(SkPathOpsDebug::GlitchLog* ,
- const SkCoincidentSpans* outer, const SkOpPtT* over1s,
- const SkOpPtT* over1e) const;
- void debugAddIfMissing(SkPathOpsDebug::GlitchLog* ,
- const SkOpPtT* over1s, const SkOpPtT* over2s,
- double tStart, double tEnd,
- const SkOpSegment* coinSeg, const SkOpSegment* oppSeg, bool* added,
- const SkOpPtT* over1e, const SkOpPtT* over2e) const;
- void debugAddEndMovedSpans(SkPathOpsDebug::GlitchLog* ,
- const SkOpSpan* base, const SkOpSpanBase* testSpan) const;
- void debugAddEndMovedSpans(SkPathOpsDebug::GlitchLog* ,
- const SkOpPtT* ptT) const;
- #endif
- void fixUp(SkCoincidentSpans* coin, SkOpPtT* deleted, const SkOpPtT* kept);
- void markCollapsed(SkCoincidentSpans* head, SkOpPtT* test);
- bool overlap(const SkOpPtT* coinStart1, const SkOpPtT* coinEnd1,
- const SkOpPtT* coinStart2, const SkOpPtT* coinEnd2,
- double* overS, double* overE) const;
- bool release(SkCoincidentSpans* coin, SkCoincidentSpans* );
- void releaseDeleted(SkCoincidentSpans* );
- void restoreHead();
- // return coinPtT->segment()->t mapped from overS->fT <= t <= overE->fT
- static double TRange(const SkOpPtT* overS, double t, const SkOpSegment* coinPtT
- SkDEBUGPARAMS(const SkOpPtT* overE));
- SkCoincidentSpans* fHead;
- SkCoincidentSpans* fTop;
- SkOpGlobalState* fGlobalState;
- bool fContinue;
- bool fSpanDeleted;
- bool fPtAllocated;
- bool fCoinExtended;
- bool fSpanMerged;
- };
- #endif
|