[varLib/cff] Allow sparse masters

Fixes https://github.com/fonttools/fonttools/issues/3233
This commit is contained in:
Behdad Esfahbod 2023-08-01 10:28:01 -06:00
parent 91731f7d2a
commit 839e76b84d

View File

@ -350,10 +350,24 @@ def merge_region_fonts(varFont, model, ordered_fonts_list, glyphOrder):
addCFFVarStore(varFont, model, cvData.varDataList, cvData.masterSupports) addCFFVarStore(varFont, model, cvData.varDataList, cvData.masterSupports)
def _get_cs(charstrings, glyphName): def _get_cs(charstrings, glyphName, filterEmpty=False):
if glyphName not in charstrings: if glyphName not in charstrings:
return None return None
return charstrings[glyphName] cs = charstrings[glyphName]
if filterEmpty:
cs.decompile()
# print(cs.program)
if cs.program == []: # CFF2 empty charstring
return None
elif (
len(cs.program) <= 2
and cs.program[-1] == "endchar"
and (len(cs.program) == 1 or type(cs.program[0]) in (int, float))
): # CFF1 empty charstring
return None
return cs
def _add_new_vsindex( def _add_new_vsindex(
@ -373,16 +387,15 @@ def _add_new_vsindex(
def merge_charstrings(glyphOrder, num_masters, top_dicts, masterModel): def merge_charstrings(glyphOrder, num_masters, top_dicts, masterModel):
vsindex_dict = {} vsindex_dict = {}
vsindex_by_key = {} vsindex_by_key = {}
varDataList = [] varDataList = []
masterSupports = [] masterSupports = []
default_charstrings = top_dicts[0].CharStrings default_charstrings = top_dicts[0].CharStrings
for gid, gname in enumerate(glyphOrder): for gid, gname in enumerate(glyphOrder):
all_cs = [_get_cs(td.CharStrings, gname) for td in top_dicts] all_cs = [
if len([gs for gs in all_cs if gs is not None]) == 1: _get_cs(td.CharStrings, gname, i != 0) for i, td in enumerate(top_dicts)
continue ]
model, model_cs = masterModel.getSubModel(all_cs) model, model_cs = masterModel.getSubModel(all_cs)
# create the first pass CFF2 charstring, from # create the first pass CFF2 charstring, from
# the default charstring. # the default charstring.
@ -411,6 +424,9 @@ def merge_charstrings(glyphOrder, num_masters, top_dicts, masterModel):
) )
default_charstrings[gname] = new_cs default_charstrings[gname] = new_cs
if not region_cs:
continue
if (not var_pen.seen_moveto) or ("blend" not in new_cs.program): if (not var_pen.seen_moveto) or ("blend" not in new_cs.program):
# If this is not a marking glyph, or if there are no blend # If this is not a marking glyph, or if there are no blend
# arguments, then we can use vsindex 0. No need to # arguments, then we can use vsindex 0. No need to