• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1from fontTools.misc.testTools import getXML, parseXML
2from fontTools.misc.textTools import deHexStr, hexStr
3from fontTools.ttLib import TTLibError, getTableModule, newTable
4from fontTools.ttLib.tables.TupleVariation import TupleVariation
5
6import unittest
7
8
9CVAR_DATA = deHexStr(
10    "0001 0000 "      #  0: majorVersion=1 minorVersion=0
11    "8002 0018 "      #  4: tupleVariationCount=2|TUPLES_SHARE_POINT_NUMBERS offsetToData=24
12    "0004 "           #  8: tvHeader[0].variationDataSize=4
13    "8000 "           # 10: tvHeader[0].tupleIndex=EMBEDDED_PEAK
14    "4000 0000 "      # 12: tvHeader[0].peakTuple=[1.0, 0.0]
15    "0004 "           # 16: tvHeader[1].variationDataSize=4
16    "8000 "           # 18: tvHeader[1].tupleIndex=EMBEDDED_PEAK
17    "C000 3333 "      # 20: tvHeader[1].peakTuple=[-1.0, 0.8]
18    "03 02 02 01 01"  # 24: shared_pointCount=03, run_count=2 cvt=[2, 3, 4]
19    "02 03 01 04 "    # 25: deltas=[3, 1, 4]
20    "02 09 07 08")    # 29: deltas=[9, 7, 8]
21
22CVAR_PRIVATE_POINT_DATA = deHexStr(
23    "0001 0000 "                    #  0: majorVersion=1 minorVersion=0
24    "0002 0018 "                    #  4: tupleVariationCount=2 offsetToData=24
25    "0009 "                         #  8: tvHeader[0].variationDataSize=9
26    "A000 "                         # 10: tvHeader[0].tupleIndex=EMBEDDED_PEAK|PRIVATE_POINT_NUMBERS
27    "4000 0000 "                    # 12: tvHeader[0].peakTuple=[1.0, 0.0]
28    "0009 "                         # 16: tvHeader[1].variationDataSize=9
29    "A000 "                         # 18: tvHeader[1].tupleIndex=EMBEDDED_PEAK|PRIVATE_POINT_NUMBERS
30    "C000 3333 "                    # 20: tvHeader[1].peakTuple=[-1.0, 0.8]
31    "03 02 02 01 01 02 03 01 04 "   # 24: pointCount=3 run_count=2 cvt=2 1 1 run_count=2 deltas=[3, 1, 4]
32    "03 02 02 01 01 02 09 07 08 ")  # 33: pointCount=3 run_count=2 cvt=2 1 1 run_count=2 deltas=[9, 7, 8]
33
34CVAR_XML = [
35    '<version major="1" minor="0"/>',
36    '<tuple>',
37    '  <coord axis="wght" value="1.0"/>',
38    '  <delta cvt="2" value="3"/>',
39    '  <delta cvt="3" value="1"/>',
40    '  <delta cvt="4" value="4"/>',
41    '</tuple>',
42    '<tuple>',
43    '  <coord axis="wght" value="-1.0"/>',
44    '  <coord axis="wdth" value="0.8"/>',
45    '  <delta cvt="2" value="9"/>',
46    '  <delta cvt="3" value="7"/>',
47    '  <delta cvt="4" value="8"/>',
48    '</tuple>',
49]
50
51CVAR_VARIATIONS = [
52    TupleVariation({"wght": (0.0, 1.0, 1.0)}, [None, None, 3, 1, 4]),
53    TupleVariation({"wght": (-1, -1.0, 0.0), "wdth": (0.0, 0.7999878, 0.7999878)},
54                   [None, None, 9, 7, 8]),
55]
56
57
58class CVARTableTest(unittest.TestCase):
59    def assertVariationsAlmostEqual(self, variations1, variations2):
60        self.assertEqual(len(variations1), len(variations2))
61        for (v1, v2) in zip(variations1, variations2):
62            self.assertSetEqual(set(v1.axes), set(v2.axes))
63            for axisTag, support1 in v1.axes.items():
64                support2 = v2.axes[axisTag]
65                self.assertEqual(len(support1), len(support2))
66                for s1, s2 in zip(support1, support2):
67                    self.assertAlmostEqual(s1, s2)
68                self.assertEqual(v1.coordinates, v2.coordinates)
69
70    def makeFont(self):
71        cvt, cvar, fvar = newTable("cvt "), newTable("cvar"), newTable("fvar")
72        font = {"cvt ": cvt, "cvar": cvar, "fvar": fvar}
73        cvt.values = [0, 0, 0, 1000, -2000]
74        Axis = getTableModule("fvar").Axis
75        fvar.axes = [Axis(), Axis()]
76        fvar.axes[0].axisTag, fvar.axes[1].axisTag = "wght", "wdth"
77        return font, cvar
78
79    def test_compile(self):
80        font, cvar = self.makeFont()
81        cvar.variations = CVAR_VARIATIONS
82        self.assertEqual(hexStr(cvar.compile(font)), hexStr(CVAR_PRIVATE_POINT_DATA))
83
84    def test_compile_shared_points(self):
85        font, cvar = self.makeFont()
86        cvar.variations = CVAR_VARIATIONS
87        self.assertEqual(hexStr(cvar.compile(font, useSharedPoints=True)), hexStr(CVAR_DATA))
88
89    def test_decompile(self):
90        font, cvar = self.makeFont()
91        cvar.decompile(CVAR_PRIVATE_POINT_DATA, font)
92        self.assertEqual(cvar.majorVersion, 1)
93        self.assertEqual(cvar.minorVersion, 0)
94        self.assertVariationsAlmostEqual(cvar.variations, CVAR_VARIATIONS)
95
96    def test_decompile_shared_points(self):
97        font, cvar = self.makeFont()
98        cvar.decompile(CVAR_DATA, font)
99        self.assertEqual(cvar.majorVersion, 1)
100        self.assertEqual(cvar.minorVersion, 0)
101        self.assertVariationsAlmostEqual(cvar.variations, CVAR_VARIATIONS)
102
103    def test_fromXML(self):
104        font, cvar = self.makeFont()
105        for name, attrs, content in parseXML(CVAR_XML):
106            cvar.fromXML(name, attrs, content, ttFont=font)
107        self.assertEqual(cvar.majorVersion, 1)
108        self.assertEqual(cvar.minorVersion, 0)
109        self.assertVariationsAlmostEqual(cvar.variations, CVAR_VARIATIONS)
110
111    def test_toXML(self):
112        font, cvar = self.makeFont()
113        cvar.variations = CVAR_VARIATIONS
114        self.assertEqual(getXML(cvar.toXML, font), CVAR_XML)
115
116
117if __name__ == "__main__":
118    import sys
119    sys.exit(unittest.main())
120