_m_a_x_p.py revision 3e097c609540944dd9290ad58df346ca86492031
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 == 0x00010000: 37 dummy, data = sstruct.unpack2(maxpFormat_1_0_add, data, self) 38 else: 39 assert self.tableVersion == 0x00005000, "unknown 'maxp' format: %x" % self.tableVersion 40 assert len(data) == 0 41 42 def compile(self, ttFont): 43 if ttFont.has_key('glyf'): 44 if ttFont.isLoaded('glyf') and ttFont.recalcBBoxes: 45 self.recalc(ttFont) 46 else: 47 pass # XXX CFF!!! 48 data = sstruct.pack(maxpFormat_0_5, self) 49 if self.tableVersion == 0x00010000: 50 data = data + sstruct.pack(maxpFormat_1_0_add, self) 51 else: 52 assert self.tableVersion == 0x00005000, "unknown 'maxp' format: %f" % self.tableVersion 53 return data 54 55 def recalc(self, ttFont): 56 """Recalculate the font bounding box, and most other maxp values except 57 for the TT instructions values. Also recalculate the value of bit 1 58 of the flags field of the 'head' table. 59 """ 60 glyfTable = ttFont['glyf'] 61 hmtxTable = ttFont['hmtx'] 62 headTable = ttFont['head'] 63 self.numGlyphs = len(glyfTable) 64 xMin = 100000 65 yMin = 100000 66 xMax = -100000 67 yMax = -100000 68 maxPoints = 0 69 maxContours = 0 70 maxCompositePoints = 0 71 maxCompositeContours = 0 72 maxComponentElements = 0 73 maxComponentDepth = 0 74 allXMaxIsLsb = 1 75 for glyphName in ttFont.getGlyphOrder(): 76 g = glyfTable[glyphName] 77 if g.numberOfContours: 78 if hmtxTable[glyphName][1] <> g.xMin: 79 allXMaxIsLsb = 0 80 xMin = min(xMin, g.xMin) 81 yMin = min(yMin, g.yMin) 82 xMax = max(xMax, g.xMax) 83 yMax = max(yMax, g.yMax) 84 if g.numberOfContours > 0: 85 nPoints, nContours = g.getMaxpValues() 86 maxPoints = max(maxPoints, nPoints) 87 maxContours = max(maxContours, nContours) 88 else: 89 nPoints, nContours, componentDepth = g.getCompositeMaxpValues(glyfTable) 90 maxCompositePoints = max(maxCompositePoints, nPoints) 91 maxCompositeContours = max(maxCompositeContours, nContours) 92 maxComponentElements = max(maxComponentElements, len(g.components)) 93 maxComponentDepth = max(maxComponentDepth, componentDepth) 94 self.xMin = xMin 95 self.yMin = yMin 96 self.xMax = xMax 97 self.yMax = yMax 98 self.maxPoints = maxPoints 99 self.maxContours = maxContours 100 self.maxCompositePoints = maxCompositePoints 101 self.maxCompositeContours = maxCompositeContours 102 self.maxComponentDepth = maxComponentDepth 103 if allXMaxIsLsb: 104 headTable.flags = headTable.flags | 0x2 105 else: 106 headTable.flags = headTable.flags & ~0x2 107 108 def testrepr(self): 109 items = self.__dict__.items() 110 items.sort() 111 print ". . . . . . . . ." 112 for combo in items: 113 print " %s: %s" % combo 114 print ". . . . . . . . ." 115 116 def toXML(self, writer, ttFont): 117 if self.tableVersion <> 0x00005000: 118 writer.comment("Most of this table will be recalculated by the compiler") 119 writer.newline() 120 formatstring, names, fixes = sstruct.getformat(maxpFormat_0_5) 121 if self.tableVersion == 0x00010000: 122 formatstring, names_1_0, fixes = sstruct.getformat(maxpFormat_1_0_add) 123 names = names + names_1_0 124 else: 125 assert self.tableVersion == 0x00005000, "unknown 'maxp' format: %f" % self.tableVersion 126 for name in names: 127 value = getattr(self, name) 128 if type(value) == type(0L): 129 value=int(value) 130 if name == "tableVersion": 131 value = hex(value) 132 writer.simpletag(name, value=value) 133 writer.newline() 134 135 def fromXML(self, (name, attrs, content), ttFont): 136 setattr(self, name, safeEval(attrs["value"])) 137 138 139