[feaLib] Handle languagesystem
, script
and languaguage
statements
Currently, the compiler uses them to figure out which set of languagesystems would apply for the current scope. However, this information is not yet used for anything.
This commit is contained in:
parent
701c72116d
commit
102c0e0e56
@ -30,6 +30,11 @@ class FeatureBlock(Block):
|
||||
Block.__init__(self, location)
|
||||
self.name, self.use_extension = name, use_extension
|
||||
|
||||
def build(self, builder):
|
||||
# TODO(sascha): Handle use_extension.
|
||||
builder.start_feature(self.location, self.name)
|
||||
Block.build(self, builder)
|
||||
|
||||
|
||||
class LookupBlock(Block):
|
||||
def __init__(self, location, name, use_extension):
|
||||
@ -63,6 +68,11 @@ class LanguageStatement(Statement):
|
||||
self.include_default = include_default
|
||||
self.required = required
|
||||
|
||||
def build(self, builder):
|
||||
# TODO(sascha): Handle required.
|
||||
builder.set_language(location=self.location, language=self.language,
|
||||
include_default=self.include_default)
|
||||
|
||||
|
||||
class LanguageSystemStatement(Statement):
|
||||
def __init__(self, location, script, language):
|
||||
@ -90,6 +100,9 @@ class ScriptStatement(Statement):
|
||||
Statement.__init__(self, location)
|
||||
self.script = script
|
||||
|
||||
def build(self, builder):
|
||||
builder.set_script(self.location, self.script)
|
||||
|
||||
|
||||
class SubtableStatement(Statement):
|
||||
def __init__(self, location):
|
||||
|
@ -14,7 +14,10 @@ class Builder(object):
|
||||
def __init__(self, featurefile_path, font):
|
||||
self.featurefile_path = featurefile_path
|
||||
self.font = font
|
||||
self.language_systems_ = []
|
||||
self.default_language_systems_ = set()
|
||||
self.script_ = None
|
||||
self.lookupflag_ = 0
|
||||
self.language_systems = set()
|
||||
|
||||
def build(self):
|
||||
self.gpos = self.font['GPOS'] = self.makeTable('GPOS')
|
||||
@ -37,9 +40,37 @@ class Builder(object):
|
||||
return table
|
||||
|
||||
def add_language_system(self, location, script, language):
|
||||
if script == "DFLT" and language == "dflt" and self.language_systems_:
|
||||
# OpenType Feature File Specification, section 4.b.i
|
||||
# OpenType Feature File Specification, section 4.b.i
|
||||
if (script == "DFLT" and language == "dflt" and
|
||||
self.default_language_systems_):
|
||||
raise FeatureLibError(
|
||||
'If "languagesystem DFLT dflt" is present, it must be '
|
||||
'the first of the languagesystem statements', location)
|
||||
self.language_systems_.append((script, language))
|
||||
self.default_language_systems_.add((script, language))
|
||||
|
||||
def get_default_language_systems_(self):
|
||||
# OpenType Feature File specification, 4.b.i. languagesystem:
|
||||
# If no "languagesystem" statement is present, then the
|
||||
# implementation must behave exactly as though the following
|
||||
# statement were present at the beginning of the feature file:
|
||||
# languagesystem DFLT dflt;
|
||||
if self.default_language_systems_:
|
||||
return frozenset(self.default_language_systems_)
|
||||
else:
|
||||
return frozenset({('DFLT', 'dflt')})
|
||||
|
||||
def start_feature(self, location, name):
|
||||
self.language_systems = self.get_default_language_systems_()
|
||||
|
||||
def set_language(self, location, language, include_default):
|
||||
if include_default:
|
||||
langsys = set(self.get_default_language_systems_())
|
||||
else:
|
||||
langsys = set()
|
||||
langsys.add((self.script_, language))
|
||||
self.language_systems = frozenset(langsys)
|
||||
|
||||
def set_script(self, location, script):
|
||||
self.script_ = script
|
||||
self.lookupflag_ = 0
|
||||
self.set_language(location, 'dflt', include_default=True)
|
||||
|
@ -1,6 +1,6 @@
|
||||
from __future__ import print_function, division, absolute_import
|
||||
from __future__ import unicode_literals
|
||||
from fontTools.feaLib.builder import addOpenTypeFeatures
|
||||
from fontTools.feaLib.builder import Builder, addOpenTypeFeatures
|
||||
from fontTools.feaLib.error import FeatureLibError
|
||||
from fontTools.ttLib import TTFont
|
||||
import codecs
|
||||
@ -77,6 +77,19 @@ class BuilderTest(unittest.TestCase):
|
||||
addOpenTypeFeatures(self.getpath("spec4h1.fea"), font)
|
||||
self.expect_ttx(font, self.getpath("spec4h1_expected.ttx"))
|
||||
|
||||
def test_languagesystem(self):
|
||||
builder = Builder(None, TTFont())
|
||||
builder.add_language_system(None, 'latn', 'FRA')
|
||||
builder.add_language_system(None, 'cyrl', 'RUS')
|
||||
builder.start_feature(location=None, name='test')
|
||||
self.assertEqual(builder.language_systems,
|
||||
{('latn', 'FRA'), ('cyrl', 'RUS')})
|
||||
|
||||
def test_languagesystem_none_specified(self):
|
||||
builder = Builder(None, TTFont())
|
||||
builder.start_feature(location=None, name='test')
|
||||
self.assertEqual(builder.language_systems, {('DFLT', 'dflt')})
|
||||
|
||||
def test_languagesystem_DFLT_dflt_not_first(self):
|
||||
self.assertRaisesRegex(
|
||||
FeatureLibError,
|
||||
@ -84,6 +97,26 @@ class BuilderTest(unittest.TestCase):
|
||||
"it must be the first of the languagesystem statements",
|
||||
self.build, "languagesystem latn TRK; languagesystem DFLT dflt;")
|
||||
|
||||
def test_script(self):
|
||||
builder = Builder(None, TTFont())
|
||||
builder.start_feature(location=None, name='test')
|
||||
builder.set_script(location=None, script='cyrl')
|
||||
self.assertEqual(builder.language_systems,
|
||||
{('DFLT', 'dflt'), ('cyrl', 'dflt')})
|
||||
|
||||
def test_language(self):
|
||||
builder = Builder(None, TTFont())
|
||||
builder.add_language_system(None, 'latn', 'FRA')
|
||||
builder.start_feature(location=None, name='test')
|
||||
builder.set_script(location=None, script='cyrl')
|
||||
builder.set_language(location=None, language='RUS',
|
||||
include_default=False)
|
||||
self.assertEqual(builder.language_systems, {('cyrl', 'RUS')})
|
||||
builder.set_language(location=None, language='BGR',
|
||||
include_default=True)
|
||||
self.assertEqual(builder.language_systems,
|
||||
{('latn', 'FRA'), ('cyrl', 'BGR')})
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
Loading…
x
Reference in New Issue
Block a user