1from __future__ import print_function, division, absolute_import
2from fontTools.misc.py23 import *
3from fontTools.misc import sstruct
4from fontTools.misc.textTools import safeEval, readHex
5from . import DefaultTable
6import sys
7import array
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("I")
26		endPos = (self.numGMAPs+1) * 4
27		GMAPoffsets.fromstring(newData[:endPos])
28		if sys.byteorder != "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("I")
38		glyphletOffsets.fromstring(newData[pos:endPos])
39		if sys.byteorder != "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 = array.array("I", GMAPoffsets)
62		if sys.byteorder != "big":
63			gmapArray.byteswap()
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 = array.array("I", glyphletOffsets)
71		if sys.byteorder != "big":
72			glyphletArray.byteswap()
73		dataList.append(glyphletArray.tostring())
74		dataList += self.GMAPs
75		dataList += self.glyphlets
76		data = bytesjoin(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, basestring):
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, basestring):
125					continue
126				itemName, itemAttrs, itemContent = element
127				if itemName == "hexdata":
128					self.glyphlets.append(readHex(itemContent))
129		else:
130			setattr(self, name, safeEval(value))
131