• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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		allXMinIsLsb = 1
77		for glyphName in ttFont.getGlyphOrder():
78			g = glyfTable[glyphName]
79			if g.numberOfContours:
80				if hmtxTable[glyphName][1] != g.xMin:
81					allXMinIsLsb = 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.maxComponentElements = maxComponentElements
111		self.maxComponentDepth = maxComponentDepth
112		if allXMinIsLsb:
113			headTable.flags = headTable.flags | 0x2
114		else:
115			headTable.flags = headTable.flags & ~0x2
116
117	def testrepr(self):
118		items = sorted(self.__dict__.items())
119		print(". . . . . . . . .")
120		for combo in items:
121			print("  %s: %s" % combo)
122		print(". . . . . . . . .")
123
124	def toXML(self, writer, ttFont):
125		if self.tableVersion != 0x00005000:
126			writer.comment("Most of this table will be recalculated by the compiler")
127			writer.newline()
128		formatstring, names, fixes = sstruct.getformat(maxpFormat_0_5)
129		if self.tableVersion != 0x00005000:
130			formatstring, names_1_0, fixes = sstruct.getformat(maxpFormat_1_0_add)
131			names = names + names_1_0
132		for name in names:
133			value = getattr(self, name)
134			if name == "tableVersion":
135				value = hex(value)
136			writer.simpletag(name, value=value)
137			writer.newline()
138
139	def fromXML(self, name, attrs, content, ttFont):
140		setattr(self, name, safeEval(attrs["value"]))
141