diff --git a/Lib/fontTools/ttLib/tables/_g_l_y_f.py b/Lib/fontTools/ttLib/tables/_g_l_y_f.py index e27feeb29..939e7d0a2 100644 --- a/Lib/fontTools/ttLib/tables/_g_l_y_f.py +++ b/Lib/fontTools/ttLib/tables/_g_l_y_f.py @@ -1427,6 +1427,7 @@ class Glyph(object): cubic = all(cuFlags) if cubic: count = len(contour) + assert count % 2 == 0, "Odd number of cubic off-curves undefined" for i in range(0, count, 2): p1 = contour[i] p2 = contour[i + 1] @@ -1462,11 +1463,23 @@ class Glyph(object): if cubic: assert all( cubicFlags - ), "Mixed segments not currently supported" + ), "Mixed cubic and quadratic segment undefined" + + count = nextOnCurve assert ( - len(cubicFlags) == 2 - ), "Cubic multi-segments not currently supported" - pen.curveTo(*contour[:nextOnCurve]) + count >= 3 + ), "At least two cubic off-curve points required" + assert ( + count - 1 + ) % 2 == 0, "Odd number of cubic off-curves undefined" + for i in range(0, count - 3, 2): + p1 = contour[i] + p2 = contour[i + 1] + p4 = contour[i + 2] + p3 = ((p2[0] + p4[0]) * 0.5, (p2[1] + p4[1]) * 0.5) + lastOnCurve = p3 + pen.curveTo(p1, p2, p3) + pen.curveTo(*contour[count - 3 : count]) else: pen.qCurveTo(*contour[:nextOnCurve]) contour = contour[nextOnCurve:] diff --git a/Tests/ttLib/tables/_g_l_y_f_test.py b/Tests/ttLib/tables/_g_l_y_f_test.py index b44824c69..ddcdb5959 100644 --- a/Tests/ttLib/tables/_g_l_y_f_test.py +++ b/Tests/ttLib/tables/_g_l_y_f_test.py @@ -8,6 +8,7 @@ from fontTools.ttLib.tables._g_l_y_f import ( Glyph, GlyphCoordinates, GlyphComponent, + flagOnCurve, flagCubic, ARGS_ARE_XY_VALUES, SCALED_COMPONENT_OFFSET, @@ -771,6 +772,32 @@ class GlyphCubicTest: ("closePath", ()), ] + def test_spline(self): + glyph = Glyph() + glyph.numberOfContours = 1 + glyph.coordinates = GlyphCoordinates( + [(0, 0), (1, 0), (1, 0), (1, 1), (1, 1), (0, 1), (0, 1)] + ) + glyph.flags = array.array("B", [flagOnCurve] + [flagCubic] * 6) + glyph.endPtsOfContours = [6] + glyph.program = ttProgram.Program() + + for i in range(2): + + if i == 1: + glyph.compile(None) + + pen = RecordingPen() + glyph.draw(pen, None) + + assert pen.value == [ + ("moveTo", ((0, 0),)), + ("curveTo", ((1, 0), (1, 0), (1.0, 0.5))), + ("curveTo", ((1, 1), (1, 1), (0.5, 1.0))), + ("curveTo", ((0, 1), (0, 1), (0, 0))), + ("closePath", ()), + ] + if __name__ == "__main__": import sys