Port hmtx table from numpy to array module
This commit is contained in:
parent
4ffd404449
commit
035bc7da23
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user