from fontTools.misc.py23 import bytesjoin from fontTools.misc.textTools import safeEval from . import DefaultTable import struct class table_V_O_R_G_(DefaultTable.DefaultTable): """ This table is structured so that you can treat it like a dictionary keyed by glyph name. ttFont['VORG'][] will return the vertical origin for any glyph ttFont['VORG'][] = will set the vertical origin for any glyph. """ def decompile(self, data, ttFont): self.getGlyphName = ttFont.getGlyphName # for use in get/set item functions, for access by GID self.majorVersion, self.minorVersion, self.defaultVertOriginY, self.numVertOriginYMetrics = struct.unpack(">HHhH", data[:8]) assert (self.majorVersion <= 1), "Major version of VORG table is higher than I know how to handle" data = data[8:] vids = [] gids = [] pos = 0 for i in range(self.numVertOriginYMetrics): gid, vOrigin = struct.unpack(">Hh", data[pos:pos+4]) pos += 4 gids.append(gid) vids.append(vOrigin) self.VOriginRecords = vOrig = {} glyphOrder = ttFont.getGlyphOrder() try: names = [glyphOrder[gid] for gid in gids] except IndexError: getGlyphName = self.getGlyphName names = map(getGlyphName, gids) for name, vid in zip(names, vids): vOrig[name] = vid def compile(self, ttFont): vorgs = list(self.VOriginRecords.values()) names = list(self.VOriginRecords.keys()) nameMap = ttFont.getReverseGlyphMap() try: gids = [nameMap[name] for name in names] except KeyError: nameMap = ttFont.getReverseGlyphMap(rebuild=True) gids = [nameMap[name] for name in names] vOriginTable = list(zip(gids, vorgs)) self.numVertOriginYMetrics = len(vorgs) vOriginTable.sort() # must be in ascending GID order dataList = [struct.pack(">Hh", rec[0], rec[1]) for rec in vOriginTable] header = struct.pack(">HHhH", self.majorVersion, self.minorVersion, self.defaultVertOriginY, self.numVertOriginYMetrics) dataList.insert(0, header) data = bytesjoin(dataList) return data def toXML(self, writer, ttFont): writer.simpletag("majorVersion", value=self.majorVersion) writer.newline() writer.simpletag("minorVersion", value=self.minorVersion) writer.newline() writer.simpletag("defaultVertOriginY", value=self.defaultVertOriginY) writer.newline() writer.simpletag("numVertOriginYMetrics", value=self.numVertOriginYMetrics) writer.newline() vOriginTable = [] glyphNames = self.VOriginRecords.keys() for glyphName in glyphNames: try: gid = ttFont.getGlyphID(glyphName) except: assert 0, "VORG table contains a glyph name not in ttFont.getGlyphNames(): " + str(glyphName) vOriginTable.append([gid, glyphName, self.VOriginRecords[glyphName]]) vOriginTable.sort() for entry in vOriginTable: vOriginRec = VOriginRecord(entry[1], entry[2]) vOriginRec.toXML(writer, ttFont) def fromXML(self, name, attrs, content, ttFont): if not hasattr(self, "VOriginRecords"): self.VOriginRecords = {} self.getGlyphName = ttFont.getGlyphName # for use in get/set item functions, for access by GID if name == "VOriginRecord": vOriginRec = VOriginRecord() for element in content: if isinstance(element, str): continue name, attrs, content = element vOriginRec.fromXML(name, attrs, content, ttFont) self.VOriginRecords[vOriginRec.glyphName] = vOriginRec.vOrigin elif "value" in attrs: setattr(self, name, safeEval(attrs["value"])) def __getitem__(self, glyphSelector): if isinstance(glyphSelector, int): # its a gid, convert to glyph name glyphSelector = self.getGlyphName(glyphSelector) if glyphSelector not in self.VOriginRecords: return self.defaultVertOriginY return self.VOriginRecords[glyphSelector] def __setitem__(self, glyphSelector, value): if isinstance(glyphSelector, int): # its a gid, convert to glyph name glyphSelector = self.getGlyphName(glyphSelector) if value != self.defaultVertOriginY: self.VOriginRecords[glyphSelector] = value elif glyphSelector in self.VOriginRecords: del self.VOriginRecords[glyphSelector] def __delitem__(self, glyphSelector): del self.VOriginRecords[glyphSelector] class VOriginRecord(object): def __init__(self, name=None, vOrigin=None): self.glyphName = name self.vOrigin = vOrigin def toXML(self, writer, ttFont): writer.begintag("VOriginRecord") writer.newline() writer.simpletag("glyphName", value=self.glyphName) writer.newline() writer.simpletag("vOrigin", value=self.vOrigin) writer.newline() writer.endtag("VOriginRecord") writer.newline() def fromXML(self, name, attrs, content, ttFont): value = attrs["value"] if name == "glyphName": setattr(self, name, value) else: setattr(self, name, safeEval(value))