1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
from fontTools.misc import sstruct
from fontTools.misc.textTools import safeEval
from . import DefaultTable
maxpFormat_0_5 = """
> # big endian
tableVersion: i
numGlyphs: H
"""
maxpFormat_1_0_add = """
> # big endian
maxPoints: H
maxContours: H
maxCompositePoints: H
maxCompositeContours: H
maxZones: H
maxTwilightPoints: H
maxStorage: H
maxFunctionDefs: H
maxInstructionDefs: H
maxStackElements: H
maxSizeOfInstructions: H
maxComponentElements: H
maxComponentDepth: H
"""
class table__m_a_x_p(DefaultTable.DefaultTable):
dependencies = ["glyf"]
def decompile(self, data, ttFont):
dummy, data = sstruct.unpack2(maxpFormat_0_5, data, self)
self.numGlyphs = int(self.numGlyphs)
if self.tableVersion != 0x00005000:
dummy, data = sstruct.unpack2(maxpFormat_1_0_add, data, self)
assert len(data) == 0
def compile(self, ttFont):
if "glyf" in ttFont:
if ttFont.isLoaded("glyf") and ttFont.recalcBBoxes:
self.recalc(ttFont)
else:
pass # CFF
self.numGlyphs = len(ttFont.getGlyphOrder())
if self.tableVersion != 0x00005000:
self.tableVersion = 0x00010000
data = sstruct.pack(maxpFormat_0_5, self)
if self.tableVersion == 0x00010000:
data = data + sstruct.pack(maxpFormat_1_0_add, self)
return data
def recalc(self, ttFont):
"""Recalculate the font bounding box, and most other maxp values except
for the TT instructions values. Also recalculate the value of bit 1
of the flags field and the font bounding box of the 'head' table.
"""
glyfTable = ttFont["glyf"]
hmtxTable = ttFont["hmtx"]
headTable = ttFont["head"]
self.numGlyphs = len(glyfTable)
INFINITY = 100000
xMin = +INFINITY
yMin = +INFINITY
xMax = -INFINITY
yMax = -INFINITY
maxPoints = 0
maxContours = 0
maxCompositePoints = 0
maxCompositeContours = 0
maxComponentElements = 0
maxComponentDepth = 0
allXMinIsLsb = 1
for glyphName in ttFont.getGlyphOrder():
g = glyfTable[glyphName]
if g.numberOfContours:
if hmtxTable[glyphName][1] != g.xMin:
allXMinIsLsb = 0
xMin = min(xMin, g.xMin)
yMin = min(yMin, g.yMin)
xMax = max(xMax, g.xMax)
yMax = max(yMax, g.yMax)
if g.numberOfContours > 0:
nPoints, nContours = g.getMaxpValues()
maxPoints = max(maxPoints, nPoints)
maxContours = max(maxContours, nContours)
elif g.isComposite():
nPoints, nContours, componentDepth = g.getCompositeMaxpValues(
glyfTable
)
maxCompositePoints = max(maxCompositePoints, nPoints)
maxCompositeContours = max(maxCompositeContours, nContours)
maxComponentElements = max(maxComponentElements, len(g.components))
maxComponentDepth = max(maxComponentDepth, componentDepth)
if xMin == +INFINITY:
headTable.xMin = 0
headTable.yMin = 0
headTable.xMax = 0
headTable.yMax = 0
else:
headTable.xMin = xMin
headTable.yMin = yMin
headTable.xMax = xMax
headTable.yMax = yMax
self.maxPoints = maxPoints
self.maxContours = maxContours
self.maxCompositePoints = maxCompositePoints
self.maxCompositeContours = maxCompositeContours
self.maxComponentElements = maxComponentElements
self.maxComponentDepth = maxComponentDepth
if allXMinIsLsb:
headTable.flags = headTable.flags | 0x2
else:
headTable.flags = headTable.flags & ~0x2
def testrepr(self):
items = sorted(self.__dict__.items())
print(". . . . . . . . .")
for combo in items:
print(" %s: %s" % combo)
print(". . . . . . . . .")
def toXML(self, writer, ttFont):
if self.tableVersion != 0x00005000:
writer.comment("Most of this table will be recalculated by the compiler")
writer.newline()
formatstring, names, fixes = sstruct.getformat(maxpFormat_0_5)
if self.tableVersion != 0x00005000:
formatstring, names_1_0, fixes = sstruct.getformat(maxpFormat_1_0_add)
names = names + names_1_0
for name in names:
value = getattr(self, name)
if name == "tableVersion":
value = hex(value)
writer.simpletag(name, value=value)
writer.newline()
def fromXML(self, name, attrs, content, ttFont):
setattr(self, name, safeEval(attrs["value"]))
|