_h_m_t_x.py revision 487b15fd9492fdb3e9d578866e539f726f12b4af
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