11ae29591efbb29492ce05378909ccf4028d7c1eeBehdad Esfahbodfrom __future__ import print_function, division, absolute_import 230e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom fontTools.misc.py23 import * 38413c108d21e8cf0e9059bbfffde8d13f2616340Behdad Esfahbodfrom fontTools.misc import sstruct 47842e56b97ce677b83bdab09cda48bc2d89ac75aJustfrom fontTools.misc.textTools import safeEval 530e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom . import DefaultTable 67842e56b97ce677b83bdab09cda48bc2d89ac75aJust 77842e56b97ce677b83bdab09cda48bc2d89ac75aJustmaxpFormat_0_5 = """ 87842e56b97ce677b83bdab09cda48bc2d89ac75aJust > # big endian 9898295619d8df4e4422c566cd9499c48d1d6b647jvr tableVersion: i 10898295619d8df4e4422c566cd9499c48d1d6b647jvr numGlyphs: H 117842e56b97ce677b83bdab09cda48bc2d89ac75aJust""" 127842e56b97ce677b83bdab09cda48bc2d89ac75aJust 137842e56b97ce677b83bdab09cda48bc2d89ac75aJustmaxpFormat_1_0_add = """ 147842e56b97ce677b83bdab09cda48bc2d89ac75aJust > # big endian 15898295619d8df4e4422c566cd9499c48d1d6b647jvr maxPoints: H 16898295619d8df4e4422c566cd9499c48d1d6b647jvr maxContours: H 17898295619d8df4e4422c566cd9499c48d1d6b647jvr maxCompositePoints: H 18898295619d8df4e4422c566cd9499c48d1d6b647jvr maxCompositeContours: H 19898295619d8df4e4422c566cd9499c48d1d6b647jvr maxZones: H 20898295619d8df4e4422c566cd9499c48d1d6b647jvr maxTwilightPoints: H 21898295619d8df4e4422c566cd9499c48d1d6b647jvr maxStorage: H 22898295619d8df4e4422c566cd9499c48d1d6b647jvr maxFunctionDefs: H 23898295619d8df4e4422c566cd9499c48d1d6b647jvr maxInstructionDefs: H 24898295619d8df4e4422c566cd9499c48d1d6b647jvr maxStackElements: H 25898295619d8df4e4422c566cd9499c48d1d6b647jvr maxSizeOfInstructions: H 26898295619d8df4e4422c566cd9499c48d1d6b647jvr maxComponentElements: H 27898295619d8df4e4422c566cd9499c48d1d6b647jvr maxComponentDepth: H 287842e56b97ce677b83bdab09cda48bc2d89ac75aJust""" 297842e56b97ce677b83bdab09cda48bc2d89ac75aJust 307842e56b97ce677b83bdab09cda48bc2d89ac75aJust 317842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass table__m_a_x_p(DefaultTable.DefaultTable): 327842e56b97ce677b83bdab09cda48bc2d89ac75aJust 337842e56b97ce677b83bdab09cda48bc2d89ac75aJust dependencies = ['glyf'] 347842e56b97ce677b83bdab09cda48bc2d89ac75aJust 357842e56b97ce677b83bdab09cda48bc2d89ac75aJust def decompile(self, data, ttFont): 367842e56b97ce677b83bdab09cda48bc2d89ac75aJust dummy, data = sstruct.unpack2(maxpFormat_0_5, data, self) 377842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.numGlyphs = int(self.numGlyphs) 38bc90c7a05b2e5114db9b0c0a6448e68d80ccf622jvr if self.tableVersion != 0x00005000: 397842e56b97ce677b83bdab09cda48bc2d89ac75aJust dummy, data = sstruct.unpack2(maxpFormat_1_0_add, data, self) 407842e56b97ce677b83bdab09cda48bc2d89ac75aJust assert len(data) == 0 417842e56b97ce677b83bdab09cda48bc2d89ac75aJust 427842e56b97ce677b83bdab09cda48bc2d89ac75aJust def compile(self, ttFont): 43bc5e1cb195c0bfa1c8e7507326d5a9ad05aecb4bBehdad Esfahbod if 'glyf' in ttFont: 443e097c609540944dd9290ad58df346ca86492031Just if ttFont.isLoaded('glyf') and ttFont.recalcBBoxes: 457842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.recalc(ttFont) 467842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 47bc90c7a05b2e5114db9b0c0a6448e68d80ccf622jvr pass # CFF 4807dd0e4504fcdf7bfb0aaee4350435e03ab2c2d8jvr self.numGlyphs = len(ttFont.getGlyphOrder()) 49bc90c7a05b2e5114db9b0c0a6448e68d80ccf622jvr if self.tableVersion != 0x00005000: 50bc90c7a05b2e5114db9b0c0a6448e68d80ccf622jvr self.tableVersion = 0x00010000 517842e56b97ce677b83bdab09cda48bc2d89ac75aJust data = sstruct.pack(maxpFormat_0_5, self) 527842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.tableVersion == 0x00010000: 537842e56b97ce677b83bdab09cda48bc2d89ac75aJust data = data + sstruct.pack(maxpFormat_1_0_add, self) 547842e56b97ce677b83bdab09cda48bc2d89ac75aJust return data 557842e56b97ce677b83bdab09cda48bc2d89ac75aJust 567842e56b97ce677b83bdab09cda48bc2d89ac75aJust def recalc(self, ttFont): 577842e56b97ce677b83bdab09cda48bc2d89ac75aJust """Recalculate the font bounding box, and most other maxp values except 587842e56b97ce677b83bdab09cda48bc2d89ac75aJust for the TT instructions values. Also recalculate the value of bit 1 59fc99ad1513ca5443a29f1cc99df6016325e8dcbbPetr of the flags field and the font bounding box of the 'head' table. 607842e56b97ce677b83bdab09cda48bc2d89ac75aJust """ 617842e56b97ce677b83bdab09cda48bc2d89ac75aJust glyfTable = ttFont['glyf'] 627842e56b97ce677b83bdab09cda48bc2d89ac75aJust hmtxTable = ttFont['hmtx'] 637842e56b97ce677b83bdab09cda48bc2d89ac75aJust headTable = ttFont['head'] 647842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.numGlyphs = len(glyfTable) 65d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader INFINITY = 100000 66d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader xMin = +INFINITY 67d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader yMin = +INFINITY 68d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader xMax = -INFINITY 69d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader yMax = -INFINITY 707842e56b97ce677b83bdab09cda48bc2d89ac75aJust maxPoints = 0 717842e56b97ce677b83bdab09cda48bc2d89ac75aJust maxContours = 0 727842e56b97ce677b83bdab09cda48bc2d89ac75aJust maxCompositePoints = 0 737842e56b97ce677b83bdab09cda48bc2d89ac75aJust maxCompositeContours = 0 747842e56b97ce677b83bdab09cda48bc2d89ac75aJust maxComponentElements = 0 757842e56b97ce677b83bdab09cda48bc2d89ac75aJust maxComponentDepth = 0 767842e56b97ce677b83bdab09cda48bc2d89ac75aJust allXMaxIsLsb = 1 777842e56b97ce677b83bdab09cda48bc2d89ac75aJust for glyphName in ttFont.getGlyphOrder(): 787842e56b97ce677b83bdab09cda48bc2d89ac75aJust g = glyfTable[glyphName] 797842e56b97ce677b83bdab09cda48bc2d89ac75aJust if g.numberOfContours: 80180ace6a5ff1399ec53bc696e8bef7cce6eef39aBehdad Esfahbod if hmtxTable[glyphName][1] != g.xMin: 817842e56b97ce677b83bdab09cda48bc2d89ac75aJust allXMaxIsLsb = 0 827842e56b97ce677b83bdab09cda48bc2d89ac75aJust xMin = min(xMin, g.xMin) 837842e56b97ce677b83bdab09cda48bc2d89ac75aJust yMin = min(yMin, g.yMin) 847842e56b97ce677b83bdab09cda48bc2d89ac75aJust xMax = max(xMax, g.xMax) 857842e56b97ce677b83bdab09cda48bc2d89ac75aJust yMax = max(yMax, g.yMax) 867842e56b97ce677b83bdab09cda48bc2d89ac75aJust if g.numberOfContours > 0: 877842e56b97ce677b83bdab09cda48bc2d89ac75aJust nPoints, nContours = g.getMaxpValues() 887842e56b97ce677b83bdab09cda48bc2d89ac75aJust maxPoints = max(maxPoints, nPoints) 897842e56b97ce677b83bdab09cda48bc2d89ac75aJust maxContours = max(maxContours, nContours) 907842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 917842e56b97ce677b83bdab09cda48bc2d89ac75aJust nPoints, nContours, componentDepth = g.getCompositeMaxpValues(glyfTable) 927842e56b97ce677b83bdab09cda48bc2d89ac75aJust maxCompositePoints = max(maxCompositePoints, nPoints) 937842e56b97ce677b83bdab09cda48bc2d89ac75aJust maxCompositeContours = max(maxCompositeContours, nContours) 947842e56b97ce677b83bdab09cda48bc2d89ac75aJust maxComponentElements = max(maxComponentElements, len(g.components)) 957842e56b97ce677b83bdab09cda48bc2d89ac75aJust maxComponentDepth = max(maxComponentDepth, componentDepth) 96d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader if xMin == +INFINITY: 97d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader headTable.xMin = 0 98d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader headTable.yMin = 0 99d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader headTable.xMax = 0 100d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader headTable.yMax = 0 101d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader else: 102cff3740f1440997cd013f538fecb06243d13c6a1Denis Jacquerye headTable.xMin = xMin 103cff3740f1440997cd013f538fecb06243d13c6a1Denis Jacquerye headTable.yMin = yMin 104cff3740f1440997cd013f538fecb06243d13c6a1Denis Jacquerye headTable.xMax = xMax 105cff3740f1440997cd013f538fecb06243d13c6a1Denis Jacquerye headTable.yMax = yMax 1067842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.maxPoints = maxPoints 1077842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.maxContours = maxContours 1087842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.maxCompositePoints = maxCompositePoints 1097842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.maxCompositeContours = maxCompositeContours 1107842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.maxComponentDepth = maxComponentDepth 1117842e56b97ce677b83bdab09cda48bc2d89ac75aJust if allXMaxIsLsb: 1127842e56b97ce677b83bdab09cda48bc2d89ac75aJust headTable.flags = headTable.flags | 0x2 1137842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 1147842e56b97ce677b83bdab09cda48bc2d89ac75aJust headTable.flags = headTable.flags & ~0x2 1157842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1167842e56b97ce677b83bdab09cda48bc2d89ac75aJust def testrepr(self): 117ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod items = sorted(self.__dict__.items()) 1183ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print(". . . . . . . . .") 1197842e56b97ce677b83bdab09cda48bc2d89ac75aJust for combo in items: 1203ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print(" %s: %s" % combo) 1213ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print(". . . . . . . . .") 1227842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1237842e56b97ce677b83bdab09cda48bc2d89ac75aJust def toXML(self, writer, ttFont): 124bc90c7a05b2e5114db9b0c0a6448e68d80ccf622jvr if self.tableVersion != 0x00005000: 1257842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.comment("Most of this table will be recalculated by the compiler") 1267842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.newline() 1277842e56b97ce677b83bdab09cda48bc2d89ac75aJust formatstring, names, fixes = sstruct.getformat(maxpFormat_0_5) 128bc90c7a05b2e5114db9b0c0a6448e68d80ccf622jvr if self.tableVersion != 0x00005000: 1297842e56b97ce677b83bdab09cda48bc2d89ac75aJust formatstring, names_1_0, fixes = sstruct.getformat(maxpFormat_1_0_add) 1307842e56b97ce677b83bdab09cda48bc2d89ac75aJust names = names + names_1_0 1317842e56b97ce677b83bdab09cda48bc2d89ac75aJust for name in names: 1327842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = getattr(self, name) 1337842e56b97ce677b83bdab09cda48bc2d89ac75aJust if name == "tableVersion": 1347842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = hex(value) 1357842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.simpletag(name, value=value) 1367842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.newline() 1377842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1383a9fd301808f5a8991ca9ac44028d1ecb22d307fBehdad Esfahbod def fromXML(self, name, attrs, content, ttFont): 1397842e56b97ce677b83bdab09cda48bc2d89ac75aJust setattr(self, name, safeEval(attrs["value"])) 1407842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1417842e56b97ce677b83bdab09cda48bc2d89ac75aJust 142