aboutsummaryrefslogtreecommitdiff
path: root/Lib/fontTools/ttLib/tables/V_O_R_G_.py
blob: b08737b224bc11b4bf56f7e8b41e901c861f5f69 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
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))