G_M_A_P_.py revision b774f9f684c5a0f91f5fa177c9a461968789123f
1from . import DefaultTable
2from fontTools.misc import sstruct
3from fontTools.misc.textTools import safeEval, num2binary, binary2num
4
5GMAPFormat = """
6		>	# big endian
7		tableVersionMajor:	H
8		tableVersionMinor: 	H
9		flags:	H
10		recordsCount:		H
11		recordsOffset:		H
12		fontNameLength:		H
13"""
14# psFontName is a byte string which follows the record above. This is zero padded
15# to the beginning of the records array. The recordsOffsst is 32 bit aligned.
16
17GMAPRecordFormat1 = """
18		>	# big endian
19		UV:			L
20		cid:		H
21		gid:		H
22		ggid:		H
23		name:		32s
24"""
25
26
27
28class GMAPRecord:
29	def __init__(self, uv = 0, cid = 0, gid = 0, ggid = 0, name = ""):
30		self.UV = uv
31		self.cid = cid
32		self.gid = gid
33		self.ggid = ggid
34		self.name = name
35
36	def toXML(self, writer, ttFont):
37		writer.begintag("GMAPRecord")
38		writer.newline()
39		writer.simpletag("UV", value=self.UV)
40		writer.newline()
41		writer.simpletag("cid", value=self.cid)
42		writer.newline()
43		writer.simpletag("gid", value=self.gid)
44		writer.newline()
45		writer.simpletag("glyphletGid", value=self.gid)
46		writer.newline()
47		writer.simpletag("GlyphletName", value=self.name)
48		writer.newline()
49		writer.endtag("GMAPRecord")
50		writer.newline()
51
52
53	def fromXML(self, name, attrs, content, ttFont):
54		value = attrs["value"]
55		if name == "GlyphletName":
56			self.name = value
57		else:
58			setattr(self, name, safeEval(value))
59
60
61	def compile(self, ttFont):
62		if 	self.UV == None:
63			self.UV = 0
64		nameLen =  len(self.name)
65		if nameLen < 32:
66			self.name = self.name + "\0"*(32 - nameLen)
67		data = sstruct.pack(GMAPRecordFormat1, self)
68		return data
69
70	def __repr__(self):
71		return "GMAPRecord[ UV: " + str(self.UV) + ", cid: " + str(self.cid) + ", gid: " + str(self.gid) + ", ggid: " + str(self.ggid) + ", Glyphlet Name: " + str(self.name) + " ]"
72
73
74class table_G_M_A_P_(DefaultTable.DefaultTable):
75
76	dependencies = []
77
78	def decompile(self, data, ttFont):
79		dummy, newData = sstruct.unpack2(GMAPFormat, data, self)
80		self.psFontName = newData[:self.fontNameLength]
81		assert (self.recordsOffset % 4) == 0, "GMAP error: recordsOffset is not 32 bit aligned."
82		newData = data[self.recordsOffset:]
83		self.gmapRecords = []
84		for i in range (self.recordsCount):
85			gmapRecord, newData = sstruct.unpack2(GMAPRecordFormat1, newData, GMAPRecord())
86			gmapRecord.name = gmapRecord.name.strip('\0')
87			self.gmapRecords.append(gmapRecord)
88
89
90	def compile(self, ttFont):
91		self.recordsCount = len(self.gmapRecords)
92		self.fontNameLength = len(self.psFontName)
93		self.recordsOffset = 4 *(((self.fontNameLength + 12)  + 3) /4)
94		data = sstruct.pack(GMAPFormat, self)
95		data = data + self.psFontName
96		data = data + "\0" * (self.recordsOffset - len(data))
97		for record in self.gmapRecords:
98			data = data + record.compile(ttFont)
99		return data
100
101
102	def toXML(self, writer, ttFont):
103		writer.comment("Most of this table will be recalculated by the compiler")
104		writer.newline()
105		formatstring, names, fixes = sstruct.getformat(GMAPFormat)
106		for name in names:
107			value = getattr(self, name)
108			writer.simpletag(name, value=value)
109			writer.newline()
110		writer.simpletag("PSFontName", value=self.psFontName)
111		writer.newline()
112		for gmapRecord in self.gmapRecords:
113			gmapRecord.toXML(writer, ttFont)
114
115	def fromXML(self, name, attrs, content, ttFont):
116		if name == "GMAPRecord":
117			if not hasattr(self, "gmapRecords"):
118				self.gmapRecords = []
119			gmapRecord = GMAPRecord()
120			self.gmapRecords.append(gmapRecord)
121			for element in content:
122				if isinstance(element, str):
123					continue
124				name, attrs, content = element
125				gmapRecord.fromXML(name, attrs, content, ttFont)
126		else:
127			value = attrs["value"]
128			if name == "PSFontName":
129				self.psFontName = value
130			else:
131				setattr(self, name, safeEval(value))
132