Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

160 lines
5.6 KiB
Python
Raw Normal View History

from fontTools.misc.textTools import bytesjoin, safeEval
2013-11-27 02:34:11 -05:00
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.
2022-12-13 11:26:36 +00:00
``ttFont['VORG'][<glyphName>]`` will return the vertical origin for any glyph.
2022-12-13 11:26:36 +00:00
``ttFont['VORG'][<glyphName>] = <value>`` will set the vertical origin for any glyph.
"""
2022-12-13 11:26:36 +00:00
def decompile(self, data, ttFont):
self.getGlyphName = (
ttFont.getGlyphName
) # for use in get/set item functions, for access by GID
2022-12-13 11:26:36 +00:00
(
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)
2022-12-13 11:26:36 +00:00
self.VOriginRecords = vOrig = {}
glyphOrder = ttFont.getGlyphOrder()
try:
names = [glyphOrder[gid] for gid in gids]
except IndexError:
getGlyphName = self.getGlyphName
names = map(getGlyphName, gids)
2022-12-13 11:26:36 +00:00
for name, vid in zip(names, vids):
vOrig[name] = vid
2022-12-13 11:26:36 +00:00
def compile(self, ttFont):
2013-11-27 06:26:55 -05:00
vorgs = list(self.VOriginRecords.values())
names = list(self.VOriginRecords.keys())
nameMap = ttFont.getReverseGlyphMap()
try:
gids = [nameMap[name] for name in names]
except KeyError:
2013-12-04 21:28:50 -05:00
nameMap = ttFont.getReverseGlyphMap(rebuild=True)
gids = [nameMap[name] for name in names]
2013-11-27 04:38:16 -05:00
vOriginTable = list(zip(gids, vorgs))
self.numVertOriginYMetrics = len(vorgs)
vOriginTable.sort() # must be in ascending GID order
2019-03-04 11:32:32 +01:00
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
2022-12-13 11:26:36 +00:00
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)
2022-12-13 11:26:36 +00:00
)
vOriginTable.append([gid, glyphName, self.VOriginRecords[glyphName]])
vOriginTable.sort()
for entry in vOriginTable:
vOriginRec = VOriginRecord(entry[1], entry[2])
vOriginRec.toXML(writer, ttFont)
2022-12-13 11:26:36 +00:00
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
2013-11-27 02:33:03 -05:00
elif "value" in attrs:
2013-11-27 04:00:15 -05:00
setattr(self, name, safeEval(attrs["value"]))
2022-12-13 11:26:36 +00:00
def __getitem__(self, glyphSelector):
if isinstance(glyphSelector, int):
# its a gid, convert to glyph name
glyphSelector = self.getGlyphName(glyphSelector)
2022-12-13 11:26:36 +00:00
2013-11-27 02:33:03 -05:00
if glyphSelector not in self.VOriginRecords:
return self.defaultVertOriginY
2022-12-13 11:26:36 +00:00
return self.VOriginRecords[glyphSelector]
2022-12-13 11:26:36 +00:00
def __setitem__(self, glyphSelector, value):
if isinstance(glyphSelector, int):
# its a gid, convert to glyph name
glyphSelector = self.getGlyphName(glyphSelector)
2022-12-13 11:26:36 +00:00
if value != self.defaultVertOriginY:
self.VOriginRecords[glyphSelector] = value
2013-11-27 02:33:03 -05:00
elif glyphSelector in self.VOriginRecords:
del self.VOriginRecords[glyphSelector]
2022-12-13 11:26:36 +00:00
2014-05-14 13:51:10 -06:00
def __delitem__(self, glyphSelector):
del self.VOriginRecords[glyphSelector]
class VOriginRecord(object):
def __init__(self, name=None, vOrigin=None):
self.glyphName = name
self.vOrigin = vOrigin
2022-12-13 11:26:36 +00:00
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()
2022-12-13 11:26:36 +00:00
def fromXML(self, name, attrs, content, ttFont):
value = attrs["value"]
if name == "glyphName":
setattr(self, name, value)
else:
2013-11-27 04:00:15 -05:00
setattr(self, name, safeEval(value))