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