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