123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- from fontTools.misc.textTools import bytesjoin, 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'][<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 = [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))
|