| from __future__ import print_function, division, absolute_import |
| from fontTools.misc.py23 import * |
| from fontTools.misc.textTools import safeEval |
| from . import DefaultTable |
| import operator |
| 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'][<glyphName>] will return the vertical origin for any glyph |
| ttFont['VORG'][<glyphName>] = <value> 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 = map(operator.getitem, [glyphOrder]*self.numVertOriginYMetrics, gids) |
| except IndexError: |
| getGlyphName = self.getGlyphName |
| names = map(getGlyphName, gids ) |
| |
| list(map(operator.setitem, [vOrig]*self.numVertOriginYMetrics, names, vids)) |
| |
| |
| def compile(self, ttFont): |
| vorgs = list(self.VOriginRecords.values()) |
| names = list(self.VOriginRecords.keys()) |
| nameMap = ttFont.getReverseGlyphMap() |
| lenRecords = len(vorgs) |
| try: |
| gids = map(operator.getitem, [nameMap]*lenRecords, names) |
| except KeyError: |
| nameMap = ttFont.getReverseGlyphMap(rebuild=True) |
| gids = map(operator.getitem, [nameMap]*lenRecords, names) |
| vOriginTable = list(zip(gids, vorgs)) |
| self.numVertOriginYMetrics = lenRecords |
| 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, basestring): |
| 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)) |