11ae29591efbb29492ce05378909ccf4028d7c1eeBehdad Esfahbodfrom __future__ import print_function, division, absolute_import
230e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom fontTools.misc.py23 import *
38413c108d21e8cf0e9059bbfffde8d13f2616340Behdad Esfahbodfrom fontTools.misc import sstruct
47842e56b97ce677b83bdab09cda48bc2d89ac75aJustfrom fontTools.misc.textTools import safeEval
530e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom . import DefaultTable
67842e56b97ce677b83bdab09cda48bc2d89ac75aJust
77842e56b97ce677b83bdab09cda48bc2d89ac75aJustmaxpFormat_0_5 = """
87842e56b97ce677b83bdab09cda48bc2d89ac75aJust		>	# big endian
9898295619d8df4e4422c566cd9499c48d1d6b647jvr		tableVersion:           i
10898295619d8df4e4422c566cd9499c48d1d6b647jvr		numGlyphs:              H
117842e56b97ce677b83bdab09cda48bc2d89ac75aJust"""
127842e56b97ce677b83bdab09cda48bc2d89ac75aJust
137842e56b97ce677b83bdab09cda48bc2d89ac75aJustmaxpFormat_1_0_add = """
147842e56b97ce677b83bdab09cda48bc2d89ac75aJust		>	# big endian
15898295619d8df4e4422c566cd9499c48d1d6b647jvr		maxPoints:              H
16898295619d8df4e4422c566cd9499c48d1d6b647jvr		maxContours:            H
17898295619d8df4e4422c566cd9499c48d1d6b647jvr		maxCompositePoints:     H
18898295619d8df4e4422c566cd9499c48d1d6b647jvr		maxCompositeContours:   H
19898295619d8df4e4422c566cd9499c48d1d6b647jvr		maxZones:               H
20898295619d8df4e4422c566cd9499c48d1d6b647jvr		maxTwilightPoints:      H
21898295619d8df4e4422c566cd9499c48d1d6b647jvr		maxStorage:             H
22898295619d8df4e4422c566cd9499c48d1d6b647jvr		maxFunctionDefs:        H
23898295619d8df4e4422c566cd9499c48d1d6b647jvr		maxInstructionDefs:     H
24898295619d8df4e4422c566cd9499c48d1d6b647jvr		maxStackElements:       H
25898295619d8df4e4422c566cd9499c48d1d6b647jvr		maxSizeOfInstructions:  H
26898295619d8df4e4422c566cd9499c48d1d6b647jvr		maxComponentElements:   H
27898295619d8df4e4422c566cd9499c48d1d6b647jvr		maxComponentDepth:      H
287842e56b97ce677b83bdab09cda48bc2d89ac75aJust"""
297842e56b97ce677b83bdab09cda48bc2d89ac75aJust
307842e56b97ce677b83bdab09cda48bc2d89ac75aJust
317842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass table__m_a_x_p(DefaultTable.DefaultTable):
327842e56b97ce677b83bdab09cda48bc2d89ac75aJust
337842e56b97ce677b83bdab09cda48bc2d89ac75aJust	dependencies = ['glyf']
347842e56b97ce677b83bdab09cda48bc2d89ac75aJust
357842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def decompile(self, data, ttFont):
367842e56b97ce677b83bdab09cda48bc2d89ac75aJust		dummy, data = sstruct.unpack2(maxpFormat_0_5, data, self)
377842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.numGlyphs = int(self.numGlyphs)
38bc90c7a05b2e5114db9b0c0a6448e68d80ccf622jvr		if self.tableVersion != 0x00005000:
397842e56b97ce677b83bdab09cda48bc2d89ac75aJust			dummy, data = sstruct.unpack2(maxpFormat_1_0_add, data, self)
407842e56b97ce677b83bdab09cda48bc2d89ac75aJust		assert len(data) == 0
417842e56b97ce677b83bdab09cda48bc2d89ac75aJust
427842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def compile(self, ttFont):
43bc5e1cb195c0bfa1c8e7507326d5a9ad05aecb4bBehdad Esfahbod		if 'glyf' in ttFont:
443e097c609540944dd9290ad58df346ca86492031Just			if ttFont.isLoaded('glyf') and ttFont.recalcBBoxes:
457842e56b97ce677b83bdab09cda48bc2d89ac75aJust				self.recalc(ttFont)
467842e56b97ce677b83bdab09cda48bc2d89ac75aJust		else:
47bc90c7a05b2e5114db9b0c0a6448e68d80ccf622jvr			pass  # CFF
4807dd0e4504fcdf7bfb0aaee4350435e03ab2c2d8jvr		self.numGlyphs = len(ttFont.getGlyphOrder())
49bc90c7a05b2e5114db9b0c0a6448e68d80ccf622jvr		if self.tableVersion != 0x00005000:
50bc90c7a05b2e5114db9b0c0a6448e68d80ccf622jvr			self.tableVersion = 0x00010000
517842e56b97ce677b83bdab09cda48bc2d89ac75aJust		data = sstruct.pack(maxpFormat_0_5, self)
527842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if self.tableVersion == 0x00010000:
537842e56b97ce677b83bdab09cda48bc2d89ac75aJust			data = data + sstruct.pack(maxpFormat_1_0_add, self)
547842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return data
557842e56b97ce677b83bdab09cda48bc2d89ac75aJust
567842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def recalc(self, ttFont):
577842e56b97ce677b83bdab09cda48bc2d89ac75aJust		"""Recalculate the font bounding box, and most other maxp values except
587842e56b97ce677b83bdab09cda48bc2d89ac75aJust		for the TT instructions values. Also recalculate the value of bit 1
59fc99ad1513ca5443a29f1cc99df6016325e8dcbbPetr		of the flags field and the font bounding box of the 'head' table.
607842e56b97ce677b83bdab09cda48bc2d89ac75aJust		"""
617842e56b97ce677b83bdab09cda48bc2d89ac75aJust		glyfTable = ttFont['glyf']
627842e56b97ce677b83bdab09cda48bc2d89ac75aJust		hmtxTable = ttFont['hmtx']
637842e56b97ce677b83bdab09cda48bc2d89ac75aJust		headTable = ttFont['head']
647842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.numGlyphs = len(glyfTable)
65d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader		INFINITY = 100000
66d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader		xMin = +INFINITY
67d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader		yMin = +INFINITY
68d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader		xMax = -INFINITY
69d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader		yMax = -INFINITY
707842e56b97ce677b83bdab09cda48bc2d89ac75aJust		maxPoints = 0
717842e56b97ce677b83bdab09cda48bc2d89ac75aJust		maxContours = 0
727842e56b97ce677b83bdab09cda48bc2d89ac75aJust		maxCompositePoints = 0
737842e56b97ce677b83bdab09cda48bc2d89ac75aJust		maxCompositeContours = 0
747842e56b97ce677b83bdab09cda48bc2d89ac75aJust		maxComponentElements = 0
757842e56b97ce677b83bdab09cda48bc2d89ac75aJust		maxComponentDepth = 0
767842e56b97ce677b83bdab09cda48bc2d89ac75aJust		allXMaxIsLsb = 1
777842e56b97ce677b83bdab09cda48bc2d89ac75aJust		for glyphName in ttFont.getGlyphOrder():
787842e56b97ce677b83bdab09cda48bc2d89ac75aJust			g = glyfTable[glyphName]
797842e56b97ce677b83bdab09cda48bc2d89ac75aJust			if g.numberOfContours:
80180ace6a5ff1399ec53bc696e8bef7cce6eef39aBehdad Esfahbod				if hmtxTable[glyphName][1] != g.xMin:
817842e56b97ce677b83bdab09cda48bc2d89ac75aJust					allXMaxIsLsb = 0
827842e56b97ce677b83bdab09cda48bc2d89ac75aJust				xMin = min(xMin, g.xMin)
837842e56b97ce677b83bdab09cda48bc2d89ac75aJust				yMin = min(yMin, g.yMin)
847842e56b97ce677b83bdab09cda48bc2d89ac75aJust				xMax = max(xMax, g.xMax)
857842e56b97ce677b83bdab09cda48bc2d89ac75aJust				yMax = max(yMax, g.yMax)
867842e56b97ce677b83bdab09cda48bc2d89ac75aJust				if g.numberOfContours > 0:
877842e56b97ce677b83bdab09cda48bc2d89ac75aJust					nPoints, nContours = g.getMaxpValues()
887842e56b97ce677b83bdab09cda48bc2d89ac75aJust					maxPoints = max(maxPoints, nPoints)
897842e56b97ce677b83bdab09cda48bc2d89ac75aJust					maxContours = max(maxContours, nContours)
907842e56b97ce677b83bdab09cda48bc2d89ac75aJust				else:
917842e56b97ce677b83bdab09cda48bc2d89ac75aJust					nPoints, nContours, componentDepth = g.getCompositeMaxpValues(glyfTable)
927842e56b97ce677b83bdab09cda48bc2d89ac75aJust					maxCompositePoints = max(maxCompositePoints, nPoints)
937842e56b97ce677b83bdab09cda48bc2d89ac75aJust					maxCompositeContours = max(maxCompositeContours, nContours)
947842e56b97ce677b83bdab09cda48bc2d89ac75aJust					maxComponentElements = max(maxComponentElements, len(g.components))
957842e56b97ce677b83bdab09cda48bc2d89ac75aJust					maxComponentDepth = max(maxComponentDepth, componentDepth)
96d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader		if xMin == +INFINITY:
97d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader			headTable.xMin = 0
98d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader			headTable.yMin = 0
99d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader			headTable.xMax = 0
100d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader			headTable.yMax = 0
101d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader		else:
102cff3740f1440997cd013f538fecb06243d13c6a1Denis Jacquerye		    headTable.xMin = xMin
103cff3740f1440997cd013f538fecb06243d13c6a1Denis Jacquerye		    headTable.yMin = yMin
104cff3740f1440997cd013f538fecb06243d13c6a1Denis Jacquerye		    headTable.xMax = xMax
105cff3740f1440997cd013f538fecb06243d13c6a1Denis Jacquerye		    headTable.yMax = yMax
1067842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.maxPoints = maxPoints
1077842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.maxContours = maxContours
1087842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.maxCompositePoints = maxCompositePoints
1097842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.maxCompositeContours = maxCompositeContours
1107842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.maxComponentDepth = maxComponentDepth
1117842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if allXMaxIsLsb:
1127842e56b97ce677b83bdab09cda48bc2d89ac75aJust			headTable.flags = headTable.flags | 0x2
1137842e56b97ce677b83bdab09cda48bc2d89ac75aJust		else:
1147842e56b97ce677b83bdab09cda48bc2d89ac75aJust			headTable.flags = headTable.flags & ~0x2
1157842e56b97ce677b83bdab09cda48bc2d89ac75aJust
1167842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def testrepr(self):
117ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod		items = sorted(self.__dict__.items())
1183ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod		print(". . . . . . . . .")
1197842e56b97ce677b83bdab09cda48bc2d89ac75aJust		for combo in items:
1203ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod			print("  %s: %s" % combo)
1213ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod		print(". . . . . . . . .")
1227842e56b97ce677b83bdab09cda48bc2d89ac75aJust
1237842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def toXML(self, writer, ttFont):
124bc90c7a05b2e5114db9b0c0a6448e68d80ccf622jvr		if self.tableVersion != 0x00005000:
1257842e56b97ce677b83bdab09cda48bc2d89ac75aJust			writer.comment("Most of this table will be recalculated by the compiler")
1267842e56b97ce677b83bdab09cda48bc2d89ac75aJust			writer.newline()
1277842e56b97ce677b83bdab09cda48bc2d89ac75aJust		formatstring, names, fixes = sstruct.getformat(maxpFormat_0_5)
128bc90c7a05b2e5114db9b0c0a6448e68d80ccf622jvr		if self.tableVersion != 0x00005000:
1297842e56b97ce677b83bdab09cda48bc2d89ac75aJust			formatstring, names_1_0, fixes = sstruct.getformat(maxpFormat_1_0_add)
1307842e56b97ce677b83bdab09cda48bc2d89ac75aJust			names = names + names_1_0
1317842e56b97ce677b83bdab09cda48bc2d89ac75aJust		for name in names:
1327842e56b97ce677b83bdab09cda48bc2d89ac75aJust			value = getattr(self, name)
1337842e56b97ce677b83bdab09cda48bc2d89ac75aJust			if name == "tableVersion":
1347842e56b97ce677b83bdab09cda48bc2d89ac75aJust				value = hex(value)
1357842e56b97ce677b83bdab09cda48bc2d89ac75aJust			writer.simpletag(name, value=value)
1367842e56b97ce677b83bdab09cda48bc2d89ac75aJust			writer.newline()
1377842e56b97ce677b83bdab09cda48bc2d89ac75aJust
1383a9fd301808f5a8991ca9ac44028d1ecb22d307fBehdad Esfahbod	def fromXML(self, name, attrs, content, ttFont):
1397842e56b97ce677b83bdab09cda48bc2d89ac75aJust		setattr(self, name, safeEval(attrs["value"]))
1407842e56b97ce677b83bdab09cda48bc2d89ac75aJust
1417842e56b97ce677b83bdab09cda48bc2d89ac75aJust
142