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