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 407b824b0..bef7316a9 100644 --- a/Lib/fontTools/ttLib/tables/_g_v_a_r_test.py +++ b/Lib/fontTools/ttLib/tables/_g_v_a_r_test.py @@ -4,11 +4,82 @@ from fontTools.misc.testTools import FakeFont from fontTools.misc.textTools import deHexStr, hexStr from fontTools.ttLib import TTLibError, getTableClass, getTableModule, newTable import unittest +from fontTools.ttLib.tables.TupleVariation import TupleVariation gvarClass = getTableClass("gvar") +GVAR_DATA = deHexStr( + "0001 0000 " # 0: majorVersion=1 minorVersion=0 + "0002 0000 " # 4: axisCount=2 sharedTupleCount=0 + "0000001C " # 8: offsetToSharedTuples=28 + "0003 0000 " # 12: glyphCount=3 flags=0 + "0000001C " # 16: offsetToGlyphVariationData=28 + "0000 0000 000C 002F " # 20: offsets=[0,0,12,47], times 2: [0,0,24,94], + # # +offsetToGlyphVariationData: [28,28,52,122] + # + # 28: Glyph variation data for glyph #0, ".notdef" + # ------------------------------------------------ + # (no variation data for this glyph) + # + # 28: Glyph variation data for glyph #1, "space" + # ---------------------------------------------- + "0001 000C " # 28: tupleVariationCount=1, offsetToData=12(+28=40) + "000B " # 32: tvHeader[0].variationDataSize=11 + "A000 " # 34: tvHeader[0].tupleIndex=EMBEDDED_PEAK|PRIVATE_POINTS + "0000 2CCD " # 36: tvHeader[0].peakTuple={wght:0.0, wdth:0.7} + "00 " # 40: all points + "03 01 02 03 04 " # 41: deltaX=[1, 2, 3, 4] + "03 0b 16 21 2C " # 46: deltaY=[11, 22, 33, 44] + "00 " # 51: padding + # + # 52: Glyph variation data for glyph #2, "I" + # ------------------------------------------ + "0002 001c " # 52: tupleVariationCount=2, offsetToData=28(+52=80) + "0013 " # 56: tvHeader[0].variationDataSize=19 + "E000 " # 58: tvHeader[0].tupleIndex= + # # EMBEDDED_PEAK|INTERMEDIATE_REGION|PRIVATE_POINTS + "2000 0000 " # 60: tvHeader[0].peakTuple={wght:0.5, wdth:0.0} + "0000 0000 " # 64: tvHeader[0].intermediateStart={wght:0.0, wdth:0.0} + "4000 0000 " # 68: tvHeader[0].intermediateEnd={wght:1.0, wdth:0.0} + "0016 " # 72: tvHeader[1].variationDataSize=22 + "A000 " # 74: tvHeader[1].tupleIndex=EMBEDDED_PEAK|PRIVATE_POINTS + "C000 3333 " # 76: tvHeader[1].peakTuple={wght:-1.0, wdth:0.8} + "00 " # 80: all points + "07 03 01 04 01 " # 81: deltaX.len=7, deltaX=[3, 1, 4, 1, + "05 09 02 06 " # 86: 5, 9, 2, 6] + "07 03 01 04 01 " # 90: deltaY.len=7, deltaY=[3, 1, 4, 1, + "05 09 02 06 " # 95: 5, 9, 2, 6] + "06 " # 99: 6 points + "05 00 01 03 01 " # 100: runLen=5(+1=6); delta-encoded run=[0, 1, 4, 5, + "01 01 " # 105: 6, 7] + "05 f8 07 fc 03 fe 01 " # 107: deltaX.len=5, deltaX=[-8,7,-4,3,-2,1] + "05 a8 4d 2c 21 ea 0b " # 114: deltaY.len=5, deltaY=[-88,77,44,33,-22,11] + "00" # 121: padding +) # 122: +assert len(GVAR_DATA) == 122 + + +GVAR_VARIATIONS = { + ".notdef": [ + ], + "space": [ + TupleVariation( + {"wdth": (0.0, 0.7, 0.7)}, + [(1, 11), (2, 22), (3, 33), (4, 44)]), + ], + "I": [ + TupleVariation( + {"wght": (0.0, 0.5, 1.0)}, + [(3,3), (1,1), (4,4), (1,1), (5,5), (9,9), (2,2), (6,6)]), + TupleVariation( + {"wght": (-1.0, -1.0, 0.0), "wdth": (0.0, 0.8, 0.8)}, + [(-8,-88), (7,77), None, None, (-4,44), (3,33), (-2,-22), (1,11)]), + ], +} + + GVAR_DATA_EMPTY_VARIATIONS = deHexStr( "0001 0000 " # 0: majorVersion=1 minorVersion=0 "0002 0000 " # 4: axisCount=2 sharedTupleCount=0 @@ -32,10 +103,16 @@ class GVARTableTest(unittest.TestCase): font = FakeFont(glyphs) font.tables = {"glyf": glyf, "gvar": gvar, "fvar": fvar} glyf.glyphs = {glyph: Glyph() for glyph in glyphs} + glyf.glyphs["I"].coordinates = [(10, 10), (10, 20), (20, 20), (20, 10)] fvar.axes = [Axis(), Axis()] fvar.axes[0].axisTag, fvar.axes[1].axisTag = "wght", "wdth" return font, gvar + def test_compile(self): + font, gvar = self.makeFont() + gvar.variations = GVAR_VARIATIONS + self.assertEqual(hexStr(gvar.compile(font)), hexStr(GVAR_DATA)) + def test_compile_noVariations(self): font, gvar = self.makeFont() self.assertEqual(hexStr(gvar.compile(font)), @@ -47,6 +124,11 @@ class GVARTableTest(unittest.TestCase): self.assertEqual(hexStr(gvar.compile(font)), hexStr(GVAR_DATA_EMPTY_VARIATIONS)) + def test_decompile(self): + font, gvar = self.makeFont() + gvar.decompile(GVAR_DATA, font) + self.assertEqual(gvar.variations, GVAR_VARIATIONS) + def test_decompile_noVariations(self): font, gvar = self.makeFont() gvar.decompile(GVAR_DATA_EMPTY_VARIATIONS, font)