[feaLib] fix mixed single/multiple substitutions

If the single substitution involved a glyph class, we were incorrectly
using only the first glyph in the class.

Broken since ec6ff821f0e72022d7aec8794b6bb589d8f81808, apparently no one
else uses this feature!
This commit is contained in:
Khaled Hosny 2020-01-29 22:34:25 +02:00
parent a37dab3824
commit 22bfc305ee
2 changed files with 24 additions and 5 deletions

View File

@ -1452,12 +1452,21 @@ class Parser(object):
# Upgrade all single substitutions to multiple substitutions.
if has_single and has_multiple:
for i, s in enumerate(statements):
statements = []
for s in block.statements:
if isinstance(s, self.ast.SingleSubstStatement):
statements[i] = self.ast.MultipleSubstStatement(
s.prefix, s.glyphs[0].glyphSet()[0], s.suffix,
[r.glyphSet()[0] for r in s.replacements],
s.forceChain, location=s.location)
glyphs = s.glyphs[0].glyphSet()
replacements = s.replacements[0].glyphSet()
if len(replacements) == 1:
replacements *= len(glyphs)
for i, glyph in enumerate(glyphs):
statements.append(
self.ast.MultipleSubstStatement(
s.prefix, glyph, s.suffix, [replacements[i]],
s.forceChain, location=s.location))
else:
statements.append(s)
block.statements = statements
def is_cur_keyword_(self, k):
if self.cur_token_type_ is Lexer.NAME:

View File

@ -1396,12 +1396,22 @@ class ParserTest(unittest.TestCase):
" sub f_f by f f;"
" sub f by f;"
" sub f_f_i by f f i;"
" sub [a a.sc] by a;"
" sub [a a.sc] by [b b.sc];"
"} Look;")
statements = doc.statements[0].statements
for sub in statements:
self.assertIsInstance(sub, ast.MultipleSubstStatement)
self.assertEqual(statements[1].glyph, "f")
self.assertEqual(statements[1].replacement, ["f"])
self.assertEqual(statements[3].glyph, "a")
self.assertEqual(statements[3].replacement, ["a"])
self.assertEqual(statements[4].glyph, "a.sc")
self.assertEqual(statements[4].replacement, ["a"])
self.assertEqual(statements[5].glyph, "a")
self.assertEqual(statements[5].replacement, ["b"])
self.assertEqual(statements[6].glyph, "a.sc")
self.assertEqual(statements[6].replacement, ["b.sc"])
def test_substitute_from(self): # GSUB LookupType 3
doc = self.parse("feature test {"