1from __future__ import print_function, division, absolute_import
2from fontTools.misc.py23 import *
3from fontTools.misc import sstruct
4from fontTools.misc.textTools import safeEval
5from . import DefaultTable
6import array
7import sys
8
9
10Gloc_header = '''
11    >        # big endian
12    version: 16.16F    # Table version
13    flags:        H    # bit 0: 1=long format, 0=short format
14                       # bit 1: 1=attribute names, 0=no names
15    numAttribs:   H    # NUmber of attributes
16'''
17
18class table_G__l_o_c(DefaultTable.DefaultTable):
19    """
20    Support Graphite Gloc tables
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.fromstring(data[:len(data) - self.numAttribs * (flags & 2)])
35        if sys.byteorder != "big": self.locations.byteswap()
36        self.attribIds = array.array('H')
37        if flags & 2:
38            self.attribIds.fromstring(data[-self.numAttribs * 2:])
39            if sys.byteorder != "big": self.attribIds.byteswap()
40
41    def compile(self, ttFont):
42        data = sstruct.pack(Gloc_header, dict(version=1.0,
43                flags=(bool(self.attribIds) << 1) + (self.locations.typecode == 'I'),
44                numAttribs=self.numAttribs))
45        if sys.byteorder != "big": self.locations.byteswap()
46        data += self.locations.tostring()
47        if sys.byteorder != "big": self.locations.byteswap()
48        if self.attribIds:
49            if sys.byteorder != "big": self.attribIds.byteswap()
50            data += self.attribIds.tostring()
51            if sys.byteorder != "big": self.attribIds.byteswap()
52        return data
53
54    def set(self, locations):
55        long_format = max(locations) >= 65536
56        self.locations = array.array('I' if long_format else 'H', locations)
57
58    def toXML(self, writer, ttFont):
59        writer.simpletag("attributes", number=self.numAttribs)
60        writer.newline()
61
62    def fromXML(self, name, attrs, content, ttFont):
63        if name == 'attributes':
64            self.numAttribs = int(safeEval(attrs['number']))
65
66    def __getitem__(self, index):
67        return self.locations[index]
68
69    def __len__(self):
70        return len(self.locations)
71
72    def __iter__(self):
73        return iter(self.locations)
74