[merge] Handle differing default/nominalWidthX in CFF (#3070)

* [merge] Handle None GDEF.table.MarkGlyphSetsDef

* [merge] Handle differing CFF nominal/defaultWidthX

Fixes https://github.com/fonttools/fonttools/issues/3069

* Update Lib/fontTools/merge/tables.py

Co-authored-by: Cosimo Lupo <clupo@google.com>

---------

Co-authored-by: Cosimo Lupo <clupo@google.com>
This commit is contained in:
Behdad Esfahbod 2023-04-19 12:14:41 -06:00 committed by GitHub
parent 1c283756a5
commit 57c7792477
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 305 additions and 285 deletions

View File

@ -194,7 +194,6 @@ ttLib.getTableClass("GDEF").mergeMap = ttLib.getTableClass(
@add_method(ttLib.getTableClass("GSUB"))
def merge(self, m, tables):
assert len(tables) == len(m.duplicateGlyphsPerFont)
for i, (table, dups) in enumerate(zip(tables, m.duplicateGlyphsPerFont)):
if not dups:
@ -445,7 +444,11 @@ def layoutPreMerge(font):
t.table.LookupList.mapLookups(lookupMap)
t.table.FeatureList.mapLookups(lookupMap)
if GDEF and GDEF.table.Version >= 0x00010002:
if (
GDEF
and GDEF.table.Version >= 0x00010002
and GDEF.table.MarkGlyphSetsDef
):
markFilteringSetMap = {
i: v for i, v in enumerate(GDEF.table.MarkGlyphSetsDef.Coverage)
}
@ -470,7 +473,6 @@ def layoutPostMerge(font):
continue
if t.table.FeatureList and t.table.ScriptList:
# Collect unregistered (new) features.
featureMap = GregariousIdentityDict(t.table.FeatureList.FeatureRecord)
t.table.ScriptList.mapFeatures(featureMap)
@ -496,7 +498,6 @@ def layoutPostMerge(font):
t.table.FeatureList.FeatureCount = len(t.table.FeatureList.FeatureRecord)
if t.table.LookupList:
# Collect unregistered (new) lookups.
lookupMap = GregariousIdentityDict(t.table.LookupList.Lookup)
t.table.FeatureList.mapLookups(lookupMap)

View File

@ -3,6 +3,7 @@
# Google Author(s): Behdad Esfahbod, Roozbeh Pournader
from fontTools import ttLib, cffLib
from fontTools.misc.psCharStrings import T2WidthExtractor
from fontTools.ttLib.tables.DefaultTable import DefaultTable
from fontTools.merge.base import add_method, mergeObjects
from fontTools.merge.cmap import computeMegaCmap
@ -238,7 +239,6 @@ ttLib.getTableClass("gasp").mergeMap = lambda self, lst: first(
@add_method(ttLib.getTableClass("CFF "))
def merge(self, m, tables):
if any(hasattr(table, "FDSelect") for table in tables):
raise NotImplementedError("Merging CID-keyed CFF tables is not supported yet")
@ -248,6 +248,7 @@ def merge(self, m, tables):
newcff = tables[0]
newfont = newcff.cff[0]
private = newfont.Private
newDefaultWidthX, newNominalWidthX = private.defaultWidthX, private.nominalWidthX
storedNamesStrings = []
glyphOrderStrings = []
glyphOrder = set(newfont.getGlyphOrder())
@ -264,6 +265,13 @@ def merge(self, m, tables):
for i, table in enumerate(tables[1:], start=1):
font = table.cff[0]
defaultWidthX, nominalWidthX = (
font.Private.defaultWidthX,
font.Private.nominalWidthX,
)
widthsDiffer = (
defaultWidthX != newDefaultWidthX or nominalWidthX != newNominalWidthX
)
font.Private = private
fontGlyphOrder = set(font.getGlyphOrder())
for name in font.strings.strings:
@ -278,6 +286,18 @@ def merge(self, m, tables):
newcs.charStrings[name] = i
newcs.charStringsIndex.items.append(None)
for name in cs.charStrings:
if widthsDiffer:
c = cs[name]
defaultWidthXToken = object()
extractor = T2WidthExtractor([], [], nominalWidthX, defaultWidthXToken)
extractor.execute(c)
width = extractor.width
if width is not defaultWidthXToken:
c.program.pop(0)
else:
width = defaultWidthX
if width != newDefaultWidthX:
c.program.insert(0, width - newNominalWidthX)
newcs[name] = cs[name]
newfont.charset = chrset
@ -289,7 +309,6 @@ def merge(self, m, tables):
@add_method(ttLib.getTableClass("cmap"))
def merge(self, m, tables):
# TODO Handle format=14.
if not hasattr(m, "cmap"):
computeMegaCmap(m, tables)

File diff suppressed because it is too large Load Diff