From 923fd2cb4d1d27a2fa44bb41420a043f5eba25d6 Mon Sep 17 00:00:00 2001 From: moyogo Date: Wed, 7 Oct 2015 23:16:55 +0100 Subject: [PATCH] [voltLib] Add adjust pair positioning --- Lib/fontTools/voltLib/ast.py | 7 +++++ Lib/fontTools/voltLib/parser.py | 39 +++++++++++++++++++++------- Lib/fontTools/voltLib/parser_test.py | 25 ++++++++++++++++++ 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/Lib/fontTools/voltLib/ast.py b/Lib/fontTools/voltLib/ast.py index f76feecde..eed8f0f87 100644 --- a/Lib/fontTools/voltLib/ast.py +++ b/Lib/fontTools/voltLib/ast.py @@ -69,6 +69,13 @@ class PositionAttachDefinition(ast.Statement): self.coverage_to = coverage_to self.anchor = anchor +class PositionAdjustPairDefinition(ast.Statement): + def __init__(self, location, coverages_1, coverages_2, adjust): + ast.Statement.__init__(self, location) + self.coverages_1 = coverages_1 + self.coverages_2 = coverages_2 + self.adjust = adjust + class ContextDefinition(ast.Statement): def __init__(self, location, ex_or_in, left=[], right=[]): ast.Statement.__init__(self, location) diff --git a/Lib/fontTools/voltLib/parser.py b/Lib/fontTools/voltLib/parser.py index d67ac7915..73d26e234 100644 --- a/Lib/fontTools/voltLib/parser.py +++ b/Lib/fontTools/voltLib/parser.py @@ -223,10 +223,10 @@ class Parser(object): def parse_position_(self): assert self.is_cur_keyword_("AS_POSITION") location = self.cur_token_location_ - position = self.expect_name_() - assert position in ("ATTACH", "ATTACH_CURSIVE", "ADJUST_PAIR", + pos_type = self.expect_name_() + assert pos_type in ("ATTACH", "ATTACH_CURSIVE", "ADJUST_PAIR", "ADJUST_SINGLE") - if position == "ATTACH": + if pos_type == "ATTACH": coverage = self.parse_coverage_() self.expect_keyword_("TO") coverage_to = self.parse_coverage_() @@ -234,19 +234,38 @@ class Parser(object): self.expect_keyword_("ANCHOR") anchor_name = self.expect_string_() self.expect_keyword_("END_ATTACH") - pos = ast.PositionAttachDefinition(location, coverage, coverage_to, + position = ast.PositionAttachDefinition(location, coverage, coverage_to, anchor_name) - elif position == "ATTACH_CURSIVE": + elif pos_type == "ATTACH_CURSIVE": raise VoltLibError("ATTACH_CURSIVE not yet implemented.", location) - elif position == "ADJUST_PAIR": - raise VoltLibError("ATTACH_CURSIVE not yet implemented.", - location) - elif position == "ADJUST_SINGLE": + elif pos_type == "ADJUST_PAIR": + coverages_1 = [] + coverages_2 = [] + adjust = {} + while self.next_token_ == "FIRST": + self.advance_lexer_() + coverage_1 = self.parse_coverage_() + coverages_1.append(coverage_1) + while self.next_token_ == "SECOND": + self.advance_lexer_() + coverage_2 = self.parse_coverage_() + coverages_2.append(coverage_2) + while self.next_token_ != "END_ADJUST": + id_1 = self.expect_number_() + id_2 = self.expect_number_() + self.expect_keyword_("BY") + pos_1 = self.parse_pos_() + pos_2 = self.parse_pos_() + adjust[(id_1, id_2)] = (pos_1, pos_2) + self.expect_keyword_("END_ADJUST") + position = ast.PositionAdjustPairDefinition(location, coverages_1, + coverages_2, adjust) + elif pos_type == "ADJUST_SINGLE": raise VoltLibError("ADJUST_SINGLE not yet implemented.", location) self.expect_keyword_("END_POSITION") - return pos + return position def parse_def_anchor_(self): assert self.is_cur_keyword_("DEF_ANCHOR") diff --git a/Lib/fontTools/voltLib/parser_test.py b/Lib/fontTools/voltLib/parser_test.py index da722bb46..16f354680 100644 --- a/Lib/fontTools/voltLib/parser_test.py +++ b/Lib/fontTools/voltLib/parser_test.py @@ -261,6 +261,31 @@ class ParserTest(unittest.TestCase): ("top", 31, "a", 1, False, (None, 210, 450, {}, {}, {})) ) + def test_adjust_pair(self): + [lookup] = self.parse( + 'DEF_LOOKUP "kern1" PROCESS_BASE PROCESS_MARKS ALL ' + 'DIRECTION RTL\n' + 'IN_CONTEXT\n' + 'END_CONTEXT\n' + 'AS_POSITION\n' + 'ADJUST_PAIR\n' + ' FIRST GLYPH "A"\n' + ' SECOND GLYPH "V"\n' + ' 1 2 BY POS ADV -30 END_POS POS END_POS\n' + ' 2 1 BY POS ADV -30 END_POS POS END_POS\n' + 'END_ADJUST\n' + 'END_POSITION\n' + ).statements + self.assertEqual( + (lookup.name, lookup.pos.coverages_1, lookup.pos.coverages_2, + lookup.pos.adjust), + ("kern1", [["A"]], [["V"]], + {(1, 2): ((-30, None, None, {}, {}, {}), + (None, None, None, {}, {}, {})), + (2, 1): ((-30, None, None, {}, {}, {}), + (None, None, None, {}, {}, {}))}) + ) + def test_def_anchor(self): [anchor] = self.parse( 'DEF_ANCHOR "MARK_top" ON 120 GLYPH acutecomb COMPONENT 1 AT POS DX 0 DY 450 END_POS END_ANCHOR'