| from __future__ import print_function, division, absolute_import |
| from fontTools.misc.py23 import * |
| from fontTools.misc import sstruct |
| from fontTools.misc.textTools import safeEval |
| from . import DefaultTable |
| |
| SINGFormat = """ |
| > # big endian |
| tableVersionMajor: H |
| tableVersionMinor: H |
| glyphletVersion: H |
| permissions: h |
| mainGID: H |
| unitsPerEm: H |
| vertAdvance: h |
| vertOrigin: h |
| uniqueName: 28s |
| METAMD5: 16s |
| nameLength: 1s |
| """ |
| # baseGlyphName is a byte string which follows the record above. |
| |
| |
| class table_S_I_N_G_(DefaultTable.DefaultTable): |
| |
| dependencies = [] |
| |
| def decompile(self, data, ttFont): |
| dummy, rest = sstruct.unpack2(SINGFormat, data, self) |
| self.uniqueName = self.decompileUniqueName(self.uniqueName) |
| self.nameLength = byteord(self.nameLength) |
| assert len(rest) == self.nameLength |
| self.baseGlyphName = tostr(rest) |
| |
| rawMETAMD5 = self.METAMD5 |
| self.METAMD5 = "[" + hex(byteord(self.METAMD5[0])) |
| for char in rawMETAMD5[1:]: |
| self.METAMD5 = self.METAMD5 + ", " + hex(byteord(char)) |
| self.METAMD5 = self.METAMD5 + "]" |
| |
| def decompileUniqueName(self, data): |
| name = "" |
| for char in data: |
| val = byteord(char) |
| if val == 0: |
| break |
| if (val > 31) or (val < 128): |
| name += chr(val) |
| else: |
| octString = oct(val) |
| if len(octString) > 3: |
| octString = octString[1:] # chop off that leading zero. |
| elif len(octString) < 3: |
| octString.zfill(3) |
| name += "\\" + octString |
| return name |
| |
| def compile(self, ttFont): |
| d = self.__dict__.copy() |
| d["nameLength"] = bytechr(len(self.baseGlyphName)) |
| d["uniqueName"] = self.compilecompileUniqueName(self.uniqueName, 28) |
| METAMD5List = eval(self.METAMD5) |
| d["METAMD5"] = b"" |
| for val in METAMD5List: |
| d["METAMD5"] += bytechr(val) |
| assert (len(d["METAMD5"]) == 16), "Failed to pack 16 byte MD5 hash in SING table" |
| data = sstruct.pack(SINGFormat, d) |
| data = data + tobytes(self.baseGlyphName) |
| return data |
| |
| def compilecompileUniqueName(self, name, length): |
| nameLen = len(name) |
| if length <= nameLen: |
| name = name[:length-1] + "\000" |
| else: |
| name += (nameLen - length) * "\000" |
| return name |
| |
| def toXML(self, writer, ttFont): |
| writer.comment("Most of this table will be recalculated by the compiler") |
| writer.newline() |
| formatstring, names, fixes = sstruct.getformat(SINGFormat) |
| for name in names: |
| value = getattr(self, name) |
| writer.simpletag(name, value=value) |
| writer.newline() |
| writer.simpletag("baseGlyphName", value=self.baseGlyphName) |
| writer.newline() |
| |
| def fromXML(self, name, attrs, content, ttFont): |
| value = attrs["value"] |
| if name in ["uniqueName", "METAMD5", "baseGlyphName"]: |
| setattr(self, name, value) |
| else: |
| setattr(self, name, safeEval(value)) |