diff options
author | caryclark <caryclark@google.com> | 2014-09-08 10:25:38 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-08 10:25:38 -0700 |
commit | 361b8b088589748e4b29895a4ebc5316e881e219 (patch) | |
tree | 8363e5d940b956d827e6ba5a62a627a185b72c8a /src/pathops | |
parent | 224310941e01b62b9b45db8656261a3d936cecf5 (diff) |
fail when coincidence is too far apart
TBR=
BUG=410552
Author: caryclark@google.com
Review URL: https://codereview.chromium.org/556433002
Diffstat (limited to 'src/pathops')
-rw-r--r-- | src/pathops/SkOpContour.cpp | 37 | ||||
-rw-r--r-- | src/pathops/SkOpSegment.cpp | 6 |
2 files changed, 24 insertions, 19 deletions
diff --git a/src/pathops/SkOpContour.cpp b/src/pathops/SkOpContour.cpp index e4dd62a653..467fab31f5 100644 --- a/src/pathops/SkOpContour.cpp +++ b/src/pathops/SkOpContour.cpp @@ -57,6 +57,21 @@ SkOpSegment* SkOpContour::nonVerticalSegment(int* start, int* end) { return NULL; } +// if one is very large the smaller may have collapsed to nothing +static void bump_out_close_span(double* startTPtr, double* endTPtr) { + double startT = *startTPtr; + double endT = *endTPtr; + if (approximately_negative(endT - startT)) { + if (endT <= 1 - FLT_EPSILON) { + *endTPtr += FLT_EPSILON; + SkASSERT(*endTPtr <= 1); + } else { + *startTPtr -= FLT_EPSILON; + SkASSERT(*startTPtr >= 0); + } + } +} + // first pass, add missing T values // second pass, determine winding values of overlaps void SkOpContour::addCoincidentPoints() { @@ -82,15 +97,7 @@ void SkOpContour::addCoincidentPoints() { if ((cancelers = startSwapped = startT > endT)) { SkTSwap(startT, endT); } - if (startT == endT) { // if one is very large the smaller may have collapsed to nothing - if (endT <= 1 - FLT_EPSILON) { - endT += FLT_EPSILON; - SkASSERT(endT <= 1); - } else { - startT -= FLT_EPSILON; - SkASSERT(startT >= 0); - } - } + bump_out_close_span(&startT, &endT); SkASSERT(!approximately_negative(endT - startT)); double oStartT = coincidence.fTs[1][0]; double oEndT = coincidence.fTs[1][1]; @@ -98,6 +105,7 @@ void SkOpContour::addCoincidentPoints() { SkTSwap(oStartT, oEndT); cancelers ^= true; } + bump_out_close_span(&oStartT, &oEndT); SkASSERT(!approximately_negative(oEndT - oStartT)); const SkPoint& startPt = coincidence.fPts[0][startSwapped]; if (cancelers) { @@ -559,15 +567,7 @@ void SkOpContour::calcCommonCoincidentWinding(const SkCoincidence& coincidence) SkTSwap<double>(startT, endT); SkTSwap<const SkPoint*>(startPt, endPt); } - if (startT == endT) { // if span is very large, the smaller may have collapsed to nothing - if (endT <= 1 - FLT_EPSILON) { - endT += FLT_EPSILON; - SkASSERT(endT <= 1); - } else { - startT -= FLT_EPSILON; - SkASSERT(startT >= 0); - } - } + bump_out_close_span(&startT, &endT); SkASSERT(!approximately_negative(endT - startT)); double oStartT = coincidence.fTs[1][0]; double oEndT = coincidence.fTs[1][1]; @@ -575,6 +575,7 @@ void SkOpContour::calcCommonCoincidentWinding(const SkCoincidence& coincidence) SkTSwap<double>(oStartT, oEndT); cancelers ^= true; } + bump_out_close_span(&oStartT, &oEndT); SkASSERT(!approximately_negative(oEndT - oStartT)); if (cancelers) { thisOne.addTCancel(*startPt, *endPt, &other); diff --git a/src/pathops/SkOpSegment.cpp b/src/pathops/SkOpSegment.cpp index f929455e0f..826495b764 100644 --- a/src/pathops/SkOpSegment.cpp +++ b/src/pathops/SkOpSegment.cpp @@ -1294,7 +1294,8 @@ void SkOpSegment::addTCoincident(const SkPoint& startPt, const SkPoint& endPt, d double testT = test->fT; SkOpSpan* oTest = &other->fTs[oIndex]; const SkPoint* oTestPt = &oTest->fPt; - SkASSERT(AlmostEqualUlps(*testPt, *oTestPt)); + // paths with extreme data will fail this test and eject out of pathops altogether later on + // SkASSERT(AlmostEqualUlps(*testPt, *oTestPt)); do { SkASSERT(test->fT < 1); SkASSERT(oTest->fT < 1); @@ -1477,6 +1478,9 @@ bool SkOpSegment::calcAngles() { const SkOpSpan* span = &fTs[0]; if (firstSpan->fT == 0 || span->fTiny || span->fOtherT != 1 || span->fOther->multipleEnds()) { index = findStartSpan(0); // curve start intersects + if (fTs[index].fT == 0) { + return false; + } SkASSERT(index > 0); if (activePrior >= 0) { addStartSpan(index); |