| Index: src/pathops/SkOpSegment.h
|
| diff --git a/src/pathops/SkOpSegment.h b/src/pathops/SkOpSegment.h
|
| index 1eaef69847fdde200bb176255d69c016f4e1da05..90ed553bd3111765f660b272223bdd8ba27a26a0 100644
|
| --- a/src/pathops/SkOpSegment.h
|
| +++ b/src/pathops/SkOpSegment.h
|
| @@ -18,6 +18,7 @@
|
| #include "SkThread.h"
|
| #endif
|
|
|
| +struct SkCoincidence;
|
| class SkPathWriter;
|
|
|
| class SkOpSegment {
|
| @@ -32,11 +33,15 @@ public:
|
| return fBounds.fTop < rh.fBounds.fTop;
|
| }
|
|
|
| - // FIXME: add some template or macro to avoid casting
|
| - SkOpAngle& angle(int index) {
|
| - const SkOpAngle& cAngle = (const_cast<const SkOpSegment*>(this))->angle(index);
|
| - return const_cast<SkOpAngle&>(cAngle);
|
| - }
|
| + struct AlignedSpan {
|
| + double fOldT;
|
| + double fT;
|
| + SkPoint fOldPt;
|
| + SkPoint fPt;
|
| + const SkOpSegment* fSegment;
|
| + const SkOpSegment* fOther1;
|
| + const SkOpSegment* fOther2;
|
| + };
|
|
|
| const SkPathOpsBounds& bounds() const {
|
| return fBounds;
|
| @@ -81,6 +86,10 @@ public:
|
| return dxdy(index).fY;
|
| }
|
|
|
| + bool hasMultiples() const {
|
| + return fMultiples;
|
| + }
|
| +
|
| bool hasSmall() const {
|
| return fSmall;
|
| }
|
| @@ -185,8 +194,7 @@ public:
|
| const SkOpAngle* spanToAngle(int tStart, int tEnd) const {
|
| SkASSERT(tStart != tEnd);
|
| const SkOpSpan& span = fTs[tStart];
|
| - int index = tStart < tEnd ? span.fToAngleIndex : span.fFromAngleIndex;
|
| - return index >= 0 ? &angle(index) : NULL;
|
| + return tStart < tEnd ? span.fToAngle : span.fFromAngle;
|
| }
|
|
|
| // FIXME: create some sort of macro or template that avoids casting
|
| @@ -278,11 +286,19 @@ public:
|
| SkOpSegment* other);
|
| const SkOpSpan* addTPair(double t, SkOpSegment* other, double otherT, bool borrowWind,
|
| const SkPoint& pt);
|
| + const SkOpSpan* addTPair(double t, SkOpSegment* other, double otherT, bool borrowWind,
|
| + const SkPoint& pt, const SkPoint& oPt);
|
| + void alignMultiples(SkTDArray<AlignedSpan>* aligned);
|
| bool alignSpan(int index, double thisT, const SkPoint& thisPt);
|
| void alignSpanState(int start, int end);
|
| - const SkOpAngle& angle(int index) const;
|
| bool betweenTs(int lesser, double testT, int greater) const;
|
| + void blindCancel(const SkCoincidence& coincidence, SkOpSegment* other);
|
| + void blindCoincident(const SkCoincidence& coincidence, SkOpSegment* other);
|
| bool calcAngles();
|
| + double calcMissingTEnd(const SkOpSegment* ref, double loEnd, double min, double max,
|
| + double hiEnd, const SkOpSegment* other, int thisEnd);
|
| + double calcMissingTStart(const SkOpSegment* ref, double loEnd, double min, double max,
|
| + double hiEnd, const SkOpSegment* other, int thisEnd);
|
| void checkDuplicates();
|
| void checkEnds();
|
| void checkMultiples();
|
| @@ -301,6 +317,7 @@ public:
|
| bool* unsortable);
|
| SkOpSegment* findNextXor(int* nextStart, int* nextEnd, bool* unsortable);
|
| int findExactT(double t, const SkOpSegment* ) const;
|
| + int findOtherT(double t, const SkOpSegment* ) const;
|
| int findT(double t, const SkPoint& , const SkOpSegment* ) const;
|
| SkOpSegment* findTop(int* tIndex, int* endIndex, bool* unsortable, bool firstPass);
|
| void fixOtherTIndex();
|
| @@ -321,6 +338,7 @@ public:
|
| void markDoneUnary(int index);
|
| bool nextCandidate(int* start, int* end) const;
|
| int nextSpan(int from, int step) const;
|
| + void pinT(const SkPoint& pt, double* t);
|
| void setUpWindings(int index, int endIndex, int* sumMiWinding, int* sumSuWinding,
|
| int* maxWinding, int* sumWinding, int* oppMaxWinding, int* oppSumWinding);
|
| void sortAngles();
|
| @@ -334,9 +352,6 @@ public:
|
| int windingAtT(double tHit, int tIndex, bool crossOpp, SkScalar* dx) const;
|
| int windSum(const SkOpAngle* angle) const;
|
| // available for testing only
|
| -#if DEBUG_VALIDATE
|
| - bool debugContains(const SkOpAngle* ) const;
|
| -#endif
|
| #if defined(SK_DEBUG) || !FORCE_RELEASE
|
| int debugID() const {
|
| return fID;
|
| @@ -358,6 +373,7 @@ public:
|
| const SkTDArray<SkOpSpan>& debugSpans() const;
|
| void debugValidate() const;
|
| // available to testing only
|
| + const SkOpAngle* debugLastAngle() const;
|
| void dumpAngles() const;
|
| void dumpContour(int firstID, int lastID) const;
|
| void dumpPts() const;
|
| @@ -382,18 +398,22 @@ private:
|
| bool activeWinding(int index, int endIndex, int* sumWinding);
|
| void addCancelOutsides(const SkPoint& startPt, const SkPoint& endPt, SkOpSegment* other);
|
| void addCoinOutsides(const SkPoint& startPt, const SkPoint& endPt, SkOpSegment* other);
|
| - int addSingletonAngleDown(int start, SkOpSegment** otherPtr);
|
| - int addSingletonAngleUp(int start, SkOpSegment** otherPtr);
|
| - SkOpAngle* addSingletonAngles(int start, int step);
|
| - void addTPair(double t, SkOpSegment* other, double otherT, bool borrowWind, const SkPoint& pt,
|
| - const SkPoint& oPt);
|
| + SkOpAngle* addSingletonAngleDown(SkOpSegment** otherPtr, SkOpAngle** );
|
| + SkOpAngle* addSingletonAngleUp(SkOpSegment** otherPtr, SkOpAngle** );
|
| + SkOpAngle* addSingletonAngles(int step);
|
| + void alignSpan(const SkPoint& newPt, double newT, const SkOpSegment* other, double otherT,
|
| + const SkOpSegment* other2, SkOpSpan* oSpan, SkTDArray<AlignedSpan>* );
|
| bool betweenPoints(double midT, const SkPoint& pt1, const SkPoint& pt2) const;
|
| + void bumpCoincidentBlind(bool binary, int index, int last);
|
| void bumpCoincidentThis(const SkOpSpan& oTest, bool binary, int* index,
|
| SkTArray<SkPoint, true>* outsideTs);
|
| + void bumpCoincidentOBlind(int index, int last);
|
| void bumpCoincidentOther(const SkOpSpan& oTest, int* index,
|
| SkTArray<SkPoint, true>* outsideTs);
|
| bool bumpSpan(SkOpSpan* span, int windDelta, int oppDelta);
|
| bool calcLoopSpanCount(const SkOpSpan& thisSpan, int* smallCounts);
|
| + bool checkForSmall(const SkOpSpan* span, const SkPoint& pt, double newT,
|
| + int* less, int* more) const;
|
| void checkLinks(const SkOpSpan* ,
|
| SkTArray<MissingSpan, true>* missingSpans) const;
|
| static void CheckOneLink(const SkOpSpan* test, const SkOpSpan* oSpan,
|
| @@ -402,19 +422,26 @@ private:
|
| SkTArray<MissingSpan, true>* missingSpans);
|
| int checkSetAngle(int tIndex) const;
|
| void checkSmallCoincidence(const SkOpSpan& span, SkTArray<MissingSpan, true>* );
|
| + bool coincidentSmall(const SkPoint& pt, double t, const SkOpSegment* other) const;
|
| bool clockwise(int tStart, int tEnd) const;
|
| static void ComputeOneSum(const SkOpAngle* baseAngle, SkOpAngle* nextAngle,
|
| SkOpAngle::IncludeType );
|
| static void ComputeOneSumReverse(const SkOpAngle* baseAngle, SkOpAngle* nextAngle,
|
| SkOpAngle::IncludeType );
|
| + bool containsT(double t, const SkOpSegment* other, double otherT) const;
|
| bool decrementSpan(SkOpSpan* span);
|
| int findEndSpan(int endIndex) const;
|
| int findStartSpan(int startIndex) const;
|
| int firstActive(int tIndex) const;
|
| const SkOpSpan& firstSpan(const SkOpSpan& thisSpan) const;
|
| void init(const SkPoint pts[], SkPath::Verb verb, bool operand, bool evenOdd);
|
| + bool inCoincidentSpan(double t, const SkOpSegment* other) const;
|
| bool inLoop(const SkOpAngle* baseAngle, int spanCount, int* indexPtr) const;
|
| +#if OLD_CHASE
|
| bool isSimple(int end) const;
|
| +#else
|
| + SkOpSegment* isSimple(int* end, int* step);
|
| +#endif
|
| bool isTiny(int index) const;
|
| const SkOpSpan& lastSpan(const SkOpSpan& thisSpan) const;
|
| void matchWindingValue(int tIndex, double t, bool borrowWind);
|
| @@ -436,20 +463,15 @@ private:
|
| void markWinding(int index, int winding, int oppWinding);
|
| bool monotonicInY(int tStart, int tEnd) const;
|
|
|
| - bool multipleEnds() const {
|
| - return fTs[count() - 2].fT == 1;
|
| - }
|
| -
|
| - bool multipleStarts() const {
|
| - return fTs[1].fT == 0;
|
| - }
|
| + bool multipleEnds() const { return fTs[count() - 2].fT == 1; }
|
| + bool multipleStarts() const { return fTs[1].fT == 0; }
|
|
|
| - bool multipleSpans(int end) const;
|
| - SkOpSegment* nextChase(int* index, const int step, int* min, SkOpSpan** last);
|
| + SkOpSegment* nextChase(int* index, int* step, int* min, SkOpSpan** last);
|
| int nextExactSpan(int from, int step) const;
|
| bool serpentine(int tStart, int tEnd) const;
|
| - void setFromAngleIndex(int endIndex, int angleIndex);
|
| - void setToAngleIndex(int endIndex, int angleIndex);
|
| + void setCoincidentRange(const SkPoint& startPt, const SkPoint& endPt, SkOpSegment* other);
|
| + void setFromAngle(int endIndex, SkOpAngle* );
|
| + void setToAngle(int endIndex, SkOpAngle* );
|
| void setUpWindings(int index, int endIndex, int* sumMiWinding,
|
| int* maxWinding, int* sumWinding);
|
| void subDivideBounds(int start, int end, SkPathOpsBounds* bounds) const;
|
| @@ -509,14 +531,13 @@ private:
|
| SkPathOpsBounds fBounds;
|
| // FIXME: can't convert to SkTArray because it uses insert
|
| SkTDArray<SkOpSpan> fTs; // 2+ (always includes t=0 t=1) -- at least (number of spans) + 1
|
| -// FIXME: replace both with bucket storage that allows direct immovable pointers to angles
|
| - SkTArray<SkOpAngle, true> fSingletonAngles; // 0 or 2 -- allocated for singletons
|
| - SkTArray<SkOpAngle, true> fAngles; // 0 or 2+ -- (number of non-zero spans) * 2
|
| + SkOpAngleSet fAngles; // empty or 2+ -- (number of non-zero spans) * 2
|
| // OPTIMIZATION: could pack donespans, verb, operand, xor into 1 int-sized value
|
| int fDoneSpans; // quick check that segment is finished
|
| // OPTIMIZATION: force the following to be byte-sized
|
| SkPath::Verb fVerb;
|
| bool fLoop; // set if cubic intersects itself
|
| + bool fMultiples; // set if curve intersects multiple other curves at one interior point
|
| bool fOperand;
|
| bool fXor; // set if original contour had even-odd fill
|
| bool fOppXor; // set if opposite operand had even-odd fill
|
|
|