[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:
parent
96223b8aee
commit
2af0adde6c
@ -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)
|
||||||
|
@ -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_()
|
||||||
|
@ -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 {"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user