1294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekfrom __future__ import print_function, division, absolute_import
2294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekfrom fontTools.misc.py23 import *
3294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekfrom . import DefaultTable
4294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
5294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekclass table_T_S_I__1(DefaultTable.DefaultTable):
6294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
7294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek	extras = {0xfffa: "ppgm", 0xfffb: "cvt", 0xfffc: "reserved", 0xfffd: "fpgm"}
8294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
9294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek	indextable = "TSI0"
10294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
11294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek	def decompile(self, data, ttFont):
12294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek		indextable = ttFont[self.indextable]
13294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek		self.glyphPrograms = {}
14d4aeb8050a1d0fe47c53a73361c8b0b8ac310f46Ted Kremenek		for i in range(len(indextable.indices)):
15294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek			glyphID, textLength, textOffset = indextable.indices[i]
16294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek			if textLength == 0x8000:
17740d490593e0de8732a697c9f77b90ddd463863bJordan Rose				# Ugh. Hi Beat!
18294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek				textLength = indextable.indices[i+1][1]
194a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer			if textLength > 0x8000:
204a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer				pass  # XXX Hmmm.
21294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek			text = data[textOffset:textOffset+textLength]
22294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek			assert len(text) == textLength
23294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek			if text:
24294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek				self.glyphPrograms[ttFont.getGlyphName(glyphID)] = text
25fdaa33818cf9bad8d092136e73bd2e489cb821baJordan Rose
26fdaa33818cf9bad8d092136e73bd2e489cb821baJordan Rose		self.extraPrograms = {}
27fdaa33818cf9bad8d092136e73bd2e489cb821baJordan Rose		for i in range(len(indextable.extra_indices)):
28fdaa33818cf9bad8d092136e73bd2e489cb821baJordan Rose			extraCode, textLength, textOffset = indextable.extra_indices[i]
29fdaa33818cf9bad8d092136e73bd2e489cb821baJordan Rose			if textLength == 0x8000:
30fdaa33818cf9bad8d092136e73bd2e489cb821baJordan Rose				if self.extras[extraCode] == "fpgm":	# this is the last one
31fdaa33818cf9bad8d092136e73bd2e489cb821baJordan Rose					textLength = len(data) - textOffset
32fdaa33818cf9bad8d092136e73bd2e489cb821baJordan Rose				else:
33fdaa33818cf9bad8d092136e73bd2e489cb821baJordan Rose					textLength = indextable.extra_indices[i+1][1]
34fdaa33818cf9bad8d092136e73bd2e489cb821baJordan Rose			text = data[textOffset:textOffset+textLength]
35fdaa33818cf9bad8d092136e73bd2e489cb821baJordan Rose			assert len(text) == textLength
36fdaa33818cf9bad8d092136e73bd2e489cb821baJordan Rose			if text:
37fdaa33818cf9bad8d092136e73bd2e489cb821baJordan Rose				self.extraPrograms[self.extras[extraCode]] = text
38fdaa33818cf9bad8d092136e73bd2e489cb821baJordan Rose
39fdaa33818cf9bad8d092136e73bd2e489cb821baJordan Rose	def compile(self, ttFont):
40fdaa33818cf9bad8d092136e73bd2e489cb821baJordan Rose		if not hasattr(self, "glyphPrograms"):
41fdaa33818cf9bad8d092136e73bd2e489cb821baJordan Rose			self.glyphPrograms = {}
423070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek			self.extraPrograms = {}
433070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek		data = b''
440849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek		indextable = ttFont[self.indextable]
450849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek		glyphNames = ttFont.getGlyphOrder()
463070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek
473070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek		indices = []
483070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek		for i in range(len(glyphNames)):
493070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek			if len(data) % 2:
503070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek				data = data + b"\015"  # align on 2-byte boundaries, fill with return chars. Yum.
513070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek			name = glyphNames[i]
523070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek			if name in self.glyphPrograms:
533070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek				text = self.glyphPrograms[name]
543070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek			else:
553070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek				text = b""
560849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek			textLength = len(text)
573070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek			if textLength >= 0x8000:
583070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek				textLength = 0x8000  # XXX ???
593070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek			indices.append((i, textLength, len(data)))
600849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek			data = data + text
618bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek
6210f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek		extra_indices = []
633070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek		codes = sorted(self.extras.items())
643070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek		for i in range(len(codes)):
653070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek			if len(data) % 2:
663070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek				data = data + b"\015"  # align on 2-byte boundaries, fill with return chars.
673070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek			code, name = codes[i]
683070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek			if name in self.extraPrograms:
693070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek				text = self.extraPrograms[name]
70294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek			else:
71294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek				text = b""
720b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks			textLength = len(text)
730b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks			if textLength >= 0x8000:
740b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks				textLength = 0x8000  # XXX ???
750b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks			extra_indices.append((code, textLength, len(data)))
760b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks			data = data + text
770b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks		indextable.set(indices, extra_indices)
780b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks		return data
790b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks
80256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek	def toXML(self, writer, ttFont):
81256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek		names = sorted(self.glyphPrograms.keys())
820b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks		writer.newline()
830b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks		for name in names:
84256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek			text = self.glyphPrograms[name]
85256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek			if not text:
86256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek				continue
870b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks			writer.begintag("glyphProgram", name=name)
880b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks			writer.newline()
890b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks			writer.write_noindent(text.replace("\r", "\n"))
900b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks			writer.newline()
91256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek			writer.endtag("glyphProgram")
920b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks			writer.newline()
930b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks			writer.newline()
940b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks		extra_names = sorted(self.extraPrograms.keys())
950b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks		for name in extra_names:
960b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks			text = self.extraPrograms[name]
970b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks			if not text:
980b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks				continue
990b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks			writer.begintag("extraProgram", name=name)
1000b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks			writer.newline()
1010b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks			writer.write_noindent(text.replace("\r", "\n"))
1020b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks			writer.newline()
1030b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks			writer.endtag("extraProgram")
1040b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks			writer.newline()
105256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek			writer.newline()
106256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek
107256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek	def fromXML(self, name, attrs, content, ttFont):
1080b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks		if not hasattr(self, "glyphPrograms"):
109256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek			self.glyphPrograms = {}
110256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek			self.extraPrograms = {}
1110b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks		lines = strjoin(content).replace("\r", "\n").split("\n")
1120b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks		text = '\r'.join(lines[1:-1])
1130b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks		if name == "glyphProgram":
1140b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks			self.glyphPrograms[attrs["name"]] = text
1150b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks		elif name == "extraProgram":
1160b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks			self.extraPrograms[attrs["name"]] = text
1170b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks
1180b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks