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