diff options
author | caryclark <caryclark@google.com> | 2014-08-12 07:46:33 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-08-12 07:46:33 -0700 |
commit | 5e27e0eb1d1d4c7674e221d3ba3314500ea0b97a (patch) | |
tree | 8f72ae01c66a4763cce3123f9956541d05ba1338 /src/pathops | |
parent | b3d4af512e9d60019790cf42701ac62edb3f5b00 (diff) |
fix pathops skp-derived bugs; add more failing tests
TBR=
Author: caryclark@google.com
Review URL: https://codereview.chromium.org/463883002
Diffstat (limited to 'src/pathops')
-rw-r--r-- | src/pathops/SkOpAngle.h | 2 | ||||
-rw-r--r-- | src/pathops/SkOpContour.cpp | 6 | ||||
-rw-r--r-- | src/pathops/SkOpSegment.cpp | 28 | ||||
-rw-r--r-- | src/pathops/SkOpSegment.h | 2 |
4 files changed, 36 insertions, 2 deletions
diff --git a/src/pathops/SkOpAngle.h b/src/pathops/SkOpAngle.h index 63d378d73c..098c470128 100644 --- a/src/pathops/SkOpAngle.h +++ b/src/pathops/SkOpAngle.h @@ -160,10 +160,10 @@ public: void reset(); private: void dump() const; // utility to be called by user from debugger + SkChunkAlloc* fAngles; #if DEBUG_ANGLE int fCount; #endif - SkChunkAlloc* fAngles; }; #endif diff --git a/src/pathops/SkOpContour.cpp b/src/pathops/SkOpContour.cpp index 5ef702d4c1..e4dd62a653 100644 --- a/src/pathops/SkOpContour.cpp +++ b/src/pathops/SkOpContour.cpp @@ -452,8 +452,14 @@ void SkOpContour::checkCoincidentPair(const SkCoincidence& oneCoin, int oneIdx, } if (cancelers) { if (missingT1 >= 0) { + if (addTo1->reversePoints(missingPt1, missingPt2)) { + SkTSwap(missingPt1, missingPt2); + } addTo1->addTCancel(missingPt1, missingPt2, addOther1); } else { + if (addTo2->reversePoints(missingPt1, missingPt2)) { + SkTSwap(missingPt1, missingPt2); + } addTo2->addTCancel(missingPt1, missingPt2, addOther2); } } else if (missingT1 >= 0) { diff --git a/src/pathops/SkOpSegment.cpp b/src/pathops/SkOpSegment.cpp index f6d989b18a..747cd9d497 100644 --- a/src/pathops/SkOpSegment.cpp +++ b/src/pathops/SkOpSegment.cpp @@ -2294,9 +2294,10 @@ void SkOpSegment::checkSmall() { } const SkOpSpan& firstSpan = this->firstSpan(*thisSpan); const SkOpSpan& lastSpan = this->lastSpan(*thisSpan); + const SkOpSpan* nextSpan = &firstSpan + 1; ptrdiff_t smallCount = &lastSpan - &firstSpan + 1; SkASSERT(1 <= smallCount && smallCount < count()); - if (smallCount <= 1) { + if (smallCount <= 1 && !nextSpan->fSmall) { SkASSERT(1 == smallCount); checkSmallCoincidence(firstSpan, NULL); continue; @@ -3067,6 +3068,13 @@ int SkOpSegment::findOtherT(double t, const SkOpSegment* match) const { int SkOpSegment::findT(double t, const SkPoint& pt, const SkOpSegment* match) const { int count = this->count(); + // prefer exact matches over approximate matches + for (int index = 0; index < count; ++index) { + const SkOpSpan& span = fTs[index]; + if (span.fT == t && span.fOther == match) { + return index; + } + } for (int index = 0; index < count; ++index) { const SkOpSpan& span = fTs[index]; if (approximately_equal_orderable(span.fT, t) && span.fOther == match) { @@ -3986,6 +3994,24 @@ void SkOpSegment::pinT(const SkPoint& pt, double* t) { } } +bool SkOpSegment::reversePoints(const SkPoint& p1, const SkPoint& p2) const { + SkASSERT(p1 != p2); + int spanCount = count(); + int p1IndexMin = -1; + int p2IndexMax = spanCount; + for (int index = 0; index < spanCount; ++index) { + const SkOpSpan& span = fTs[index]; + if (span.fPt == p1) { + if (p1IndexMin < 0) { + p1IndexMin = index; + } + } else if (span.fPt == p2) { + p2IndexMax = index; + } + } + return p1IndexMin > p2IndexMax; +} + void SkOpSegment::setCoincidentRange(const SkPoint& startPt, const SkPoint& endPt, SkOpSegment* other) { int count = this->count(); diff --git a/src/pathops/SkOpSegment.h b/src/pathops/SkOpSegment.h index d191e88af2..df87d058b6 100644 --- a/src/pathops/SkOpSegment.h +++ b/src/pathops/SkOpSegment.h @@ -177,6 +177,8 @@ public: fTs.reset(); } + bool reversePoints(const SkPoint& p1, const SkPoint& p2) const; + void setOppXor(bool isOppXor) { fOppXor = isOppXor; } |