• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1from fontTools.misc import sstruct
2from fontTools.misc.textTools import bytesjoin, safeEval, readHex
3from . import DefaultTable
4import sys
5import array
6
7GPKGFormat = """
8		>	# big endian
9		version:	H
10		flags:	H
11		numGMAPs:		H
12		numGlyplets:		H
13"""
14# psFontName is a byte string which follows the record above. This is zero padded
15# to the beginning of the records array. The recordsOffsst is 32 bit aligned.
16
17
18class table_G_P_K_G_(DefaultTable.DefaultTable):
19    def decompile(self, data, ttFont):
20        dummy, newData = sstruct.unpack2(GPKGFormat, data, self)
21
22        GMAPoffsets = array.array("I")
23        endPos = (self.numGMAPs + 1) * 4
24        GMAPoffsets.frombytes(newData[:endPos])
25        if sys.byteorder != "big":
26            GMAPoffsets.byteswap()
27        self.GMAPs = []
28        for i in range(self.numGMAPs):
29            start = GMAPoffsets[i]
30            end = GMAPoffsets[i + 1]
31            self.GMAPs.append(data[start:end])
32        pos = endPos
33        endPos = pos + (self.numGlyplets + 1) * 4
34        glyphletOffsets = array.array("I")
35        glyphletOffsets.frombytes(newData[pos:endPos])
36        if sys.byteorder != "big":
37            glyphletOffsets.byteswap()
38        self.glyphlets = []
39        for i in range(self.numGlyplets):
40            start = glyphletOffsets[i]
41            end = glyphletOffsets[i + 1]
42            self.glyphlets.append(data[start:end])
43
44    def compile(self, ttFont):
45        self.numGMAPs = len(self.GMAPs)
46        self.numGlyplets = len(self.glyphlets)
47        GMAPoffsets = [0] * (self.numGMAPs + 1)
48        glyphletOffsets = [0] * (self.numGlyplets + 1)
49
50        dataList = [sstruct.pack(GPKGFormat, self)]
51
52        pos = len(dataList[0]) + (self.numGMAPs + 1) * 4 + (self.numGlyplets + 1) * 4
53        GMAPoffsets[0] = pos
54        for i in range(1, self.numGMAPs + 1):
55            pos += len(self.GMAPs[i - 1])
56            GMAPoffsets[i] = pos
57        gmapArray = array.array("I", GMAPoffsets)
58        if sys.byteorder != "big":
59            gmapArray.byteswap()
60        dataList.append(gmapArray.tobytes())
61
62        glyphletOffsets[0] = pos
63        for i in range(1, self.numGlyplets + 1):
64            pos += len(self.glyphlets[i - 1])
65            glyphletOffsets[i] = pos
66        glyphletArray = array.array("I", glyphletOffsets)
67        if sys.byteorder != "big":
68            glyphletArray.byteswap()
69        dataList.append(glyphletArray.tobytes())
70        dataList += self.GMAPs
71        dataList += self.glyphlets
72        data = bytesjoin(dataList)
73        return data
74
75    def toXML(self, writer, ttFont):
76        writer.comment("Most of this table will be recalculated by the compiler")
77        writer.newline()
78        formatstring, names, fixes = sstruct.getformat(GPKGFormat)
79        for name in names:
80            value = getattr(self, name)
81            writer.simpletag(name, value=value)
82            writer.newline()
83
84        writer.begintag("GMAPs")
85        writer.newline()
86        for gmapData in self.GMAPs:
87            writer.begintag("hexdata")
88            writer.newline()
89            writer.dumphex(gmapData)
90            writer.endtag("hexdata")
91            writer.newline()
92        writer.endtag("GMAPs")
93        writer.newline()
94
95        writer.begintag("glyphlets")
96        writer.newline()
97        for glyphletData in self.glyphlets:
98            writer.begintag("hexdata")
99            writer.newline()
100            writer.dumphex(glyphletData)
101            writer.endtag("hexdata")
102            writer.newline()
103        writer.endtag("glyphlets")
104        writer.newline()
105
106    def fromXML(self, name, attrs, content, ttFont):
107        if name == "GMAPs":
108            if not hasattr(self, "GMAPs"):
109                self.GMAPs = []
110            for element in content:
111                if isinstance(element, str):
112                    continue
113                itemName, itemAttrs, itemContent = element
114                if itemName == "hexdata":
115                    self.GMAPs.append(readHex(itemContent))
116        elif name == "glyphlets":
117            if not hasattr(self, "glyphlets"):
118                self.glyphlets = []
119            for element in content:
120                if isinstance(element, str):
121                    continue
122                itemName, itemAttrs, itemContent = element
123                if itemName == "hexdata":
124                    self.glyphlets.append(readHex(itemContent))
125        else:
126            setattr(self, name, safeEval(attrs["value"]))
127