3
from fontTools import ttLib
4
from fontTools.misc.textTools import safeEval
7
class table__h_m_t_x(DefaultTable.DefaultTable):
11
sideBearingName = 'lsb'
12
numberOfMetricsName = 'numberOfHMetrics'
14
def decompile(self, data, ttFont):
15
numberOfMetrics = int(getattr(ttFont[self.headerTag], self.numberOfMetricsName))
16
metrics = Numeric.fromstring(data[:4 * numberOfMetrics],
18
if ttLib.endian <> "big":
19
metrics = metrics.byteswapped()
20
metrics.shape = (numberOfMetrics, 2)
21
data = data[4 * numberOfMetrics:]
22
numberOfSideBearings = ttFont['maxp'].numGlyphs - numberOfMetrics
23
numberOfSideBearings = int(numberOfSideBearings)
24
if numberOfSideBearings:
25
assert numberOfSideBearings > 0, "bad hmtx/vmtx table"
26
lastAdvance = metrics[-1][0]
27
advances = Numeric.array([lastAdvance] * numberOfSideBearings,
29
sideBearings = Numeric.fromstring(data[:2 * numberOfSideBearings],
31
if ttLib.endian <> "big":
32
sideBearings = sideBearings.byteswapped()
33
data = data[2 * numberOfSideBearings:]
34
additionalMetrics = Numeric.array([advances, sideBearings],
36
metrics = Numeric.concatenate((metrics,
37
Numeric.transpose(additionalMetrics)))
40
sys.stderr.write("too much data for hmtx/vmtx table\n")
41
metrics = metrics.tolist()
43
for i in range(len(metrics)):
44
glyphName = ttFont.getGlyphName(i)
45
self.metrics[glyphName] = metrics[i]
47
def compile(self, ttFont):
49
for glyphName in ttFont.getGlyphOrder():
50
metrics.append(self.metrics[glyphName])
51
lastAdvance = metrics[-1][0]
52
lastIndex = len(metrics)
53
while metrics[lastIndex-2][0] == lastAdvance:
54
lastIndex = lastIndex - 1
56
# all advances are equal
59
additionalMetrics = metrics[lastIndex:]
60
additionalMetrics = map(lambda (advance, sb): sb, additionalMetrics)
61
metrics = metrics[:lastIndex]
62
setattr(ttFont[self.headerTag], self.numberOfMetricsName, len(metrics))
64
metrics = Numeric.array(metrics, Numeric.Int16)
65
if ttLib.endian <> "big":
66
metrics = metrics.byteswapped()
67
data = metrics.tostring()
69
additionalMetrics = Numeric.array(additionalMetrics, Numeric.Int16)
70
if ttLib.endian <> "big":
71
additionalMetrics = additionalMetrics.byteswapped()
72
data = data + additionalMetrics.tostring()
75
def toXML(self, writer, ttFont):
76
names = self.metrics.keys()
78
for glyphName in names:
79
advance, sb = self.metrics[glyphName]
80
writer.simpletag("mtx", [
82
(self.advanceName, advance),
83
(self.sideBearingName, sb),
87
def fromXML(self, (name, attrs, content), ttFont):
88
if not hasattr(self, "metrics"):
91
self.metrics[attrs["name"]] = [safeEval(attrs[self.advanceName]),
92
safeEval(attrs[self.sideBearingName])]
94
def __getitem__(self, glyphName):
95
return self.metrics[glyphName]
97
def __setitem__(self, glyphName, (advance, sb)):
98
self.metrics[glyphName] = advance, sb