aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pathops
diff options
context:
space:
mode:
authorGravatar caryclark <caryclark@google.com>2014-08-12 07:46:33 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-08-12 07:46:33 -0700
commit5e27e0eb1d1d4c7674e221d3ba3314500ea0b97a (patch)
tree8f72ae01c66a4763cce3123f9956541d05ba1338 /src/pathops
parentb3d4af512e9d60019790cf42701ac62edb3f5b00 (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.h2
-rw-r--r--src/pathops/SkOpContour.cpp6
-rw-r--r--src/pathops/SkOpSegment.cpp28
-rw-r--r--src/pathops/SkOpSegment.h2
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;
}