| 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) { | 
|  |