aboutsummaryrefslogtreecommitdiff
path: root/Lib/fontTools/ttLib/tables/_m_a_x_p.py
blob: fc1e69dd67bb53704086181812e038b02846035b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
from fontTools.misc.py23 import *
from fontTools.misc import sstruct
from fontTools.misc.textTools import safeEval
from . import DefaultTable

maxpFormat_0_5 = """
		>	# big endian
		tableVersion:           i
		numGlyphs:              H
"""

maxpFormat_1_0_add = """
		>	# big endian
		maxPoints:              H
		maxContours:            H
		maxCompositePoints:     H
		maxCompositeContours:   H
		maxZones:               H
		maxTwilightPoints:      H
		maxStorage:             H
		maxFunctionDefs:        H
		maxInstructionDefs:     H
		maxStackElements:       H
		maxSizeOfInstructions:  H
		maxComponentElements:   H
		maxComponentDepth:      H
"""


class table__m_a_x_p(DefaultTable.DefaultTable):

	dependencies = ['glyf']

	def decompile(self, data, ttFont):
		dummy, data = sstruct.unpack2(maxpFormat_0_5, data, self)
		self.numGlyphs = int(self.numGlyphs)
		if self.tableVersion != 0x00005000:
			dummy, data = sstruct.unpack2(maxpFormat_1_0_add, data, self)
		assert len(data) == 0

	def compile(self, ttFont):
		if 'glyf' in ttFont:
			if ttFont.isLoaded('glyf') and ttFont.recalcBBoxes:
				self.recalc(ttFont)
		else:
			pass  # CFF
		self.numGlyphs = len(ttFont.getGlyphOrder())
		if self.tableVersion != 0x00005000:
			self.tableVersion = 0x00010000
		data = sstruct.pack(maxpFormat_0_5, self)
		if self.tableVersion == 0x00010000:
			data = data + sstruct.pack(maxpFormat_1_0_add, self)
		return data

	def recalc(self, ttFont):
		"""Recalculate the font bounding box, and most other maxp values except
		for the TT instructions values. Also recalculate the value of bit 1
		of the flags field and the font bounding box of the 'head' table.
		"""
		glyfTable = ttFont['glyf']
		hmtxTable = ttFont['hmtx']
		headTable = ttFont['head']
		self.numGlyphs = len(glyfTable)
		INFINITY = 100000
		xMin = +INFINITY
		yMin = +INFINITY
		xMax = -INFINITY
		yMax = -INFINITY
		maxPoints = 0
		maxContours = 0
		maxCompositePoints = 0
		maxCompositeContours = 0
		maxComponentElements = 0
		maxComponentDepth = 0
		allXMinIsLsb = 1
		for glyphName in ttFont.getGlyphOrder():
			g = glyfTable[glyphName]
			if g.numberOfContours:
				if hmtxTable[glyphName][1] != g.xMin:
					allXMinIsLsb = 0
				xMin = min(xMin, g.xMin)
				yMin = min(yMin, g.yMin)
				xMax = max(xMax, g.xMax)
				yMax = max(yMax, g.yMax)
				if g.numberOfContours > 0:
					nPoints, nContours = g.getMaxpValues()
					maxPoints = max(maxPoints, nPoints)
					maxContours = max(maxContours, nContours)
				else:
					nPoints, nContours, componentDepth = g.getCompositeMaxpValues(glyfTable)
					maxCompositePoints = max(maxCompositePoints, nPoints)
					maxCompositeContours = max(maxCompositeContours, nContours)
					maxComponentElements = max(maxComponentElements, len(g.components))
					maxComponentDepth = max(maxComponentDepth, componentDepth)
		if xMin == +INFINITY:
			headTable.xMin = 0
			headTable.yMin = 0
			headTable.xMax = 0
			headTable.yMax = 0
		else:
			headTable.xMin = xMin
			headTable.yMin = yMin
			headTable.xMax = xMax
			headTable.yMax = yMax
		self.maxPoints = maxPoints
		self.maxContours = maxContours
		self.maxCompositePoints = maxCompositePoints
		self.maxCompositeContours = maxCompositeContours
		self.maxComponentElements = maxComponentElements
		self.maxComponentDepth = maxComponentDepth
		if allXMinIsLsb:
			headTable.flags = headTable.flags | 0x2
		else:
			headTable.flags = headTable.flags & ~0x2

	def testrepr(self):
		items = sorted(self.__dict__.items())
		print(". . . . . . . . .")
		for combo in items:
			print("  %s: %s" % combo)
		print(". . . . . . . . .")

	def toXML(self, writer, ttFont):
		if self.tableVersion != 0x00005000:
			writer.comment("Most of this table will be recalculated by the compiler")
			writer.newline()
		formatstring, names, fixes = sstruct.getformat(maxpFormat_0_5)
		if self.tableVersion != 0x00005000:
			formatstring, names_1_0, fixes = sstruct.getformat(maxpFormat_1_0_add)
			names = names + names_1_0
		for name in names:
			value = getattr(self, name)
			if name == "tableVersion":
				value = hex(value)
			writer.simpletag(name, value=value)
			writer.newline()

	def fromXML(self, name, attrs, content, ttFont):
		setattr(self, name, safeEval(attrs["value"]))