Skip to content

Commit

Permalink
[merge] Clean up glyphOrder and cmap computation
Browse files Browse the repository at this point in the history
  • Loading branch information
behdad committed Dec 16, 2021
1 parent 915c077 commit e6719f4
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 33 deletions.
28 changes: 10 additions & 18 deletions Lib/fontTools/merge/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,33 +74,25 @@ def merge(self, fontfiles):
# Settle on a mega glyph order.
#
fonts = self._openFonts(fontfiles)
glyphOrders = [font.getGlyphOrder() for font in fonts]
megaGlyphOrder = computeMegaGlyphOrder(self, glyphOrders)
self.duplicateGlyphsPerFont = [{} for _ in fonts]
computeMegaCmap(self, [font['cmap'] for font in fonts])
glyphOrders = [list(font.getGlyphOrder()) for font in fonts]
computeMegaGlyphOrder(self, glyphOrders)

# Take first input file sfntVersion
sfntVersion = fonts[0].sfntVersion

cffTables = [None] * len(fonts)
if sfntVersion == "OTTO":
for i, font in enumerate(fonts):
cffTables[i] = font['CFF ']

# Reload fonts and set new glyph names on them.
# TODO Is it necessary to reload font? I think it is. At least
# it's safer, in case tables were loaded to provide glyph names.
fonts = self._openFonts(fontfiles)
for font, glyphOrder, cffTable in zip(fonts, glyphOrders, cffTables):
for font,glyphOrder in zip(fonts, glyphOrders):
font.setGlyphOrder(glyphOrder)
if cffTable:
# Rename CFF CharStrings to match the new glyphOrder.
# Using cffTable from before reloading the fonts, because reasons.
renameCFFCharStrings(self, glyphOrder, cffTable)
font['CFF '] = cffTable
if 'CFF ' in font:
renameCFFCharStrings(self, glyphOrder, font['CFF '])

cmaps = [font['cmap'] for font in fonts]
self.duplicateGlyphsPerFont = [{} for _ in fonts]
computeMegaCmap(self, cmaps)

mega = ttLib.TTFont(sfntVersion=sfntVersion)
mega.setGlyphOrder(megaGlyphOrder)
mega.setGlyphOrder(self.glyphOrder)

for font in fonts:
self._preMerge(font)
Expand Down
31 changes: 16 additions & 15 deletions Lib/fontTools/merge/cmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@

def computeMegaGlyphOrder(merger, glyphOrders):
"""Modifies passed-in glyphOrders to reflect new glyph names.
Returns glyphOrder for the merged font."""
mega = {}
Stores merger.glyphOrder."""
megaOrder = {}
for glyphOrder in glyphOrders:
for i,glyphName in enumerate(glyphOrder):
if glyphName in mega:
n = mega[glyphName]
while (glyphName + "#" + repr(n)) in mega:
if glyphName in megaOrder:
n = megaOrder[glyphName]
while (glyphName + "#" + repr(n)) in megaOrder:
n += 1
mega[glyphName] = n
megaOrder[glyphName] = n
glyphName += "#" + repr(n)
glyphOrder[i] = glyphName
mega[glyphName] = 1
return list(mega.keys())
megaOrder[glyphName] = 1
merger.glyphOrder = megaOrder = list(megaOrder.keys())


def _glyphsAreSame(glyphSet1, glyphSet2, glyph1, glyph2,
Expand Down Expand Up @@ -56,13 +56,14 @@ class CmapUnicodePlatEncodings:
BMP = {(4, 3, 1), (4, 0, 3), (4, 0, 4), (4, 0, 6)}
FullRepertoire = {(12, 3, 10), (12, 0, 4), (12, 0, 6)}

def computeMegaCmap(merger, cmapTables):
"""Sets merger.cmap and merger.glyphOrder."""

def computeMegaCmap(merger, tables):
# TODO Handle format=14.
# Only merge format 4 and 12 Unicode subtables, ignores all other subtables
# If there is a format 12 table for a font, ignore the format 4 table of it
cmapTables = []
for fontIdx,table in enumerate(tables):
chosenCmapTables = []
for fontIdx,table in enumerate(cmapTables):
format4 = None
format12 = None
for subtable in table.tables:
Expand All @@ -78,15 +79,16 @@ def computeMegaCmap(merger, tables):
fontIdx, subtable.format, subtable.platformID, subtable.platEncID
)
if format12 is not None:
cmapTables.append((format12, fontIdx))
chosenCmapTables.append((format12, fontIdx))
elif format4 is not None:
cmapTables.append((format4, fontIdx))
chosenCmapTables.append((format4, fontIdx))

# Build the unicode mapping
merger.cmap = cmap = {}
fontIndexForGlyph = {}
glyphSets = [None for f in merger.fonts] if hasattr(merger, 'fonts') else None
for table,fontIdx in cmapTables:

for table,fontIdx in chosenCmapTables:
# handle duplicates
for uni,gid in table.cmap.items():
oldgid = cmap.get(uni, None)
Expand All @@ -112,4 +114,3 @@ def computeMegaCmap(merger, tables):
# gid, because of another Unicode character.
# TODO: Try harder to do something about these.
log.warning("Dropped mapping from codepoint %#06X to glyphId '%s'", uni, gid)

0 comments on commit e6719f4

Please sign in to comment.