• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1from fontTools.misc.py23 import bytechr, byteord, tobytes, tostr
2from fontTools.misc import sstruct
3from fontTools.misc.textTools import safeEval
4from . import DefaultTable
5
6SINGFormat = """
7		>	# big endian
8		tableVersionMajor:	H
9		tableVersionMinor: 	H
10		glyphletVersion:	H
11		permissions:		h
12		mainGID:			H
13		unitsPerEm:			H
14		vertAdvance:		h
15		vertOrigin:			h
16		uniqueName:			28s
17		METAMD5:			16s
18		nameLength:			1s
19"""
20# baseGlyphName is a byte string which follows the record above.
21
22
23class table_S_I_N_G_(DefaultTable.DefaultTable):
24
25	dependencies = []
26
27	def decompile(self, data, ttFont):
28		dummy, rest = sstruct.unpack2(SINGFormat, data, self)
29		self.uniqueName = self.decompileUniqueName(self.uniqueName)
30		self.nameLength = byteord(self.nameLength)
31		assert len(rest) == self.nameLength
32		self.baseGlyphName = tostr(rest)
33
34		rawMETAMD5 = self.METAMD5
35		self.METAMD5 = "[" + hex(byteord(self.METAMD5[0]))
36		for char in rawMETAMD5[1:]:
37			self.METAMD5 = self.METAMD5 + ", " + hex(byteord(char))
38		self.METAMD5 = self.METAMD5 + "]"
39
40	def decompileUniqueName(self, data):
41		name = ""
42		for char in data:
43			val = byteord(char)
44			if val == 0:
45				break
46			if (val > 31) or (val < 128):
47				name += chr(val)
48			else:
49				octString = oct(val)
50				if len(octString) > 3:
51					octString = octString[1:] # chop off that leading zero.
52				elif len(octString) < 3:
53					octString.zfill(3)
54				name += "\\" + octString
55		return name
56
57	def compile(self, ttFont):
58		d = self.__dict__.copy()
59		d["nameLength"] = bytechr(len(self.baseGlyphName))
60		d["uniqueName"] = self.compilecompileUniqueName(self.uniqueName, 28)
61		METAMD5List = eval(self.METAMD5)
62		d["METAMD5"] = b""
63		for val in METAMD5List:
64			d["METAMD5"] += bytechr(val)
65		assert (len(d["METAMD5"]) == 16), "Failed to pack 16 byte MD5 hash in SING table"
66		data = sstruct.pack(SINGFormat, d)
67		data = data + tobytes(self.baseGlyphName)
68		return data
69
70	def compilecompileUniqueName(self, name, length):
71		nameLen = len(name)
72		if length <= nameLen:
73			name = name[:length-1] + "\000"
74		else:
75			name += (nameLen - length) * "\000"
76		return name
77
78	def toXML(self, writer, ttFont):
79		writer.comment("Most of this table will be recalculated by the compiler")
80		writer.newline()
81		formatstring, names, fixes = sstruct.getformat(SINGFormat)
82		for name in names:
83			value = getattr(self, name)
84			writer.simpletag(name, value=value)
85			writer.newline()
86		writer.simpletag("baseGlyphName", value=self.baseGlyphName)
87		writer.newline()
88
89	def fromXML(self, name, attrs, content, ttFont):
90		value = attrs["value"]
91		if name in ["uniqueName", "METAMD5", "baseGlyphName"]:
92			setattr(self, name, value)
93		else:
94			setattr(self, name, safeEval(value))
95