Coverage for /usr/lib/python3/dist-packages/fontTools/ttLib/tables/V_O_R_G_.py: 14%
111 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
1from fontTools.misc.textTools import bytesjoin, safeEval
2from . import DefaultTable
3import struct
6class table_V_O_R_G_(DefaultTable.DefaultTable):
8 """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.
12 ``ttFont['VORG'][<glyphName>] = <value>`` will set the vertical origin for any glyph.
13 """
15 def decompile(self, data, ttFont):
16 self.getGlyphName = (
17 ttFont.getGlyphName
18 ) # for use in get/set item functions, for access by GID
19 (
20 self.majorVersion,
21 self.minorVersion,
22 self.defaultVertOriginY,
23 self.numVertOriginYMetrics,
24 ) = struct.unpack(">HHhH", data[:8])
25 assert (
26 self.majorVersion <= 1
27 ), "Major version of VORG table is higher than I know how to handle"
28 data = data[8:]
29 vids = []
30 gids = []
31 pos = 0
32 for i in range(self.numVertOriginYMetrics):
33 gid, vOrigin = struct.unpack(">Hh", data[pos : pos + 4])
34 pos += 4
35 gids.append(gid)
36 vids.append(vOrigin)
38 self.VOriginRecords = vOrig = {}
39 glyphOrder = ttFont.getGlyphOrder()
40 try:
41 names = [glyphOrder[gid] for gid in gids]
42 except IndexError:
43 getGlyphName = self.getGlyphName
44 names = map(getGlyphName, gids)
46 for name, vid in zip(names, vids):
47 vOrig[name] = vid
49 def compile(self, ttFont):
50 vorgs = list(self.VOriginRecords.values())
51 names = list(self.VOriginRecords.keys())
52 nameMap = ttFont.getReverseGlyphMap()
53 try:
54 gids = [nameMap[name] for name in names]
55 except KeyError:
56 nameMap = ttFont.getReverseGlyphMap(rebuild=True)
57 gids = [nameMap[name] for name in names]
58 vOriginTable = list(zip(gids, vorgs))
59 self.numVertOriginYMetrics = len(vorgs)
60 vOriginTable.sort() # must be in ascending GID order
61 dataList = [struct.pack(">Hh", rec[0], rec[1]) for rec in vOriginTable]
62 header = struct.pack(
63 ">HHhH",
64 self.majorVersion,
65 self.minorVersion,
66 self.defaultVertOriginY,
67 self.numVertOriginYMetrics,
68 )
69 dataList.insert(0, header)
70 data = bytesjoin(dataList)
71 return data
73 def toXML(self, writer, ttFont):
74 writer.simpletag("majorVersion", value=self.majorVersion)
75 writer.newline()
76 writer.simpletag("minorVersion", value=self.minorVersion)
77 writer.newline()
78 writer.simpletag("defaultVertOriginY", value=self.defaultVertOriginY)
79 writer.newline()
80 writer.simpletag("numVertOriginYMetrics", value=self.numVertOriginYMetrics)
81 writer.newline()
82 vOriginTable = []
83 glyphNames = self.VOriginRecords.keys()
84 for glyphName in glyphNames:
85 try:
86 gid = ttFont.getGlyphID(glyphName)
87 except:
88 assert 0, (
89 "VORG table contains a glyph name not in ttFont.getGlyphNames(): "
90 + str(glyphName)
91 )
92 vOriginTable.append([gid, glyphName, self.VOriginRecords[glyphName]])
93 vOriginTable.sort()
94 for entry in vOriginTable:
95 vOriginRec = VOriginRecord(entry[1], entry[2])
96 vOriginRec.toXML(writer, ttFont)
98 def fromXML(self, name, attrs, content, ttFont):
99 if not hasattr(self, "VOriginRecords"):
100 self.VOriginRecords = {}
101 self.getGlyphName = (
102 ttFont.getGlyphName
103 ) # for use in get/set item functions, for access by GID
104 if name == "VOriginRecord":
105 vOriginRec = VOriginRecord()
106 for element in content:
107 if isinstance(element, str):
108 continue
109 name, attrs, content = element
110 vOriginRec.fromXML(name, attrs, content, ttFont)
111 self.VOriginRecords[vOriginRec.glyphName] = vOriginRec.vOrigin
112 elif "value" in attrs:
113 setattr(self, name, safeEval(attrs["value"]))
115 def __getitem__(self, glyphSelector):
116 if isinstance(glyphSelector, int):
117 # its a gid, convert to glyph name
118 glyphSelector = self.getGlyphName(glyphSelector)
120 if glyphSelector not in self.VOriginRecords:
121 return self.defaultVertOriginY
123 return self.VOriginRecords[glyphSelector]
125 def __setitem__(self, glyphSelector, value):
126 if isinstance(glyphSelector, int):
127 # its a gid, convert to glyph name
128 glyphSelector = self.getGlyphName(glyphSelector)
130 if value != self.defaultVertOriginY:
131 self.VOriginRecords[glyphSelector] = value
132 elif glyphSelector in self.VOriginRecords:
133 del self.VOriginRecords[glyphSelector]
135 def __delitem__(self, glyphSelector):
136 del self.VOriginRecords[glyphSelector]
139class VOriginRecord(object):
140 def __init__(self, name=None, vOrigin=None):
141 self.glyphName = name
142 self.vOrigin = vOrigin
144 def toXML(self, writer, ttFont):
145 writer.begintag("VOriginRecord")
146 writer.newline()
147 writer.simpletag("glyphName", value=self.glyphName)
148 writer.newline()
149 writer.simpletag("vOrigin", value=self.vOrigin)
150 writer.newline()
151 writer.endtag("VOriginRecord")
152 writer.newline()
154 def fromXML(self, name, attrs, content, ttFont):
155 value = attrs["value"]
156 if name == "glyphName":
157 setattr(self, name, value)
158 else:
159 setattr(self, name, safeEval(value))