11ae29591efbb29492ce05378909ccf4028d7c1eeBehdad Esfahbodfrom __future__ import print_function, division, absolute_import
230e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom fontTools.misc.py23 import *
38413c108d21e8cf0e9059bbfffde8d13f2616340Behdad Esfahbodfrom fontTools.misc import sstruct
47ed91eca1eaa96b79eae780778e89bb9ec44c1eeBehdad Esfahbodfrom fontTools.misc.textTools import safeEval
530e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom . import DefaultTable
64cc0051c087e7e9c294559a21540e296cfe9ef4ajvr
74cc0051c087e7e9c294559a21540e296cfe9ef4ajvrSINGFormat = """
84cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		>	# big endian
94cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		tableVersionMajor:	H
104cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		tableVersionMinor: 	H
114cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		glyphletVersion:	H
124cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		permissions:		h
134cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		mainGID:			H
144cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		unitsPerEm:			H
154cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		vertAdvance:		h
164cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		vertOrigin:			h
174cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		uniqueName:			28s
184cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		METAMD5:			16s
194cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		nameLength:			1s
204cc0051c087e7e9c294559a21540e296cfe9ef4ajvr"""
214cc0051c087e7e9c294559a21540e296cfe9ef4ajvr# baseGlyphName is a byte string which follows the record above.
224cc0051c087e7e9c294559a21540e296cfe9ef4ajvr
234cc0051c087e7e9c294559a21540e296cfe9ef4ajvr
244cc0051c087e7e9c294559a21540e296cfe9ef4ajvr
254cc0051c087e7e9c294559a21540e296cfe9ef4ajvrclass table_S_I_N_G_(DefaultTable.DefaultTable):
264cc0051c087e7e9c294559a21540e296cfe9ef4ajvr
274cc0051c087e7e9c294559a21540e296cfe9ef4ajvr	dependencies = []
284cc0051c087e7e9c294559a21540e296cfe9ef4ajvr
294cc0051c087e7e9c294559a21540e296cfe9ef4ajvr	def decompile(self, data, ttFont):
304cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		dummy, rest = sstruct.unpack2(SINGFormat, data, self)
314cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		self.uniqueName = self.decompileUniqueName(self.uniqueName)
32319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod		self.nameLength = byteord(self.nameLength)
334cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		assert len(rest) == self.nameLength
34fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod		self.baseGlyphName = tostr(rest)
354cc0051c087e7e9c294559a21540e296cfe9ef4ajvr
364cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		rawMETAMD5 = self.METAMD5
37319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod		self.METAMD5 = "[" + hex(byteord(self.METAMD5[0]))
384cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		for char in rawMETAMD5[1:]:
39319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod			self.METAMD5 = self.METAMD5 + ", " + hex(byteord(char))
404cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		self.METAMD5 = self.METAMD5 + "]"
414cc0051c087e7e9c294559a21540e296cfe9ef4ajvr
424cc0051c087e7e9c294559a21540e296cfe9ef4ajvr	def decompileUniqueName(self, data):
434cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		name = ""
444cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		for char in data:
45319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod			val = byteord(char)
464cc0051c087e7e9c294559a21540e296cfe9ef4ajvr			if val == 0:
474cc0051c087e7e9c294559a21540e296cfe9ef4ajvr				break
484cc0051c087e7e9c294559a21540e296cfe9ef4ajvr			if (val > 31) or (val < 128):
49fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod				name += chr(val)
504cc0051c087e7e9c294559a21540e296cfe9ef4ajvr			else:
514cc0051c087e7e9c294559a21540e296cfe9ef4ajvr				octString = oct(val)
524cc0051c087e7e9c294559a21540e296cfe9ef4ajvr				if len(octString) > 3:
534cc0051c087e7e9c294559a21540e296cfe9ef4ajvr					octString = octString[1:] # chop off that leading zero.
544cc0051c087e7e9c294559a21540e296cfe9ef4ajvr				elif len(octString) < 3:
554cc0051c087e7e9c294559a21540e296cfe9ef4ajvr					octString.zfill(3)
56fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod				name += "\\" + octString
574cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		return name
584cc0051c087e7e9c294559a21540e296cfe9ef4ajvr
594cc0051c087e7e9c294559a21540e296cfe9ef4ajvr
604cc0051c087e7e9c294559a21540e296cfe9ef4ajvr	def compile(self, ttFont):
61fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod		d = self.__dict__.copy()
62fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod		d["nameLength"] = bytechr(len(self.baseGlyphName))
63fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod		d["uniqueName"] = self.compilecompileUniqueName(self.uniqueName, 28)
644cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		METAMD5List = eval(self.METAMD5)
65fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod		d["METAMD5"] = b""
664cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		for val in METAMD5List:
67fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod			d["METAMD5"] += bytechr(val)
68fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod		assert (len(d["METAMD5"]) == 16), "Failed to pack 16 byte MD5 hash in SING table"
69fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod		data = sstruct.pack(SINGFormat, d)
70fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod		data = data + tobytes(self.baseGlyphName)
714cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		return data
724cc0051c087e7e9c294559a21540e296cfe9ef4ajvr
734cc0051c087e7e9c294559a21540e296cfe9ef4ajvr	def compilecompileUniqueName(self, name, length):
744cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		nameLen = len(name)
754cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		if length <= nameLen:
76fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod			name = name[:length-1] + "\000"
774cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		else:
78fd68c9d25143d12a2e004c10b2be4ef68cfa0435Behdad Esfahbod			name += (nameLen - length) * "\000"
794cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		return name
804cc0051c087e7e9c294559a21540e296cfe9ef4ajvr
814cc0051c087e7e9c294559a21540e296cfe9ef4ajvr
824cc0051c087e7e9c294559a21540e296cfe9ef4ajvr	def toXML(self, writer, ttFont):
834cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		writer.comment("Most of this table will be recalculated by the compiler")
844cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		writer.newline()
854cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		formatstring, names, fixes = sstruct.getformat(SINGFormat)
864cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		for name in names:
874cc0051c087e7e9c294559a21540e296cfe9ef4ajvr			value = getattr(self, name)
884cc0051c087e7e9c294559a21540e296cfe9ef4ajvr			writer.simpletag(name, value=value)
894cc0051c087e7e9c294559a21540e296cfe9ef4ajvr			writer.newline()
904cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		writer.simpletag("baseGlyphName", value=self.baseGlyphName)
914cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		writer.newline()
924cc0051c087e7e9c294559a21540e296cfe9ef4ajvr
933a9fd301808f5a8991ca9ac44028d1ecb22d307fBehdad Esfahbod	def fromXML(self, name, attrs, content, ttFont):
944cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		value = attrs["value"]
954cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		if name in ["uniqueName", "METAMD5", "baseGlyphName"]:
964cc0051c087e7e9c294559a21540e296cfe9ef4ajvr			setattr(self, name, value)
974cc0051c087e7e9c294559a21540e296cfe9ef4ajvr		else:
987cc6d271ac955782d730161b27e728001fb5f347Behdad Esfahbod			setattr(self, name, safeEval(value))
99