• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1from __future__ import print_function, division, absolute_import
2from fontTools.misc.py23 import *
3from fontTools.misc.testTools import FakeFont, getXML, parseXML
4from fontTools.misc.textTools import deHexStr
5from fontTools.ttLib import newTable
6import unittest
7
8
9STAT_DATA = deHexStr(
10    '0001 0000 '           #   0: Version=1.0
11    '0008 0002 '           #   4: DesignAxisSize=8, DesignAxisCount=2
12    '0000 0012 '           #   8: OffsetToDesignAxes=18
13    '0003 0000 0022 '      #  12: AxisValueCount=3, OffsetToAxisValueOffsets=34
14    '7767 6874 '           #  18: DesignAxis[0].AxisTag='wght'
15    '012D 0002 '           #  22: DesignAxis[0].NameID=301, .AxisOrdering=2
16    '5445 5354 '           #  26: DesignAxis[1].AxisTag='TEST'
17    '012E 0001 '           #  30: DesignAxis[1].NameID=302, .AxisOrdering=1
18    '0006 0012 0026 '      #  34: AxisValueOffsets = [6, 18, 38] (+34)
19    '0001 0000 0000  '     #  40: AxisValue[0].Format=1, .AxisIndex=0, .Flags=0
20    '0191 0190 0000 '      #  46: AxisValue[0].ValueNameID=401, .Value=400.0
21    '0002 0001 0000 '      #  52: AxisValue[1].Format=2, .AxisIndex=1, .Flags=0
22    '0192 '                #  58: AxisValue[1].ValueNameID=402
23    '0002 0000 '           #  60: AxisValue[1].NominalValue=2.0
24    '0001 0000 '           #  64: AxisValue[1].RangeMinValue=1.0
25    '0003 0000 '           #  68: AxisValue[1].RangeMaxValue=3.0
26    '0003 0000 0000 '      #  72: AxisValue[2].Format=3, .AxisIndex=0, .Flags=0
27    '0002 '                #  78: AxisValue[2].ValueNameID=2 'Regular'
28    '0190 0000 02BC 0000 ' #  80: AxisValue[2].Value=400.0, .LinkedValue=700.0
29)                          #  88: <end>
30assert(len(STAT_DATA) == 88)
31
32
33STAT_XML = [
34    '<Version value="0x00010000"/>',
35    '<DesignAxisRecordSize value="8"/>',
36    '<!-- DesignAxisCount=2 -->',
37    '<DesignAxisRecord>',
38    '  <Axis index="0">',
39    '    <AxisTag value="wght"/>',
40    '    <AxisNameID value="301"/>',
41    '    <AxisOrdering value="2"/>',
42    '  </Axis>',
43    '  <Axis index="1">',
44    '    <AxisTag value="TEST"/>',
45    '    <AxisNameID value="302"/>',
46    '    <AxisOrdering value="1"/>',
47    '  </Axis>',
48    '</DesignAxisRecord>',
49    '<!-- AxisValueCount=3 -->',
50    '<AxisValueArray>',
51    '  <AxisValue index="0" Format="1">',
52    '    <AxisIndex value="0"/>',
53    '    <Flags value="0"/>',
54    '    <ValueNameID value="401"/>',
55    '    <Value value="400.0"/>',
56    '  </AxisValue>',
57    '  <AxisValue index="1" Format="2">',
58    '    <AxisIndex value="1"/>',
59    '    <Flags value="0"/>',
60    '    <ValueNameID value="402"/>',
61    '    <NominalValue value="2.0"/>',
62    '    <RangeMinValue value="1.0"/>',
63    '    <RangeMaxValue value="3.0"/>',
64    '  </AxisValue>',
65    '  <AxisValue index="2" Format="3">',
66    '    <AxisIndex value="0"/>',
67    '    <Flags value="0"/>',
68    '    <ValueNameID value="2"/>',
69    '    <Value value="400.0"/>',
70    '    <LinkedValue value="700.0"/>',
71    '  </AxisValue>',
72    '</AxisValueArray>',
73]
74
75
76# Contains junk data for making sure we get our offset decoding right.
77STAT_DATA_WITH_AXIS_JUNK = deHexStr(
78    '0001 0000 '           #   0: Version=1.0
79    '000A 0002 '           #   4: DesignAxisSize=10, DesignAxisCount=2
80    '0000 0012 '           #   8: OffsetToDesignAxes=18
81    '0000 0000 0000 '      #  12: AxisValueCount=3, OffsetToAxisValueOffsets=34
82    '7767 6874 '           #  18: DesignAxis[0].AxisTag='wght'
83    '012D 0002 '           #  22: DesignAxis[0].NameID=301, .AxisOrdering=2
84    'DEAD '                #  26: <junk>
85    '5445 5354 '           #  28: DesignAxis[1].AxisTag='TEST'
86    '012E 0001 '           #  32: DesignAxis[1].NameID=302, .AxisOrdering=1
87    'BEEF '                #  36: <junk>
88)                          #  38: <end>
89
90assert(len(STAT_DATA_WITH_AXIS_JUNK) == 38)
91
92
93STAT_XML_WITH_AXIS_JUNK = [
94    '<Version value="0x00010000"/>',
95    '<DesignAxisRecordSize value="10"/>',
96    '<!-- DesignAxisCount=2 -->',
97    '<DesignAxisRecord>',
98    '  <Axis index="0">',
99    '    <AxisTag value="wght"/>',
100    '    <AxisNameID value="301"/>',
101    '    <AxisOrdering value="2"/>',
102    '    <MoreBytes index="0" value="222"/>',  # 0xDE
103    '    <MoreBytes index="1" value="173"/>',  # 0xAD
104    '  </Axis>',
105    '  <Axis index="1">',
106    '    <AxisTag value="TEST"/>',
107    '    <AxisNameID value="302"/>',
108    '    <AxisOrdering value="1"/>',
109    '    <MoreBytes index="0" value="190"/>',  # 0xBE
110    '    <MoreBytes index="1" value="239"/>',  # 0xEF
111    '  </Axis>',
112    '</DesignAxisRecord>',
113    '<!-- AxisValueCount=0 -->',
114]
115
116
117STAT_DATA_AXIS_VALUE_FORMAT3 = deHexStr(
118    '0001 0000 '  #  0: Version=1.0
119    '0008 0001 '  #  4: DesignAxisSize=8, DesignAxisCount=1
120    '0000 0012 '  #  8: OffsetToDesignAxes=18
121    '0001 '       # 12: AxisValueCount=1
122    '0000 001A '  # 14: OffsetToAxisValueOffsets=26
123    '7767 6874 '  # 18: DesignAxis[0].AxisTag='wght'
124    '0102  '      # 22: DesignAxis[0].AxisNameID=258 'Weight'
125    '0000 '       # 24: DesignAxis[0].AxisOrdering=0
126    '0002 '       # 26: AxisValueOffsets=[2] (+26)
127    '0003 '       # 28: AxisValue[0].Format=3
128    '0000 0002 '  # 30: AxisValue[0].AxisIndex=0, .Flags=0x2
129    '0002 '       # 34: AxisValue[0].ValueNameID=2 'Regular'
130    '0190 0000 '  # 36: AxisValue[0].Value=400.0
131    '02BC 0000 '  # 40: AxisValue[0].LinkedValue=700.0
132)                 # 44: <end>
133assert(len(STAT_DATA_AXIS_VALUE_FORMAT3) == 44)
134
135
136STAT_XML_AXIS_VALUE_FORMAT3 = [
137    '<Version value="0x00010000"/>',
138    '<DesignAxisRecordSize value="8"/>',
139    '<!-- DesignAxisCount=1 -->',
140    '<DesignAxisRecord>',
141    '  <Axis index="0">',
142    '    <AxisTag value="wght"/>',
143    '    <AxisNameID value="258"/>',
144    '    <AxisOrdering value="0"/>',
145    '  </Axis>',
146    '</DesignAxisRecord>',
147    '<!-- AxisValueCount=1 -->',
148    '<AxisValueArray>',
149    '  <AxisValue index="0" Format="3">',
150    '    <AxisIndex value="0"/>',
151    '    <Flags value="2"/>',
152    '    <ValueNameID value="2"/>',
153    '    <Value value="400.0"/>',
154    '    <LinkedValue value="700.0"/>',
155    '  </AxisValue>',
156    '</AxisValueArray>',
157]
158
159
160STAT_DATA_VERSION_1_1 = deHexStr(
161    '0001 0001 '  #  0: Version=1.1
162    '0008 0001 '  #  4: DesignAxisSize=8, DesignAxisCount=1
163    '0000 0014 '  #  8: OffsetToDesignAxes=20
164    '0001 '       # 12: AxisValueCount=1
165    '0000 001C '  # 14: OffsetToAxisValueOffsets=28
166    '0101 '       # 18: ElidedFallbackNameID: 257
167    '7767 6874 '  # 20: DesignAxis[0].AxisTag='wght'
168    '0102  '      # 24: DesignAxis[0].AxisNameID=258 'Weight'
169    '0000 '       # 26: DesignAxis[0].AxisOrdering=0
170    '0002 '       # 28: AxisValueOffsets=[2] (+28)
171    '0003 '       # 30: AxisValue[0].Format=3
172    '0000 0002 '  # 32: AxisValue[0].AxisIndex=0, .Flags=0x2
173    '0002 '       # 36: AxisValue[0].ValueNameID=2 'Regular'
174    '0190 0000 '  # 38: AxisValue[0].Value=400.0
175    '02BC 0000 '  # 42: AxisValue[0].LinkedValue=700.0
176)                 # 46: <end>
177assert(len(STAT_DATA_VERSION_1_1) == 46)
178
179
180STAT_XML_VERSION_1_1 = [
181    '<Version value="0x00010001"/>',
182    '<DesignAxisRecordSize value="8"/>',
183    '<!-- DesignAxisCount=1 -->',
184    '<DesignAxisRecord>',
185    '  <Axis index="0">',
186    '    <AxisTag value="wght"/>',
187    '    <AxisNameID value="258"/>',
188    '    <AxisOrdering value="0"/>',
189    '  </Axis>',
190    '</DesignAxisRecord>',
191    '<!-- AxisValueCount=1 -->',
192    '<AxisValueArray>',
193    '  <AxisValue index="0" Format="3">',
194    '    <AxisIndex value="0"/>',
195    '    <Flags value="2"/>',
196    '    <ValueNameID value="2"/>',
197    '    <Value value="400.0"/>',
198    '    <LinkedValue value="700.0"/>',
199    '  </AxisValue>',
200    '</AxisValueArray>',
201    '<ElidedFallbackNameID value="257"/>',
202]
203
204
205class STATTest(unittest.TestCase):
206
207    @classmethod
208    def setUpClass(cls):
209        cls.maxDiff = None
210
211    def test_decompile_toXML(self):
212        table = newTable('STAT')
213        table.decompile(STAT_DATA, font=FakeFont(['.notdef']))
214        self.assertEqual(getXML(table.toXML), STAT_XML)
215
216    def test_decompile_toXML_withAxisJunk(self):
217        table = newTable('STAT')
218        table.decompile(STAT_DATA_WITH_AXIS_JUNK, font=FakeFont(['.notdef']))
219        self.assertEqual(getXML(table.toXML), STAT_XML_WITH_AXIS_JUNK)
220
221    def test_decompile_toXML_format3(self):
222        table = newTable('STAT')
223        table.decompile(STAT_DATA_AXIS_VALUE_FORMAT3,
224                        font=FakeFont(['.notdef']))
225        self.assertEqual(getXML(table.toXML), STAT_XML_AXIS_VALUE_FORMAT3)
226
227    def test_decompile_toXML_version_1_1(self):
228        table = newTable('STAT')
229        table.decompile(STAT_DATA_VERSION_1_1,
230                        font=FakeFont(['.notdef']))
231        self.assertEqual(getXML(table.toXML), STAT_XML_VERSION_1_1)
232
233    def test_compile_fromXML(self):
234        table = newTable('STAT')
235        font = FakeFont(['.notdef'])
236        for name, attrs, content in parseXML(STAT_XML):
237            table.fromXML(name, attrs, content, font=font)
238        self.assertEqual(table.compile(font), STAT_DATA)
239
240    def test_compile_fromXML_withAxisJunk(self):
241        table = newTable('STAT')
242        font = FakeFont(['.notdef'])
243        for name, attrs, content in parseXML(STAT_XML_WITH_AXIS_JUNK):
244            table.fromXML(name, attrs, content, font=font)
245        self.assertEqual(table.compile(font), STAT_DATA_WITH_AXIS_JUNK)
246
247    def test_compile_fromXML_format3(self):
248        table = newTable('STAT')
249        font = FakeFont(['.notdef'])
250        for name, attrs, content in parseXML(STAT_XML_AXIS_VALUE_FORMAT3):
251            table.fromXML(name, attrs, content, font=font)
252        self.assertEqual(table.compile(font), STAT_DATA_AXIS_VALUE_FORMAT3)
253
254    def test_compile_fromXML_version_1_1(self):
255        table = newTable('STAT')
256        font = FakeFont(['.notdef'])
257        for name, attrs, content in parseXML(STAT_XML_VERSION_1_1):
258            table.fromXML(name, attrs, content, font=font)
259        self.assertEqual(table.compile(font), STAT_DATA_VERSION_1_1)
260
261
262if __name__ == '__main__':
263    import sys
264    sys.exit(unittest.main())
265