Merge pull request #1439 from anthrotype/hmtx-without-hhea

{v,h}mtx: allow to compile/decompile even without {v,h}hhea table
This commit is contained in:
Cosimo Lupo 2019-01-14 13:59:58 +00:00 committed by GitHub
commit f782a1197b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 14 deletions

View File

@ -23,7 +23,11 @@ class table__h_m_t_x(DefaultTable.DefaultTable):
def decompile(self, data, ttFont):
numGlyphs = ttFont['maxp'].numGlyphs
numberOfMetrics = int(getattr(ttFont[self.headerTag], self.numberOfMetricsName))
headerTable = ttFont.get(self.headerTag)
if headerTable is not None:
numberOfMetrics = int(getattr(headerTable, self.numberOfMetricsName))
else:
numberOfMetrics = numGlyphs
if numberOfMetrics > numGlyphs:
log.warning("The %s.%s exceeds the maxp.numGlyphs" % (
self.headerTag, self.numberOfMetricsName))
@ -69,19 +73,26 @@ class table__h_m_t_x(DefaultTable.DefaultTable):
glyphName, self.advanceName))
hasNegativeAdvances = True
metrics.append([advanceWidth, sideBearing])
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 = [otRound(sb) for _, sb in additionalMetrics]
metrics = metrics[:lastIndex]
numberOfMetrics = len(metrics)
setattr(ttFont[self.headerTag], self.numberOfMetricsName, numberOfMetrics)
headerTable = ttFont.get(self.headerTag)
if headerTable is not None:
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 = [otRound(sb) for _, sb in additionalMetrics]
metrics = metrics[:lastIndex]
numberOfMetrics = len(metrics)
setattr(headerTable, self.numberOfMetricsName, numberOfMetrics)
else:
# no hhea/vhea, can't store numberOfMetrics; assume == numGlyphs
numberOfMetrics = ttFont["maxp"].numGlyphs
additionalMetrics = []
allMetrics = []
for advance, sb in metrics:

View File

@ -107,6 +107,27 @@ class HmtxTableTest(unittest.TestCase):
len([r for r in captor.records
if "has a huge advance" in r.msg]) == 1)
def test_decompile_no_header_table(self):
font = TTFont()
maxp = font['maxp'] = newTable('maxp')
maxp.numGlyphs = 3
font.glyphOrder = ["A", "B", "C"]
self.assertNotIn(self.tableClass.headerTag, font)
data = deHexStr("0190 001E 0190 0028 0190 0032")
mtxTable = newTable(self.tag)
mtxTable.decompile(data, font)
self.assertEqual(
mtxTable.metrics,
{
"A": (400, 30),
"B": (400, 40),
"C": (400, 50),
}
)
def test_compile(self):
# we set the wrong 'numberOfMetrics' to check it gets adjusted
font = self.makeFont(numGlyphs=3, numberOfMetrics=4)
@ -173,6 +194,24 @@ class HmtxTableTest(unittest.TestCase):
self.assertEqual(data, deHexStr("0001 0001 0000 0001 0000"))
def test_compile_no_header_table(self):
font = TTFont()
maxp = font['maxp'] = newTable('maxp')
maxp.numGlyphs = 3
font.glyphOrder = [chr(i) for i in range(65, 68)]
mtxTable = font[self.tag] = newTable(self.tag)
mtxTable.metrics = {
"A": (400, 30),
"B": (400, 40),
"C": (400, 50),
}
self.assertNotIn(self.tableClass.headerTag, font)
data = mtxTable.compile(font)
self.assertEqual(data, deHexStr("0190 001E 0190 0028 0190 0032"))
def test_toXML(self):
font = self.makeFont(numGlyphs=2, numberOfMetrics=2)
mtxTable = font[self.tag] = newTable(self.tag)