1from __future__ import print_function, division, absolute_import
2from fontTools.misc.py23 import *
3from . import DefaultTable
4
5class table_T_S_I__1(DefaultTable.DefaultTable):
6
7	extras = {0xfffa: "ppgm", 0xfffb: "cvt", 0xfffc: "reserved", 0xfffd: "fpgm"}
8
9	indextable = "TSI0"
10
11	def decompile(self, data, ttFont):
12		indextable = ttFont[self.indextable]
13		self.glyphPrograms = {}
14		for i in range(len(indextable.indices)):
15			glyphID, textLength, textOffset = indextable.indices[i]
16			if textLength == 0x8000:
17				# Ugh. Hi Beat!
18				textLength = indextable.indices[i+1][1]
19			if textLength > 0x8000:
20				pass  # XXX Hmmm.
21			text = data[textOffset:textOffset+textLength]
22			assert len(text) == textLength
23			if text:
24				self.glyphPrograms[ttFont.getGlyphName(glyphID)] = text
25
26		self.extraPrograms = {}
27		for i in range(len(indextable.extra_indices)):
28			extraCode, textLength, textOffset = indextable.extra_indices[i]
29			if textLength == 0x8000:
30				if self.extras[extraCode] == "fpgm":	# this is the last one
31					textLength = len(data) - textOffset
32				else:
33					textLength = indextable.extra_indices[i+1][1]
34			text = data[textOffset:textOffset+textLength]
35			assert len(text) == textLength
36			if text:
37				self.extraPrograms[self.extras[extraCode]] = text
38
39	def compile(self, ttFont):
40		if not hasattr(self, "glyphPrograms"):
41			self.glyphPrograms = {}
42			self.extraPrograms = {}
43		data = b''
44		indextable = ttFont[self.indextable]
45		glyphNames = ttFont.getGlyphOrder()
46
47		indices = []
48		for i in range(len(glyphNames)):
49			if len(data) % 2:
50				data = data + b"\015"  # align on 2-byte boundaries, fill with return chars. Yum.
51			name = glyphNames[i]
52			if name in self.glyphPrograms:
53				text = self.glyphPrograms[name]
54			else:
55				text = b""
56			textLength = len(text)
57			if textLength >= 0x8000:
58				textLength = 0x8000  # XXX ???
59			indices.append((i, textLength, len(data)))
60			data = data + text
61
62		extra_indices = []
63		codes = sorted(self.extras.items())
64		for i in range(len(codes)):
65			if len(data) % 2:
66				data = data + b"\015"  # align on 2-byte boundaries, fill with return chars.
67			code, name = codes[i]
68			if name in self.extraPrograms:
69				text = self.extraPrograms[name]
70			else:
71				text = b""
72			textLength = len(text)
73			if textLength >= 0x8000:
74				textLength = 0x8000  # XXX ???
75			extra_indices.append((code, textLength, len(data)))
76			data = data + text
77		indextable.set(indices, extra_indices)
78		return data
79
80	def toXML(self, writer, ttFont):
81		names = sorted(self.glyphPrograms.keys())
82		writer.newline()
83		for name in names:
84			text = self.glyphPrograms[name]
85			if not text:
86				continue
87			writer.begintag("glyphProgram", name=name)
88			writer.newline()
89			writer.write_noindent(text.replace("\r", "\n"))
90			writer.newline()
91			writer.endtag("glyphProgram")
92			writer.newline()
93			writer.newline()
94		extra_names = sorted(self.extraPrograms.keys())
95		for name in extra_names:
96			text = self.extraPrograms[name]
97			if not text:
98				continue
99			writer.begintag("extraProgram", name=name)
100			writer.newline()
101			writer.write_noindent(text.replace("\r", "\n"))
102			writer.newline()
103			writer.endtag("extraProgram")
104			writer.newline()
105			writer.newline()
106
107	def fromXML(self, name, attrs, content, ttFont):
108		if not hasattr(self, "glyphPrograms"):
109			self.glyphPrograms = {}
110			self.extraPrograms = {}
111		lines = strjoin(content).replace("\r", "\n").split("\n")
112		text = '\r'.join(lines[1:-1])
113		if name == "glyphProgram":
114			self.glyphPrograms[attrs["name"]] = text
115		elif name == "extraProgram":
116			self.extraPrograms[attrs["name"]] = text
117
118