2014-01-14 15:07:50 +08:00
|
|
|
from __future__ import print_function, division, absolute_import
|
2013-11-27 17:27:45 -05:00
|
|
|
from fontTools.misc.py23 import *
|
|
|
|
from fontTools.misc.textTools import safeEval
|
2013-11-27 02:34:11 -05:00
|
|
|
from . import DefaultTable
|
2013-11-27 17:27:45 -05:00
|
|
|
import sys
|
2013-08-16 11:49:23 -04:00
|
|
|
import array
|
2011-02-13 07:01:11 +00:00
|
|
|
import warnings
|
1999-12-16 21:34:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
class table__h_m_t_x(DefaultTable.DefaultTable):
|
|
|
|
|
|
|
|
headerTag = 'hhea'
|
|
|
|
advanceName = 'width'
|
|
|
|
sideBearingName = 'lsb'
|
|
|
|
numberOfMetricsName = 'numberOfHMetrics'
|
|
|
|
|
|
|
|
def decompile(self, data, ttFont):
|
2013-08-16 11:49:23 -04:00
|
|
|
numGlyphs = ttFont['maxp'].numGlyphs
|
1999-12-16 21:34:53 +00:00
|
|
|
numberOfMetrics = int(getattr(ttFont[self.headerTag], self.numberOfMetricsName))
|
2013-08-16 11:49:23 -04:00
|
|
|
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])
|
2013-11-27 02:40:30 -05:00
|
|
|
if sys.byteorder != "big":
|
2013-08-16 11:49:23 -04:00
|
|
|
metrics.byteswap()
|
1999-12-16 21:34:53 +00:00
|
|
|
data = data[4 * numberOfMetrics:]
|
2013-08-16 11:49:23 -04:00
|
|
|
numberOfSideBearings = numGlyphs - numberOfMetrics
|
|
|
|
sideBearings = array.array("h", data[:2 * numberOfSideBearings])
|
|
|
|
data = data[2 * numberOfSideBearings:]
|
|
|
|
|
2013-11-27 02:40:30 -05:00
|
|
|
if sys.byteorder != "big":
|
2013-08-16 11:49:23 -04:00
|
|
|
sideBearings.byteswap()
|
1999-12-16 21:34:53 +00:00
|
|
|
if data:
|
2013-12-04 21:15:36 -05:00
|
|
|
warnings.warn("too much 'hmtx'/'vmtx' table data")
|
1999-12-16 21:34:53 +00:00
|
|
|
self.metrics = {}
|
2014-05-14 00:30:02 -04:00
|
|
|
glyphOrder = ttFont.getGlyphOrder()
|
2013-08-16 11:49:23 -04:00
|
|
|
for i in range(numberOfMetrics):
|
2014-05-14 00:30:02 -04:00
|
|
|
glyphName = glyphOrder[i]
|
2013-08-16 11:49:23 -04:00
|
|
|
self.metrics[glyphName] = list(metrics[i*2:i*2+2])
|
|
|
|
lastAdvance = metrics[-2]
|
|
|
|
for i in range(numberOfSideBearings):
|
2014-05-14 00:30:02 -04:00
|
|
|
glyphName = glyphOrder[i + numberOfMetrics]
|
2013-08-16 11:49:23 -04:00
|
|
|
self.metrics[glyphName] = [lastAdvance, sideBearings[i]]
|
1999-12-16 21:34:53 +00:00
|
|
|
|
|
|
|
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:
|
2013-08-16 11:49:23 -04:00
|
|
|
lastIndex -= 1
|
2002-05-02 10:53:10 +00:00
|
|
|
if lastIndex <= 1:
|
2002-05-01 21:06:11 +00:00
|
|
|
# all advances are equal
|
2002-05-02 10:53:10 +00:00
|
|
|
lastIndex = 1
|
2002-05-01 21:06:11 +00:00
|
|
|
break
|
1999-12-16 21:34:53 +00:00
|
|
|
additionalMetrics = metrics[lastIndex:]
|
2013-08-16 11:49:23 -04:00
|
|
|
additionalMetrics = [sb for advance, sb in additionalMetrics]
|
1999-12-16 21:34:53 +00:00
|
|
|
metrics = metrics[:lastIndex]
|
|
|
|
setattr(ttFont[self.headerTag], self.numberOfMetricsName, len(metrics))
|
|
|
|
|
2013-11-25 04:47:36 -05:00
|
|
|
allMetrics = []
|
|
|
|
for item in metrics:
|
|
|
|
allMetrics.extend(item)
|
|
|
|
allMetrics = array.array("h", allMetrics)
|
2013-11-27 02:40:30 -05:00
|
|
|
if sys.byteorder != "big":
|
2013-11-25 04:47:36 -05:00
|
|
|
allMetrics.byteswap()
|
|
|
|
data = allMetrics.tostring()
|
1999-12-16 21:34:53 +00:00
|
|
|
|
2013-08-16 11:49:23 -04:00
|
|
|
additionalMetrics = array.array("h", additionalMetrics)
|
2013-11-27 02:40:30 -05:00
|
|
|
if sys.byteorder != "big":
|
2013-08-16 11:49:23 -04:00
|
|
|
additionalMetrics.byteswap()
|
1999-12-16 21:34:53 +00:00
|
|
|
data = data + additionalMetrics.tostring()
|
|
|
|
return data
|
|
|
|
|
|
|
|
def toXML(self, writer, ttFont):
|
2013-11-27 04:15:34 -05:00
|
|
|
names = sorted(self.metrics.keys())
|
1999-12-16 21:34:53 +00:00
|
|
|
for glyphName in names:
|
|
|
|
advance, sb = self.metrics[glyphName]
|
|
|
|
writer.simpletag("mtx", [
|
|
|
|
("name", glyphName),
|
|
|
|
(self.advanceName, advance),
|
|
|
|
(self.sideBearingName, sb),
|
|
|
|
])
|
|
|
|
writer.newline()
|
|
|
|
|
2013-11-27 03:19:32 -05:00
|
|
|
def fromXML(self, name, attrs, content, ttFont):
|
1999-12-16 21:34:53 +00:00
|
|
|
if not hasattr(self, "metrics"):
|
|
|
|
self.metrics = {}
|
|
|
|
if name == "mtx":
|
|
|
|
self.metrics[attrs["name"]] = [safeEval(attrs[self.advanceName]),
|
|
|
|
safeEval(attrs[self.sideBearingName])]
|
2014-05-14 13:51:10 -06:00
|
|
|
|
|
|
|
def __delitem__(self, glyphName):
|
|
|
|
del self.metrics[glyphName]
|
1999-12-16 21:34:53 +00:00
|
|
|
|
|
|
|
def __getitem__(self, glyphName):
|
|
|
|
return self.metrics[glyphName]
|
|
|
|
|
2013-11-27 03:19:32 -05:00
|
|
|
def __setitem__(self, glyphName, advance_sb_pair):
|
|
|
|
self.metrics[glyphName] = tuple(advance_sb_pair)
|
1999-12-16 21:34:53 +00:00
|
|
|
|