| Index: src/pathops/SkDCubicIntersection.cpp
|
| diff --git a/src/pathops/SkDCubicIntersection.cpp b/src/pathops/SkDCubicIntersection.cpp
|
| index dd51195d77ac746c1078da27b59f482d0a139d9f..1c237d9cf12fbebdb072be8a2feb3e46a1b06abc 100644
|
| --- a/src/pathops/SkDCubicIntersection.cpp
|
| +++ b/src/pathops/SkDCubicIntersection.cpp
|
| @@ -303,15 +303,39 @@ bool SkIntersections::cubicExactEnd(const SkDCubic& cubic1, bool start, const Sk
|
| continue;
|
| }
|
| if (swap) {
|
| - insert(testT, impTs[0][index], tmpLine[0]);
|
| + cubicInsert(testT, impTs[0][index], tmpLine[0], cubic2, cubic1);
|
| } else {
|
| - insert(impTs[0][index], testT, tmpLine[0]);
|
| + cubicInsert(impTs[0][index], testT, tmpLine[0], cubic1, cubic2);
|
| }
|
| return true;
|
| }
|
| return false;
|
| }
|
|
|
| +
|
| +void SkIntersections::cubicInsert(double one, double two, const SkDPoint& pt,
|
| + const SkDCubic& cubic1, const SkDCubic& cubic2) {
|
| + for (int index = 0; index < fUsed; ++index) {
|
| + if (fT[0][index] == one) {
|
| + double oldTwo = fT[1][index];
|
| + if (oldTwo == two) {
|
| + return;
|
| + }
|
| + SkDPoint mid = cubic2.ptAtT((oldTwo + two) / 2);
|
| + if (mid.approximatelyEqual(fPt[index])) {
|
| + return;
|
| + }
|
| + }
|
| + if (fT[1][index] == two) {
|
| + SkDPoint mid = cubic1.ptAtT((fT[0][index] + two) / 2);
|
| + if (mid.approximatelyEqual(fPt[index])) {
|
| + return;
|
| + }
|
| + }
|
| + }
|
| + insert(one, two, pt);
|
| +}
|
| +
|
| void SkIntersections::cubicNearEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cubic2,
|
| const SkDRect& bounds2) {
|
| SkDLine line;
|
| @@ -371,11 +395,15 @@ void SkIntersections::cubicNearEnd(const SkDCubic& cubic1, bool start, const SkD
|
| double tMin2 = SkTMax(tVals[tIdx] - LINE_FRACTION, 0.0);
|
| double tMax2 = SkTMin(tVals[tLast] + LINE_FRACTION, 1.0);
|
| int lastUsed = used();
|
| - ::intersect(cubic1, tMin1, tMax1, cubic2, tMin2, tMax2, 1, *this);
|
| + if (start ? tMax1 < tMin2 : tMax2 < tMin1) {
|
| + ::intersect(cubic1, tMin1, tMax1, cubic2, tMin2, tMax2, 1, *this);
|
| + }
|
| if (lastUsed == used()) {
|
| tMin2 = SkTMax(tVals[tIdx] - (1.0 / SkDCubic::gPrecisionUnit), 0.0);
|
| tMax2 = SkTMin(tVals[tLast] + (1.0 / SkDCubic::gPrecisionUnit), 1.0);
|
| - ::intersect(cubic1, tMin1, tMax1, cubic2, tMin2, tMax2, 1, *this);
|
| + if (start ? tMax1 < tMin2 : tMax2 < tMin1) {
|
| + ::intersect(cubic1, tMin1, tMax1, cubic2, tMin2, tMax2, 1, *this);
|
| + }
|
| }
|
| tIdx = tLast + 1;
|
| } while (tIdx < tVals.count());
|
| @@ -421,6 +449,9 @@ static bool only_end_pts_in_common(const SkDCubic& c1, const SkDCubic& c2) {
|
| }
|
| double adj = endPt[oppTest]->fX - origX;
|
| double opp = endPt[oppTest]->fY - origY;
|
| + if (adj == 0 && opp == 0) { // if the other point equals the test point, ignore it
|
| + continue;
|
| + }
|
| double sign = (c1[oddMan].fY - origY) * adj - (c1[oddMan].fX - origX) * opp;
|
| if (approximately_zero(sign)) {
|
| goto tryNextHalfPlane;
|
| @@ -531,7 +562,7 @@ int SkIntersections::intersect(const SkDCubic& c1, const SkDCubic& c2) {
|
| if (compCount) {
|
| int exactCount = used();
|
| if (exactCount == 0) {
|
| - set(i);
|
| + *this = i;
|
| } else {
|
| // at least one is exact or near, and at least one was computed. Eliminate duplicates
|
| for (int exIdx = 0; exIdx < exactCount; ++exIdx) {
|
|
|