blob: 42214bfa2a329345810c105dae3d752bd7ff805d [file] [log] [blame]
jvr4cc00512006-10-21 13:27:25 +00001import DefaultTable
2import sstruct
3import array
4import Numeric
5from 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
25 GMAPoffsets = array.array("L")
26 endPos = (self.numGMAPs+1) * 4
27 GMAPoffsets.fromstring(newData[:endPos])
28 if ttLib.endian <> "big":
29 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
37 glyphletOffsets = array.array("L")
38 glyphletOffsets.fromstring(newData[pos:endPos])
39 if ttLib.endian <> "big":
40 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
61 gmapArray = Numeric.array(GMAPoffsets, Numeric.UInt32)
62 if ttLib.endian <> "big":
63 gmapArray = gmapArray.byteswapped()
64 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
70 glyphletArray = Numeric.array(glyphletOffsets, Numeric.UInt32)
71 if ttLib.endian <> "big":
72 glyphletArray = glyphletArray.byteswapped()
73 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)