[feaLib] fix ordering of alternates in aalt lookups
Fixes https://github.com/fonttools/fonttools/issues/2937
This commit is contained in:
parent
a1cb14d3ec
commit
6ff7d00e06
@ -285,7 +285,11 @@ class Builder(object):
|
||||
def build_feature_aalt_(self):
|
||||
if not self.aalt_features_ and not self.aalt_alternates_:
|
||||
return
|
||||
alternates = {g: set(a) for g, a in self.aalt_alternates_.items()}
|
||||
# > alternate glyphs will be sorted in the order that the source features
|
||||
# > are named in the aalt definition, not the order of the feature definitions
|
||||
# > in the file. Alternates defined explicitly ... will precede all others.
|
||||
# https://github.com/fonttools/fonttools/issues/836
|
||||
alternates = {g: list(a) for g, a in self.aalt_alternates_.items()}
|
||||
for location, name in self.aalt_features_ + [(None, "aalt")]:
|
||||
feature = [
|
||||
(script, lang, feature, lookups)
|
||||
@ -302,17 +306,14 @@ class Builder(object):
|
||||
lookuplist = [lookuplist]
|
||||
for lookup in lookuplist:
|
||||
for glyph, alts in lookup.getAlternateGlyphs().items():
|
||||
alternates.setdefault(glyph, set()).update(alts)
|
||||
alts_for_glyph = alternates.setdefault(glyph, [])
|
||||
alts_for_glyph.extend(
|
||||
g for g in alts if g not in alts_for_glyph
|
||||
)
|
||||
single = {
|
||||
glyph: list(repl)[0] for glyph, repl in alternates.items() if len(repl) == 1
|
||||
}
|
||||
# TODO: Figure out the glyph alternate ordering used by makeotf.
|
||||
# https://github.com/fonttools/fonttools/issues/836
|
||||
multi = {
|
||||
glyph: sorted(repl, key=self.font.getGlyphID)
|
||||
for glyph, repl in alternates.items()
|
||||
if len(repl) > 1
|
||||
glyph: repl[0] for glyph, repl in alternates.items() if len(repl) == 1
|
||||
}
|
||||
multi = {glyph: repl for glyph, repl in alternates.items() if len(repl) > 1}
|
||||
if not single and not multi:
|
||||
return
|
||||
self.features_ = {
|
||||
@ -1249,8 +1250,9 @@ class Builder(object):
|
||||
def add_single_subst(self, location, prefix, suffix, mapping, forceChain):
|
||||
if self.cur_feature_name_ == "aalt":
|
||||
for from_glyph, to_glyph in mapping.items():
|
||||
alts = self.aalt_alternates_.setdefault(from_glyph, set())
|
||||
alts.add(to_glyph)
|
||||
alts = self.aalt_alternates_.setdefault(from_glyph, [])
|
||||
if to_glyph not in alts:
|
||||
alts.append(to_glyph)
|
||||
return
|
||||
if prefix or suffix or forceChain:
|
||||
self.add_single_subst_chained_(location, prefix, suffix, mapping)
|
||||
@ -1303,8 +1305,8 @@ class Builder(object):
|
||||
# GSUB 3
|
||||
def add_alternate_subst(self, location, prefix, glyph, suffix, replacement):
|
||||
if self.cur_feature_name_ == "aalt":
|
||||
alts = self.aalt_alternates_.setdefault(glyph, set())
|
||||
alts.update(replacement)
|
||||
alts = self.aalt_alternates_.setdefault(glyph, [])
|
||||
alts.extend(g for g in replacement if g not in alts)
|
||||
return
|
||||
if prefix or suffix:
|
||||
chain = self.get_lookup_(location, ChainContextSubstBuilder)
|
||||
|
@ -774,7 +774,10 @@ class ChainContextSubstBuilder(ChainContextualBuilder):
|
||||
if lookup is not None:
|
||||
alts = lookup.getAlternateGlyphs()
|
||||
for glyph, replacements in alts.items():
|
||||
result.setdefault(glyph, set()).update(replacements)
|
||||
alts_for_glyph = result.setdefault(glyph, [])
|
||||
alts_for_glyph.extend(
|
||||
g for g in replacements if g not in alts_for_glyph
|
||||
)
|
||||
return result
|
||||
|
||||
def find_chainable_single_subst(self, mapping):
|
||||
@ -1238,7 +1241,7 @@ class SingleSubstBuilder(LookupBuilder):
|
||||
return self.buildLookup_(subtables)
|
||||
|
||||
def getAlternateGlyphs(self):
|
||||
return {glyph: set([repl]) for glyph, repl in self.mapping.items()}
|
||||
return {glyph: [repl] for glyph, repl in self.mapping.items()}
|
||||
|
||||
def add_subtable_break(self, location):
|
||||
self.mapping[(self.SUBTABLE_BREAK_, location)] = self.SUBTABLE_BREAK_
|
||||
|
@ -99,18 +99,18 @@
|
||||
<!-- SubTableCount=1 -->
|
||||
<AlternateSubst index="0">
|
||||
<AlternateSet glyph="a">
|
||||
<Alternate glyph="A.sc"/>
|
||||
<Alternate glyph="a.alt1"/>
|
||||
<Alternate glyph="a.alt2"/>
|
||||
<Alternate glyph="a.alt3"/>
|
||||
<Alternate glyph="A.sc"/>
|
||||
</AlternateSet>
|
||||
<AlternateSet glyph="b">
|
||||
<Alternate glyph="B.sc"/>
|
||||
<Alternate glyph="b.alt"/>
|
||||
<Alternate glyph="B.sc"/>
|
||||
</AlternateSet>
|
||||
<AlternateSet glyph="c">
|
||||
<Alternate glyph="C.sc"/>
|
||||
<Alternate glyph="c.mid"/>
|
||||
<Alternate glyph="C.sc"/>
|
||||
</AlternateSet>
|
||||
<AlternateSet glyph="d">
|
||||
<Alternate glyph="d.alt"/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user