| from __future__ import print_function, division, absolute_import |
| from fontTools.misc.py23 import * |
| from fontTools.misc.textTools import safeEval |
| from . import DefaultTable |
| import sys |
| import array |
| import warnings |
| |
| |
| class table__h_m_t_x(DefaultTable.DefaultTable): |
| |
| headerTag = 'hhea' |
| advanceName = 'width' |
| sideBearingName = 'lsb' |
| numberOfMetricsName = 'numberOfHMetrics' |
| |
| def decompile(self, data, ttFont): |
| numGlyphs = ttFont['maxp'].numGlyphs |
| numberOfMetrics = int(getattr(ttFont[self.headerTag], self.numberOfMetricsName)) |
| if numberOfMetrics > numGlyphs: |
| numberOfMetrics = numGlyphs # We warn later. |
| # Note: advanceWidth is unsigned, but we read/write as signed. |
| metrics = array.array("h", data[:4 * numberOfMetrics]) |
| if sys.byteorder != "big": |
| metrics.byteswap() |
| data = data[4 * numberOfMetrics:] |
| numberOfSideBearings = numGlyphs - numberOfMetrics |
| sideBearings = array.array("h", data[:2 * numberOfSideBearings]) |
| data = data[2 * numberOfSideBearings:] |
| |
| if sys.byteorder != "big": |
| sideBearings.byteswap() |
| if data: |
| warnings.warn("too much 'hmtx'/'vmtx' table data") |
| self.metrics = {} |
| glyphOrder = ttFont.getGlyphOrder() |
| for i in range(numberOfMetrics): |
| glyphName = glyphOrder[i] |
| self.metrics[glyphName] = list(metrics[i*2:i*2+2]) |
| lastAdvance = metrics[-2] |
| for i in range(numberOfSideBearings): |
| glyphName = glyphOrder[i + numberOfMetrics] |
| self.metrics[glyphName] = [lastAdvance, sideBearings[i]] |
| |
| def compile(self, ttFont): |
| metrics = [] |
| for glyphName in ttFont.getGlyphOrder(): |
| metrics.append(self.metrics[glyphName]) |
| lastAdvance = metrics[-1][0] |
| lastIndex = len(metrics) |
| while metrics[lastIndex-2][0] == lastAdvance: |
| lastIndex -= 1 |
| if lastIndex <= 1: |
| # all advances are equal |
| lastIndex = 1 |
| break |
| additionalMetrics = metrics[lastIndex:] |
| additionalMetrics = [sb for advance, sb in additionalMetrics] |
| metrics = metrics[:lastIndex] |
| setattr(ttFont[self.headerTag], self.numberOfMetricsName, len(metrics)) |
| |
| allMetrics = [] |
| for item in metrics: |
| allMetrics.extend(item) |
| allMetrics = array.array("h", allMetrics) |
| if sys.byteorder != "big": |
| allMetrics.byteswap() |
| data = allMetrics.tostring() |
| |
| additionalMetrics = array.array("h", additionalMetrics) |
| if sys.byteorder != "big": |
| additionalMetrics.byteswap() |
| data = data + additionalMetrics.tostring() |
| return data |
| |
| def toXML(self, writer, ttFont): |
| names = sorted(self.metrics.keys()) |
| for glyphName in names: |
| advance, sb = self.metrics[glyphName] |
| writer.simpletag("mtx", [ |
| ("name", glyphName), |
| (self.advanceName, advance), |
| (self.sideBearingName, sb), |
| ]) |
| writer.newline() |
| |
| def fromXML(self, name, attrs, content, ttFont): |
| if not hasattr(self, "metrics"): |
| self.metrics = {} |
| if name == "mtx": |
| self.metrics[attrs["name"]] = [safeEval(attrs[self.advanceName]), |
| safeEval(attrs[self.sideBearingName])] |
| |
| def __getitem__(self, glyphName): |
| return self.metrics[glyphName] |
| |
| def __setitem__(self, glyphName, advance_sb_pair): |
| self.metrics[glyphName] = tuple(advance_sb_pair) |
| |