• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1from fontTools.misc.py23 import bytesjoin
2from fontTools.misc.textTools import safeEval
3from . import DefaultTable
4import struct
5
6
7class table_V_O_R_G_(DefaultTable.DefaultTable):
8
9	""" This table is structured so that you can treat it like a dictionary keyed by glyph name.
10	ttFont['VORG'][<glyphName>] will return the vertical origin for any glyph
11	ttFont['VORG'][<glyphName>] = <value> will set the vertical origin for any glyph.
12	"""
13
14	def decompile(self, data, ttFont):
15		self.getGlyphName = ttFont.getGlyphName # for use in get/set item functions, for access by GID
16		self.majorVersion, self.minorVersion, self.defaultVertOriginY, self.numVertOriginYMetrics = struct.unpack(">HHhH", data[:8])
17		assert (self.majorVersion <= 1), "Major version of VORG table is higher than I know how to handle"
18		data = data[8:]
19		vids = []
20		gids = []
21		pos = 0
22		for i in range(self.numVertOriginYMetrics):
23			gid, vOrigin = struct.unpack(">Hh", data[pos:pos+4])
24			pos += 4
25			gids.append(gid)
26			vids.append(vOrigin)
27
28		self.VOriginRecords = vOrig = {}
29		glyphOrder = ttFont.getGlyphOrder()
30		try:
31			names = [glyphOrder[gid] for gid in gids]
32		except IndexError:
33			getGlyphName = self.getGlyphName
34			names = map(getGlyphName, gids)
35
36		for name, vid in zip(names, vids):
37			vOrig[name] = vid
38
39	def compile(self, ttFont):
40		vorgs = list(self.VOriginRecords.values())
41		names = list(self.VOriginRecords.keys())
42		nameMap = ttFont.getReverseGlyphMap()
43		try:
44			gids = [nameMap[name] for name in names]
45		except KeyError:
46			nameMap = ttFont.getReverseGlyphMap(rebuild=True)
47			gids = [nameMap[name] for name in names]
48		vOriginTable = list(zip(gids, vorgs))
49		self.numVertOriginYMetrics = len(vorgs)
50		vOriginTable.sort() # must be in ascending GID order
51		dataList = [struct.pack(">Hh", rec[0], rec[1]) for rec in vOriginTable]
52		header = struct.pack(">HHhH", self.majorVersion, self.minorVersion, self.defaultVertOriginY, self.numVertOriginYMetrics)
53		dataList.insert(0, header)
54		data = bytesjoin(dataList)
55		return data
56
57	def toXML(self, writer, ttFont):
58		writer.simpletag("majorVersion", value=self.majorVersion)
59		writer.newline()
60		writer.simpletag("minorVersion", value=self.minorVersion)
61		writer.newline()
62		writer.simpletag("defaultVertOriginY", value=self.defaultVertOriginY)
63		writer.newline()
64		writer.simpletag("numVertOriginYMetrics", value=self.numVertOriginYMetrics)
65		writer.newline()
66		vOriginTable = []
67		glyphNames = self.VOriginRecords.keys()
68		for glyphName in glyphNames:
69			try:
70				gid = ttFont.getGlyphID(glyphName)
71			except:
72				assert 0, "VORG table contains a glyph name not in ttFont.getGlyphNames(): " + str(glyphName)
73			vOriginTable.append([gid, glyphName, self.VOriginRecords[glyphName]])
74		vOriginTable.sort()
75		for entry in vOriginTable:
76			vOriginRec = VOriginRecord(entry[1], entry[2])
77			vOriginRec.toXML(writer, ttFont)
78
79	def fromXML(self, name, attrs, content, ttFont):
80		if not hasattr(self, "VOriginRecords"):
81			self.VOriginRecords = {}
82		self.getGlyphName = ttFont.getGlyphName # for use in get/set item functions, for access by GID
83		if name == "VOriginRecord":
84			vOriginRec = VOriginRecord()
85			for element in content:
86				if isinstance(element, str):
87					continue
88				name, attrs, content = element
89				vOriginRec.fromXML(name, attrs, content, ttFont)
90			self.VOriginRecords[vOriginRec.glyphName] = vOriginRec.vOrigin
91		elif "value" in attrs:
92			setattr(self, name, safeEval(attrs["value"]))
93
94	def __getitem__(self, glyphSelector):
95		if isinstance(glyphSelector, int):
96			# its a gid, convert to glyph name
97			glyphSelector = self.getGlyphName(glyphSelector)
98
99		if glyphSelector not in self.VOriginRecords:
100			return self.defaultVertOriginY
101
102		return self.VOriginRecords[glyphSelector]
103
104	def __setitem__(self, glyphSelector, value):
105		if isinstance(glyphSelector, int):
106			# its a gid, convert to glyph name
107			glyphSelector = self.getGlyphName(glyphSelector)
108
109		if  value != self.defaultVertOriginY:
110			self.VOriginRecords[glyphSelector] = value
111		elif glyphSelector in self.VOriginRecords:
112			del self.VOriginRecords[glyphSelector]
113
114	def __delitem__(self, glyphSelector):
115		del self.VOriginRecords[glyphSelector]
116
117class VOriginRecord(object):
118
119	def __init__(self, name=None, vOrigin=None):
120		self.glyphName = name
121		self.vOrigin = vOrigin
122
123	def toXML(self, writer, ttFont):
124		writer.begintag("VOriginRecord")
125		writer.newline()
126		writer.simpletag("glyphName", value=self.glyphName)
127		writer.newline()
128		writer.simpletag("vOrigin", value=self.vOrigin)
129		writer.newline()
130		writer.endtag("VOriginRecord")
131		writer.newline()
132
133	def fromXML(self, name, attrs, content, ttFont):
134		value = attrs["value"]
135		if name == "glyphName":
136			setattr(self, name, value)
137		else:
138			setattr(self, name, safeEval(value))
139