Port hmtx table from numpy to array module

This commit is contained in:
Behdad Esfahbod 2013-08-16 11:49:23 -04:00
parent 4ffd404449
commit 035bc7da23

View File

@ -1,6 +1,6 @@
import sys
import DefaultTable
import numpy
import array
from fontTools import ttLib
from fontTools.misc.textTools import safeEval
import warnings
@ -14,37 +14,31 @@ class table__h_m_t_x(DefaultTable.DefaultTable):
numberOfMetricsName = 'numberOfHMetrics'
def decompile(self, data, ttFont):
numGlyphs = ttFont['maxp'].numGlyphs
numberOfMetrics = int(getattr(ttFont[self.headerTag], self.numberOfMetricsName))
metrics = numpy.fromstring(data[:4 * numberOfMetrics],
numpy.int16)
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 = metrics.byteswap()
metrics.shape = (numberOfMetrics, 2)
metrics.byteswap()
data = data[4 * numberOfMetrics:]
numberOfSideBearings = ttFont['maxp'].numGlyphs - numberOfMetrics
numberOfSideBearings = int(numberOfSideBearings)
if numberOfSideBearings:
assert numberOfSideBearings > 0, "bad hmtx/vmtx table"
lastAdvance = metrics[-1][0]
advances = numpy.array([lastAdvance] * numberOfSideBearings,
numpy.int16)
sideBearings = numpy.fromstring(data[:2 * numberOfSideBearings],
numpy.int16)
if sys.byteorder <> "big":
sideBearings = sideBearings.byteswap()
data = data[2 * numberOfSideBearings:]
if len(advances) and len(sideBearings):
additionalMetrics = numpy.array([advances, sideBearings], numpy.int16)
metrics = numpy.concatenate((metrics, numpy.transpose(additionalMetrics)))
else:
warnings.warn('Unable to include additional metrics')
numberOfSideBearings = numGlyphs - numberOfMetrics
sideBearings = array.array("h", data[:2 * numberOfSideBearings])
data = data[2 * numberOfSideBearings:]
if sys.byteorder <> "big":
sideBearings.byteswap()
if data:
sys.stderr.write("too much data for hmtx/vmtx table\n")
metrics = metrics.tolist()
self.metrics = {}
for i in range(len(metrics)):
for i in range(numberOfMetrics):
glyphName = ttFont.getGlyphName(i)
self.metrics[glyphName] = metrics[i]
self.metrics[glyphName] = list(metrics[i*2:i*2+2])
lastAdvance = metrics[-2]
for i in range(numberOfSideBearings):
glyphName = ttFont.getGlyphName(i + numberOfMetrics)
self.metrics[glyphName] = [lastAdvance, sideBearings[i]]
def compile(self, ttFont):
metrics = []
@ -53,24 +47,25 @@ class table__h_m_t_x(DefaultTable.DefaultTable):
lastAdvance = metrics[-1][0]
lastIndex = len(metrics)
while metrics[lastIndex-2][0] == lastAdvance:
lastIndex = lastIndex - 1
lastIndex -= 1
if lastIndex <= 1:
# all advances are equal
lastIndex = 1
break
additionalMetrics = metrics[lastIndex:]
additionalMetrics = map(lambda (advance, sb): sb, additionalMetrics)
additionalMetrics = [sb for advance, sb in additionalMetrics]
metrics = metrics[:lastIndex]
setattr(ttFont[self.headerTag], self.numberOfMetricsName, len(metrics))
metrics = numpy.array(metrics, numpy.int16)
metrics = sum(metrics,[])
metrics = array.array("h", metrics)
if sys.byteorder <> "big":
metrics = metrics.byteswap()
metrics.byteswap()
data = metrics.tostring()
additionalMetrics = numpy.array(additionalMetrics, numpy.int16)
additionalMetrics = array.array("h", additionalMetrics)
if sys.byteorder <> "big":
additionalMetrics = additionalMetrics.byteswap()
additionalMetrics.byteswap()
data = data + additionalMetrics.tostring()
return data