[feaLib] Parse Mark-to-mark attachment positioning statements

No output is produced yet; this will come in an upcoming change.
This commit is contained in:
Sascha Brawer 2015-12-09 17:14:13 +01:00
parent 96223b8aee
commit 2af0adde6c
3 changed files with 51 additions and 4 deletions

View File

@ -198,6 +198,17 @@ class MarkLigPosStatement(Statement):
builder.add_mark_lig_pos(self.location, self.ligatures, self.marks) builder.add_mark_lig_pos(self.location, self.ligatures, self.marks)
class MarkMarkPosStatement(Statement):
def __init__(self, location, baseMarks, marks):
Statement.__init__(self, location)
self.baseMarks, self.marks = baseMarks, marks
def build(self, builder):
# TODO: Implement this.
# builder.add_mark_mark_pos(self.location, self.baseMarks, self.marks)
pass
class MultipleSubstStatement(Statement): class MultipleSubstStatement(Statement):
def __init__(self, location, glyph, replacement): def __init__(self, location, glyph, replacement):
Statement.__init__(self, location) Statement.__init__(self, location)

View File

@ -286,6 +286,8 @@ class Parser(object):
return self.parse_position_base_(enumerated, vertical) return self.parse_position_base_(enumerated, vertical)
elif self.next_token_ == "ligature": # GPOS type 5 elif self.next_token_ == "ligature": # GPOS type 5
return self.parse_position_ligature_(enumerated, vertical) return self.parse_position_ligature_(enumerated, vertical)
elif self.next_token_ == "mark": # GPOS type 6
return self.parse_position_mark_(enumerated, vertical)
location = self.cur_token_location_ location = self.cur_token_location_
gc2, value2 = None, None gc2, value2 = None, None
@ -353,6 +355,19 @@ class Parser(object):
self.expect_symbol_(";") self.expect_symbol_(";")
return ast.MarkLigPosStatement(location, ligatures, marks) return ast.MarkLigPosStatement(location, ligatures, marks)
def parse_position_mark_(self, enumerated, vertical):
location = self.cur_token_location_
self.expect_keyword_("mark")
if enumerated:
raise FeatureLibError(
'"enumerate" is not allowed with '
'mark-to-mark attachment positioning',
location)
baseMarks = self.parse_glyphclass_(accept_glyphname=True)
marks = self.parse_anchor_marks_()
self.expect_symbol_(";")
return ast.MarkMarkPosStatement(location, baseMarks, marks)
def parse_script_(self): def parse_script_(self):
assert self.is_cur_keyword_("script") assert self.is_cur_keyword_("script")
location, script = self.cur_token_location_, self.expect_script_tag_() location, script = self.cur_token_location_, self.expect_script_tag_()

View File

@ -456,10 +456,8 @@ class ParserTest(unittest.TestCase):
self.assertEqual(type(pos), ast.MarkBasePosStatement) self.assertEqual(type(pos), ast.MarkBasePosStatement)
self.assertEqual(pos.base, {"a", "e", "o", "u"}) self.assertEqual(pos.base, {"a", "e", "o", "u"})
(a1, m1), (a2, m2) = pos.marks (a1, m1), (a2, m2) = pos.marks
self.assertEqual((a1.x, a1.y), (250, 450)) self.assertEqual((a1.x, a1.y, m1.name), (250, 450, "TOP_MARKS"))
self.assertEqual(m1.name, "TOP_MARKS") self.assertEqual((a2.x, a2.y, m2.name), (210, -10, "BOTTOM_MARKS"))
self.assertEqual((a2.x, a2.y), (210, -10))
self.assertEqual(m2.name, "BOTTOM_MARKS")
def test_gpos_type_4_enumerated(self): def test_gpos_type_4_enumerated(self):
self.assertRaisesRegex( self.assertRaisesRegex(
@ -510,6 +508,29 @@ class ParserTest(unittest.TestCase):
" ligComponent <anchor NULL>;" " ligComponent <anchor NULL>;"
"} test;") "} test;")
def test_gpos_type_6(self):
doc = self.parse(
"markClass damma <anchor 189 -103> @MARK_CLASS_1;"
"feature test {"
" position mark hamza <anchor 221 301> mark @MARK_CLASS_1;"
"} test;")
pos = doc.statements[-1].statements[0]
self.assertEqual(type(pos), ast.MarkMarkPosStatement)
self.assertEqual(pos.baseMarks, {"hamza"})
[(a1, m1)] = pos.marks
self.assertEqual((a1.x, a1.y, m1.name), (221, 301, "MARK_CLASS_1"))
def test_gpos_type_6_enumerated(self):
self.assertRaisesRegex(
FeatureLibError,
'"enumerate" is not allowed with '
'mark-to-mark attachment positioning',
self.parse,
"markClass damma <anchor 189 -103> @MARK_CLASS_1;"
"feature test {"
" enum pos mark hamza <anchor 221 301> mark @MARK_CLASS_1;"
"} test;")
def test_markClass(self): def test_markClass(self):
doc = self.parse("markClass [acute grave] <anchor 350 3> @MARKS;" doc = self.parse("markClass [acute grave] <anchor 350 3> @MARKS;"
"feature test {" "feature test {"