1 from __future__ import absolute_import, unicode_literals 2 from fontTools.misc.py23 import * 3 from fontTools.misc.loggingTools import CapturingLogHandler 4 from fontTools.misc.testTools import parseXML, getXML 5 from fontTools.misc.textTools import deHexStr 6 from fontTools.ttLib import TTFont, newTable 7 from fontTools.misc.fixedTools import log 8 import os 9 import unittest 10 11 12 CURR_DIR = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) 13 DATA_DIR = os.path.join(CURR_DIR, 'data') 14 15 VHEA_DATA_VERSION_11 = deHexStr( 16 '0001 1000 ' # 1.1 version 17 '01F4 ' # 500 ascent 18 'FE0C ' # -500 descent 19 '0000 ' # 0 lineGap 20 '0BB8 ' # 3000 advanceHeightMax 21 'FC16 ' # -1002 minTopSideBearing 22 'FD5B ' # -677 minBottomSideBearing 23 '0B70 ' # 2928 yMaxExtent 24 '0000 ' # 0 caretSlopeRise 25 '0001 ' # 1 caretSlopeRun 26 '0000 ' # 0 caretOffset 27 '0000 ' # 0 reserved1 28 '0000 ' # 0 reserved2 29 '0000 ' # 0 reserved3 30 '0000 ' # 0 reserved4 31 '0000 ' # 0 metricDataFormat 32 '000C ' # 12 numberOfVMetrics 33 ) 34 35 VHEA_DATA_VERSION_10 = deHexStr('00010000') + VHEA_DATA_VERSION_11[4:] 36 37 VHEA_VERSION_11_AS_DICT = { 38 'tableTag': 'vhea', 39 'tableVersion': 0x00011000, 40 'ascent': 500, 41 'descent': -500, 42 'lineGap': 0, 43 'advanceHeightMax': 3000, 44 'minTopSideBearing': -1002, 45 'minBottomSideBearing': -677, 46 'yMaxExtent': 2928, 47 'caretSlopeRise': 0, 48 'caretSlopeRun': 1, 49 'caretOffset': 0, 50 'reserved1': 0, 51 'reserved2': 0, 52 'reserved3': 0, 53 'reserved4': 0, 54 'metricDataFormat': 0, 55 'numberOfVMetrics': 12, 56 } 57 58 VHEA_VERSION_10_AS_DICT = dict(VHEA_VERSION_11_AS_DICT) 59 VHEA_VERSION_10_AS_DICT['tableVersion'] = 0x00010000 60 61 VHEA_XML_VERSION_11 = [ 62 '<tableVersion value="0x00011000"/>', 63 '<ascent value="500"/>', 64 '<descent value="-500"/>', 65 '<lineGap value="0"/>', 66 '<advanceHeightMax value="3000"/>', 67 '<minTopSideBearing value="-1002"/>', 68 '<minBottomSideBearing value="-677"/>', 69 '<yMaxExtent value="2928"/>', 70 '<caretSlopeRise value="0"/>', 71 '<caretSlopeRun value="1"/>', 72 '<caretOffset value="0"/>', 73 '<reserved1 value="0"/>', 74 '<reserved2 value="0"/>', 75 '<reserved3 value="0"/>', 76 '<reserved4 value="0"/>', 77 '<metricDataFormat value="0"/>', 78 '<numberOfVMetrics value="12"/>', 79 ] 80 81 VHEA_XML_VERSION_11_AS_FLOAT = [ 82 '<tableVersion value="1.0625"/>', 83 ] + VHEA_XML_VERSION_11[1:] 84 85 VHEA_XML_VERSION_10 = [ 86 '<tableVersion value="0x00010000"/>', 87 ] + VHEA_XML_VERSION_11[1:] 88 89 VHEA_XML_VERSION_10_AS_FLOAT = [ 90 '<tableVersion value="1.0"/>', 91 ] + VHEA_XML_VERSION_11[1:] 92 93 94 class VheaCompileOrToXMLTest(unittest.TestCase): 95 96 def setUp(self): 97 vhea = newTable('vhea') 98 vhea.tableVersion = 0x00010000 99 vhea.ascent = 500 100 vhea.descent = -500 101 vhea.lineGap = 0 102 vhea.advanceHeightMax = 3000 103 vhea.minTopSideBearing = -1002 104 vhea.minBottomSideBearing = -677 105 vhea.yMaxExtent = 2928 106 vhea.caretSlopeRise = 0 107 vhea.caretSlopeRun = 1 108 vhea.caretOffset = 0 109 vhea.metricDataFormat = 0 110 vhea.numberOfVMetrics = 12 111 vhea.reserved1 = vhea.reserved2 = vhea.reserved3 = vhea.reserved4 = 0 112 self.font = TTFont(sfntVersion='OTTO') 113 self.font['vhea'] = vhea 114 115 def test_compile_caretOffset_as_reserved0(self): 116 vhea = self.font['vhea'] 117 del vhea.caretOffset 118 vhea.reserved0 = 0 119 self.assertEqual(VHEA_DATA_VERSION_10, vhea.compile(self.font)) 120 121 def test_compile_version_10(self): 122 vhea = self.font['vhea'] 123 vhea.tableVersion = 0x00010000 124 self.assertEqual(VHEA_DATA_VERSION_10, vhea.compile(self.font)) 125 126 def test_compile_version_10_as_float(self): 127 vhea = self.font['vhea'] 128 vhea.tableVersion = 1.0 129 with CapturingLogHandler(log, "WARNING") as captor: 130 self.assertEqual(VHEA_DATA_VERSION_10, vhea.compile(self.font)) 131 self.assertTrue( 132 len([r for r in captor.records 133 if "Table version value is a float" in r.msg]) == 1) 134 135 def test_compile_version_11(self): 136 vhea = self.font['vhea'] 137 vhea.tableVersion = 0x00011000 138 self.assertEqual(VHEA_DATA_VERSION_11, vhea.compile(self.font)) 139 140 def test_compile_version_11_as_float(self): 141 vhea = self.font['vhea'] 142 vhea.tableVersion = 1.0625 143 with CapturingLogHandler(log, "WARNING") as captor: 144 self.assertEqual(VHEA_DATA_VERSION_11, vhea.compile(self.font)) 145 self.assertTrue( 146 len([r for r in captor.records 147 if "Table version value is a float" in r.msg]) == 1) 148 149 def test_toXML_caretOffset_as_reserved0(self): 150 vhea = self.font['vhea'] 151 del vhea.caretOffset 152 vhea.reserved0 = 0 153 self.assertEqual(getXML(vhea.toXML), VHEA_XML_VERSION_10) 154 155 def test_toXML_version_10(self): 156 vhea = self.font['vhea'] 157 self.font['vhea'].tableVersion = 0x00010000 158 self.assertEqual(getXML(vhea.toXML), VHEA_XML_VERSION_10) 159 160 def test_toXML_version_10_as_float(self): 161 vhea = self.font['vhea'] 162 vhea.tableVersion = 1.0 163 with CapturingLogHandler(log, "WARNING") as captor: 164 self.assertEqual(getXML(vhea.toXML), VHEA_XML_VERSION_10) 165 self.assertTrue( 166 len([r for r in captor.records 167 if "Table version value is a float" in r.msg]) == 1) 168 169 def test_toXML_version_11(self): 170 vhea = self.font['vhea'] 171 self.font['vhea'].tableVersion = 0x00011000 172 self.assertEqual(getXML(vhea.toXML), VHEA_XML_VERSION_11) 173 174 def test_toXML_version_11_as_float(self): 175 vhea = self.font['vhea'] 176 vhea.tableVersion = 1.0625 177 with CapturingLogHandler(log, "WARNING") as captor: 178 self.assertEqual(getXML(vhea.toXML), VHEA_XML_VERSION_11) 179 self.assertTrue( 180 len([r for r in captor.records 181 if "Table version value is a float" in r.msg]) == 1) 182 183 184 class VheaDecompileOrFromXMLTest(unittest.TestCase): 185 186 def setUp(self): 187 vhea = newTable('vhea') 188 self.font = TTFont(sfntVersion='OTTO') 189 self.font['vhea'] = vhea 190 191 def test_decompile_version_10(self): 192 vhea = self.font['vhea'] 193 vhea.decompile(VHEA_DATA_VERSION_10, self.font) 194 for key in vhea.__dict__: 195 self.assertEqual(getattr(vhea, key), VHEA_VERSION_10_AS_DICT[key]) 196 197 def test_decompile_version_11(self): 198 vhea = self.font['vhea'] 199 vhea.decompile(VHEA_DATA_VERSION_11, self.font) 200 for key in vhea.__dict__: 201 self.assertEqual(getattr(vhea, key), VHEA_VERSION_11_AS_DICT[key]) 202 203 def test_fromXML_version_10(self): 204 vhea = self.font['vhea'] 205 for name, attrs, content in parseXML(VHEA_XML_VERSION_10): 206 vhea.fromXML(name, attrs, content, self.font) 207 for key in vhea.__dict__: 208 self.assertEqual(getattr(vhea, key), VHEA_VERSION_10_AS_DICT[key]) 209 210 def test_fromXML_version_10_as_float(self): 211 vhea = self.font['vhea'] 212 with CapturingLogHandler(log, "WARNING") as captor: 213 for name, attrs, content in parseXML(VHEA_XML_VERSION_10_AS_FLOAT): 214 vhea.fromXML(name, attrs, content, self.font) 215 self.assertTrue( 216 len([r for r in captor.records 217 if "Table version value is a float" in r.msg]) == 1) 218 for key in vhea.__dict__: 219 self.assertEqual(getattr(vhea, key), VHEA_VERSION_10_AS_DICT[key]) 220 221 def test_fromXML_version_11(self): 222 vhea = self.font['vhea'] 223 for name, attrs, content in parseXML(VHEA_XML_VERSION_11): 224 vhea.fromXML(name, attrs, content, self.font) 225 for key in vhea.__dict__: 226 self.assertEqual(getattr(vhea, key), VHEA_VERSION_11_AS_DICT[key]) 227 228 def test_fromXML_version_11_as_float(self): 229 vhea = self.font['vhea'] 230 with CapturingLogHandler(log, "WARNING") as captor: 231 for name, attrs, content in parseXML(VHEA_XML_VERSION_11_AS_FLOAT): 232 vhea.fromXML(name, attrs, content, self.font) 233 self.assertTrue( 234 len([r for r in captor.records 235 if "Table version value is a float" in r.msg]) == 1) 236 for key in vhea.__dict__: 237 self.assertEqual(getattr(vhea, key), VHEA_VERSION_11_AS_DICT[key]) 238 239 240 class VheaRecalcTest(unittest.TestCase): 241 242 def test_recalc_TTF(self): 243 font = TTFont() 244 font.importXML(os.path.join(DATA_DIR, '_v_h_e_a_recalc_TTF.ttx')) 245 vhea = font['vhea'] 246 vhea.recalc(font) 247 self.assertEqual(vhea.advanceHeightMax, 900) 248 self.assertEqual(vhea.minTopSideBearing, 200) 249 self.assertEqual(vhea.minBottomSideBearing, 377) 250 self.assertEqual(vhea.yMaxExtent, 312) 251 252 def test_recalc_OTF(self): 253 font = TTFont() 254 font.importXML(os.path.join(DATA_DIR, '_v_h_e_a_recalc_OTF.ttx')) 255 vhea = font['vhea'] 256 vhea.recalc(font) 257 self.assertEqual(vhea.advanceHeightMax, 900) 258 self.assertEqual(vhea.minTopSideBearing, 200) 259 self.assertEqual(vhea.minBottomSideBearing, 377) 260 self.assertEqual(vhea.yMaxExtent, 312) 261 262 def test_recalc_empty(self): 263 font = TTFont() 264 font.importXML(os.path.join(DATA_DIR, '_v_h_e_a_recalc_empty.ttx')) 265 vhea = font['vhea'] 266 vhea.recalc(font) 267 self.assertEqual(vhea.advanceHeightMax, 900) 268 self.assertEqual(vhea.minTopSideBearing, 0) 269 self.assertEqual(vhea.minBottomSideBearing, 0) 270 self.assertEqual(vhea.yMaxExtent, 0) 271 272 273 if __name__ == "__main__": 274 import sys 275 sys.exit(unittest.main()) 276