blob: 06fca7dd4adc28d330611820f1c0628bf1f9e7e0 [file] [log] [blame]
Behdad Esfahbod1ae29592014-01-14 15:07:50 +08001from __future__ import print_function, division, absolute_import
Behdad Esfahbod7ed91ec2013-11-27 15:16:28 -05002from fontTools.misc.py23 import *
Behdad Esfahbod30e691e2013-11-27 17:27:45 -05003from fontTools.misc import sstruct
4from . import DefaultTable
Just7842e561999-12-16 21:34:53 +00005
6hdmxHeaderFormat = """
Justfd5a9321999-12-23 12:32:30 +00007 > # big endian!
Just7842e561999-12-16 21:34:53 +00008 version: H
9 numRecords: H
10 recordSize: l
11"""
12
13class table__h_d_m_x(DefaultTable.DefaultTable):
14
15 def decompile(self, data, ttFont):
16 numGlyphs = ttFont['maxp'].numGlyphs
17 glyphOrder = ttFont.getGlyphOrder()
18 dummy, data = sstruct.unpack2(hdmxHeaderFormat, data, self)
19 self.hdmx = {}
20 for i in range(self.numRecords):
Behdad Esfahbod319c5fd2013-11-27 18:13:48 -050021 ppem = byteord(data[0])
22 maxSize = byteord(data[1])
Just7842e561999-12-16 21:34:53 +000023 widths = {}
24 for glyphID in range(numGlyphs):
Behdad Esfahbod319c5fd2013-11-27 18:13:48 -050025 widths[glyphOrder[glyphID]] = byteord(data[glyphID+2])
Just7842e561999-12-16 21:34:53 +000026 self.hdmx[ppem] = widths
27 data = data[self.recordSize:]
28 assert len(data) == 0, "too much hdmx data"
29
30 def compile(self, ttFont):
31 self.version = 0
32 numGlyphs = ttFont['maxp'].numGlyphs
33 glyphOrder = ttFont.getGlyphOrder()
Behdad Esfahbod32c10ee2013-11-27 17:46:17 -050034 self.recordSize = 4 * ((2 + numGlyphs + 3) // 4)
Behdad Esfahbod18316aa2013-11-27 21:17:35 -050035 pad = (self.recordSize - 2 - numGlyphs) * b"\0"
Just7842e561999-12-16 21:34:53 +000036 self.numRecords = len(self.hdmx)
37 data = sstruct.pack(hdmxHeaderFormat, self)
Behdad Esfahbodac1b4352013-11-27 04:15:34 -050038 items = sorted(self.hdmx.items())
Just7842e561999-12-16 21:34:53 +000039 for ppem, widths in items:
Behdad Esfahbodb7a2d792013-11-27 15:19:40 -050040 data = data + bytechr(ppem) + bytechr(max(widths.values()))
Just7842e561999-12-16 21:34:53 +000041 for glyphID in range(len(glyphOrder)):
42 width = widths[glyphOrder[glyphID]]
Behdad Esfahbodb7a2d792013-11-27 15:19:40 -050043 data = data + bytechr(width)
Just7842e561999-12-16 21:34:53 +000044 data = data + pad
45 return data
46
47 def toXML(self, writer, ttFont):
48 writer.begintag("hdmxData")
49 writer.newline()
Behdad Esfahbodac1b4352013-11-27 04:15:34 -050050 ppems = sorted(self.hdmx.keys())
Just7842e561999-12-16 21:34:53 +000051 records = []
52 format = ""
53 for ppem in ppems:
54 widths = self.hdmx[ppem]
55 records.append(widths)
56 format = format + "%4d"
57 glyphNames = ttFont.getGlyphOrder()[:]
58 glyphNames.sort()
59 maxNameLen = max(map(len, glyphNames))
Behdad Esfahboddc7e6f32013-11-27 02:44:56 -050060 format = "%" + repr(maxNameLen) + 's:' + format + ' ;'
Just7842e561999-12-16 21:34:53 +000061 writer.write(format % (("ppem",) + tuple(ppems)))
62 writer.newline()
63 writer.newline()
64 for glyphName in glyphNames:
65 row = []
66 for ppem in ppems:
67 widths = self.hdmx[ppem]
68 row.append(widths[glyphName])
jvr18725572002-05-24 17:42:04 +000069 if ";" in glyphName:
70 glyphName = "\\x3b".join(glyphName.split(";"))
Just7842e561999-12-16 21:34:53 +000071 writer.write(format % ((glyphName,) + tuple(row)))
72 writer.newline()
73 writer.endtag("hdmxData")
74 writer.newline()
75
Behdad Esfahbod3a9fd302013-11-27 03:19:32 -050076 def fromXML(self, name, attrs, content, ttFont):
Behdad Esfahbod180ace62013-11-27 02:40:30 -050077 if name != "hdmxData":
Just7842e561999-12-16 21:34:53 +000078 return
Behdad Esfahbod18316aa2013-11-27 21:17:35 -050079 content = strjoin(content)
Behdad Esfahbod14fb0312013-11-27 05:47:34 -050080 lines = content.split(";")
81 topRow = lines[0].split()
Just7842e561999-12-16 21:34:53 +000082 assert topRow[0] == "ppem:", "illegal hdmx format"
Behdad Esfahbode5ca7962013-11-27 04:38:16 -050083 ppems = list(map(int, topRow[1:]))
Just7842e561999-12-16 21:34:53 +000084 self.hdmx = hdmx = {}
85 for ppem in ppems:
86 hdmx[ppem] = {}
Behdad Esfahbod14fb0312013-11-27 05:47:34 -050087 lines = (line.split() for line in lines[1:])
Just7842e561999-12-16 21:34:53 +000088 for line in lines:
89 if not line:
90 continue
91 assert line[0][-1] == ":", "illegal hdmx format"
92 glyphName = line[0][:-1]
jvr18725572002-05-24 17:42:04 +000093 if "\\" in glyphName:
94 from fontTools.misc.textTools import safeEval
95 glyphName = safeEval('"""' + glyphName + '"""')
Behdad Esfahbode5ca7962013-11-27 04:38:16 -050096 line = list(map(int, line[1:]))
Just7842e561999-12-16 21:34:53 +000097 assert len(line) == len(ppems), "illegal hdmx format"
98 for i in range(len(ppems)):
99 hdmx[ppems[i]][glyphName] = line[i]
100