Some non-official OT tables from rrboerts. He wrote:

There are also some new files, for SING glyphlet support, that you
may or may not want to add, because they are not in the OpenType spec.

M_E_T_A_.py # SING glyphlet meta data table. see
'http://partners.adobe.com/public/developer/opentype/gdk/topic.html"
S_I_N_G_.py # SING glyphlet basic info. See same web site as for META
data table.

G_M_A_P_.py # Summary of sing glyphlet info that has been stuck into
a parent font. Not documented anywhere yet.
G_P_K_G_.py # Opaque wrapper for SING glyphlet info; travels with
application document. Is also stuck into augmented parent font. Not
documented anywhere yet


git-svn-id: svn://svn.code.sf.net/p/fonttools/code/trunk@507 4cde692c-a291-49d1-8350-778aa11640f8
diff --git a/Lib/fontTools/ttLib/tables/G_P_K_G_.py b/Lib/fontTools/ttLib/tables/G_P_K_G_.py
new file mode 100644
index 0000000..42214bf
--- /dev/null
+++ b/Lib/fontTools/ttLib/tables/G_P_K_G_.py
@@ -0,0 +1,135 @@
+import DefaultTable
+import sstruct
+import array
+import Numeric
+from types import StringType
+from fontTools.misc.textTools import safeEval, readHex
+from fontTools import ttLib
+
+GPKGFormat = """
+		>	# big endian
+		version:	H
+		flags:	H
+		numGMAPs:		H
+		numGlyplets:		H
+"""
+# psFontName is a byte string which follows the record above. This is zero padded 
+# to the beginning of the records array. The recordsOffsst is 32 bit aligned.
+
+
+class table_G_P_K_G_(DefaultTable.DefaultTable):
+	
+	def decompile(self, data, ttFont):
+		dummy, newData = sstruct.unpack2(GPKGFormat, data, self)
+
+		GMAPoffsets = array.array("L")
+		endPos = (self.numGMAPs+1) * 4
+		GMAPoffsets.fromstring(newData[:endPos])
+		if ttLib.endian <> "big":
+			GMAPoffsets.byteswap()
+		self.GMAPs = []
+		for i in range(self.numGMAPs):
+			start = GMAPoffsets[i]
+			end = GMAPoffsets[i+1]
+			self.GMAPs.append(data[start:end])
+		pos = endPos
+		endPos = pos + (self.numGlyplets + 1)*4
+		glyphletOffsets = array.array("L")
+		glyphletOffsets.fromstring(newData[pos:endPos])
+		if ttLib.endian <> "big":
+			glyphletOffsets.byteswap()
+		self.glyphlets = []
+		for i in range(self.numGlyplets):
+			start = glyphletOffsets[i]
+			end = glyphletOffsets[i+1]
+			self.glyphlets.append(data[start:end])
+
+
+	def compile(self, ttFont):
+		self.numGMAPs = len(self.GMAPs)
+		self.numGlyplets = len(self.glyphlets)
+		GMAPoffsets = [0]*(self.numGMAPs + 1)
+		glyphletOffsets = [0]*(self.numGlyplets + 1)
+
+		dataList =[ sstruct.pack(GPKGFormat, self)]
+
+		pos = len(dataList[0]) + (self.numGMAPs + 1)*4 + (self.numGlyplets + 1)*4
+		GMAPoffsets[0] = pos
+		for i in range(1, self.numGMAPs +1):
+			pos += len(self.GMAPs[i-1])
+			GMAPoffsets[i] = pos
+		gmapArray = Numeric.array(GMAPoffsets, Numeric.UInt32)
+		if ttLib.endian <> "big":
+			gmapArray = gmapArray.byteswapped()
+		dataList.append(gmapArray.tostring())
+
+		glyphletOffsets[0] = pos
+		for i in range(1, self.numGlyplets +1):
+			pos += len(self.glyphlets[i-1])
+			glyphletOffsets[i] = pos
+		glyphletArray = Numeric.array(glyphletOffsets, Numeric.UInt32)
+		if ttLib.endian <> "big":
+			glyphletArray = glyphletArray.byteswapped()
+		dataList.append(glyphletArray.tostring())
+		dataList += self.GMAPs
+		dataList += self.glyphlets
+		data = "".join(dataList)
+		return data
+	
+	def toXML(self, writer, ttFont):
+		writer.comment("Most of this table will be recalculated by the compiler")
+		writer.newline()
+		formatstring, names, fixes = sstruct.getformat(GPKGFormat)
+		for name in names:
+			value = getattr(self, name)
+			writer.simpletag(name, value=value)
+			writer.newline()
+
+		writer.begintag("GMAPs")
+		writer.newline()
+		for gmapData in self.GMAPs:
+			writer.begintag("hexdata")
+			writer.newline()
+			writer.dumphex(gmapData)
+			writer.endtag("hexdata")
+			writer.newline()
+		writer.endtag("GMAPs")
+		writer.newline()
+
+		writer.begintag("glyphlets")
+		writer.newline()
+		for glyphletData in self.glyphlets:
+			writer.begintag("hexdata")
+			writer.newline()
+			writer.dumphex(glyphletData)
+			writer.endtag("hexdata")
+			writer.newline()
+		writer.endtag("glyphlets")
+		writer.newline()
+
+	def fromXML(self, (name, attrs, content), ttFont):
+		if name == "GMAPs":
+			if not hasattr(self, "GMAPs"):
+				self.GMAPs = []
+			for element in content:
+				if isinstance(element, StringType):
+					continue
+				itemName, itemAttrs, itemContent = element
+				if itemName == "hexdata":
+					self.GMAPs.append(readHex(itemContent))
+		elif name == "glyphlets":
+			if not hasattr(self, "glyphlets"):
+				self.glyphlets = []
+			for element in content:
+				if isinstance(element, StringType):
+					continue
+				itemName, itemAttrs, itemContent = element
+				if itemName == "hexdata":
+					self.glyphlets.append(readHex(itemContent))
+		else:	
+			value = attrs["value"]
+			try:
+				value = safeEval(value)
+			except OverflowError:
+				value = long(value)
+			setattr(self, name, value)