11ae29591efbb29492ce05378909ccf4028d7c1eeBehdad Esfahbodfrom __future__ import print_function, division, absolute_import
230e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom fontTools.misc.py23 import *
330e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom fontTools.misc.textTools import safeEval
42b06aaa2a6bcd363c25fb0c43f6bb906906594bdBehdad Esfahbodfrom . import DefaultTable
530e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodimport sys
6035bc7da2318f0dcacecba2e1e24c0a4bf3cf80cBehdad Esfahbodimport array
7d3d7250fc3147b6333e365e5be4ff29aa92ee506pabsimport warnings
87842e56b97ce677b83bdab09cda48bc2d89ac75aJust
97842e56b97ce677b83bdab09cda48bc2d89ac75aJust
107842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass table__h_m_t_x(DefaultTable.DefaultTable):
117842e56b97ce677b83bdab09cda48bc2d89ac75aJust
127842e56b97ce677b83bdab09cda48bc2d89ac75aJust	headerTag = 'hhea'
137842e56b97ce677b83bdab09cda48bc2d89ac75aJust	advanceName = 'width'
147842e56b97ce677b83bdab09cda48bc2d89ac75aJust	sideBearingName = 'lsb'
157842e56b97ce677b83bdab09cda48bc2d89ac75aJust	numberOfMetricsName = 'numberOfHMetrics'
167842e56b97ce677b83bdab09cda48bc2d89ac75aJust
177842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def decompile(self, data, ttFont):
18035bc7da2318f0dcacecba2e1e24c0a4bf3cf80cBehdad Esfahbod		numGlyphs = ttFont['maxp'].numGlyphs
197842e56b97ce677b83bdab09cda48bc2d89ac75aJust		numberOfMetrics = int(getattr(ttFont[self.headerTag], self.numberOfMetricsName))
20035bc7da2318f0dcacecba2e1e24c0a4bf3cf80cBehdad Esfahbod		if numberOfMetrics > numGlyphs:
21035bc7da2318f0dcacecba2e1e24c0a4bf3cf80cBehdad Esfahbod			numberOfMetrics = numGlyphs # We warn later.
22035bc7da2318f0dcacecba2e1e24c0a4bf3cf80cBehdad Esfahbod		# Note: advanceWidth is unsigned, but we read/write as signed.
23035bc7da2318f0dcacecba2e1e24c0a4bf3cf80cBehdad Esfahbod		metrics = array.array("h", data[:4 * numberOfMetrics])
24180ace6a5ff1399ec53bc696e8bef7cce6eef39aBehdad Esfahbod		if sys.byteorder != "big":
25035bc7da2318f0dcacecba2e1e24c0a4bf3cf80cBehdad Esfahbod			metrics.byteswap()
267842e56b97ce677b83bdab09cda48bc2d89ac75aJust		data = data[4 * numberOfMetrics:]
27035bc7da2318f0dcacecba2e1e24c0a4bf3cf80cBehdad Esfahbod		numberOfSideBearings = numGlyphs - numberOfMetrics
28035bc7da2318f0dcacecba2e1e24c0a4bf3cf80cBehdad Esfahbod		sideBearings = array.array("h", data[:2 * numberOfSideBearings])
29035bc7da2318f0dcacecba2e1e24c0a4bf3cf80cBehdad Esfahbod		data = data[2 * numberOfSideBearings:]
30035bc7da2318f0dcacecba2e1e24c0a4bf3cf80cBehdad Esfahbod
31180ace6a5ff1399ec53bc696e8bef7cce6eef39aBehdad Esfahbod		if sys.byteorder != "big":
32035bc7da2318f0dcacecba2e1e24c0a4bf3cf80cBehdad Esfahbod			sideBearings.byteswap()
337842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if data:
34f4e39bf3637499c00c8e7a55866988699dcac97fBehdad Esfahbod			warnings.warn("too much 'hmtx'/'vmtx' table data")
357842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.metrics = {}
3637b7bad5b1c39ccbe8b778ede4b8fe18138b1e25Behdad Esfahbod		glyphOrder = ttFont.getGlyphOrder()
37035bc7da2318f0dcacecba2e1e24c0a4bf3cf80cBehdad Esfahbod		for i in range(numberOfMetrics):
3837b7bad5b1c39ccbe8b778ede4b8fe18138b1e25Behdad Esfahbod			glyphName = glyphOrder[i]
39035bc7da2318f0dcacecba2e1e24c0a4bf3cf80cBehdad Esfahbod			self.metrics[glyphName] = list(metrics[i*2:i*2+2])
40035bc7da2318f0dcacecba2e1e24c0a4bf3cf80cBehdad Esfahbod		lastAdvance = metrics[-2]
41035bc7da2318f0dcacecba2e1e24c0a4bf3cf80cBehdad Esfahbod		for i in range(numberOfSideBearings):
4237b7bad5b1c39ccbe8b778ede4b8fe18138b1e25Behdad Esfahbod			glyphName = glyphOrder[i + numberOfMetrics]
43035bc7da2318f0dcacecba2e1e24c0a4bf3cf80cBehdad Esfahbod			self.metrics[glyphName] = [lastAdvance, sideBearings[i]]
447842e56b97ce677b83bdab09cda48bc2d89ac75aJust
457842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def compile(self, ttFont):
467842e56b97ce677b83bdab09cda48bc2d89ac75aJust		metrics = []
477842e56b97ce677b83bdab09cda48bc2d89ac75aJust		for glyphName in ttFont.getGlyphOrder():
487842e56b97ce677b83bdab09cda48bc2d89ac75aJust			metrics.append(self.metrics[glyphName])
497842e56b97ce677b83bdab09cda48bc2d89ac75aJust		lastAdvance = metrics[-1][0]
507842e56b97ce677b83bdab09cda48bc2d89ac75aJust		lastIndex = len(metrics)
517842e56b97ce677b83bdab09cda48bc2d89ac75aJust		while metrics[lastIndex-2][0] == lastAdvance:
52035bc7da2318f0dcacecba2e1e24c0a4bf3cf80cBehdad Esfahbod			lastIndex -= 1
531288f8ad41b183ccdc3a8657b751ce53e03953a7jvr			if lastIndex <= 1:
54ca4c45681ef2ea9290c6845f8bf61dff281fc5c4jvr				# all advances are equal
551288f8ad41b183ccdc3a8657b751ce53e03953a7jvr				lastIndex = 1
56ca4c45681ef2ea9290c6845f8bf61dff281fc5c4jvr				break
577842e56b97ce677b83bdab09cda48bc2d89ac75aJust		additionalMetrics = metrics[lastIndex:]
58035bc7da2318f0dcacecba2e1e24c0a4bf3cf80cBehdad Esfahbod		additionalMetrics = [sb for advance, sb in additionalMetrics]
597842e56b97ce677b83bdab09cda48bc2d89ac75aJust		metrics = metrics[:lastIndex]
607842e56b97ce677b83bdab09cda48bc2d89ac75aJust		setattr(ttFont[self.headerTag], self.numberOfMetricsName, len(metrics))
617842e56b97ce677b83bdab09cda48bc2d89ac75aJust
624c2f1b6a2c2e4d85d4987606795097d592b1586aBehdad Esfahbod		allMetrics = []
634c2f1b6a2c2e4d85d4987606795097d592b1586aBehdad Esfahbod		for item in metrics:
644c2f1b6a2c2e4d85d4987606795097d592b1586aBehdad Esfahbod			allMetrics.extend(item)
654c2f1b6a2c2e4d85d4987606795097d592b1586aBehdad Esfahbod		allMetrics = array.array("h", allMetrics)
66180ace6a5ff1399ec53bc696e8bef7cce6eef39aBehdad Esfahbod		if sys.byteorder != "big":
674c2f1b6a2c2e4d85d4987606795097d592b1586aBehdad Esfahbod			allMetrics.byteswap()
684c2f1b6a2c2e4d85d4987606795097d592b1586aBehdad Esfahbod		data = allMetrics.tostring()
697842e56b97ce677b83bdab09cda48bc2d89ac75aJust
70035bc7da2318f0dcacecba2e1e24c0a4bf3cf80cBehdad Esfahbod		additionalMetrics = array.array("h", additionalMetrics)
71180ace6a5ff1399ec53bc696e8bef7cce6eef39aBehdad Esfahbod		if sys.byteorder != "big":
72035bc7da2318f0dcacecba2e1e24c0a4bf3cf80cBehdad Esfahbod			additionalMetrics.byteswap()
737842e56b97ce677b83bdab09cda48bc2d89ac75aJust		data = data + additionalMetrics.tostring()
747842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return data
757842e56b97ce677b83bdab09cda48bc2d89ac75aJust
767842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def toXML(self, writer, ttFont):
77ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod		names = sorted(self.metrics.keys())
787842e56b97ce677b83bdab09cda48bc2d89ac75aJust		for glyphName in names:
797842e56b97ce677b83bdab09cda48bc2d89ac75aJust			advance, sb = self.metrics[glyphName]
807842e56b97ce677b83bdab09cda48bc2d89ac75aJust			writer.simpletag("mtx", [
817842e56b97ce677b83bdab09cda48bc2d89ac75aJust					("name", glyphName),
827842e56b97ce677b83bdab09cda48bc2d89ac75aJust					(self.advanceName, advance),
837842e56b97ce677b83bdab09cda48bc2d89ac75aJust					(self.sideBearingName, sb),
847842e56b97ce677b83bdab09cda48bc2d89ac75aJust					])
857842e56b97ce677b83bdab09cda48bc2d89ac75aJust			writer.newline()
867842e56b97ce677b83bdab09cda48bc2d89ac75aJust
873a9fd301808f5a8991ca9ac44028d1ecb22d307fBehdad Esfahbod	def fromXML(self, name, attrs, content, ttFont):
887842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if not hasattr(self, "metrics"):
897842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.metrics = {}
907842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if name == "mtx":
917842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.metrics[attrs["name"]] = [safeEval(attrs[self.advanceName]),
927842e56b97ce677b83bdab09cda48bc2d89ac75aJust					safeEval(attrs[self.sideBearingName])]
93487b15fd9492fdb3e9d578866e539f726f12b4afBehdad Esfahbod
94487b15fd9492fdb3e9d578866e539f726f12b4afBehdad Esfahbod	def __delitem__(self, glyphName):
95487b15fd9492fdb3e9d578866e539f726f12b4afBehdad Esfahbod		del self.metrics[glyphName]
967842e56b97ce677b83bdab09cda48bc2d89ac75aJust
977842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def __getitem__(self, glyphName):
987842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return self.metrics[glyphName]
997842e56b97ce677b83bdab09cda48bc2d89ac75aJust
1003a9fd301808f5a8991ca9ac44028d1ecb22d307fBehdad Esfahbod	def __setitem__(self, glyphName, advance_sb_pair):
1013a9fd301808f5a8991ca9ac44028d1ecb22d307fBehdad Esfahbod		self.metrics[glyphName] = tuple(advance_sb_pair)
1027842e56b97ce677b83bdab09cda48bc2d89ac75aJust
103