diff --git a/Lib/fontTools/misc/bezierTools.py b/Lib/fontTools/misc/bezierTools.py index 57dfd4891..7e4bed215 100644 --- a/Lib/fontTools/misc/bezierTools.py +++ b/Lib/fontTools/misc/bezierTools.py @@ -65,14 +65,17 @@ def splitLine(pt1, pt2, where, isHorizontal): line was successfully split, or a list containing the original line. - >>> _testrepr(splitLine((0, 0), (100, 100), 50, True)) - '(((0, 0), (50.0, 50.0)), ((50.0, 50.0), (100, 100)))' - >>> _testrepr(splitLine((0, 0), (100, 100), 100, True)) - '(((0, 0), (100, 100)))' - >>> _testrepr(splitLine((0, 0), (100, 100), 0, True)) - '(((0, 0), (0.0, 0.0)), ((0.0, 0.0), (100, 100)))' - >>> _testrepr(splitLine((0, 0), (100, 100), 0, False)) - '(((0, 0), (0.0, 0.0)), ((0.0, 0.0), (100, 100)))' + >>> printSegments(splitLine((0, 0), (100, 100), 50, True)) + ((0, 0), (50.0, 50.0)) + ((50.0, 50.0), (100, 100)) + >>> printSegments(splitLine((0, 0), (100, 100), 100, True)) + ((0, 0), (100, 100)) + >>> printSegments(splitLine((0, 0), (100, 100), 0, True)) + ((0, 0), (0.0, 0.0)) + ((0.0, 0.0), (100, 100)) + >>> printSegments(splitLine((0, 0), (100, 100), 0, False)) + ((0, 0), (0.0, 0.0)) + ((0.0, 0.0), (100, 100)) """ pt1, pt2 = Numeric.array((pt1, pt2)) a = (pt2 - pt1) @@ -93,17 +96,23 @@ def splitQuadratic(pt1, pt2, pt3, where, isHorizontal): which is an x coordinate if isHorizontal is False, a y coordinate if isHorizontal is True. Return a list of curve segments. - >>> splitQuadratic((0, 0), (50, 100), (100, 0), 150, False) - [((0, 0), (50, 100), (100, 0))] - >>> _testrepr(splitQuadratic((0, 0), (50, 100), (100, 0), 50, False)) - '(((0.0, 0.0), (25.0, 50.0), (50.0, 50.0)), ((50.0, 50.0), (75.0, 50.0), (100.0, 0.0)))' - >>> _testrepr(splitQuadratic((0, 0), (50, 100), (100, 0), 25, False)) - '(((0.0, 0.0), (12.5, 25.0), (25.0, 37.5)), ((25.0, 37.5), (62.5, 75.0), (100.0, 0.0)))' - >>> _testrepr(splitQuadratic((0, 0), (50, 100), (100, 0), 25, True)) - '(((0.0, 0.0), (7.32233047034, 14.6446609407), (14.6446609407, 25.0)), ((14.6446609407, 25.0), (50.0, 75.0), (85.3553390593, 25.0)), ((85.3553390593, 25.0), (92.6776695297, 14.6446609407), (100.0, -7.1054273576e-15)))' + >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 150, False)) + ((0, 0), (50, 100), (100, 0)) + >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 50, False)) + ((0.0, 0.0), (25.0, 50.0), (50.0, 50.0)) + ((50.0, 50.0), (75.0, 50.0), (100.0, 0.0)) + >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 25, False)) + ((0.0, 0.0), (12.5, 25.0), (25.0, 37.5)) + ((25.0, 37.5), (62.5, 75.0), (100.0, 0.0)) + >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 25, True)) + ((0.0, 0.0), (7.32233047034, 14.6446609407), (14.6446609407, 25.0)) + ((14.6446609407, 25.0), (50.0, 75.0), (85.3553390593, 25.0)) + ((85.3553390593, 25.0), (92.6776695297, 14.6446609407), (100.0, -7.1054273576e-15)) >>> # XXX I'm not at all sure it the following behavior is desirable: - >>> _testrepr(splitQuadratic((0, 0), (50, 100), (100, 0), 50, True)) - '(((0.0, 0.0), (25.0, 50.0), (50.0, 50.0)), ((50.0, 50.0), (50.0, 50.0), (50.0, 50.0)), ((50.0, 50.0), (75.0, 50.0), (100.0, 0.0)))' + >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 50, True)) + ((0.0, 0.0), (25.0, 50.0), (50.0, 50.0)) + ((50.0, 50.0), (50.0, 50.0), (50.0, 50.0)) + ((50.0, 50.0), (75.0, 50.0), (100.0, 0.0)) """ a, b, c = calcQuadraticParameters(pt1, pt2, pt3) solutions = solveQuadratic(a[isHorizontal], b[isHorizontal], @@ -120,12 +129,15 @@ def splitCubic(pt1, pt2, pt3, pt4, where, isHorizontal): which is an x coordinate if isHorizontal is False, a y coordinate if isHorizontal is True. Return a list of curve segments. - >>> splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 150, False) - [((0, 0), (25, 100), (75, 100), (100, 0))] - >>> _testrepr(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 50, False)) - '(((0.0, 0.0), (12.5, 50.0), (31.25, 75.0), (50.0, 75.0)), ((50.0, 75.0), (68.75, 75.0), (87.5, 50.0), (100.0, 0.0)))' - >>> _testrepr(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 25, True)) - '(((0.0, 0.0), (2.2937927384, 9.17517095361), (4.79804488188, 17.5085042869), (7.47413641001, 25.0)), ((7.47413641001, 25.0), (31.2886200204, 91.6666666667), (68.7113799796, 91.6666666667), (92.52586359, 25.0)), ((92.52586359, 25.0), (95.2019551181, 17.5085042869), (97.7062072616, 9.17517095361), (100.0, 1.7763568394e-15)))' + >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 150, False)) + ((0, 0), (25, 100), (75, 100), (100, 0)) + >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 50, False)) + ((0.0, 0.0), (12.5, 50.0), (31.25, 75.0), (50.0, 75.0)) + ((50.0, 75.0), (68.75, 75.0), (87.5, 50.0), (100.0, 0.0)) + >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 25, True)) + ((0.0, 0.0), (2.2937927384, 9.17517095361), (4.79804488188, 17.5085042869), (7.47413641001, 25.0)) + ((7.47413641001, 25.0), (31.2886200204, 91.6666666667), (68.7113799796, 91.6666666667), (92.52586359, 25.0)) + ((92.52586359, 25.0), (95.2019551181, 17.5085042869), (97.7062072616, 9.17517095361), (100.0, 1.7763568394e-15)) """ a, b, c, d = calcCubicParameters(pt1, pt2, pt3, pt4) solutions = solveCubic(a[isHorizontal], b[isHorizontal], c[isHorizontal], @@ -139,10 +151,13 @@ def splitCubic(pt1, pt2, pt3, pt4, where, isHorizontal): def splitQuadraticAtT(pt1, pt2, pt3, *ts): """ - >>> _testrepr(splitQuadraticAtT((0, 0), (50, 100), (100, 0), 0.5)) - '(((0.0, 0.0), (25.0, 50.0), (50.0, 50.0)), ((50.0, 50.0), (75.0, 50.0), (100.0, 0.0)))' - >>> _testrepr(splitQuadraticAtT((0, 0), (50, 100), (100, 0), 0.5, 0.75)) - '(((0.0, 0.0), (25.0, 50.0), (50.0, 50.0)), ((50.0, 50.0), (62.5, 50.0), (75.0, 37.5)), ((75.0, 37.5), (87.5, 25.0), (100.0, 0.0)))' + >>> printSegments(splitQuadraticAtT((0, 0), (50, 100), (100, 0), 0.5)) + ((0.0, 0.0), (25.0, 50.0), (50.0, 50.0)) + ((50.0, 50.0), (75.0, 50.0), (100.0, 0.0)) + >>> printSegments(splitQuadraticAtT((0, 0), (50, 100), (100, 0), 0.5, 0.75)) + ((0.0, 0.0), (25.0, 50.0), (50.0, 50.0)) + ((50.0, 50.0), (62.5, 50.0), (75.0, 37.5)) + ((75.0, 37.5), (87.5, 25.0), (100.0, 0.0)) """ a, b, c = calcQuadraticParameters(pt1, pt2, pt3) return _splitQuadraticAtT(a, b, c, *ts) @@ -150,10 +165,13 @@ def splitQuadraticAtT(pt1, pt2, pt3, *ts): def splitCubicAtT(pt1, pt2, pt3, pt4, *ts): """ - >>> _testrepr(splitCubicAtT((0, 0), (25, 100), (75, 100), (100, 0), 0.5)) - '(((0.0, 0.0), (12.5, 50.0), (31.25, 75.0), (50.0, 75.0)), ((50.0, 75.0), (68.75, 75.0), (87.5, 50.0), (100.0, 0.0)))' - >>> _testrepr(splitCubicAtT((0, 0), (25, 100), (75, 100), (100, 0), 0.5, 0.75)) - '(((0.0, 0.0), (12.5, 50.0), (31.25, 75.0), (50.0, 75.0)), ((50.0, 75.0), (59.375, 75.0), (68.75, 68.75), (77.34375, 56.25)), ((77.34375, 56.25), (85.9375, 43.75), (93.75, 25.0), (100.0, 0.0)))' + >>> printSegments(splitCubicAtT((0, 0), (25, 100), (75, 100), (100, 0), 0.5)) + ((0.0, 0.0), (12.5, 50.0), (31.25, 75.0), (50.0, 75.0)) + ((50.0, 75.0), (68.75, 75.0), (87.5, 50.0), (100.0, 0.0)) + >>> printSegments(splitCubicAtT((0, 0), (25, 100), (75, 100), (100, 0), 0.5, 0.75)) + ((0.0, 0.0), (12.5, 50.0), (31.25, 75.0), (50.0, 75.0)) + ((50.0, 75.0), (59.375, 75.0), (68.75, 68.75), (77.34375, 56.25)) + ((77.34375, 56.25), (85.9375, 43.75), (93.75, 25.0), (100.0, 0.0)) """ a, b, c, d = calcCubicParameters(pt1, pt2, pt3, pt4) return _splitCubicAtT(a, b, c, d, *ts) @@ -310,9 +328,9 @@ def calcCubicPoints(a, b, c, d): return pt1, pt2, pt3, pt4 -def _testrepr(obj): +def _segmentrepr(obj): """ - >>> _testrepr([1, [2, 3], [], [[2, [3, 4], Numeric.array([0.1, 2.2])]]]) + >>> _segmentrepr([1, [2, 3], [], [[2, [3, 4], Numeric.array([0.1, 2.2])]]]) '(1, (2, 3), (), ((2, (3, 4), (0.1, 2.2))))' """ try: @@ -320,7 +338,12 @@ def _testrepr(obj): except TypeError: return str(obj) else: - return "(%s)" % ", ".join([_testrepr(x) for x in it]) + return "(%s)" % ", ".join([_segmentrepr(x) for x in it]) + + +def printSegments(segments): + for segment in segments: + print _segmentrepr(segment) if __name__ == "__main__":