_m_a_x_p.py revision 898295619d8df4e4422c566cd9499c48d1d6b647
1import DefaultTable
2import sstruct
3from fontTools.misc.textTools import safeEval
4
5maxpFormat_0_5 = """
6		>	# big endian
7		tableVersion:           i
8		numGlyphs:              H
9"""
10
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"""
27
28
29class table__m_a_x_p(DefaultTable.DefaultTable):
30
31	dependencies = ['glyf']
32
33	def decompile(self, data, ttFont):
34		dummy, data = sstruct.unpack2(maxpFormat_0_5, data, self)
35		self.numGlyphs = int(self.numGlyphs)
36		if self.tableVersion != 0x00005000:
37			dummy, data = sstruct.unpack2(maxpFormat_1_0_add, data, self)
38		assert len(data) == 0
39
40	def compile(self, ttFont):
41		if ttFont.has_key('glyf'):
42			if ttFont.isLoaded('glyf') and ttFont.recalcBBoxes:
43				self.recalc(ttFont)
44		else:
45			pass  # CFF
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
52
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		xMin = 100000
63		yMin = 100000
64		xMax = -100000
65		yMax = -100000
66		maxPoints = 0
67		maxContours = 0
68		maxCompositePoints = 0
69		maxCompositeContours = 0
70		maxComponentElements = 0
71		maxComponentDepth = 0
72		allXMaxIsLsb = 1
73		for glyphName in ttFont.getGlyphOrder():
74			g = glyfTable[glyphName]
75			if g.numberOfContours:
76				if hmtxTable[glyphName][1] <> g.xMin:
77					allXMaxIsLsb = 0
78				xMin = min(xMin, g.xMin)
79				yMin = min(yMin, g.yMin)
80				xMax = max(xMax, g.xMax)
81				yMax = max(yMax, g.yMax)
82				if g.numberOfContours > 0:
83					nPoints, nContours = g.getMaxpValues()
84					maxPoints = max(maxPoints, nPoints)
85					maxContours = max(maxContours, nContours)
86				else:
87					nPoints, nContours, componentDepth = g.getCompositeMaxpValues(glyfTable)
88					maxCompositePoints = max(maxCompositePoints, nPoints)
89					maxCompositeContours = max(maxCompositeContours, nContours)
90					maxComponentElements = max(maxComponentElements, len(g.components))
91					maxComponentDepth = max(maxComponentDepth, componentDepth)
92		headTable.xMin = xMin
93		headTable.yMin = yMin
94		headTable.xMax = xMax
95		headTable.yMax = yMax
96		self.maxPoints = maxPoints
97		self.maxContours = maxContours
98		self.maxCompositePoints = maxCompositePoints
99		self.maxCompositeContours = maxCompositeContours
100		self.maxComponentDepth = maxComponentDepth
101		if allXMaxIsLsb:
102			headTable.flags = headTable.flags | 0x2
103		else:
104			headTable.flags = headTable.flags & ~0x2
105
106	def testrepr(self):
107		items = self.__dict__.items()
108		items.sort()
109		print ". . . . . . . . ."
110		for combo in items:
111			print "  %s: %s" % combo
112		print ". . . . . . . . ."
113
114	def toXML(self, writer, ttFont):
115		if self.tableVersion != 0x00005000:
116			writer.comment("Most of this table will be recalculated by the compiler")
117			writer.newline()
118		formatstring, names, fixes = sstruct.getformat(maxpFormat_0_5)
119		if self.tableVersion != 0x00005000:
120			formatstring, names_1_0, fixes = sstruct.getformat(maxpFormat_1_0_add)
121			names = names + names_1_0
122		for name in names:
123			value = getattr(self, name)
124			if type(value) == type(0L):
125				value=int(value)
126			if name == "tableVersion":
127				value = hex(value)
128			writer.simpletag(name, value=value)
129			writer.newline()
130
131	def fromXML(self, (name, attrs, content), ttFont):
132		setattr(self, name, safeEval(attrs["value"]))
133
134
135