[feaLib] Prohibit script
and language
statements within named lookups
This commit is contained in:
parent
5f2e55d5fc
commit
8e8a0d68c7
@ -42,6 +42,12 @@ class LookupBlock(Block):
|
||||
Block.__init__(self, location)
|
||||
self.name, self.use_extension = name, use_extension
|
||||
|
||||
def build(self, builder):
|
||||
# TODO(sascha): Handle use_extension.
|
||||
builder.start_lookup_block(self.location, self.name)
|
||||
Block.build(self, builder)
|
||||
builder.end_lookup_block()
|
||||
|
||||
|
||||
class GlyphClassDefinition(Statement):
|
||||
def __init__(self, location, name, glyphs):
|
||||
|
@ -18,7 +18,9 @@ class Builder(object):
|
||||
self.script_ = None
|
||||
self.lookup_flag_ = 0
|
||||
self.language_systems = set()
|
||||
self.named_lookups_ = {}
|
||||
self.cur_lookup_ = None
|
||||
self.cur_lookup_name_ = None
|
||||
self.lookups_ = []
|
||||
|
||||
def build(self):
|
||||
@ -28,10 +30,14 @@ class Builder(object):
|
||||
self.gsub = self.font['GSUB'] = self.makeTable('GSUB')
|
||||
|
||||
def get_lookup_(self, location, builder_class):
|
||||
if self.cur_lookup_ and type(self.cur_lookup_) == builder_class:
|
||||
if (self.cur_lookup_ and
|
||||
type(self.cur_lookup_) == builder_class and
|
||||
self.cur_lookup_.lookup_flag == self.lookup_flag_):
|
||||
return self.cur_lookup_
|
||||
self.cur_lookup_ = builder_class(location, self.lookup_flag_)
|
||||
self.lookups_.append(self.cur_lookup_)
|
||||
if self.cur_lookup_name_:
|
||||
self.named_lookups_[self.cur_lookup_name_] = self.cur_lookup_
|
||||
return self.cur_lookup_
|
||||
|
||||
def makeTable(self, tag):
|
||||
@ -88,12 +94,30 @@ class Builder(object):
|
||||
|
||||
def start_feature(self, location, name):
|
||||
self.language_systems = self.get_default_language_systems_()
|
||||
self.cur_lookup_ = None
|
||||
|
||||
def end_feature(self):
|
||||
self.language_systems = None
|
||||
self.cur_lookup_ = None
|
||||
|
||||
def start_lookup_block(self, location, name):
|
||||
if name in self.named_lookups_:
|
||||
raise FeatureLibError(
|
||||
'Lookup "%s" has already been defined' % name, location)
|
||||
self.cur_lookup_name_ = name
|
||||
self.named_lookups_[name] = None
|
||||
self.cur_lookup_ = None
|
||||
|
||||
def end_lookup_block(self):
|
||||
assert self.cur_lookup_name_ is not None
|
||||
self.cur_lookup_name_ = None
|
||||
self.cur_lookup_ = None
|
||||
|
||||
def set_language(self, location, language, include_default):
|
||||
if self.cur_lookup_name_:
|
||||
raise FeatureLibError(
|
||||
"Within a named lookup block, it is not allowed "
|
||||
"to change the language", location)
|
||||
self.cur_lookup_ = None
|
||||
if include_default:
|
||||
langsys = set(self.get_default_language_systems_())
|
||||
@ -103,6 +127,10 @@ class Builder(object):
|
||||
self.language_systems = frozenset(langsys)
|
||||
|
||||
def set_script(self, location, script):
|
||||
if self.cur_lookup_name_:
|
||||
raise FeatureLibError(
|
||||
"Within a named lookup block, it is not allowed "
|
||||
"to change the script", location)
|
||||
self.cur_lookup_ = None
|
||||
self.script_ = script
|
||||
self.lookup_flag_ = 0
|
||||
|
@ -120,6 +120,13 @@ class BuilderTest(unittest.TestCase):
|
||||
self.assertEqual(builder.language_systems,
|
||||
{('DFLT', 'dflt'), ('cyrl', 'dflt')})
|
||||
|
||||
def test_script_in_lookup_block(self):
|
||||
self.assertRaisesRegex(
|
||||
FeatureLibError,
|
||||
"Within a named lookup block, it is not allowed "
|
||||
"to change the script",
|
||||
self.build, "lookup Foo { script latn; } Foo;")
|
||||
|
||||
def test_language(self):
|
||||
builder = Builder(None, TTFont())
|
||||
builder.add_language_system(None, 'latn', 'FRA')
|
||||
@ -133,6 +140,19 @@ class BuilderTest(unittest.TestCase):
|
||||
self.assertEqual(builder.language_systems,
|
||||
{('latn', 'FRA'), ('cyrl', 'BGR')})
|
||||
|
||||
def test_language_in_lookup_block(self):
|
||||
self.assertRaisesRegex(
|
||||
FeatureLibError,
|
||||
"Within a named lookup block, it is not allowed "
|
||||
"to change the language",
|
||||
self.build, "lookup Foo { language RUS; } Foo;")
|
||||
|
||||
def test_lookup_already_defined(self):
|
||||
self.assertRaisesRegex(
|
||||
FeatureLibError,
|
||||
"Lookup \"foo\" has already been defined",
|
||||
self.build, "lookup foo {} foo; lookup foo {} foo;")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
Loading…
x
Reference in New Issue
Block a user