1from __future__ import absolute_import, unicode_literals 2from fontTools.misc.py23 import * 3from fontTools.misc.loggingTools import CapturingLogHandler 4from fontTools.misc.testTools import parseXML, getXML 5from fontTools.misc.textTools import deHexStr 6from fontTools.ttLib import TTFont, newTable 7from fontTools.misc.fixedTools import log 8import os 9import unittest 10 11 12CURR_DIR = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) 13DATA_DIR = os.path.join(CURR_DIR, 'data') 14 15HHEA_DATA = deHexStr( 16 '0001 0000 ' # 1.0 version 17 '02EE ' # 750 ascent 18 'FF06 ' # -250 descent 19 '00C8 ' # 200 lineGap 20 '03E8 ' # 1000 advanceWidthMax 21 'FFE7 ' # -25 minLeftSideBearing 22 'FFEC ' # -20 minRightSideBearing 23 '03D1 ' # 977 xMaxExtent 24 '0000 ' # 0 caretSlopeRise 25 '0001 ' # 1 caretSlopeRun 26 '0010 ' # 16 caretOffset 27 '0000 ' # 0 reserved0 28 '0000 ' # 0 reserved1 29 '0000 ' # 0 reserved2 30 '0000 ' # 0 reserved3 31 '0000 ' # 0 metricDataFormat 32 '002A ' # 42 numberOfHMetrics 33) 34 35HHEA_AS_DICT = { 36 'tableTag': 'hhea', 37 'tableVersion': 0x00010000, 38 'ascent': 750, 39 'descent': -250, 40 'lineGap': 200, 41 'advanceWidthMax': 1000, 42 'minLeftSideBearing': -25, 43 'minRightSideBearing': -20, 44 'xMaxExtent': 977, 45 'caretSlopeRise': 0, 46 'caretSlopeRun': 1, 47 'caretOffset': 16, 48 'reserved0': 0, 49 'reserved1': 0, 50 'reserved2': 0, 51 'reserved3': 0, 52 'metricDataFormat': 0, 53 'numberOfHMetrics': 42, 54} 55 56HHEA_XML = [ 57 '<tableVersion value="0x00010000"/>', 58 '<ascent value="750"/>', 59 '<descent value="-250"/>', 60 '<lineGap value="200"/>', 61 '<advanceWidthMax value="1000"/>', 62 '<minLeftSideBearing value="-25"/>', 63 '<minRightSideBearing value="-20"/>', 64 '<xMaxExtent value="977"/>', 65 '<caretSlopeRise value="0"/>', 66 '<caretSlopeRun value="1"/>', 67 '<caretOffset value="16"/>', 68 '<reserved0 value="0"/>', 69 '<reserved1 value="0"/>', 70 '<reserved2 value="0"/>', 71 '<reserved3 value="0"/>', 72 '<metricDataFormat value="0"/>', 73 '<numberOfHMetrics value="42"/>', 74] 75 76HHEA_XML_VERSION_AS_FLOAT = [ 77 '<tableVersion value="1.0"/>', 78] + HHEA_XML[1:] 79 80 81class HheaCompileOrToXMLTest(unittest.TestCase): 82 83 def setUp(self): 84 hhea = newTable('hhea') 85 hhea.tableVersion = 0x00010000 86 hhea.ascent = 750 87 hhea.descent = -250 88 hhea.lineGap = 200 89 hhea.advanceWidthMax = 1000 90 hhea.minLeftSideBearing = -25 91 hhea.minRightSideBearing = -20 92 hhea.xMaxExtent = 977 93 hhea.caretSlopeRise = 0 94 hhea.caretSlopeRun = 1 95 hhea.caretOffset = 16 96 hhea.metricDataFormat = 0 97 hhea.numberOfHMetrics = 42 98 hhea.reserved0 = hhea.reserved1 = hhea.reserved2 = hhea.reserved3 = 0 99 self.font = TTFont(sfntVersion='OTTO') 100 self.font['hhea'] = hhea 101 102 def test_compile(self): 103 hhea = self.font['hhea'] 104 hhea.tableVersion = 0x00010000 105 self.assertEqual(HHEA_DATA, hhea.compile(self.font)) 106 107 def test_compile_version_10_as_float(self): 108 hhea = self.font['hhea'] 109 hhea.tableVersion = 1.0 110 with CapturingLogHandler(log, "WARNING") as captor: 111 self.assertEqual(HHEA_DATA, hhea.compile(self.font)) 112 self.assertTrue( 113 len([r for r in captor.records 114 if "Table version value is a float" in r.msg]) == 1) 115 116 def test_toXML(self): 117 hhea = self.font['hhea'] 118 self.font['hhea'].tableVersion = 0x00010000 119 self.assertEqual(getXML(hhea.toXML), HHEA_XML) 120 121 def test_toXML_version_as_float(self): 122 hhea = self.font['hhea'] 123 hhea.tableVersion = 1.0 124 with CapturingLogHandler(log, "WARNING") as captor: 125 self.assertEqual(getXML(hhea.toXML), HHEA_XML) 126 self.assertTrue( 127 len([r for r in captor.records 128 if "Table version value is a float" in r.msg]) == 1) 129 130 131class HheaDecompileOrFromXMLTest(unittest.TestCase): 132 133 def setUp(self): 134 hhea = newTable('hhea') 135 self.font = TTFont(sfntVersion='OTTO') 136 self.font['hhea'] = hhea 137 138 def test_decompile(self): 139 hhea = self.font['hhea'] 140 hhea.decompile(HHEA_DATA, self.font) 141 for key in hhea.__dict__: 142 self.assertEqual(getattr(hhea, key), HHEA_AS_DICT[key]) 143 144 def test_fromXML(self): 145 hhea = self.font['hhea'] 146 for name, attrs, content in parseXML(HHEA_XML): 147 hhea.fromXML(name, attrs, content, self.font) 148 for key in hhea.__dict__: 149 self.assertEqual(getattr(hhea, key), HHEA_AS_DICT[key]) 150 151 def test_fromXML_version_as_float(self): 152 hhea = self.font['hhea'] 153 with CapturingLogHandler(log, "WARNING") as captor: 154 for name, attrs, content in parseXML(HHEA_XML_VERSION_AS_FLOAT): 155 hhea.fromXML(name, attrs, content, self.font) 156 self.assertTrue( 157 len([r for r in captor.records 158 if "Table version value is a float" in r.msg]) == 1) 159 for key in hhea.__dict__: 160 self.assertEqual(getattr(hhea, key), HHEA_AS_DICT[key]) 161 162 163class HheaRecalcTest(unittest.TestCase): 164 165 def test_recalc_TTF(self): 166 font = TTFont() 167 font.importXML(os.path.join(DATA_DIR, '_h_h_e_a_recalc_TTF.ttx')) 168 hhea = font['hhea'] 169 hhea.recalc(font) 170 self.assertEqual(hhea.advanceWidthMax, 600) 171 self.assertEqual(hhea.minLeftSideBearing, -56) 172 self.assertEqual(hhea.minRightSideBearing, 100) 173 self.assertEqual(hhea.xMaxExtent, 400) 174 175 def test_recalc_OTF(self): 176 font = TTFont() 177 font.importXML(os.path.join(DATA_DIR, '_h_h_e_a_recalc_OTF.ttx')) 178 hhea = font['hhea'] 179 hhea.recalc(font) 180 self.assertEqual(hhea.advanceWidthMax, 600) 181 self.assertEqual(hhea.minLeftSideBearing, -56) 182 self.assertEqual(hhea.minRightSideBearing, 100) 183 self.assertEqual(hhea.xMaxExtent, 400) 184 185 def test_recalc_empty(self): 186 font = TTFont() 187 font.importXML(os.path.join(DATA_DIR, '_h_h_e_a_recalc_empty.ttx')) 188 hhea = font['hhea'] 189 hhea.recalc(font) 190 self.assertEqual(hhea.advanceWidthMax, 600) 191 self.assertEqual(hhea.minLeftSideBearing, 0) 192 self.assertEqual(hhea.minRightSideBearing, 0) 193 self.assertEqual(hhea.xMaxExtent, 0) 194 195 196if __name__ == "__main__": 197 import sys 198 sys.exit(unittest.main()) 199