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