[cffLib] Make sure glyph names are unique

Similar to what we do with “post” table names. I’d have said the font is
broken, but all applications I tried it with loaded it just fine, though
they differed in which glyph to pick from the duplicate ones.

Fixes https://github.com/fonttools/fonttools/issues/1602
This commit is contained in:
Khaled Hosny 2019-08-17 04:03:22 +02:00
parent 0ea19f3bd3
commit 6cb0a56020
3 changed files with 29 additions and 0 deletions

View File

@ -1319,6 +1319,20 @@ class CharsetConverter(SimpleConverter):
raise NotImplementedError
assert len(charset) == numGlyphs
log.log(DEBUG, " charset end at %s", file.tell())
# make sure glyph names are unique
allNames = {}
newCharset = []
for glyphName in charset:
if glyphName in allNames:
# make up a new glyphName that's unique
n = allNames[glyphName]
while (glyphName + "#" + str(n)) in allNames:
n += 1
allNames[glyphName] = n + 1
glyphName = glyphName + "#" + str(n)
allNames[glyphName] = 1
newCharset.append(glyphName)
charset = newCharset
else: # offset == 0 -> no charset data.
if isCID or "CharStrings" not in parent.rawDict:
# We get here only when processing fontDicts from the FDArray of

View File

@ -92,6 +92,21 @@ class CffLibTest(DataFilesHandler):
self.assertEqual(topDict2.FDSelect.format, 4)
self.assertEqual(topDict2.FDSelect.gidArray, [0, 0, 1])
def test_unique_glyph_names(self):
font_path = self.getpath('LinLibertine_RBI.otf')
font = TTFont(font_path, recalcBBoxes=False, recalcTimestamp=False)
glyphOrder = font.getGlyphOrder()
self.assertEqual(len(glyphOrder), len(set(glyphOrder)))
self.temp_dir()
save_path = os.path.join(self.tempdir, 'TestOTF.otf')
font.save(save_path)
font2 = TTFont(save_path)
glyphOrder = font2.getGlyphOrder()
self.assertEqual(len(glyphOrder), len(set(glyphOrder)))
if __name__ == "__main__":
sys.exit(unittest.main())

Binary file not shown.