11ae29591efbb29492ce05378909ccf4028d7c1eeBehdad Esfahbodfrom __future__ import print_function, division, absolute_import 27ed91eca1eaa96b79eae780778e89bb9ec44c1eeBehdad Esfahbodfrom fontTools.misc.py23 import * 330e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom fontTools.misc import sstruct 430e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom . import DefaultTable 57842e56b97ce677b83bdab09cda48bc2d89ac75aJust 67842e56b97ce677b83bdab09cda48bc2d89ac75aJusthdmxHeaderFormat = """ 7fd5a93240e40e265ab3f956300790e2eea0afa54Just > # big endian! 87842e56b97ce677b83bdab09cda48bc2d89ac75aJust version: H 97842e56b97ce677b83bdab09cda48bc2d89ac75aJust numRecords: H 107842e56b97ce677b83bdab09cda48bc2d89ac75aJust recordSize: l 117842e56b97ce677b83bdab09cda48bc2d89ac75aJust""" 127842e56b97ce677b83bdab09cda48bc2d89ac75aJust 137842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass table__h_d_m_x(DefaultTable.DefaultTable): 147842e56b97ce677b83bdab09cda48bc2d89ac75aJust 157842e56b97ce677b83bdab09cda48bc2d89ac75aJust def decompile(self, data, ttFont): 167842e56b97ce677b83bdab09cda48bc2d89ac75aJust numGlyphs = ttFont['maxp'].numGlyphs 177842e56b97ce677b83bdab09cda48bc2d89ac75aJust glyphOrder = ttFont.getGlyphOrder() 187842e56b97ce677b83bdab09cda48bc2d89ac75aJust dummy, data = sstruct.unpack2(hdmxHeaderFormat, data, self) 197842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.hdmx = {} 207842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(self.numRecords): 21319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod ppem = byteord(data[0]) 22319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod maxSize = byteord(data[1]) 237842e56b97ce677b83bdab09cda48bc2d89ac75aJust widths = {} 247842e56b97ce677b83bdab09cda48bc2d89ac75aJust for glyphID in range(numGlyphs): 25319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod widths[glyphOrder[glyphID]] = byteord(data[glyphID+2]) 267842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.hdmx[ppem] = widths 277842e56b97ce677b83bdab09cda48bc2d89ac75aJust data = data[self.recordSize:] 287842e56b97ce677b83bdab09cda48bc2d89ac75aJust assert len(data) == 0, "too much hdmx data" 297842e56b97ce677b83bdab09cda48bc2d89ac75aJust 307842e56b97ce677b83bdab09cda48bc2d89ac75aJust def compile(self, ttFont): 317842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.version = 0 327842e56b97ce677b83bdab09cda48bc2d89ac75aJust numGlyphs = ttFont['maxp'].numGlyphs 337842e56b97ce677b83bdab09cda48bc2d89ac75aJust glyphOrder = ttFont.getGlyphOrder() 3432c10eecffb4923e0721c395e4b80fb732543f18Behdad Esfahbod self.recordSize = 4 * ((2 + numGlyphs + 3) // 4) 3518316aa769566eeb6f3f4a6ed2685fa8f8e861c2Behdad Esfahbod pad = (self.recordSize - 2 - numGlyphs) * b"\0" 367842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.numRecords = len(self.hdmx) 377842e56b97ce677b83bdab09cda48bc2d89ac75aJust data = sstruct.pack(hdmxHeaderFormat, self) 38ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod items = sorted(self.hdmx.items()) 397842e56b97ce677b83bdab09cda48bc2d89ac75aJust for ppem, widths in items: 40b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod data = data + bytechr(ppem) + bytechr(max(widths.values())) 417842e56b97ce677b83bdab09cda48bc2d89ac75aJust for glyphID in range(len(glyphOrder)): 427842e56b97ce677b83bdab09cda48bc2d89ac75aJust width = widths[glyphOrder[glyphID]] 43b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod data = data + bytechr(width) 447842e56b97ce677b83bdab09cda48bc2d89ac75aJust data = data + pad 457842e56b97ce677b83bdab09cda48bc2d89ac75aJust return data 467842e56b97ce677b83bdab09cda48bc2d89ac75aJust 477842e56b97ce677b83bdab09cda48bc2d89ac75aJust def toXML(self, writer, ttFont): 487842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.begintag("hdmxData") 497842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.newline() 50ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod ppems = sorted(self.hdmx.keys()) 517842e56b97ce677b83bdab09cda48bc2d89ac75aJust records = [] 527842e56b97ce677b83bdab09cda48bc2d89ac75aJust format = "" 537842e56b97ce677b83bdab09cda48bc2d89ac75aJust for ppem in ppems: 547842e56b97ce677b83bdab09cda48bc2d89ac75aJust widths = self.hdmx[ppem] 557842e56b97ce677b83bdab09cda48bc2d89ac75aJust records.append(widths) 567842e56b97ce677b83bdab09cda48bc2d89ac75aJust format = format + "%4d" 577842e56b97ce677b83bdab09cda48bc2d89ac75aJust glyphNames = ttFont.getGlyphOrder()[:] 587842e56b97ce677b83bdab09cda48bc2d89ac75aJust glyphNames.sort() 597842e56b97ce677b83bdab09cda48bc2d89ac75aJust maxNameLen = max(map(len, glyphNames)) 60dc7e6f3e5563a853477ebe26166b002c158dbe8bBehdad Esfahbod format = "%" + repr(maxNameLen) + 's:' + format + ' ;' 617842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.write(format % (("ppem",) + tuple(ppems))) 627842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.newline() 637842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.newline() 647842e56b97ce677b83bdab09cda48bc2d89ac75aJust for glyphName in glyphNames: 657842e56b97ce677b83bdab09cda48bc2d89ac75aJust row = [] 667842e56b97ce677b83bdab09cda48bc2d89ac75aJust for ppem in ppems: 677842e56b97ce677b83bdab09cda48bc2d89ac75aJust widths = self.hdmx[ppem] 687842e56b97ce677b83bdab09cda48bc2d89ac75aJust row.append(widths[glyphName]) 691872557451256004f27133686eeddbbbdf163c69jvr if ";" in glyphName: 701872557451256004f27133686eeddbbbdf163c69jvr glyphName = "\\x3b".join(glyphName.split(";")) 717842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.write(format % ((glyphName,) + tuple(row))) 727842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.newline() 737842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.endtag("hdmxData") 747842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.newline() 757842e56b97ce677b83bdab09cda48bc2d89ac75aJust 763a9fd301808f5a8991ca9ac44028d1ecb22d307fBehdad Esfahbod def fromXML(self, name, attrs, content, ttFont): 77180ace6a5ff1399ec53bc696e8bef7cce6eef39aBehdad Esfahbod if name != "hdmxData": 787842e56b97ce677b83bdab09cda48bc2d89ac75aJust return 7918316aa769566eeb6f3f4a6ed2685fa8f8e861c2Behdad Esfahbod content = strjoin(content) 8014fb031125b773f0a15eb19be4f02ed8540b2db6Behdad Esfahbod lines = content.split(";") 8114fb031125b773f0a15eb19be4f02ed8540b2db6Behdad Esfahbod topRow = lines[0].split() 827842e56b97ce677b83bdab09cda48bc2d89ac75aJust assert topRow[0] == "ppem:", "illegal hdmx format" 83e5ca79699d00fdf7ac6eaceaed372aea8d6bc1fdBehdad Esfahbod ppems = list(map(int, topRow[1:])) 847842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.hdmx = hdmx = {} 857842e56b97ce677b83bdab09cda48bc2d89ac75aJust for ppem in ppems: 867842e56b97ce677b83bdab09cda48bc2d89ac75aJust hdmx[ppem] = {} 8714fb031125b773f0a15eb19be4f02ed8540b2db6Behdad Esfahbod lines = (line.split() for line in lines[1:]) 887842e56b97ce677b83bdab09cda48bc2d89ac75aJust for line in lines: 897842e56b97ce677b83bdab09cda48bc2d89ac75aJust if not line: 907842e56b97ce677b83bdab09cda48bc2d89ac75aJust continue 917842e56b97ce677b83bdab09cda48bc2d89ac75aJust assert line[0][-1] == ":", "illegal hdmx format" 927842e56b97ce677b83bdab09cda48bc2d89ac75aJust glyphName = line[0][:-1] 931872557451256004f27133686eeddbbbdf163c69jvr if "\\" in glyphName: 941872557451256004f27133686eeddbbbdf163c69jvr from fontTools.misc.textTools import safeEval 951872557451256004f27133686eeddbbbdf163c69jvr glyphName = safeEval('"""' + glyphName + '"""') 96e5ca79699d00fdf7ac6eaceaed372aea8d6bc1fdBehdad Esfahbod line = list(map(int, line[1:])) 977842e56b97ce677b83bdab09cda48bc2d89ac75aJust assert len(line) == len(ppems), "illegal hdmx format" 987842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(len(ppems)): 997842e56b97ce677b83bdab09cda48bc2d89ac75aJust hdmx[ppems[i]][glyphName] = line[i] 1007842e56b97ce677b83bdab09cda48bc2d89ac75aJust 101