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