2014-01-14 15:07:50 +08:00
|
|
|
from __future__ import print_function, division, absolute_import
|
2013-11-27 17:27:45 -05:00
|
|
|
from fontTools.misc.py23 import *
|
|
|
|
from fontTools.misc.textTools import safeEval
|
2013-11-27 02:34:11 -05:00
|
|
|
from . import DefaultTable
|
2013-11-27 15:16:28 -05:00
|
|
|
import operator
|
2003-08-22 20:02:25 +00:00
|
|
|
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):
|
2006-10-21 13:29:47 +00:00
|
|
|
self.getGlyphName = ttFont.getGlyphName # for use in get/set item functions, for access by GID
|
2003-08-22 20:02:25 +00:00
|
|
|
self.majorVersion, self.minorVersion, self.defaultVertOriginY, self.numVertOriginYMetrics = struct.unpack(">HHhH", data[:8])
|
2006-10-21 13:29:47 +00:00
|
|
|
assert (self.majorVersion <= 1), "Major version of VORG table is higher than I know how to handle"
|
2003-08-22 20:02:25 +00:00
|
|
|
data = data[8:]
|
2006-10-21 13:29:47 +00:00
|
|
|
vids = []
|
|
|
|
gids = []
|
|
|
|
pos = 0
|
2003-08-22 20:02:25 +00:00
|
|
|
for i in range(self.numVertOriginYMetrics):
|
2006-10-21 13:29:47 +00:00
|
|
|
gid, vOrigin = struct.unpack(">Hh", data[pos:pos+4])
|
|
|
|
pos += 4
|
|
|
|
gids.append(gid)
|
|
|
|
vids.append(vOrigin)
|
|
|
|
|
|
|
|
self.VOriginRecords = vOrig = {}
|
|
|
|
glyphOrder = ttFont.getGlyphOrder()
|
|
|
|
try:
|
2013-11-27 04:38:16 -05:00
|
|
|
names = map(operator.getitem, [glyphOrder]*self.numVertOriginYMetrics, gids)
|
2006-10-21 13:29:47 +00:00
|
|
|
except IndexError:
|
|
|
|
getGlyphName = self.getGlyphName
|
|
|
|
names = map(getGlyphName, gids )
|
|
|
|
|
2013-11-27 04:38:16 -05:00
|
|
|
list(map(operator.setitem, [vOrig]*self.numVertOriginYMetrics, names, vids))
|
2006-10-21 13:29:47 +00:00
|
|
|
|
2003-08-22 20:02:25 +00:00
|
|
|
|
|
|
|
def compile(self, ttFont):
|
2013-11-27 06:26:55 -05:00
|
|
|
vorgs = list(self.VOriginRecords.values())
|
|
|
|
names = list(self.VOriginRecords.keys())
|
2006-10-21 13:29:47 +00:00
|
|
|
nameMap = ttFont.getReverseGlyphMap()
|
|
|
|
lenRecords = len(vorgs)
|
|
|
|
try:
|
|
|
|
gids = map(operator.getitem, [nameMap]*lenRecords, names)
|
|
|
|
except KeyError:
|
2013-12-04 21:28:50 -05:00
|
|
|
nameMap = ttFont.getReverseGlyphMap(rebuild=True)
|
2006-10-21 13:29:47 +00:00
|
|
|
gids = map(operator.getitem, [nameMap]*lenRecords, names)
|
2013-11-27 04:38:16 -05:00
|
|
|
vOriginTable = list(zip(gids, vorgs))
|
2006-10-21 13:29:47 +00:00
|
|
|
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)
|
2013-11-27 21:17:35 -05:00
|
|
|
data = bytesjoin(dataList)
|
2003-08-22 20:02:25 +00:00
|
|
|
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)
|
|
|
|
|
2013-11-27 03:19:32 -05:00
|
|
|
def fromXML(self, name, attrs, content, ttFont):
|
2008-03-09 08:58:36 +00:00
|
|
|
if not hasattr(self, "VOriginRecords"):
|
|
|
|
self.VOriginRecords = {}
|
2006-10-21 13:29:47 +00:00
|
|
|
self.getGlyphName = ttFont.getGlyphName # for use in get/set item functions, for access by GID
|
2003-08-22 20:02:25 +00:00
|
|
|
if name == "VOriginRecord":
|
|
|
|
vOriginRec = VOriginRecord()
|
|
|
|
for element in content:
|
2013-11-27 23:37:57 -05:00
|
|
|
if isinstance(element, basestring):
|
2003-08-22 20:02:25 +00:00
|
|
|
continue
|
2013-11-27 03:19:32 -05:00
|
|
|
name, attrs, content = element
|
|
|
|
vOriginRec.fromXML(name, attrs, content, ttFont)
|
2003-08-22 20:02:25 +00:00
|
|
|
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"]))
|
2003-08-22 20:02:25 +00:00
|
|
|
|
2006-10-21 13:29:47 +00:00
|
|
|
|
|
|
|
def __getitem__(self, glyphSelector):
|
2013-11-27 05:17:37 -05:00
|
|
|
if isinstance(glyphSelector, int):
|
2006-10-21 13:29:47 +00:00
|
|
|
# its a gid, convert to glyph name
|
|
|
|
glyphSelector = self.getGlyphName(glyphSelector)
|
|
|
|
|
2013-11-27 02:33:03 -05:00
|
|
|
if glyphSelector not in self.VOriginRecords:
|
2003-08-22 20:02:25 +00:00
|
|
|
return self.defaultVertOriginY
|
|
|
|
|
2006-10-21 13:29:47 +00:00
|
|
|
return self.VOriginRecords[glyphSelector]
|
2003-08-22 20:02:25 +00:00
|
|
|
|
2006-10-21 13:29:47 +00:00
|
|
|
def __setitem__(self, glyphSelector, value):
|
2013-11-27 05:17:37 -05:00
|
|
|
if isinstance(glyphSelector, int):
|
2006-10-21 13:29:47 +00:00
|
|
|
# its a gid, convert to glyph name
|
|
|
|
glyphSelector = self.getGlyphName(glyphSelector)
|
2003-08-22 20:02:25 +00:00
|
|
|
|
2006-10-21 13:29:47 +00:00
|
|
|
if value != self.defaultVertOriginY:
|
|
|
|
self.VOriginRecords[glyphSelector] = value
|
2013-11-27 02:33:03 -05:00
|
|
|
elif glyphSelector in self.VOriginRecords:
|
2006-10-21 13:29:47 +00:00
|
|
|
del self.VOriginRecords[glyphSelector]
|
2003-08-22 20:02:25 +00:00
|
|
|
|
2014-05-14 13:51:10 -06:00
|
|
|
def __delitem__(self, glyphSelector):
|
|
|
|
del self.VOriginRecords[glyphSelector]
|
|
|
|
|
2013-11-28 14:26:58 -05:00
|
|
|
class VOriginRecord(object):
|
2003-08-22 20:02:25 +00:00
|
|
|
|
|
|
|
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()
|
|
|
|
|
2013-11-27 03:19:32 -05:00
|
|
|
def fromXML(self, name, attrs, content, ttFont):
|
2003-08-22 20:02:25 +00:00
|
|
|
value = attrs["value"]
|
|
|
|
if name == "glyphName":
|
|
|
|
setattr(self, name, value)
|
|
|
|
else:
|
2013-11-27 04:00:15 -05:00
|
|
|
setattr(self, name, safeEval(value))
|