blob: 8ffd2d6c5564d8a6b69033bcf686f2c2081731c8 [file] [log] [blame]
jvr9be387c2008-03-01 11:43:01 +00001import sys
jvr4cc00512006-10-21 13:27:25 +00002import DefaultTable
3import sstruct
4import array
jvr1b7d54f2008-03-04 15:25:27 +00005import numpy
jvr4cc00512006-10-21 13:27:25 +00006from types import StringType
7from fontTools.misc.textTools import safeEval, readHex
8from fontTools import ttLib
9
10GPKGFormat = """
11 > # big endian
12 version: H
13 flags: H
14 numGMAPs: H
15 numGlyplets: H
16"""
17# psFontName is a byte string which follows the record above. This is zero padded
18# to the beginning of the records array. The recordsOffsst is 32 bit aligned.
19
20
21class table_G_P_K_G_(DefaultTable.DefaultTable):
22
23 def decompile(self, data, ttFont):
24 dummy, newData = sstruct.unpack2(GPKGFormat, data, self)
25
Behdad Esfahbod4ffd4042013-08-16 13:02:23 -040026 GMAPoffsets = array.array("I")
jvr4cc00512006-10-21 13:27:25 +000027 endPos = (self.numGMAPs+1) * 4
28 GMAPoffsets.fromstring(newData[:endPos])
jvr9be387c2008-03-01 11:43:01 +000029 if sys.byteorder <> "big":
jvr4cc00512006-10-21 13:27:25 +000030 GMAPoffsets.byteswap()
31 self.GMAPs = []
32 for i in range(self.numGMAPs):
33 start = GMAPoffsets[i]
34 end = GMAPoffsets[i+1]
35 self.GMAPs.append(data[start:end])
36 pos = endPos
37 endPos = pos + (self.numGlyplets + 1)*4
Behdad Esfahbod4ffd4042013-08-16 13:02:23 -040038 glyphletOffsets = array.array("I")
jvr4cc00512006-10-21 13:27:25 +000039 glyphletOffsets.fromstring(newData[pos:endPos])
jvr9be387c2008-03-01 11:43:01 +000040 if sys.byteorder <> "big":
jvr4cc00512006-10-21 13:27:25 +000041 glyphletOffsets.byteswap()
42 self.glyphlets = []
43 for i in range(self.numGlyplets):
44 start = glyphletOffsets[i]
45 end = glyphletOffsets[i+1]
46 self.glyphlets.append(data[start:end])
47
48
49 def compile(self, ttFont):
50 self.numGMAPs = len(self.GMAPs)
51 self.numGlyplets = len(self.glyphlets)
52 GMAPoffsets = [0]*(self.numGMAPs + 1)
53 glyphletOffsets = [0]*(self.numGlyplets + 1)
54
55 dataList =[ sstruct.pack(GPKGFormat, self)]
56
57 pos = len(dataList[0]) + (self.numGMAPs + 1)*4 + (self.numGlyplets + 1)*4
58 GMAPoffsets[0] = pos
59 for i in range(1, self.numGMAPs +1):
60 pos += len(self.GMAPs[i-1])
61 GMAPoffsets[i] = pos
jvr1b7d54f2008-03-04 15:25:27 +000062 gmapArray = numpy.array(GMAPoffsets, numpy.uint32)
jvr9be387c2008-03-01 11:43:01 +000063 if sys.byteorder <> "big":
jvr1b7d54f2008-03-04 15:25:27 +000064 gmapArray = gmapArray.byteswap()
jvr4cc00512006-10-21 13:27:25 +000065 dataList.append(gmapArray.tostring())
66
67 glyphletOffsets[0] = pos
68 for i in range(1, self.numGlyplets +1):
69 pos += len(self.glyphlets[i-1])
70 glyphletOffsets[i] = pos
jvr1b7d54f2008-03-04 15:25:27 +000071 glyphletArray = numpy.array(glyphletOffsets, numpy.uint32)
jvr9be387c2008-03-01 11:43:01 +000072 if sys.byteorder <> "big":
jvr1b7d54f2008-03-04 15:25:27 +000073 glyphletArray = glyphletArray.byteswap()
jvr4cc00512006-10-21 13:27:25 +000074 dataList.append(glyphletArray.tostring())
75 dataList += self.GMAPs
76 dataList += self.glyphlets
77 data = "".join(dataList)
78 return data
79
80 def toXML(self, writer, ttFont):
81 writer.comment("Most of this table will be recalculated by the compiler")
82 writer.newline()
83 formatstring, names, fixes = sstruct.getformat(GPKGFormat)
84 for name in names:
85 value = getattr(self, name)
86 writer.simpletag(name, value=value)
87 writer.newline()
88
89 writer.begintag("GMAPs")
90 writer.newline()
91 for gmapData in self.GMAPs:
92 writer.begintag("hexdata")
93 writer.newline()
94 writer.dumphex(gmapData)
95 writer.endtag("hexdata")
96 writer.newline()
97 writer.endtag("GMAPs")
98 writer.newline()
99
100 writer.begintag("glyphlets")
101 writer.newline()
102 for glyphletData in self.glyphlets:
103 writer.begintag("hexdata")
104 writer.newline()
105 writer.dumphex(glyphletData)
106 writer.endtag("hexdata")
107 writer.newline()
108 writer.endtag("glyphlets")
109 writer.newline()
110
111 def fromXML(self, (name, attrs, content), ttFont):
112 if name == "GMAPs":
113 if not hasattr(self, "GMAPs"):
114 self.GMAPs = []
115 for element in content:
116 if isinstance(element, StringType):
117 continue
118 itemName, itemAttrs, itemContent = element
119 if itemName == "hexdata":
120 self.GMAPs.append(readHex(itemContent))
121 elif name == "glyphlets":
122 if not hasattr(self, "glyphlets"):
123 self.glyphlets = []
124 for element in content:
125 if isinstance(element, StringType):
126 continue
127 itemName, itemAttrs, itemContent = element
128 if itemName == "hexdata":
129 self.glyphlets.append(readHex(itemContent))
130 else:
131 value = attrs["value"]
132 try:
133 value = safeEval(value)
134 except OverflowError:
135 value = long(value)
136 setattr(self, name, value)