diff --git a/Lib/fontTools/misc/arrayTools.py b/Lib/fontTools/misc/arrayTools.py index ced8d87a61..0c99395303 100644 --- a/Lib/fontTools/misc/arrayTools.py +++ b/Lib/fontTools/misc/arrayTools.py @@ -208,7 +208,7 @@ def sectRect(rect1, rect2): min(xMax1, xMax2), min(yMax1, yMax2), ) - if xMin >= xMax or yMin >= yMax: + if xMin > xMax or yMin > yMax: return False, (0, 0, 0, 0) return True, (xMin, yMin, xMax, yMax) diff --git a/Lib/fontTools/misc/bezierTools.py b/Lib/fontTools/misc/bezierTools.py index a1a707b098..213e2544f4 100644 --- a/Lib/fontTools/misc/bezierTools.py +++ b/Lib/fontTools/misc/bezierTools.py @@ -1323,7 +1323,8 @@ def midpoint(r): return 0.5 * (r[0] + r[1]) # If they do overlap but they're tiny, approximate - if rectArea(bounds1) < precision and rectArea(bounds2) < precision: + precision2 = precision * precision + if rectArea(bounds1) < precision2 and rectArea(bounds2) < precision2: return [(midpoint(range1), midpoint(range2))] c11, c12 = _split_segment_at_t(curve1, 0.5) @@ -1356,7 +1357,7 @@ def midpoint(r): ) ) - unique_key = lambda ts: (int(ts[0] / precision), int(ts[1] / precision)) + unique_key = lambda ts: (round(ts[0] / precision), round(ts[1] / precision)) seen = set() unique_values = [] @@ -1394,7 +1395,7 @@ def curveCurveIntersections(curve1, curve2): >>> len(intersections) 3 >>> intersections[0].pt - (81.7831487395506, 109.88904552375288) + (81.7904225872997, 109.89939633675462) """ if _is_linelike(curve1): line1 = curve1[0], curve1[-1] @@ -1433,7 +1434,7 @@ def segmentSegmentIntersections(seg1, seg2): >>> len(intersections) 3 >>> intersections[0].pt - (81.7831487395506, 109.88904552375288) + (81.7904225872997, 109.89939633675462) >>> curve3 = [ (100, 240), (30, 60), (210, 230), (160, 30) ] >>> line = [ (25, 260), (230, 20) ] >>> intersections = segmentSegmentIntersections(curve3, line) diff --git a/Tests/misc/arrayTools_test.py b/Tests/misc/arrayTools_test.py index c8de7bda0e..8ed7a52f5c 100644 --- a/Tests/misc/arrayTools_test.py +++ b/Tests/misc/arrayTools_test.py @@ -89,6 +89,13 @@ def test_sectRect(): assert rect == (5, 20, 20, 30) +def test_sectRect_perpendicular(): + # https://github.com/fonttools/fonttools/issues/3352 + intersects, rect = sectRect((0.0, 0.0, 0.0, 1.0), (0.0, 0.5, 1.0, 0.5)) + assert intersects + assert rect == (0.0, 0.5, 0.0, 0.5) + + def test_unionRect(): assert unionRect((0, 10, 20, 30), (0, 40, 20, 50)) == (0, 10, 20, 50) diff --git a/Tests/misc/bezierTools_test.py b/Tests/misc/bezierTools_test.py index ce8a9e17e4..a88a32a04c 100644 --- a/Tests/misc/bezierTools_test.py +++ b/Tests/misc/bezierTools_test.py @@ -197,3 +197,12 @@ def test_intersections_linelike(): seg2 = [(0.0, 0.5), (0.25, 0.5), (0.75, 0.5), (1.0, 0.5)] pt = curveCurveIntersections(seg1, seg2)[0][0] assert pt == (0.0, 0.5) + + +def test_curve_curve_touching_each_other(): + seg1 = [(0, 0), (0, 100), (100, 100), (100, 0)] + seg2 = [(0, 150), (0, 50), (100, 50), (100, 150)] + intersections = curveCurveIntersections(seg1, seg2) + assert len(intersections) == 1 + pt = intersections[0][0] + assert pt == pytest.approx((50.0, 75.0), rel=1e-3)