/* * 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 "SkOpTAllocator.h" #include "SkOpSpan.h" #include "SkPathOpsTypes.h" class SkOpPtT; struct SkCoincidentSpans { SkCoincidentSpans* fNext; SkOpPtT* fCoinPtTStart; SkOpPtT* fCoinPtTEnd; SkOpPtT* fOppPtTStart; SkOpPtT* fOppPtTEnd; bool fFlipped; SkDEBUGCODE(int fID); int debugID() const { return SkDEBUGRELEASE(fID, -1); } void dump() const; }; class SkOpCoincidence { public: SkOpCoincidence() : fHead(nullptr) , fTop(nullptr) SkDEBUGPARAMS(fDebugState(nullptr)) { } void add(SkOpPtT* coinPtTStart, SkOpPtT* coinPtTEnd, SkOpPtT* oppPtTStart, SkOpPtT* oppPtTEnd, SkChunkAlloc* allocator); bool addExpanded(SkChunkAlloc* allocator PATH_OPS_DEBUG_VALIDATE_PARAMS(SkOpGlobalState* )); bool addMissing(SkChunkAlloc* allocator); bool apply(); bool contains(const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, const SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd, bool flipped) const; void debugAddExpanded(const char* id, SkPathOpsDebug::GlitchLog* ) const; void debugAddMissing(const char* id, SkPathOpsDebug::GlitchLog* ) const; const SkOpAngle* debugAngle(int id) const { return SkDEBUGRELEASE(fDebugState->debugAngle(id), nullptr); } SkOpContour* debugContour(int id) { return SkDEBUGRELEASE(fDebugState->debugContour(id), nullptr); } bool debugExpand(const char* id, SkPathOpsDebug::GlitchLog* ) const; void debugMark(const char* id, SkPathOpsDebug::GlitchLog* ) const; const SkOpPtT* debugPtT(int id) const { return SkDEBUGRELEASE(fDebugState->debugPtT(id), nullptr); } const SkOpSegment* debugSegment(int id) const { return SkDEBUGRELEASE(fDebugState->debugSegment(id), nullptr); } void debugSetGlobalState(SkOpGlobalState* debugState) { SkDEBUGCODE(fDebugState = debugState); } void debugFixAligned(const char* id, SkPathOpsDebug::GlitchLog* ) const; void debugShowCoincidence() const; const SkOpSpanBase* debugSpan(int id) const { return SkDEBUGRELEASE(fDebugState->debugSpan(id), nullptr); } void detach(SkCoincidentSpans* ); void dump() const; bool expand(); bool extend(SkOpPtT* coinPtTStart, SkOpPtT* coinPtTEnd, SkOpPtT* oppPtTStart, SkOpPtT* oppPtTEnd); void findOverlaps(SkOpCoincidence* , SkChunkAlloc* allocator) const; void fixAligned(); void fixUp(SkOpPtT* deleted, SkOpPtT* kept); bool isEmpty() const { return !fHead; } void mark(); private: bool addIfMissing(const SkCoincidentSpans* outer, SkOpPtT* over1s, SkOpPtT* over1e, SkChunkAlloc* ); bool addIfMissing(const SkOpPtT* over1s, const SkOpPtT* over1e, const SkOpPtT* over2s, const SkOpPtT* over2e, double tStart, double tEnd, SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd, SkChunkAlloc* ); void addOverlap(SkOpSegment* seg1, SkOpSegment* seg1o, SkOpSegment* seg2, SkOpSegment* seg2o, SkOpPtT* overS, SkOpPtT* overE, SkChunkAlloc* ); bool debugAddIfMissing(const SkCoincidentSpans* outer, const SkOpPtT* over1s, const SkOpPtT* over1e) const; bool debugAddIfMissing(const SkOpPtT* over1s, const SkOpPtT* over1e, const SkOpPtT* over2s, const SkOpPtT* over2e, double tStart, double tEnd, SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd) const; bool overlap(const SkOpPtT* coinStart1, const SkOpPtT* coinEnd1, const SkOpPtT* coinStart2, const SkOpPtT* coinEnd2, double* overS, double* overE) const; bool testForCoincidence(const SkCoincidentSpans* outer, const SkOpPtT* testS, const SkOpPtT* testE) const; SkCoincidentSpans* fHead; SkCoincidentSpans* fTop; SkDEBUGCODE_(SkOpGlobalState* fDebugState); }; #endif