11ae29591efbb29492ce05378909ccf4028d7c1eeBehdad Esfahbodfrom __future__ import print_function, division, absolute_import
230e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom fontTools.misc.py23 import *
38413c108d21e8cf0e9059bbfffde8d13f2616340Behdad Esfahbodfrom fontTools.misc import sstruct
47842e56b97ce677b83bdab09cda48bc2d89ac75aJustfrom fontTools.misc.textTools import safeEval
530e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom . import DefaultTable
67842e56b97ce677b83bdab09cda48bc2d89ac75aJust
7e69caf8771a0dd675ca3c4490625dac963a6b65cjvr
87842e56b97ce677b83bdab09cda48bc2d89ac75aJusthheaFormat = """
9e69caf8771a0dd675ca3c4490625dac963a6b65cjvr		>  # big endian
10e69caf8771a0dd675ca3c4490625dac963a6b65cjvr		tableVersion:           16.16F
11e69caf8771a0dd675ca3c4490625dac963a6b65cjvr		ascent:                 h
12e69caf8771a0dd675ca3c4490625dac963a6b65cjvr		descent:                h
13e69caf8771a0dd675ca3c4490625dac963a6b65cjvr		lineGap:                h
14e69caf8771a0dd675ca3c4490625dac963a6b65cjvr		advanceWidthMax:        H
15e69caf8771a0dd675ca3c4490625dac963a6b65cjvr		minLeftSideBearing:     h
16e69caf8771a0dd675ca3c4490625dac963a6b65cjvr		minRightSideBearing:    h
17e69caf8771a0dd675ca3c4490625dac963a6b65cjvr		xMaxExtent:             h
18e69caf8771a0dd675ca3c4490625dac963a6b65cjvr		caretSlopeRise:         h
19e69caf8771a0dd675ca3c4490625dac963a6b65cjvr		caretSlopeRun:          h
205aaeac333388f2859191e2648e2b8287372a1637jvr		caretOffset:            h
21e69caf8771a0dd675ca3c4490625dac963a6b65cjvr		reserved0:              h
22e69caf8771a0dd675ca3c4490625dac963a6b65cjvr		reserved1:              h
23e69caf8771a0dd675ca3c4490625dac963a6b65cjvr		reserved2:              h
24e69caf8771a0dd675ca3c4490625dac963a6b65cjvr		reserved3:              h
25e69caf8771a0dd675ca3c4490625dac963a6b65cjvr		metricDataFormat:       h
26e69caf8771a0dd675ca3c4490625dac963a6b65cjvr		numberOfHMetrics:       H
277842e56b97ce677b83bdab09cda48bc2d89ac75aJust"""
287842e56b97ce677b83bdab09cda48bc2d89ac75aJust
29e69caf8771a0dd675ca3c4490625dac963a6b65cjvr
307842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass table__h_h_e_a(DefaultTable.DefaultTable):
317842e56b97ce677b83bdab09cda48bc2d89ac75aJust
327842e56b97ce677b83bdab09cda48bc2d89ac75aJust	dependencies = ['hmtx', 'glyf']
337842e56b97ce677b83bdab09cda48bc2d89ac75aJust
347842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def decompile(self, data, ttFont):
356d73fdef1cd1e62a230647845d37915f0f8df792jvr		sstruct.unpack(hheaFormat, data, self)
367842e56b97ce677b83bdab09cda48bc2d89ac75aJust
377842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def compile(self, ttFont):
383e097c609540944dd9290ad58df346ca86492031Just		if ttFont.isLoaded('glyf') and ttFont.recalcBBoxes:
393e097c609540944dd9290ad58df346ca86492031Just			self.recalc(ttFont)
407842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return sstruct.pack(hheaFormat, self)
417842e56b97ce677b83bdab09cda48bc2d89ac75aJust
427842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def recalc(self, ttFont):
437842e56b97ce677b83bdab09cda48bc2d89ac75aJust		hmtxTable = ttFont['hmtx']
44bc5e1cb195c0bfa1c8e7507326d5a9ad05aecb4bBehdad Esfahbod		if 'glyf' in ttFont:
457842e56b97ce677b83bdab09cda48bc2d89ac75aJust			glyfTable = ttFont['glyf']
46d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader			INFINITY = 100000
47246301acc9a54c38f83dcbc9b15127edff33b804Behdad Esfahbod			advanceWidthMax = 0
48d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader			minLeftSideBearing = +INFINITY  # arbitrary big number
49d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader			minRightSideBearing = +INFINITY # arbitrary big number
50d7921e33d9d1944c394e6c17b3746e7108dd1da4Roozbeh Pournader			xMaxExtent = -INFINITY          # arbitrary big negative number
517842e56b97ce677b83bdab09cda48bc2d89ac75aJust
527842e56b97ce677b83bdab09cda48bc2d89ac75aJust			for name in ttFont.getGlyphOrder():
537842e56b97ce677b83bdab09cda48bc2d89ac75aJust				width, lsb = hmtxTable[name]
54335f182a585975725c316d66add5e8cdd9f34e6aBehdad Esfahbod				advanceWidthMax = max(advanceWidthMax, width)
557bdf6d39fc124bfcbc8bafb0c3f7a64b5c85cd2fBehdad Esfahbod				g = glyfTable[name]
569222b8ef93fd6b41f9c4dcf152593cd0c80f0ba4Behdad Esfahbod				if g.numberOfContours == 0:
577842e56b97ce677b83bdab09cda48bc2d89ac75aJust					continue
589222b8ef93fd6b41f9c4dcf152593cd0c80f0ba4Behdad Esfahbod				if g.numberOfContours < 0 and not hasattr(g, "xMax"):
599222b8ef93fd6b41f9c4dcf152593cd0c80f0ba4Behdad Esfahbod					# Composite glyph without extents set.
609222b8ef93fd6b41f9c4dcf152593cd0c80f0ba4Behdad Esfahbod					# Calculate those.
619222b8ef93fd6b41f9c4dcf152593cd0c80f0ba4Behdad Esfahbod					g.recalcBounds(glyfTable)
627842e56b97ce677b83bdab09cda48bc2d89ac75aJust				minLeftSideBearing = min(minLeftSideBearing, lsb)
637842e56b97ce677b83bdab09cda48bc2d89ac75aJust				rsb = width - lsb - (g.xMax - g.xMin)
647842e56b97ce677b83bdab09cda48bc2d89ac75aJust				minRightSideBearing = min(minRightSideBearing, rsb)
657842e56b97ce677b83bdab09cda48bc2d89ac75aJust				extent = lsb + (g.xMax - g.xMin)
667842e56b97ce677b83bdab09cda48bc2d89ac75aJust				xMaxExtent = max(xMaxExtent, extent)
67246301acc9a54c38f83dcbc9b15127edff33b804Behdad Esfahbod
68978b1ea8774d2ed24d12099b60bfa53fea3239b4Behdad Esfahbod			if xMaxExtent == -INFINITY:
69246301acc9a54c38f83dcbc9b15127edff33b804Behdad Esfahbod				# No glyph has outlines.
70246301acc9a54c38f83dcbc9b15127edff33b804Behdad Esfahbod				minLeftSideBearing = 0
71246301acc9a54c38f83dcbc9b15127edff33b804Behdad Esfahbod				minRightSideBearing = 0
72246301acc9a54c38f83dcbc9b15127edff33b804Behdad Esfahbod				xMaxExtent = 0
73246301acc9a54c38f83dcbc9b15127edff33b804Behdad Esfahbod
74246301acc9a54c38f83dcbc9b15127edff33b804Behdad Esfahbod			self.advanceWidthMax = advanceWidthMax
75246301acc9a54c38f83dcbc9b15127edff33b804Behdad Esfahbod			self.minLeftSideBearing = minLeftSideBearing
76246301acc9a54c38f83dcbc9b15127edff33b804Behdad Esfahbod			self.minRightSideBearing = minRightSideBearing
77246301acc9a54c38f83dcbc9b15127edff33b804Behdad Esfahbod			self.xMaxExtent = xMaxExtent
787842e56b97ce677b83bdab09cda48bc2d89ac75aJust		else:
797842e56b97ce677b83bdab09cda48bc2d89ac75aJust			# XXX CFF recalc...
807842e56b97ce677b83bdab09cda48bc2d89ac75aJust			pass
817842e56b97ce677b83bdab09cda48bc2d89ac75aJust
827842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def toXML(self, writer, ttFont):
837842e56b97ce677b83bdab09cda48bc2d89ac75aJust		formatstring, names, fixes = sstruct.getformat(hheaFormat)
847842e56b97ce677b83bdab09cda48bc2d89ac75aJust		for name in names:
857842e56b97ce677b83bdab09cda48bc2d89ac75aJust			value = getattr(self, name)
867842e56b97ce677b83bdab09cda48bc2d89ac75aJust			writer.simpletag(name, value=value)
877842e56b97ce677b83bdab09cda48bc2d89ac75aJust			writer.newline()
887842e56b97ce677b83bdab09cda48bc2d89ac75aJust
893a9fd301808f5a8991ca9ac44028d1ecb22d307fBehdad Esfahbod	def fromXML(self, name, attrs, content, ttFont):
907842e56b97ce677b83bdab09cda48bc2d89ac75aJust		setattr(self, name, safeEval(attrs["value"]))
917842e56b97ce677b83bdab09cda48bc2d89ac75aJust
92