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