Index: src/pathops/SkOpContour.h |
diff --git a/src/pathops/SkOpContour.h b/src/pathops/SkOpContour.h |
index 7fad7a40e46637c62dd47c9c8b8b2ec332ef0d87..d1b3cd0179da6dccdfa310e03cfaf8e21f87c723 100644 |
--- a/src/pathops/SkOpContour.h |
+++ b/src/pathops/SkOpContour.h |
@@ -22,7 +22,8 @@ struct SkCoincidence { |
SkOpContour* fOther; |
int fSegments[2]; |
double fTs[2][2]; |
- SkPoint fPts[2]; |
+ SkPoint fPts[2][2]; |
+ int fNearly[2]; |
}; |
class SkOpContour { |
@@ -86,6 +87,28 @@ public: |
return fSegments[segIndex].addSelfT(pt, newT); |
} |
+ void align(const SkOpSegment::AlignedSpan& aligned, bool swap, SkCoincidence* coincidence); |
+ void alignCoincidence(const SkOpSegment::AlignedSpan& aligned, |
+ SkTArray<SkCoincidence, true>* coincidences); |
+ |
+ void alignCoincidence(const SkOpSegment::AlignedSpan& aligned) { |
+ alignCoincidence(aligned, &fCoincidences); |
+ alignCoincidence(aligned, &fPartialCoincidences); |
+ } |
+ |
+ void alignMultiples(SkTDArray<SkOpSegment::AlignedSpan>* aligned) { |
+ int segmentCount = fSegments.count(); |
+ for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { |
+ SkOpSegment& segment = fSegments[sIndex]; |
+ if (segment.hasMultiples()) { |
+ segment.alignMultiples(aligned); |
+ } |
+ } |
+ } |
+ |
+ void alignTPt(int segmentIndex, const SkOpContour* other, int otherIndex, |
+ bool swap, int tIndex, SkIntersections* ts, SkPoint* point) const; |
+ |
const SkPathOpsBounds& bounds() const { |
return fBounds; |
} |
@@ -127,6 +150,7 @@ public: |
SkOpSegment& segment = fSegments[sIndex]; |
if (segment.count() > 2) { |
segment.checkMultiples(); |
+ fMultiples |= segment.hasMultiples(); |
} |
} |
} |
@@ -135,6 +159,7 @@ public: |
int segmentCount = fSegments.count(); |
for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { |
SkOpSegment& segment = fSegments[sIndex]; |
+ // OPTIMIZATION : skip segments that are done? |
if (segment.hasSmall()) { |
segment.checkSmall(); |
} |
@@ -189,6 +214,10 @@ public: |
} |
} |
+ bool hasMultiples() const { |
+ return fMultiples; |
+ } |
+ |
void joinCoincidence() { |
joinCoincidence(fCoincidences, false); |
joinCoincidence(fPartialCoincidences, true); |
@@ -203,9 +232,11 @@ public: |
void reset() { |
fSegments.reset(); |
fBounds.set(SK_ScalarMax, SK_ScalarMax, SK_ScalarMax, SK_ScalarMax); |
- fContainsCurves = fContainsCubics = fContainsIntercepts = fDone = false; |
+ fContainsCurves = fContainsCubics = fContainsIntercepts = fDone = fMultiples = false; |
} |
+ void resolveNearCoincidence(); |
+ |
SkTArray<SkOpSegment>& segments() { |
return fSegments; |
} |
@@ -284,11 +315,19 @@ public: |
// available to test routines only |
void dump() const; |
void dumpAngles() const; |
+ void dumpCoincidence(const SkCoincidence& ) const; |
+ void dumpCoincidences() const; |
+ void dumpPt(int ) const; |
void dumpPts() const; |
+ void dumpSpan(int ) const; |
void dumpSpans() const; |
private: |
+ void alignPt(int index, SkPoint* point, int zeroPt) const; |
+ int alignT(bool swap, int tIndex, SkIntersections* ts) const; |
void calcCommonCoincidentWinding(const SkCoincidence& ); |
+ void checkCoincidentPair(const SkCoincidence& oneCoin, int oneIdx, |
+ const SkCoincidence& twoCoin, int twoIdx, bool partial); |
void joinCoincidence(const SkTArray<SkCoincidence, true>& , bool partial); |
void setBounds(); |
@@ -303,6 +342,7 @@ private: |
bool fContainsCubics; |
bool fContainsCurves; |
bool fDone; |
+ bool fMultiples; // set if some segment has multiple identical intersections with other curves |
bool fOperand; // true for the second argument to a binary operator |
bool fXor; |
bool fOppXor; |