1999-12-16 21:34:53 +00:00
|
|
|
import DefaultTable
|
2013-09-17 16:59:39 -04:00
|
|
|
from fontTools.misc import sstruct
|
1999-12-16 21:34:53 +00:00
|
|
|
import string
|
|
|
|
|
|
|
|
hdmxHeaderFormat = """
|
1999-12-23 12:32:30 +00:00
|
|
|
> # big endian!
|
1999-12-16 21:34:53 +00:00
|
|
|
version: H
|
|
|
|
numRecords: H
|
|
|
|
recordSize: l
|
|
|
|
"""
|
|
|
|
|
|
|
|
class table__h_d_m_x(DefaultTable.DefaultTable):
|
|
|
|
|
|
|
|
def decompile(self, data, ttFont):
|
|
|
|
numGlyphs = ttFont['maxp'].numGlyphs
|
|
|
|
glyphOrder = ttFont.getGlyphOrder()
|
|
|
|
dummy, data = sstruct.unpack2(hdmxHeaderFormat, data, self)
|
|
|
|
self.hdmx = {}
|
|
|
|
for i in range(self.numRecords):
|
|
|
|
ppem = ord(data[0])
|
|
|
|
maxSize = ord(data[1])
|
|
|
|
widths = {}
|
|
|
|
for glyphID in range(numGlyphs):
|
|
|
|
widths[glyphOrder[glyphID]] = ord(data[glyphID+2])
|
|
|
|
self.hdmx[ppem] = widths
|
|
|
|
data = data[self.recordSize:]
|
|
|
|
assert len(data) == 0, "too much hdmx data"
|
|
|
|
|
|
|
|
def compile(self, ttFont):
|
|
|
|
self.version = 0
|
|
|
|
numGlyphs = ttFont['maxp'].numGlyphs
|
|
|
|
glyphOrder = ttFont.getGlyphOrder()
|
|
|
|
self.recordSize = 4 * ((2 + numGlyphs + 3) / 4)
|
|
|
|
pad = (self.recordSize - 2 - numGlyphs) * "\0"
|
|
|
|
self.numRecords = len(self.hdmx)
|
|
|
|
data = sstruct.pack(hdmxHeaderFormat, self)
|
|
|
|
items = self.hdmx.items()
|
|
|
|
items.sort()
|
|
|
|
for ppem, widths in items:
|
|
|
|
data = data + chr(ppem) + chr(max(widths.values()))
|
|
|
|
for glyphID in range(len(glyphOrder)):
|
|
|
|
width = widths[glyphOrder[glyphID]]
|
|
|
|
data = data + chr(width)
|
|
|
|
data = data + pad
|
|
|
|
return data
|
|
|
|
|
|
|
|
def toXML(self, writer, ttFont):
|
|
|
|
writer.begintag("hdmxData")
|
|
|
|
writer.newline()
|
|
|
|
ppems = self.hdmx.keys()
|
|
|
|
ppems.sort()
|
|
|
|
records = []
|
|
|
|
format = ""
|
|
|
|
for ppem in ppems:
|
|
|
|
widths = self.hdmx[ppem]
|
|
|
|
records.append(widths)
|
|
|
|
format = format + "%4d"
|
|
|
|
glyphNames = ttFont.getGlyphOrder()[:]
|
|
|
|
glyphNames.sort()
|
|
|
|
maxNameLen = max(map(len, glyphNames))
|
|
|
|
format = "%" + `maxNameLen` + 's:' + format + ' ;'
|
|
|
|
writer.write(format % (("ppem",) + tuple(ppems)))
|
|
|
|
writer.newline()
|
|
|
|
writer.newline()
|
|
|
|
for glyphName in glyphNames:
|
|
|
|
row = []
|
|
|
|
for ppem in ppems:
|
|
|
|
widths = self.hdmx[ppem]
|
|
|
|
row.append(widths[glyphName])
|
2002-05-24 17:42:04 +00:00
|
|
|
if ";" in glyphName:
|
|
|
|
glyphName = "\\x3b".join(glyphName.split(";"))
|
1999-12-16 21:34:53 +00:00
|
|
|
writer.write(format % ((glyphName,) + tuple(row)))
|
|
|
|
writer.newline()
|
|
|
|
writer.endtag("hdmxData")
|
|
|
|
writer.newline()
|
|
|
|
|
|
|
|
def fromXML(self, (name, attrs, content), ttFont):
|
|
|
|
if name <> "hdmxData":
|
|
|
|
return
|
2002-05-01 21:06:11 +00:00
|
|
|
content = string.join(content, "")
|
1999-12-16 21:34:53 +00:00
|
|
|
lines = string.split(content, ";")
|
|
|
|
topRow = string.split(lines[0])
|
|
|
|
assert topRow[0] == "ppem:", "illegal hdmx format"
|
|
|
|
ppems = map(int, topRow[1:])
|
|
|
|
self.hdmx = hdmx = {}
|
|
|
|
for ppem in ppems:
|
|
|
|
hdmx[ppem] = {}
|
|
|
|
lines = map(string.split, lines[1:])
|
|
|
|
for line in lines:
|
|
|
|
if not line:
|
|
|
|
continue
|
|
|
|
assert line[0][-1] == ":", "illegal hdmx format"
|
|
|
|
glyphName = line[0][:-1]
|
2002-05-24 17:42:04 +00:00
|
|
|
if "\\" in glyphName:
|
|
|
|
from fontTools.misc.textTools import safeEval
|
|
|
|
glyphName = safeEval('"""' + glyphName + '"""')
|
1999-12-16 21:34:53 +00:00
|
|
|
line = map(int, line[1:])
|
|
|
|
assert len(line) == len(ppems), "illegal hdmx format"
|
|
|
|
for i in range(len(ppems)):
|
|
|
|
hdmx[ppems[i]][glyphName] = line[i]
|
|
|
|
|