11ae29591efbb29492ce05378909ccf4028d7c1eeBehdad Esfahbodfrom __future__ import print_function, division, absolute_import 230e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom fontTools.misc.py23 import * 38413c108d21e8cf0e9059bbfffde8d13f2616340Behdad Esfahbodfrom fontTools.misc import sstruct 47ed91eca1eaa96b79eae780778e89bb9ec44c1eeBehdad Esfahbodfrom fontTools.misc.textTools import safeEval 530e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom . import DefaultTable 64cc0051c087e7e9c294559a21540e296cfe9ef4ajvr 74cc0051c087e7e9c294559a21540e296cfe9ef4ajvrSINGFormat = """ 84cc0051c087e7e9c294559a21540e296cfe9ef4ajvr > # big endian 94cc0051c087e7e9c294559a21540e296cfe9ef4ajvr tableVersionMajor: H 104cc0051c087e7e9c294559a21540e296cfe9ef4ajvr tableVersionMinor: H 114cc0051c087e7e9c294559a21540e296cfe9ef4ajvr glyphletVersion: H 124cc0051c087e7e9c294559a21540e296cfe9ef4ajvr permissions: h 134cc0051c087e7e9c294559a21540e296cfe9ef4ajvr mainGID: H 144cc0051c087e7e9c294559a21540e296cfe9ef4ajvr unitsPerEm: H 154cc0051c087e7e9c294559a21540e296cfe9ef4ajvr vertAdvance: h 164cc0051c087e7e9c294559a21540e296cfe9ef4ajvr vertOrigin: h 174cc0051c087e7e9c294559a21540e296cfe9ef4ajvr uniqueName: 28s 184cc0051c087e7e9c294559a21540e296cfe9ef4ajvr METAMD5: 16s 194cc0051c087e7e9c294559a21540e296cfe9ef4ajvr nameLength: 1s 204cc0051c087e7e9c294559a21540e296cfe9ef4ajvr""" 214cc0051c087e7e9c294559a21540e296cfe9ef4ajvr# baseGlyphName is a byte string which follows the record above. 224cc0051c087e7e9c294559a21540e296cfe9ef4ajvr 234cc0051c087e7e9c294559a21540e296cfe9ef4ajvr 244cc0051c087e7e9c294559a21540e296cfe9ef4ajvr 254cc0051c087e7e9c294559a21540e296cfe9ef4ajvrclass table_S_I_N_G_(DefaultTable.DefaultTable): 264cc0051c087e7e9c294559a21540e296cfe9ef4ajvr 274cc0051c087e7e9c294559a21540e296cfe9ef4ajvr dependencies = [] 284cc0051c087e7e9c294559a21540e296cfe9ef4ajvr 294cc0051c087e7e9c294559a21540e296cfe9ef4ajvr def decompile(self, data, ttFont): 304cc0051c087e7e9c294559a21540e296cfe9ef4ajvr dummy, rest = sstruct.unpack2(SINGFormat, data, self) 314cc0051c087e7e9c294559a21540e296cfe9ef4ajvr self.uniqueName = self.decompileUniqueName(self.uniqueName) 32319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod self.nameLength = byteord(self.nameLength) 334cc0051c087e7e9c294559a21540e296cfe9ef4ajvr assert len(rest) == self.nameLength 34fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod self.baseGlyphName = tostr(rest) 354cc0051c087e7e9c294559a21540e296cfe9ef4ajvr 364cc0051c087e7e9c294559a21540e296cfe9ef4ajvr rawMETAMD5 = self.METAMD5 37319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod self.METAMD5 = "[" + hex(byteord(self.METAMD5[0])) 384cc0051c087e7e9c294559a21540e296cfe9ef4ajvr for char in rawMETAMD5[1:]: 39319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod self.METAMD5 = self.METAMD5 + ", " + hex(byteord(char)) 404cc0051c087e7e9c294559a21540e296cfe9ef4ajvr self.METAMD5 = self.METAMD5 + "]" 414cc0051c087e7e9c294559a21540e296cfe9ef4ajvr 424cc0051c087e7e9c294559a21540e296cfe9ef4ajvr def decompileUniqueName(self, data): 434cc0051c087e7e9c294559a21540e296cfe9ef4ajvr name = "" 444cc0051c087e7e9c294559a21540e296cfe9ef4ajvr for char in data: 45319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod val = byteord(char) 464cc0051c087e7e9c294559a21540e296cfe9ef4ajvr if val == 0: 474cc0051c087e7e9c294559a21540e296cfe9ef4ajvr break 484cc0051c087e7e9c294559a21540e296cfe9ef4ajvr if (val > 31) or (val < 128): 49fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod name += chr(val) 504cc0051c087e7e9c294559a21540e296cfe9ef4ajvr else: 514cc0051c087e7e9c294559a21540e296cfe9ef4ajvr octString = oct(val) 524cc0051c087e7e9c294559a21540e296cfe9ef4ajvr if len(octString) > 3: 534cc0051c087e7e9c294559a21540e296cfe9ef4ajvr octString = octString[1:] # chop off that leading zero. 544cc0051c087e7e9c294559a21540e296cfe9ef4ajvr elif len(octString) < 3: 554cc0051c087e7e9c294559a21540e296cfe9ef4ajvr octString.zfill(3) 56fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod name += "\\" + octString 574cc0051c087e7e9c294559a21540e296cfe9ef4ajvr return name 584cc0051c087e7e9c294559a21540e296cfe9ef4ajvr 594cc0051c087e7e9c294559a21540e296cfe9ef4ajvr 604cc0051c087e7e9c294559a21540e296cfe9ef4ajvr def compile(self, ttFont): 61fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod d = self.__dict__.copy() 62fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod d["nameLength"] = bytechr(len(self.baseGlyphName)) 63fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod d["uniqueName"] = self.compilecompileUniqueName(self.uniqueName, 28) 644cc0051c087e7e9c294559a21540e296cfe9ef4ajvr METAMD5List = eval(self.METAMD5) 65fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod d["METAMD5"] = b"" 664cc0051c087e7e9c294559a21540e296cfe9ef4ajvr for val in METAMD5List: 67fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod d["METAMD5"] += bytechr(val) 68fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod assert (len(d["METAMD5"]) == 16), "Failed to pack 16 byte MD5 hash in SING table" 69fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod data = sstruct.pack(SINGFormat, d) 70fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod data = data + tobytes(self.baseGlyphName) 714cc0051c087e7e9c294559a21540e296cfe9ef4ajvr return data 724cc0051c087e7e9c294559a21540e296cfe9ef4ajvr 734cc0051c087e7e9c294559a21540e296cfe9ef4ajvr def compilecompileUniqueName(self, name, length): 744cc0051c087e7e9c294559a21540e296cfe9ef4ajvr nameLen = len(name) 754cc0051c087e7e9c294559a21540e296cfe9ef4ajvr if length <= nameLen: 76fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod name = name[:length-1] + "\000" 774cc0051c087e7e9c294559a21540e296cfe9ef4ajvr else: 78fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod name += (nameLen - length) * "\000" 794cc0051c087e7e9c294559a21540e296cfe9ef4ajvr return name 804cc0051c087e7e9c294559a21540e296cfe9ef4ajvr 814cc0051c087e7e9c294559a21540e296cfe9ef4ajvr 824cc0051c087e7e9c294559a21540e296cfe9ef4ajvr def toXML(self, writer, ttFont): 834cc0051c087e7e9c294559a21540e296cfe9ef4ajvr writer.comment("Most of this table will be recalculated by the compiler") 844cc0051c087e7e9c294559a21540e296cfe9ef4ajvr writer.newline() 854cc0051c087e7e9c294559a21540e296cfe9ef4ajvr formatstring, names, fixes = sstruct.getformat(SINGFormat) 864cc0051c087e7e9c294559a21540e296cfe9ef4ajvr for name in names: 874cc0051c087e7e9c294559a21540e296cfe9ef4ajvr value = getattr(self, name) 884cc0051c087e7e9c294559a21540e296cfe9ef4ajvr writer.simpletag(name, value=value) 894cc0051c087e7e9c294559a21540e296cfe9ef4ajvr writer.newline() 904cc0051c087e7e9c294559a21540e296cfe9ef4ajvr writer.simpletag("baseGlyphName", value=self.baseGlyphName) 914cc0051c087e7e9c294559a21540e296cfe9ef4ajvr writer.newline() 924cc0051c087e7e9c294559a21540e296cfe9ef4ajvr 933a9fd301808f5a8991ca9ac44028d1ecb22d307fBehdad Esfahbod def fromXML(self, name, attrs, content, ttFont): 944cc0051c087e7e9c294559a21540e296cfe9ef4ajvr value = attrs["value"] 954cc0051c087e7e9c294559a21540e296cfe9ef4ajvr if name in ["uniqueName", "METAMD5", "baseGlyphName"]: 964cc0051c087e7e9c294559a21540e296cfe9ef4ajvr setattr(self, name, value) 974cc0051c087e7e9c294559a21540e296cfe9ef4ajvr else: 987cc6d271ac955782d730161b27e728001fb5f347Behdad Esfahbod setattr(self, name, safeEval(value)) 99