[bezierTools] Fix infinite-recursion in calcCubicArcLength
Fixes https://github.com/fonttools/fonttools/issues/3502
This commit is contained in:
parent
9acbd12637
commit
2ce45c2861
@ -18,6 +18,9 @@ except (AttributeError, ImportError):
|
|||||||
COMPILED = False
|
COMPILED = False
|
||||||
|
|
||||||
|
|
||||||
|
EPSILON = 1e-9
|
||||||
|
|
||||||
|
|
||||||
Intersection = namedtuple("Intersection", ["pt", "t1", "t2"])
|
Intersection = namedtuple("Intersection", ["pt", "t1", "t2"])
|
||||||
|
|
||||||
|
|
||||||
@ -92,7 +95,7 @@ def _split_cubic_into_two(p0, p1, p2, p3):
|
|||||||
def _calcCubicArcLengthCRecurse(mult, p0, p1, p2, p3):
|
def _calcCubicArcLengthCRecurse(mult, p0, p1, p2, p3):
|
||||||
arch = abs(p0 - p3)
|
arch = abs(p0 - p3)
|
||||||
box = abs(p0 - p1) + abs(p1 - p2) + abs(p2 - p3)
|
box = abs(p0 - p1) + abs(p1 - p2) + abs(p2 - p3)
|
||||||
if arch * mult >= box:
|
if arch * mult + EPSILON >= box:
|
||||||
return (arch + box) * 0.5
|
return (arch + box) * 0.5
|
||||||
else:
|
else:
|
||||||
one, two = _split_cubic_into_two(p0, p1, p2, p3)
|
one, two = _split_cubic_into_two(p0, p1, p2, p3)
|
||||||
|
@ -3,6 +3,7 @@ from fontTools.misc.bezierTools import (
|
|||||||
calcQuadraticBounds,
|
calcQuadraticBounds,
|
||||||
calcQuadraticArcLength,
|
calcQuadraticArcLength,
|
||||||
calcCubicBounds,
|
calcCubicBounds,
|
||||||
|
calcCubicArcLength,
|
||||||
curveLineIntersections,
|
curveLineIntersections,
|
||||||
curveCurveIntersections,
|
curveCurveIntersections,
|
||||||
segmentPointAtT,
|
segmentPointAtT,
|
||||||
@ -192,6 +193,25 @@ def test_calcQuadraticArcLength():
|
|||||||
) == pytest.approx(127.9225)
|
) == pytest.approx(127.9225)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"segment, expectedLength",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
# https://github.com/fonttools/fonttools/issues/3502
|
||||||
|
((377, 469), (377, 468), (377, 472), (377, 472)), # off by one unit
|
||||||
|
3.32098765445,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
# https://github.com/fonttools/fonttools/issues/3502
|
||||||
|
((242, 402), (242, 403), (242, 399), (242, 399)), # off by one unit
|
||||||
|
3.32098765445,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_calcCubicArcLength(segment, expectedLength):
|
||||||
|
assert calcCubicArcLength(*segment) == pytest.approx(expectedLength)
|
||||||
|
|
||||||
|
|
||||||
def test_intersections_linelike():
|
def test_intersections_linelike():
|
||||||
seg1 = [(0.0, 0.0), (0.0, 0.25), (0.0, 0.75), (0.0, 1.0)]
|
seg1 = [(0.0, 0.0), (0.0, 0.25), (0.0, 0.75), (0.0, 1.0)]
|
||||||
seg2 = [(0.0, 0.5), (0.25, 0.5), (0.75, 0.5), (1.0, 0.5)]
|
seg2 = [(0.0, 0.5), (0.25, 0.5), (0.75, 0.5), (1.0, 0.5)]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user