11ae29591efbb29492ce05378909ccf4028d7c1eeBehdad Esfahbodfrom __future__ import print_function, division, absolute_import
27ed91eca1eaa96b79eae780778e89bb9ec44c1eeBehdad Esfahbodfrom fontTools.misc.py23 import *
330e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom fontTools.misc import sstruct
430e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom . import DefaultTable
57842e56b97ce677b83bdab09cda48bc2d89ac75aJust
67842e56b97ce677b83bdab09cda48bc2d89ac75aJusthdmxHeaderFormat = """
7fd5a93240e40e265ab3f956300790e2eea0afa54Just	>   # big endian!
87842e56b97ce677b83bdab09cda48bc2d89ac75aJust	version:	H
97842e56b97ce677b83bdab09cda48bc2d89ac75aJust	numRecords:	H
107842e56b97ce677b83bdab09cda48bc2d89ac75aJust	recordSize:	l
117842e56b97ce677b83bdab09cda48bc2d89ac75aJust"""
127842e56b97ce677b83bdab09cda48bc2d89ac75aJust
137842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass table__h_d_m_x(DefaultTable.DefaultTable):
147842e56b97ce677b83bdab09cda48bc2d89ac75aJust
157842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def decompile(self, data, ttFont):
167842e56b97ce677b83bdab09cda48bc2d89ac75aJust		numGlyphs = ttFont['maxp'].numGlyphs
177842e56b97ce677b83bdab09cda48bc2d89ac75aJust		glyphOrder = ttFont.getGlyphOrder()
187842e56b97ce677b83bdab09cda48bc2d89ac75aJust		dummy, data = sstruct.unpack2(hdmxHeaderFormat, data, self)
197842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.hdmx = {}
207842e56b97ce677b83bdab09cda48bc2d89ac75aJust		for i in range(self.numRecords):
21319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod			ppem = byteord(data[0])
22319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod			maxSize = byteord(data[1])
237842e56b97ce677b83bdab09cda48bc2d89ac75aJust			widths = {}
247842e56b97ce677b83bdab09cda48bc2d89ac75aJust			for glyphID in range(numGlyphs):
25319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod				widths[glyphOrder[glyphID]] = byteord(data[glyphID+2])
267842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.hdmx[ppem] = widths
277842e56b97ce677b83bdab09cda48bc2d89ac75aJust			data = data[self.recordSize:]
287842e56b97ce677b83bdab09cda48bc2d89ac75aJust		assert len(data) == 0, "too much hdmx data"
297842e56b97ce677b83bdab09cda48bc2d89ac75aJust
307842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def compile(self, ttFont):
317842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.version = 0
327842e56b97ce677b83bdab09cda48bc2d89ac75aJust		numGlyphs = ttFont['maxp'].numGlyphs
337842e56b97ce677b83bdab09cda48bc2d89ac75aJust		glyphOrder = ttFont.getGlyphOrder()
3432c10eecffb4923e0721c395e4b80fb732543f18Behdad Esfahbod		self.recordSize = 4 * ((2 + numGlyphs + 3) // 4)
3518316aa769566eeb6f3f4a6ed2685fa8f8e861c2Behdad Esfahbod		pad = (self.recordSize - 2 - numGlyphs) * b"\0"
367842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.numRecords = len(self.hdmx)
377842e56b97ce677b83bdab09cda48bc2d89ac75aJust		data = sstruct.pack(hdmxHeaderFormat, self)
38ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod		items = sorted(self.hdmx.items())
397842e56b97ce677b83bdab09cda48bc2d89ac75aJust		for ppem, widths in items:
40b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod			data = data + bytechr(ppem) + bytechr(max(widths.values()))
417842e56b97ce677b83bdab09cda48bc2d89ac75aJust			for glyphID in range(len(glyphOrder)):
427842e56b97ce677b83bdab09cda48bc2d89ac75aJust				width = widths[glyphOrder[glyphID]]
43b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod				data = data + bytechr(width)
447842e56b97ce677b83bdab09cda48bc2d89ac75aJust			data = data + pad
457842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return data
467842e56b97ce677b83bdab09cda48bc2d89ac75aJust
477842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def toXML(self, writer, ttFont):
487842e56b97ce677b83bdab09cda48bc2d89ac75aJust		writer.begintag("hdmxData")
497842e56b97ce677b83bdab09cda48bc2d89ac75aJust		writer.newline()
50ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod		ppems = sorted(self.hdmx.keys())
517842e56b97ce677b83bdab09cda48bc2d89ac75aJust		records = []
527842e56b97ce677b83bdab09cda48bc2d89ac75aJust		format = ""
537842e56b97ce677b83bdab09cda48bc2d89ac75aJust		for ppem in ppems:
547842e56b97ce677b83bdab09cda48bc2d89ac75aJust			widths = self.hdmx[ppem]
557842e56b97ce677b83bdab09cda48bc2d89ac75aJust			records.append(widths)
567842e56b97ce677b83bdab09cda48bc2d89ac75aJust			format = format + "%4d"
577842e56b97ce677b83bdab09cda48bc2d89ac75aJust		glyphNames = ttFont.getGlyphOrder()[:]
587842e56b97ce677b83bdab09cda48bc2d89ac75aJust		glyphNames.sort()
597842e56b97ce677b83bdab09cda48bc2d89ac75aJust		maxNameLen = max(map(len, glyphNames))
60dc7e6f3e5563a853477ebe26166b002c158dbe8bBehdad Esfahbod		format = "%" + repr(maxNameLen) + 's:' + format + ' ;'
617842e56b97ce677b83bdab09cda48bc2d89ac75aJust		writer.write(format % (("ppem",) + tuple(ppems)))
627842e56b97ce677b83bdab09cda48bc2d89ac75aJust		writer.newline()
637842e56b97ce677b83bdab09cda48bc2d89ac75aJust		writer.newline()
647842e56b97ce677b83bdab09cda48bc2d89ac75aJust		for glyphName in glyphNames:
657842e56b97ce677b83bdab09cda48bc2d89ac75aJust			row = []
667842e56b97ce677b83bdab09cda48bc2d89ac75aJust			for ppem in ppems:
677842e56b97ce677b83bdab09cda48bc2d89ac75aJust				widths = self.hdmx[ppem]
687842e56b97ce677b83bdab09cda48bc2d89ac75aJust				row.append(widths[glyphName])
691872557451256004f27133686eeddbbbdf163c69jvr			if ";" in glyphName:
701872557451256004f27133686eeddbbbdf163c69jvr				glyphName = "\\x3b".join(glyphName.split(";"))
717842e56b97ce677b83bdab09cda48bc2d89ac75aJust			writer.write(format % ((glyphName,) + tuple(row)))
727842e56b97ce677b83bdab09cda48bc2d89ac75aJust			writer.newline()
737842e56b97ce677b83bdab09cda48bc2d89ac75aJust		writer.endtag("hdmxData")
747842e56b97ce677b83bdab09cda48bc2d89ac75aJust		writer.newline()
757842e56b97ce677b83bdab09cda48bc2d89ac75aJust
763a9fd301808f5a8991ca9ac44028d1ecb22d307fBehdad Esfahbod	def fromXML(self, name, attrs, content, ttFont):
77180ace6a5ff1399ec53bc696e8bef7cce6eef39aBehdad Esfahbod		if name != "hdmxData":
787842e56b97ce677b83bdab09cda48bc2d89ac75aJust			return
7918316aa769566eeb6f3f4a6ed2685fa8f8e861c2Behdad Esfahbod		content = strjoin(content)
8014fb031125b773f0a15eb19be4f02ed8540b2db6Behdad Esfahbod		lines = content.split(";")
8114fb031125b773f0a15eb19be4f02ed8540b2db6Behdad Esfahbod		topRow = lines[0].split()
827842e56b97ce677b83bdab09cda48bc2d89ac75aJust		assert topRow[0] == "ppem:", "illegal hdmx format"
83e5ca79699d00fdf7ac6eaceaed372aea8d6bc1fdBehdad Esfahbod		ppems = list(map(int, topRow[1:]))
847842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.hdmx = hdmx = {}
857842e56b97ce677b83bdab09cda48bc2d89ac75aJust		for ppem in ppems:
867842e56b97ce677b83bdab09cda48bc2d89ac75aJust			hdmx[ppem] = {}
8714fb031125b773f0a15eb19be4f02ed8540b2db6Behdad Esfahbod		lines = (line.split() for line in lines[1:])
887842e56b97ce677b83bdab09cda48bc2d89ac75aJust		for line in lines:
897842e56b97ce677b83bdab09cda48bc2d89ac75aJust			if not line:
907842e56b97ce677b83bdab09cda48bc2d89ac75aJust				continue
917842e56b97ce677b83bdab09cda48bc2d89ac75aJust			assert line[0][-1] == ":", "illegal hdmx format"
927842e56b97ce677b83bdab09cda48bc2d89ac75aJust			glyphName = line[0][:-1]
931872557451256004f27133686eeddbbbdf163c69jvr			if "\\" in glyphName:
941872557451256004f27133686eeddbbbdf163c69jvr				from fontTools.misc.textTools import safeEval
951872557451256004f27133686eeddbbbdf163c69jvr				glyphName = safeEval('"""' + glyphName + '"""')
96e5ca79699d00fdf7ac6eaceaed372aea8d6bc1fdBehdad Esfahbod			line = list(map(int, line[1:]))
977842e56b97ce677b83bdab09cda48bc2d89ac75aJust			assert len(line) == len(ppems), "illegal hdmx format"
987842e56b97ce677b83bdab09cda48bc2d89ac75aJust			for i in range(len(ppems)):
997842e56b97ce677b83bdab09cda48bc2d89ac75aJust				hdmx[ppems[i]][glyphName] = line[i]
1007842e56b97ce677b83bdab09cda48bc2d89ac75aJust
101