• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1from fontTools.misc import sstruct
2from fontTools.misc.textTools import safeEval
3from . import DefaultTable
4import array
5import sys
6
7
8Gloc_header = """
9    >        # big endian
10    version: 16.16F    # Table version
11    flags:        H    # bit 0: 1=long format, 0=short format
12                       # bit 1: 1=attribute names, 0=no names
13    numAttribs:   H    # NUmber of attributes
14"""
15
16
17class table_G__l_o_c(DefaultTable.DefaultTable):
18    """
19    Support Graphite Gloc tables
20    """
21
22    dependencies = ["Glat"]
23
24    def __init__(self, tag=None):
25        DefaultTable.DefaultTable.__init__(self, tag)
26        self.attribIds = None
27        self.numAttribs = 0
28
29    def decompile(self, data, ttFont):
30        _, data = sstruct.unpack2(Gloc_header, data, self)
31        flags = self.flags
32        del self.flags
33        self.locations = array.array("I" if flags & 1 else "H")
34        self.locations.frombytes(data[: len(data) - self.numAttribs * (flags & 2)])
35        if sys.byteorder != "big":
36            self.locations.byteswap()
37        self.attribIds = array.array("H")
38        if flags & 2:
39            self.attribIds.frombytes(data[-self.numAttribs * 2 :])
40            if sys.byteorder != "big":
41                self.attribIds.byteswap()
42
43    def compile(self, ttFont):
44        data = sstruct.pack(
45            Gloc_header,
46            dict(
47                version=1.0,
48                flags=(bool(self.attribIds) << 1) + (self.locations.typecode == "I"),
49                numAttribs=self.numAttribs,
50            ),
51        )
52        if sys.byteorder != "big":
53            self.locations.byteswap()
54        data += self.locations.tobytes()
55        if sys.byteorder != "big":
56            self.locations.byteswap()
57        if self.attribIds:
58            if sys.byteorder != "big":
59                self.attribIds.byteswap()
60            data += self.attribIds.tobytes()
61            if sys.byteorder != "big":
62                self.attribIds.byteswap()
63        return data
64
65    def set(self, locations):
66        long_format = max(locations) >= 65536
67        self.locations = array.array("I" if long_format else "H", locations)
68
69    def toXML(self, writer, ttFont):
70        writer.simpletag("attributes", number=self.numAttribs)
71        writer.newline()
72
73    def fromXML(self, name, attrs, content, ttFont):
74        if name == "attributes":
75            self.numAttribs = int(safeEval(attrs["number"]))
76
77    def __getitem__(self, index):
78        return self.locations[index]
79
80    def __len__(self):
81        return len(self.locations)
82
83    def __iter__(self):
84        return iter(self.locations)
85