From ca716e0925b630f64afdf5d4d4c6e7dc8866df24 Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Tue, 15 Jan 2019 23:31:16 +0200 Subject: [PATCH] [voltLib] Fix check for duplicate anchors When checking for duplicate anchors, the component number should be taken into account since the same anchors can be used for different components i.e. over ligatures. --- Lib/fontTools/voltLib/parser.py | 17 +++++++++-------- Tests/voltLib/parser_test.py | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/Lib/fontTools/voltLib/parser.py b/Lib/fontTools/voltLib/parser.py index db3ccf3ba..09044bbf0 100644 --- a/Lib/fontTools/voltLib/parser.py +++ b/Lib/fontTools/voltLib/parser.py @@ -422,16 +422,17 @@ class Parser(object): gid = self.expect_number_() self.expect_keyword_("GLYPH") glyph_name = self.expect_name_() - # check for duplicate anchor names on this glyph - if (glyph_name in self.anchors_ - and self.anchors_[glyph_name].resolve(name) is not None): - raise VoltLibError( - 'Anchor "%s" already defined, ' - 'anchor names are case insensitive' % name, - location - ) self.expect_keyword_("COMPONENT") component = self.expect_number_() + # check for duplicate anchor names on this glyph + if glyph_name in self.anchors_: + anchor = self.anchors_[glyph_name].resolve(name) + if anchor is not None and anchor.component == component: + raise VoltLibError( + 'Anchor "%s" already defined, ' + 'anchor names are case insensitive' % name, + location + ) if self.next_token_ == "LOCKED": locked = True self.advance_lexer_() diff --git a/Tests/voltLib/parser_test.py b/Tests/voltLib/parser_test.py index 6baf9003a..efe1d373e 100644 --- a/Tests/voltLib/parser_test.py +++ b/Tests/voltLib/parser_test.py @@ -936,6 +936,22 @@ class ParserTest(unittest.TestCase): False, (None, 250, 0, {}, {}, {})) ) + def test_def_anchor_multi_component(self): + [anchor1, anchor2] = self.parse( + 'DEF_ANCHOR "top" ON 120 GLYPH a ' + 'COMPONENT 1 AT POS DX 250 DY 450 END_POS END_ANCHOR\n' + 'DEF_ANCHOR "top" ON 120 GLYPH a ' + 'COMPONENT 2 AT POS DX 250 DY 450 END_POS END_ANCHOR\n' + ).statements + self.assertEqual( + (anchor1.name, anchor1.gid, anchor1.glyph_name, anchor1.component), + ("top", 120, "a", 1) + ) + self.assertEqual( + (anchor2.name, anchor2.gid, anchor2.glyph_name, anchor2.component), + ("top", 120, "a", 2) + ) + def test_def_anchor_duplicate(self): self.assertRaisesRegex( VoltLibError,