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