diff --git a/Lib/fontTools/ttLib/tables/_g_v_a_r.py b/Lib/fontTools/ttLib/tables/_g_v_a_r.py index 57f6f446d..4339ef0db 100644 --- a/Lib/fontTools/ttLib/tables/_g_v_a_r.py +++ b/Lib/fontTools/ttLib/tables/_g_v_a_r.py @@ -205,10 +205,11 @@ class table__g_v_a_r(DefaultTable.DefaultTable): coord = sharedCoords[flags & TUPLE_INDEX_MASK] else: coord, pos = GlyphVariation.decompileCoord_(axisTags, data, pos) - minCoord = maxCoord = coord if (flags & INTERMEDIATE_TUPLE) != 0: minCoord, pos = GlyphVariation.decompileCoord_(axisTags, data, pos) maxCoord, pos = GlyphVariation.decompileCoord_(axisTags, data, pos) + else: + minCoord, maxCoord = table__g_v_a_r.computeMinMaxCoord_(coord) axes = {} for axis in axisTags: coords = minCoord[axis], coord[axis], maxCoord[axis] @@ -226,6 +227,15 @@ class table__g_v_a_r(DefaultTable.DefaultTable): deltas[p] = (x, y) return GlyphVariation(axes, deltas) + @staticmethod + def computeMinMaxCoord_(coord): + minCoord = {} + maxCoord = {} + for (axis, value) in coord.iteritems(): + minCoord[axis] = min(value, 0.0) # -0.3 --> -0.3; 0.7 --> 0.0 + maxCoord[axis] = max(value, 0.0) # -0.3 --> 0.0; 0.7 --> 0.7 + return (minCoord, maxCoord) + def toXML(self, writer, ttFont): writer.simpletag("version", value=self.version) writer.newline() @@ -293,7 +303,9 @@ class GlyphVariation: value = self.axes.get(axis) if value != None: minValue, value, maxValue = value - if minValue == value and maxValue == value: + defaultMinValue = min(value, 0.0) # -0.3 --> -0.3; 0.7 --> 0.0 + defaultMaxValue = max(value, 0.0) # -0.3 --> 0.0; 0.7 --> 0.7 + if minValue == defaultMinValue and maxValue == defaultMaxValue: writer.simpletag("coord", axis=axis, value=value) else: writer.simpletag("coord", axis=axis, value=value, @@ -315,10 +327,12 @@ class GlyphVariation: def fromXML(self, name, attrs, content): if name == "coord": axis = attrs["axis"] - value = attrs["value"] - minValue = attrs.get("min", value) - maxValue = attrs.get("max", value) - self.axes[axis] = (safeEval(minValue), safeEval(value), safeEval(maxValue)) + value = float(attrs["value"]) + defaultMinValue = min(value, 0.0) # -0.3 --> -0.3; 0.7 --> 0.0 + defaultMaxValue = max(value, 0.0) # -0.3 --> 0.0; 0.7 --> 0.7 + minValue = float(attrs.get("min", defaultMinValue)) + maxValue = float(attrs.get("max", defaultMaxValue)) + self.axes[axis] = (minValue, value, maxValue) elif name == "delta": point = safeEval(attrs["pt"]) x = safeEval(attrs["x"]) @@ -336,7 +350,9 @@ class GlyphVariation: needed = False for axis in axisTags: minValue, value, maxValue = self.axes.get(axis, (0.0, 0.0, 0.0)) - if (minValue != value) or (maxValue != value): + defaultMinValue = min(value, 0.0) # -0.3 --> -0.3; 0.7 --> 0.0 + defaultMaxValue = max(value, 0.0) # -0.3 --> 0.0; 0.7 --> 0.7 + if (minValue != defaultMinValue) or (maxValue != defaultMaxValue): needed = True break if not needed: diff --git a/Lib/fontTools/ttLib/tables/_g_v_a_r_test.py b/Lib/fontTools/ttLib/tables/_g_v_a_r_test.py index c8babf87a..f43bff229 100644 --- a/Lib/fontTools/ttLib/tables/_g_v_a_r_test.py +++ b/Lib/fontTools/ttLib/tables/_g_v_a_r_test.py @@ -126,7 +126,7 @@ class GlyphVariationTableTest(unittest.TestCase): sharedCoords = table.decompileSharedCoords_(axes, SKIA_SHARED_COORDS) tuples = table.decompileTuples_(18, sharedCoords, axes, SKIA_GVAR_I) self.assertEqual(8, len(tuples)) - self.assertEqual({"wght": (1.0, 1.0, 1.0)}, tuples[0].axes) + self.assertEqual({"wght": (0.0, 1.0, 1.0)}, tuples[0].axes) self.assertEqual("257,0 -127,0 -128,58 -130,90 -130,62 -130,67 -130,32 -127,0 257,0 " "259,14 260,64 260,21 260,69 258,124 0,0 130,0 0,0 0,0", " ".join(["%d,%d" % c for c in tuples[0].coordinates])) @@ -135,17 +135,23 @@ class GlyphVariationTableTest(unittest.TestCase): table = table__g_v_a_r() self.assertEqual([], table.decompileTuples_(numPoints=5, sharedCoords=[], axisTags=[], data=b"")) + def test_computeMinMaxCord(self): + coord = {"wght": -0.3, "wdth": 0.7} + minCoord, maxCoord = table__g_v_a_r.computeMinMaxCoord_(coord) + self.assertEqual({"wght": -0.3, "wdth": 0.0}, minCoord) + self.assertEqual({"wght": 0.0, "wdth": 0.7}, maxCoord) class GlyphVariationTest(unittest.TestCase): def test_toXML(self): writer = XMLWriter(StringIO()) - axes = {"wdth":(0.3, 0.4, 0.5), "wght":(1.0, 1.0, 1.0)} + axes = {"wdth":(0.3, 0.4, 0.5), "wght":(0.0, 1.0, 1.0), "opsz":(-0.7, -0.7, 0.0)} g = GlyphVariation(axes, GlyphCoordinates([(9,8), (7,6), (0,0), (-1,-2)])) - g.toXML(writer, ["wght", "wdth"]) + g.toXML(writer, ["wdth", "wght", "opsz"]) self.assertEqual([ '', - '', '', + '', + '', '', '', '', @@ -154,24 +160,28 @@ class GlyphVariationTest(unittest.TestCase): def test_toXML_allDeltasZero(self): writer = XMLWriter(StringIO()) - axes = {"wdth":(0.3, 0.4, 0.5), "wght":(1.0, 1.0, 1.0)} + axes = {"wght":(0.0, 1.0, 1.0)} g = GlyphVariation(axes, GlyphCoordinates.zeros(5)) g.toXML(writer, ["wght", "wdth"]) self.assertEqual([ '', '', - '', '', '' ], GlyphVariationTest.xml_lines(writer)) def test_fromXML(self): g = GlyphVariation({}, GlyphCoordinates.zeros(4)) - g.fromXML("coord", {"axis":"wght", "value":"1.0"}, []) g.fromXML("coord", {"axis":"wdth", "min":"0.3", "value":"0.4", "max":"0.5"}, []) + g.fromXML("coord", {"axis":"wght", "value":"1.0"}, []) + g.fromXML("coord", {"axis":"opsz", "value":"-0.5"}, []) g.fromXML("delta", {"pt":"1", "x":"33", "y":"44"}, []) g.fromXML("delta", {"pt":"2", "x":"-2", "y":"170"}, []) - self.assertEqual({"wght":(1.0, 1.0, 1.0), "wdth":(0.3, 0.4, 0.5)}, g.axes) + self.assertEqual({ + "wdth":( 0.3, 0.4, 0.5), + "wght":( 0.0, 1.0, 1.0), + "opsz":(-0.5, -0.5, 0.0) + }, g.axes) self.assertEqual("0,0 33,44 -2,170 0,0", " ".join(["%d,%d" % c for c in g.coordinates])) def test_compileCoord(self): @@ -181,9 +191,9 @@ class GlyphVariationTest(unittest.TestCase): self.assertEqual("C0 00", hexencode(gvar.compileCoord(["wght"]))) def test_compileIntermediateCoord(self): - gvar = GlyphVariation({"wght": (-1.0, -1.0, -1.0), "wdth": (0.4, 0.5, 0.6)}, GlyphCoordinates.zeros(4)) - self.assertEqual("C0 00 19 9A C0 00 26 66", hexencode(gvar.compileIntermediateCoord(["wght", "wdth"]))) - self.assertEqual("19 9A C0 00 26 66 C0 00", hexencode(gvar.compileIntermediateCoord(["wdth", "wght"]))) + gvar = GlyphVariation({"wght": (-1.0, -1.0, 0.0), "wdth": (0.4, 0.5, 0.6)}, GlyphCoordinates.zeros(4)) + self.assertEqual("C0 00 19 9A 00 00 26 66", hexencode(gvar.compileIntermediateCoord(["wght", "wdth"]))) + self.assertEqual("19 9A C0 00 26 66 00 00", hexencode(gvar.compileIntermediateCoord(["wdth", "wght"]))) self.assertEqual(None, gvar.compileIntermediateCoord(["wght"])) self.assertEqual("19 9A 26 66", hexencode(gvar.compileIntermediateCoord(["wdth"])))