| Index: src/pathops/SkOpSegment.h
|
| diff --git a/src/pathops/SkOpSegment.h b/src/pathops/SkOpSegment.h
|
| index 1d67b1c1318515d5e6018bd0d7ff201cd3dd26a3..55e67a5d80bbf6f6bbbf56c827543fac72f3d7f1 100644
|
| --- a/src/pathops/SkOpSegment.h
|
| +++ b/src/pathops/SkOpSegment.h
|
| @@ -23,9 +23,9 @@ class SkPathWriter;
|
|
|
| class SkOpSegment {
|
| public:
|
| - enum AllowAlias {
|
| - kAllowAlias,
|
| - kNoAlias
|
| + enum AliasMatch {
|
| + kNoAliasMatch,
|
| + kAllowAliasMatch,
|
| };
|
|
|
| bool operator<(const SkOpSegment& rh) const {
|
| @@ -45,13 +45,6 @@ public:
|
|
|
| bool activeWinding(SkOpSpanBase* start, SkOpSpanBase* end);
|
| bool activeWinding(SkOpSpanBase* start, SkOpSpanBase* end, int* sumWinding);
|
| - void addAlignIntersection(SkOpPtT& endPtT, SkPoint& oldPt,
|
| - SkOpContourHead* contourList, SkChunkAlloc* allocator);
|
| -
|
| - void addAlignIntersections(SkOpContourHead* contourList, SkChunkAlloc* allocator) {
|
| - this->addAlignIntersection(*fHead.ptT(), fOriginal[0], contourList, allocator);
|
| - this->addAlignIntersection(*fTail.ptT(), fOriginal[1], contourList, allocator);
|
| - }
|
|
|
| SkOpSegment* addConic(SkPoint pts[3], SkScalar weight, SkOpContour* parent) {
|
| init(pts, weight, parent, SkPath::kConic_Verb);
|
| @@ -71,23 +64,25 @@ public:
|
|
|
| bool addCurveTo(const SkOpSpanBase* start, const SkOpSpanBase* end, SkPathWriter* path) const;
|
|
|
| - SkOpAngle* addEndSpan(SkChunkAlloc* allocator) {
|
| - SkOpAngle* angle = SkOpTAllocator<SkOpAngle>::Allocate(allocator);
|
| + SkOpAngle* addEndSpan() {
|
| + SkOpAngle* angle = SkOpTAllocator<SkOpAngle>::Allocate(this->globalState()->allocator());
|
| angle->set(&fTail, fTail.prev());
|
| fTail.setFromAngle(angle);
|
| return angle;
|
| }
|
|
|
| + bool addExpanded(double newT, const SkOpSpanBase* test, bool* startOver);
|
| +
|
| SkOpSegment* addLine(SkPoint pts[2], SkOpContour* parent) {
|
| init(pts, 1, parent, SkPath::kLine_Verb);
|
| fBounds.set(pts, 2);
|
| return this;
|
| }
|
|
|
| - SkOpPtT* addMissing(double t, SkOpSegment* opp, SkChunkAlloc* );
|
| + SkOpPtT* addMissing(double t, SkOpSegment* opp, bool* allExist);
|
|
|
| - SkOpAngle* addStartSpan(SkChunkAlloc* allocator) {
|
| - SkOpAngle* angle = SkOpTAllocator<SkOpAngle>::Allocate(allocator);
|
| + SkOpAngle* addStartSpan() {
|
| + SkOpAngle* angle = SkOpTAllocator<SkOpAngle>::Allocate(this->globalState()->allocator());
|
| angle->set(&fHead, fHead.next());
|
| fHead.setToAngle(angle);
|
| return angle;
|
| @@ -101,9 +96,11 @@ public:
|
| return this;
|
| }
|
|
|
| - SkOpPtT* addT(double t, AllowAlias , SkChunkAlloc* );
|
| + SkOpPtT* addT(double t, AliasMatch, bool* allocated);
|
|
|
| - void align();
|
| + template<typename T> T* allocateArray(int count) {
|
| + return SkOpTAllocator<T>::AllocateArray(this->globalState()->allocator(), count);
|
| + }
|
|
|
| const SkPathOpsBounds& bounds() const {
|
| return fBounds;
|
| @@ -113,7 +110,7 @@ public:
|
| ++fCount;
|
| }
|
|
|
| - void calcAngles(SkChunkAlloc*);
|
| + void calcAngles();
|
| bool collapsed() const;
|
| static void ComputeOneSum(const SkOpAngle* baseAngle, SkOpAngle* nextAngle,
|
| SkOpAngle::IncludeType );
|
| @@ -121,6 +118,11 @@ public:
|
| SkOpAngle::IncludeType );
|
| int computeSum(SkOpSpanBase* start, SkOpSpanBase* end, SkOpAngle::IncludeType includeType);
|
|
|
| + void clearAll();
|
| + void clearOne(SkOpSpan* span);
|
| + static void ClearVisited(SkOpSpanBase* span);
|
| + bool contains(double t) const;
|
| +
|
| SkOpContour* contour() const {
|
| return fContour;
|
| }
|
| @@ -129,36 +131,30 @@ public:
|
| return fCount;
|
| }
|
|
|
| - void debugAddAngle(double startT, double endT, SkChunkAlloc*);
|
| - void debugAddAlignIntersection(const char* id, SkPathOpsDebug::GlitchLog* glitches,
|
| - const SkOpPtT& endPtT, const SkPoint& oldPt,
|
| - const SkOpContourHead* ) const;
|
| -
|
| - void debugAddAlignIntersections(const char* id, SkPathOpsDebug::GlitchLog* glitches,
|
| - SkOpContourHead* contourList) const {
|
| - this->debugAddAlignIntersection(id, glitches, *fHead.ptT(), fOriginal[0], contourList);
|
| - this->debugAddAlignIntersection(id, glitches, *fTail.ptT(), fOriginal[1], contourList);
|
| - }
|
| -
|
| - bool debugAddMissing(double t, const SkOpSegment* opp) const;
|
| - void debugAlign(const char* id, SkPathOpsDebug::GlitchLog* glitches) const;
|
| + void debugAddAngle(double startT, double endT);
|
| + const SkOpPtT* debugAddT(double t, AliasMatch , bool* allocated) const;
|
| const SkOpAngle* debugAngle(int id) const;
|
| #if DEBUG_ANGLE
|
| void debugCheckAngleCoin() const;
|
| #endif
|
| +#if DEBUG_COINCIDENCE_VERBOSE
|
| void debugCheckHealth(const char* id, SkPathOpsDebug::GlitchLog* ) const;
|
| + void debugClearAll(const char* id, SkPathOpsDebug::GlitchLog* glitches) const;
|
| + void debugClearOne(const SkOpSpan* span, const char* id, SkPathOpsDebug::GlitchLog* glitches) const;
|
| +#endif
|
| + const SkOpCoincidence* debugCoincidence() const;
|
| SkOpContour* debugContour(int id);
|
| - void debugFindCollapsed(const char* id, SkPathOpsDebug::GlitchLog* glitches) const;
|
|
|
| int debugID() const {
|
| return SkDEBUGRELEASE(fID, -1);
|
| }
|
|
|
| SkOpAngle* debugLastAngle();
|
| - void debugMissingCoincidence(const char* id, SkPathOpsDebug::GlitchLog* glitches,
|
| - const SkOpCoincidence* coincidences) const;
|
| +#if DEBUG_COINCIDENCE_VERBOSE
|
| + void debugMissingCoincidence(const char* id, SkPathOpsDebug::GlitchLog* glitches) const;
|
| void debugMoveMultiples(const char* id, SkPathOpsDebug::GlitchLog* glitches) const;
|
| void debugMoveNearby(const char* id, SkPathOpsDebug::GlitchLog* glitches) const;
|
| +#endif
|
| const SkOpPtT* debugPtT(int id) const;
|
| void debugReset();
|
| const SkOpSegment* debugSegment(int id) const;
|
| @@ -173,11 +169,24 @@ public:
|
|
|
| const SkOpSpanBase* debugSpan(int id) const;
|
| void debugValidate() const;
|
| +
|
| +#if DEBUG_COINCIDENCE
|
| + static void SkOpSegment::DebugClearVisited(const SkOpSpanBase* span);
|
| +
|
| + bool debugVisited() const {
|
| + if (!fDebugVisited) {
|
| + fDebugVisited = true;
|
| + return false;
|
| + }
|
| + return true;
|
| + }
|
| +#endif
|
| +
|
| void release(const SkOpSpan* );
|
| double distSq(double t, const SkOpAngle* opp) const;
|
|
|
| bool done() const {
|
| - SkASSERT(fDoneCount <= fCount);
|
| + SkASSERT(this->globalState()->debugSkipAssert() || fDoneCount <= fCount);
|
| return fDoneCount == fCount;
|
| }
|
|
|
| @@ -200,7 +209,7 @@ public:
|
| void dumpPts(const char* prefix = "seg") const;
|
| void dumpPtsInner(const char* prefix = "seg") const;
|
|
|
| - void findCollapsed();
|
| + const SkOpPtT* existing(double t, const SkOpSegment* opp) const;
|
| SkOpSegment* findNextOp(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** nextStart,
|
| SkOpSpanBase** nextEnd, bool* unsortable, SkPathOp op,
|
| int xorMiMask, int xorSuMask);
|
| @@ -220,8 +229,8 @@ public:
|
|
|
| void init(SkPoint pts[], SkScalar weight, SkOpContour* parent, SkPath::Verb verb);
|
|
|
| - SkOpSpan* insert(SkOpSpan* prev, SkChunkAlloc* allocator) {
|
| - SkOpSpan* result = SkOpTAllocator<SkOpSpan>::Allocate(allocator);
|
| + SkOpSpan* insert(SkOpSpan* prev) {
|
| + SkOpSpan* result = SkOpTAllocator<SkOpSpan>::Allocate(this->globalState()->allocator());
|
| SkOpSpanBase* next = prev->next();
|
| result->setPrev(prev);
|
| prev->setNext(result);
|
| @@ -269,8 +278,9 @@ public:
|
| void markDone(SkOpSpan* );
|
| bool markWinding(SkOpSpan* , int winding);
|
| bool markWinding(SkOpSpan* , int winding, int oppWinding);
|
| - bool match(const SkOpPtT* span, const SkOpSegment* parent, double t, const SkPoint& pt) const;
|
| - bool missingCoincidence(SkOpCoincidence* coincidences, SkChunkAlloc* allocator);
|
| + bool match(const SkOpPtT* span, const SkOpSegment* parent, double t, const SkPoint& pt,
|
| + AliasMatch ) const;
|
| + bool missingCoincidence();
|
| bool moveMultiples();
|
| void moveNearby();
|
|
|
| @@ -302,17 +312,31 @@ public:
|
| }
|
|
|
| bool ptsDisjoint(const SkOpPtT& span, const SkOpPtT& test) const {
|
| + SkASSERT(this == span.segment());
|
| + SkASSERT(this == test.segment());
|
| return ptsDisjoint(span.fT, span.fPt, test.fT, test.fPt);
|
| }
|
|
|
| bool ptsDisjoint(const SkOpPtT& span, double t, const SkPoint& pt) const {
|
| + SkASSERT(this == span.segment());
|
| return ptsDisjoint(span.fT, span.fPt, t, pt);
|
| }
|
|
|
| + bool ptsDisjoint(const SkOpSpanBase* span, const SkOpSpanBase* test) const {
|
| + SkASSERT(this == span->segment());
|
| + SkASSERT(this == test->segment());
|
| + return ptsDisjoint(span->t(), span->pt(), test->t(), test->pt());
|
| + }
|
| +
|
| bool ptsDisjoint(double t1, const SkPoint& pt1, double t2, const SkPoint& pt2) const;
|
|
|
| - void rayCheck(const SkOpRayHit& base, SkOpRayDir dir, SkOpRayHit** hits,
|
| - SkChunkAlloc* allocator);
|
| + void rayCheck(const SkOpRayHit& base, SkOpRayDir dir, SkOpRayHit** hits, SkChunkAlloc*);
|
| +
|
| +#if DEBUG_COINCIDENCE
|
| + void resetDebugVisited() const {
|
| + fDebugVisited = false;
|
| + }
|
| +#endif
|
|
|
| void resetVisited() {
|
| fVisited = false;
|
| @@ -330,10 +354,6 @@ public:
|
| fPrev = prev;
|
| }
|
|
|
| - void setVisited() {
|
| - fVisited = true;
|
| - }
|
| -
|
| void setUpWinding(SkOpSpanBase* start, SkOpSpanBase* end, int* maxWinding, int* sumWinding) {
|
| int deltaSum = SpanSign(start, end);
|
| *maxWinding = *sumWinding;
|
| @@ -348,6 +368,7 @@ public:
|
| void setUpWindings(SkOpSpanBase* start, SkOpSpanBase* end, int* sumMiWinding, int* sumSuWinding,
|
| int* maxWinding, int* sumWinding, int* oppMaxWinding, int* oppSumWinding);
|
| void sortAngles();
|
| + bool spansNearby(const SkOpSpanBase* ref, const SkOpSpanBase* check) const;
|
|
|
| static int SpanSign(const SkOpSpanBase* start, const SkOpSpanBase* end) {
|
| int result = start->t() < end->t() ? -start->upCast()->windValue()
|
| @@ -372,9 +393,10 @@ public:
|
| }
|
|
|
| bool testForCoincidence(const SkOpPtT* priorPtT, const SkOpPtT* ptT, const SkOpSpanBase* prior,
|
| - const SkOpSpanBase* spanBase, const SkOpSegment* opp, SkScalar flatnessLimit) const;
|
| + const SkOpSpanBase* spanBase, const SkOpSegment* opp) const;
|
|
|
| void undoneSpan(SkOpSpanBase** start, SkOpSpanBase** end);
|
| + bool uniqueT(double t, AliasMatch allowAlias) const;
|
| int updateOppWinding(const SkOpSpanBase* start, const SkOpSpanBase* end) const;
|
| int updateOppWinding(const SkOpAngle* angle) const;
|
| int updateOppWindingReverse(const SkOpAngle* angle) const;
|
| @@ -404,17 +426,12 @@ public:
|
| SkOpSpan* windingSpanAtT(double tHit);
|
| int windSum(const SkOpAngle* angle) const;
|
|
|
| - SkPoint* writablePt(bool end) {
|
| - return &fPts[end ? SkPathOpsVerbToPoints(fVerb) : 0];
|
| - }
|
| -
|
| private:
|
| SkOpSpan fHead; // the head span always has its t set to zero
|
| SkOpSpanBase fTail; // the tail span always has its t set to one
|
| SkOpContour* fContour;
|
| SkOpSegment* fNext; // forward-only linked list used by contour to walk the segments
|
| const SkOpSegment* fPrev;
|
| - SkPoint fOriginal[2]; // if aligned, the original unaligned points are here
|
| SkPoint* fPts; // pointer into array of points owned by edge builder that may be tweaked
|
| SkPathOpsBounds fBounds; // tight bounds
|
| SkScalar fWeight;
|
| @@ -422,6 +439,9 @@ private:
|
| int fDoneCount; // number of processed spans (zero initially)
|
| SkPath::Verb fVerb;
|
| bool fVisited; // used by missing coincidence check
|
| +#if DEBUG_COINCIDENCE
|
| + mutable bool fDebugVisited; // used by debug missing coincidence check
|
| +#endif
|
| SkDEBUGCODE(int fID);
|
| };
|
|
|
|
|