_m_a_x_p.py revision 3e097c609540944dd9290ad58df346ca86492031
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 == 0x00010000:
37			dummy, data = sstruct.unpack2(maxpFormat_1_0_add, data, self)
38		else:
39			assert self.tableVersion == 0x00005000, "unknown 'maxp' format: %x" % self.tableVersion
40		assert len(data) == 0
41
42	def compile(self, ttFont):
43		if ttFont.has_key('glyf'):
44			if ttFont.isLoaded('glyf') and ttFont.recalcBBoxes:
45				self.recalc(ttFont)
46		else:
47			pass # XXX CFF!!!
48		data = sstruct.pack(maxpFormat_0_5, self)
49		if self.tableVersion == 0x00010000:
50			data = data + sstruct.pack(maxpFormat_1_0_add, self)
51		else:
52			assert self.tableVersion == 0x00005000, "unknown 'maxp' format: %f" % self.tableVersion
53		return data
54
55	def recalc(self, ttFont):
56		"""Recalculate the font bounding box, and most other maxp values except
57		for the TT instructions values. Also recalculate the value of bit 1
58		of the flags field of the 'head' table.
59		"""
60		glyfTable = ttFont['glyf']
61		hmtxTable = ttFont['hmtx']
62		headTable = ttFont['head']
63		self.numGlyphs = len(glyfTable)
64		xMin = 100000
65		yMin = 100000
66		xMax = -100000
67		yMax = -100000
68		maxPoints = 0
69		maxContours = 0
70		maxCompositePoints = 0
71		maxCompositeContours = 0
72		maxComponentElements = 0
73		maxComponentDepth = 0
74		allXMaxIsLsb = 1
75		for glyphName in ttFont.getGlyphOrder():
76			g = glyfTable[glyphName]
77			if g.numberOfContours:
78				if hmtxTable[glyphName][1] <> g.xMin:
79					allXMaxIsLsb = 0
80				xMin = min(xMin, g.xMin)
81				yMin = min(yMin, g.yMin)
82				xMax = max(xMax, g.xMax)
83				yMax = max(yMax, g.yMax)
84				if g.numberOfContours > 0:
85					nPoints, nContours = g.getMaxpValues()
86					maxPoints = max(maxPoints, nPoints)
87					maxContours = max(maxContours, nContours)
88				else:
89					nPoints, nContours, componentDepth = g.getCompositeMaxpValues(glyfTable)
90					maxCompositePoints = max(maxCompositePoints, nPoints)
91					maxCompositeContours = max(maxCompositeContours, nContours)
92					maxComponentElements = max(maxComponentElements, len(g.components))
93					maxComponentDepth = max(maxComponentDepth, componentDepth)
94		self.xMin = xMin
95		self.yMin = yMin
96		self.xMax = xMax
97		self.yMax = yMax
98		self.maxPoints = maxPoints
99		self.maxContours = maxContours
100		self.maxCompositePoints = maxCompositePoints
101		self.maxCompositeContours = maxCompositeContours
102		self.maxComponentDepth = maxComponentDepth
103		if allXMaxIsLsb:
104			headTable.flags = headTable.flags | 0x2
105		else:
106			headTable.flags = headTable.flags & ~0x2
107
108	def testrepr(self):
109		items = self.__dict__.items()
110		items.sort()
111		print ". . . . . . . . ."
112		for combo in items:
113			print "  %s: %s" % combo
114		print ". . . . . . . . ."
115
116	def toXML(self, writer, ttFont):
117		if self.tableVersion <> 0x00005000:
118			writer.comment("Most of this table will be recalculated by the compiler")
119			writer.newline()
120		formatstring, names, fixes = sstruct.getformat(maxpFormat_0_5)
121		if self.tableVersion == 0x00010000:
122			formatstring, names_1_0, fixes = sstruct.getformat(maxpFormat_1_0_add)
123			names = names + names_1_0
124		else:
125			assert self.tableVersion == 0x00005000, "unknown 'maxp' format: %f" % self.tableVersion
126		for name in names:
127			value = getattr(self, name)
128			if type(value) == type(0L):
129				value=int(value)
130			if name == "tableVersion":
131				value = hex(value)
132			writer.simpletag(name, value=value)
133			writer.newline()
134
135	def fromXML(self, (name, attrs, content), ttFont):
136		setattr(self, name, safeEval(attrs["value"]))
137
138
139