| Index: src/pathops/SkOpSpan.h
|
| diff --git a/src/pathops/SkOpSpan.h b/src/pathops/SkOpSpan.h
|
| index 9e5939a5e1e90f15a696b01af243144d1470085a..d9ce44eb7720fb4fb4cd78521b1ec750f15b9358 100644
|
| --- a/src/pathops/SkOpSpan.h
|
| +++ b/src/pathops/SkOpSpan.h
|
| @@ -7,460 +7,36 @@
|
| #ifndef SkOpSpan_DEFINED
|
| #define SkOpSpan_DEFINED
|
|
|
| -#include "SkPathOpsDebug.h"
|
| #include "SkPoint.h"
|
|
|
| -class SkChunkAlloc;
|
| -struct SkOpAngle;
|
| -class SkOpContour;
|
| -class SkOpGlobalState;
|
| +class SkOpAngle;
|
| class SkOpSegment;
|
| -class SkOpSpanBase;
|
| -class SkOpSpan;
|
|
|
| -// subset of op span used by terminal span (when t is equal to one)
|
| -class SkOpPtT {
|
| -public:
|
| - enum {
|
| - kIsAlias = 1,
|
| - kIsDuplicate = 1
|
| - };
|
| -
|
| - void addOpp(SkOpPtT* opp) {
|
| - // find the fOpp ptr to opp
|
| - SkOpPtT* oppPrev = opp->fNext;
|
| - if (oppPrev == this) {
|
| - return;
|
| - }
|
| - while (oppPrev->fNext != opp) {
|
| - oppPrev = oppPrev->fNext;
|
| - if (oppPrev == this) {
|
| - return;
|
| - }
|
| - }
|
| -
|
| - SkOpPtT* oldNext = this->fNext;
|
| - SkASSERT(this != opp);
|
| - this->fNext = opp;
|
| - SkASSERT(oppPrev != oldNext);
|
| - oppPrev->fNext = oldNext;
|
| - }
|
| -
|
| - bool alias() const;
|
| - SkOpContour* contour() const;
|
| -
|
| - int debugID() const {
|
| - return PATH_OPS_DEBUG_RELEASE(fID, -1);
|
| - }
|
| -
|
| - const SkOpAngle* debugAngle(int id) const;
|
| - SkOpContour* debugContour(int id);
|
| - int debugLoopLimit(bool report) const;
|
| - bool debugMatchID(int id) const;
|
| - const SkOpPtT* debugPtT(int id) const;
|
| - const SkOpSegment* debugSegment(int id) const;
|
| - const SkOpSpanBase* debugSpan(int id) const;
|
| - SkOpGlobalState* globalState() const;
|
| - void debugValidate() const;
|
| -
|
| - bool deleted() const {
|
| - return fDeleted;
|
| - }
|
| -
|
| - bool duplicate() const {
|
| - return fDuplicatePt;
|
| - }
|
| -
|
| - void dump() const; // available to testing only
|
| - void dumpAll() const;
|
| - void dumpBase() const;
|
| -
|
| - void init(SkOpSpanBase* , double t, const SkPoint& , bool dup);
|
| -
|
| - void insert(SkOpPtT* span) {
|
| - SkASSERT(span != this);
|
| - span->fNext = fNext;
|
| - fNext = span;
|
| - }
|
| -
|
| - const SkOpPtT* next() const {
|
| - return fNext;
|
| - }
|
| -
|
| - SkOpPtT* next() {
|
| - return fNext;
|
| - }
|
| -
|
| - bool onEnd() const;
|
| - SkOpPtT* prev();
|
| - SkOpPtT* remove();
|
| - void removeNext(SkOpPtT* kept);
|
| -
|
| - const SkOpSegment* segment() const;
|
| - SkOpSegment* segment();
|
| -
|
| - void setDeleted() {
|
| - SkASSERT(!fDeleted);
|
| - fDeleted = true;
|
| - }
|
| -
|
| - const SkOpSpanBase* span() const {
|
| - return fSpan;
|
| - }
|
| -
|
| - SkOpSpanBase* span() {
|
| - return fSpan;
|
| - }
|
| -
|
| - double fT;
|
| - SkPoint fPt; // cache of point value at this t
|
| -protected:
|
| - SkOpSpanBase* fSpan; // contains winding data
|
| - SkOpPtT* fNext; // intersection on opposite curve or alias on this curve
|
| - bool fDeleted; // set if removed from span list
|
| - bool fDuplicatePt; // set if identical pt is somewhere in the next loop
|
| - PATH_OPS_DEBUG_CODE(int fID);
|
| -};
|
| -
|
| -class SkOpSpanBase {
|
| -public:
|
| - void addSimpleAngle(bool checkFrom , SkChunkAlloc* );
|
| - void align();
|
| -
|
| - bool aligned() const {
|
| - return fAligned;
|
| - }
|
| -
|
| - void alignEnd(double t, const SkPoint& pt);
|
| -
|
| - bool chased() const {
|
| - return fChased;
|
| - }
|
| -
|
| - void clearCoinEnd() {
|
| - SkASSERT(fCoinEnd != this);
|
| - fCoinEnd = this;
|
| - }
|
| -
|
| - const SkOpSpanBase* coinEnd() const {
|
| - return fCoinEnd;
|
| - }
|
| -
|
| - bool contains(const SkOpSpanBase* ) const;
|
| - SkOpPtT* contains(const SkOpSegment* );
|
| -
|
| - bool containsCoinEnd(const SkOpSpanBase* coin) const {
|
| - SkASSERT(this != coin);
|
| - const SkOpSpanBase* next = this;
|
| - while ((next = next->fCoinEnd) != this) {
|
| - if (next == coin) {
|
| - return true;
|
| - }
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - bool containsCoinEnd(const SkOpSegment* ) const;
|
| - SkOpContour* contour() const;
|
| -
|
| - int debugBumpCount() {
|
| - return PATH_OPS_DEBUG_RELEASE(++fCount, -1);
|
| - }
|
| -
|
| - int debugID() const {
|
| - return PATH_OPS_DEBUG_RELEASE(fID, -1);
|
| - }
|
| -
|
| - const SkOpAngle* debugAngle(int id) const;
|
| - bool debugCoinEndLoopCheck() const;
|
| - SkOpContour* debugContour(int id);
|
| - const SkOpPtT* debugPtT(int id) const;
|
| - const SkOpSegment* debugSegment(int id) const;
|
| - const SkOpSpanBase* debugSpan(int id) const;
|
| - SkOpGlobalState* globalState() const;
|
| - void debugValidate() const;
|
| -
|
| - bool deleted() const {
|
| - return fPtT.deleted();
|
| - }
|
| -
|
| - void dump() const; // available to testing only
|
| - void dumpCoin() const;
|
| - void dumpAll() const;
|
| - void dumpBase() const;
|
| -
|
| - bool final() const {
|
| - return fPtT.fT == 1;
|
| - }
|
| -
|
| - SkOpAngle* fromAngle() const {
|
| - return fFromAngle;
|
| - }
|
| -
|
| - void initBase(SkOpSegment* parent, SkOpSpan* prev, double t, const SkPoint& pt);
|
| -
|
| - void insertCoinEnd(SkOpSpanBase* coin) {
|
| - if (containsCoinEnd(coin)) {
|
| - SkASSERT(coin->containsCoinEnd(this));
|
| - return;
|
| - }
|
| - debugValidate();
|
| - SkASSERT(this != coin);
|
| - SkOpSpanBase* coinNext = coin->fCoinEnd;
|
| - coin->fCoinEnd = this->fCoinEnd;
|
| - this->fCoinEnd = coinNext;
|
| - debugValidate();
|
| - }
|
| -
|
| - void merge(SkOpSpan* span);
|
| -
|
| - SkOpSpan* prev() const {
|
| - return fPrev;
|
| - }
|
| -
|
| - const SkPoint& pt() const {
|
| - return fPtT.fPt;
|
| - }
|
| -
|
| - const SkOpPtT* ptT() const {
|
| - return &fPtT;
|
| - }
|
| -
|
| - SkOpPtT* ptT() {
|
| - return &fPtT;
|
| - }
|
| -
|
| - SkOpSegment* segment() const {
|
| - return fSegment;
|
| - }
|
| -
|
| - void setChased(bool chased) {
|
| - fChased = chased;
|
| - }
|
| -
|
| - SkOpPtT* setCoinEnd(SkOpSpanBase* oldCoinEnd, SkOpSegment* oppSegment);
|
| -
|
| - void setFromAngle(SkOpAngle* angle) {
|
| - fFromAngle = angle;
|
| - }
|
| -
|
| - void setPrev(SkOpSpan* prev) {
|
| - fPrev = prev;
|
| - }
|
| -
|
| - bool simple() const {
|
| - fPtT.debugValidate();
|
| - return fPtT.next()->next() == &fPtT;
|
| - }
|
| -
|
| - const SkOpSpan* starter(const SkOpSpanBase* end) const {
|
| - const SkOpSpanBase* result = t() < end->t() ? this : end;
|
| - return result->upCast();
|
| - }
|
| -
|
| - SkOpSpan* starter(SkOpSpanBase* end) {
|
| - SkASSERT(this->segment() == end->segment());
|
| - SkOpSpanBase* result = t() < end->t() ? this : end;
|
| - return result->upCast();
|
| - }
|
| -
|
| - SkOpSpan* starter(SkOpSpanBase** endPtr) {
|
| - SkOpSpanBase* end = *endPtr;
|
| - SkASSERT(this->segment() == end->segment());
|
| - SkOpSpanBase* result;
|
| - if (t() < end->t()) {
|
| - result = this;
|
| - } else {
|
| - result = end;
|
| - *endPtr = this;
|
| - }
|
| - return result->upCast();
|
| - }
|
| -
|
| - int step(const SkOpSpanBase* end) const {
|
| - return t() < end->t() ? 1 : -1;
|
| - }
|
| -
|
| - double t() const {
|
| - return fPtT.fT;
|
| - }
|
| -
|
| - void unaligned() {
|
| - fAligned = false;
|
| - }
|
| -
|
| - SkOpSpan* upCast() {
|
| - SkASSERT(!final());
|
| - return (SkOpSpan*) this;
|
| - }
|
| -
|
| - const SkOpSpan* upCast() const {
|
| - SkASSERT(!final());
|
| - return (const SkOpSpan*) this;
|
| - }
|
| -
|
| - SkOpSpan* upCastable() {
|
| - return final() ? NULL : upCast();
|
| - }
|
| -
|
| - const SkOpSpan* upCastable() const {
|
| - return final() ? NULL : upCast();
|
| - }
|
| -
|
| -private:
|
| - void alignInner();
|
| -
|
| -protected: // no direct access to internals to avoid treating a span base as a span
|
| - SkOpPtT fPtT; // list of points and t values associated with the start of this span
|
| - SkOpSegment* fSegment; // segment that contains this span
|
| - SkOpSpanBase* fCoinEnd; // linked list of coincident spans that end here (may point to itself)
|
| - SkOpAngle* fFromAngle; // points to next angle from span start to end
|
| - SkOpSpan* fPrev; // previous intersection point
|
| - bool fAligned;
|
| - bool fChased; // set after span has been added to chase array
|
| - PATH_OPS_DEBUG_CODE(int fCount); // number of pt/t pairs added
|
| - PATH_OPS_DEBUG_CODE(int fID);
|
| -};
|
| -
|
| -class SkOpSpan : public SkOpSpanBase {
|
| -public:
|
| - void applyCoincidence(SkOpSpan* opp);
|
| -
|
| - bool clearCoincident() {
|
| - SkASSERT(!final());
|
| - if (fCoincident == this) {
|
| - return false;
|
| - }
|
| - fCoincident = this;
|
| - return true;
|
| - }
|
| -
|
| - bool containsCoincidence(const SkOpSegment* ) const;
|
| -
|
| - bool containsCoincidence(const SkOpSpan* coin) const {
|
| - SkASSERT(this != coin);
|
| - const SkOpSpan* next = this;
|
| - while ((next = next->fCoincident) != this) {
|
| - if (next == coin) {
|
| - return true;
|
| - }
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - bool debugCoinLoopCheck() const;
|
| - void detach(SkOpPtT* );
|
| -
|
| - bool done() const {
|
| - SkASSERT(!final());
|
| - return fDone;
|
| - }
|
| -
|
| - void dumpCoin() const;
|
| - bool dumpSpan() const;
|
| - void init(SkOpSegment* parent, SkOpSpan* prev, double t, const SkPoint& pt);
|
| -
|
| - void insertCoincidence(SkOpSpan* coin) {
|
| - if (containsCoincidence(coin)) {
|
| - SkASSERT(coin->containsCoincidence(this));
|
| - return;
|
| - }
|
| - debugValidate();
|
| - SkASSERT(this != coin);
|
| - SkOpSpan* coinNext = coin->fCoincident;
|
| - coin->fCoincident = this->fCoincident;
|
| - this->fCoincident = coinNext;
|
| - debugValidate();
|
| - }
|
| -
|
| - bool isCanceled() const {
|
| - SkASSERT(!final());
|
| - return fWindValue == 0 && fOppValue == 0;
|
| - }
|
| -
|
| - bool isCoincident() const {
|
| - SkASSERT(!final());
|
| - return fCoincident != this;
|
| - }
|
| -
|
| - SkOpSpanBase* next() const {
|
| - SkASSERT(!final());
|
| - return fNext;
|
| - }
|
| -
|
| - int oppSum() const {
|
| - SkASSERT(!final());
|
| - return fOppSum;
|
| - }
|
| -
|
| - int oppValue() const {
|
| - SkASSERT(!final());
|
| - return fOppValue;
|
| - }
|
| -
|
| - SkOpPtT* setCoinStart(SkOpSpan* oldCoinStart, SkOpSegment* oppSegment);
|
| -
|
| - void setDone(bool done) {
|
| - SkASSERT(!final());
|
| - fDone = done;
|
| - }
|
| -
|
| - void setNext(SkOpSpanBase* nextT) {
|
| - SkASSERT(!final());
|
| - fNext = nextT;
|
| - }
|
| -
|
| - void setOppSum(int oppSum);
|
| -
|
| - void setOppValue(int oppValue) {
|
| - SkASSERT(!final());
|
| - SkASSERT(fOppSum == SK_MinS32);
|
| - fOppValue = oppValue;
|
| - }
|
| -
|
| - void setToAngle(SkOpAngle* angle) {
|
| - SkASSERT(!final());
|
| - fToAngle = angle;
|
| - }
|
| -
|
| - void setWindSum(int windSum) {
|
| - SkASSERT(!final());
|
| - SkASSERT(fWindSum == SK_MinS32 || fWindSum == windSum);
|
| - SkASSERT(!DEBUG_LIMIT_WIND_SUM || abs(windSum) <= DEBUG_LIMIT_WIND_SUM);
|
| - fWindSum = windSum;
|
| - }
|
| -
|
| - void setWindValue(int windValue) {
|
| - SkASSERT(!final());
|
| - SkASSERT(windValue >= 0);
|
| - SkASSERT(fWindSum == SK_MinS32);
|
| - fWindValue = windValue;
|
| - }
|
| -
|
| - SkOpAngle* toAngle() const {
|
| - SkASSERT(!final());
|
| - return fToAngle;
|
| - }
|
| -
|
| - int windSum() const {
|
| - SkASSERT(!final());
|
| - return fWindSum;
|
| - }
|
| -
|
| - int windValue() const {
|
| - SkASSERT(!final());
|
| - return fWindValue;
|
| - }
|
| -
|
| -private: // no direct access to internals to avoid treating a span base as a span
|
| - SkOpSpan* fCoincident; // linked list of spans coincident with this one (may point to itself)
|
| - SkOpAngle* fToAngle; // points to next angle from span start to end
|
| - SkOpSpanBase* fNext; // next intersection point
|
| +struct SkOpSpan {
|
| + SkPoint fPt; // computed when the curves are intersected
|
| + double fT;
|
| + double fOtherT; // value at fOther[fOtherIndex].fT
|
| + SkOpSegment* fOther;
|
| + SkOpAngle* fFromAngle; // (if t > 0) index into segment's angle array going negative in t
|
| + SkOpAngle* fToAngle; // (if t < 1) index into segment's angle array going positive in t
|
| + int fOtherIndex; // can't be used during intersection
|
| int fWindSum; // accumulated from contours surrounding this one.
|
| int fOppSum; // for binary operators: the opposite winding sum
|
| int fWindValue; // 0 == canceled; 1 == normal; >1 == coincident
|
| int fOppValue; // normally 0 -- when binary coincident edges combine, opp value goes here
|
| + bool fChased; // set after span has been added to chase array
|
| + bool fCoincident; // set if span is bumped -- if set additional points aren't inserted
|
| bool fDone; // if set, this span to next higher T has been processed
|
| + bool fLoop; // set when a cubic loops back to this point
|
| + bool fMultiple; // set if this is one of mutiple spans with identical t and pt values
|
| + bool fNear; // set if opposite end point is near but not equal to this one
|
| + bool fSmall; // if set, consecutive points are almost equal
|
| + bool fTiny; // if set, consecutive points are equal but consecutive ts are not precisely equal
|
| +
|
| + // available to testing only
|
| + const SkOpSegment* debugToSegment(ptrdiff_t* ) const;
|
| + void dump() const;
|
| + void dumpOne() const;
|
| };
|
|
|
| #endif
|
|
|