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