From f6d2ff8d2a6479a830c550b1f3253b985142d441 Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Wed, 12 May 2021 08:48:43 +0200 Subject: [PATCH] [feaLib] Allow substituting a glyph class with NULL sub [a b c] by NULL; was producing errors, now it builds as multiple statements. --- Lib/fontTools/feaLib/ast.py | 12 +++++++++--- Lib/fontTools/feaLib/parser.py | 18 ++++++++++++++---- Tests/feaLib/data/delete_glyph.fea | 4 ++++ Tests/feaLib/data/delete_glyph.ttx | 15 +++++++++++++-- 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/Lib/fontTools/feaLib/ast.py b/Lib/fontTools/feaLib/ast.py index 763d0d2c6..4672eb089 100644 --- a/Lib/fontTools/feaLib/ast.py +++ b/Lib/fontTools/feaLib/ast.py @@ -1258,9 +1258,15 @@ class MultipleSubstStatement(Statement): """Calls the builder object's ``add_multiple_subst`` callback.""" prefix = [p.glyphSet() for p in self.prefix] suffix = [s.glyphSet() for s in self.suffix] - builder.add_multiple_subst( - self.location, prefix, self.glyph, suffix, self.replacement, self.forceChain - ) + if not self.replacement and hasattr(self.glyph, "glyphSet"): + for glyph in self.glyph.glyphSet(): + builder.add_multiple_subst( + self.location, prefix, glyph, suffix, self.replacement, self.forceChain + ) + else: + builder.add_multiple_subst( + self.location, prefix, self.glyph, suffix, self.replacement, self.forceChain + ) def asFea(self, indent=""): res = "sub " diff --git a/Lib/fontTools/feaLib/parser.py b/Lib/fontTools/feaLib/parser.py index c4bdc55ee..199d9b3bf 100644 --- a/Lib/fontTools/feaLib/parser.py +++ b/Lib/fontTools/feaLib/parser.py @@ -892,16 +892,26 @@ class Parser(object): old, new, old_prefix, old_suffix, forceChain=hasMarks, location=location ) + # Glyph deletion, built as GSUB lookup type 2: Multiple substitution + # with empty replacement. + if is_deletion and len(old) == 1 and num_lookups == 0: + return self.ast.MultipleSubstStatement( + old_prefix, + old[0], + old_suffix, + (), + forceChain=hasMarks, + location=location, + ) + # GSUB lookup type 2: Multiple substitution. # Format: "substitute f_f_i by f f i;" if ( not reverse and len(old) == 1 and len(old[0].glyphSet()) == 1 - and ( - (len(new) > 1 and max([len(n.glyphSet()) for n in new]) == 1) - or len(new) == 0 - ) + and len(new) > 1 + and max([len(n.glyphSet()) for n in new]) == 1 and num_lookups == 0 ): return self.ast.MultipleSubstStatement( diff --git a/Tests/feaLib/data/delete_glyph.fea b/Tests/feaLib/data/delete_glyph.fea index 36e0f0f9a..ab4b93f11 100644 --- a/Tests/feaLib/data/delete_glyph.fea +++ b/Tests/feaLib/data/delete_glyph.fea @@ -1,3 +1,7 @@ feature test { sub a by NULL; } test; + +feature test { + sub [a b c] by NULL; +} test; diff --git a/Tests/feaLib/data/delete_glyph.ttx b/Tests/feaLib/data/delete_glyph.ttx index 777f6e364..b28259fb6 100644 --- a/Tests/feaLib/data/delete_glyph.ttx +++ b/Tests/feaLib/data/delete_glyph.ttx @@ -22,13 +22,14 @@ - + + - + @@ -37,6 +38,16 @@ + + + + + + + + + +