From 06678755387b86f7144790c4b5b988f187176365 Mon Sep 17 00:00:00 2001 From: Miguel Sousa Date: Mon, 5 Feb 2018 23:17:16 -0800 Subject: [PATCH] [feaLib] Method to parse Character statements --- Lib/fontTools/feaLib/ast.py | 13 +++++++++++++ Lib/fontTools/feaLib/parser.py | 17 +++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/Lib/fontTools/feaLib/ast.py b/Lib/fontTools/feaLib/ast.py index bcb8f1006..7bb071a54 100644 --- a/Lib/fontTools/feaLib/ast.py +++ b/Lib/fontTools/feaLib/ast.py @@ -1153,6 +1153,19 @@ class SizeParameters(Statement): return res + ";" +class CharacterStatement(Statement): + """ + Statement used in cvParameters blocks of Character Variant features (cvXX). + The Unicode value may be written with either decimal or hexadecimal + notation. The value must be preceded by '0x' if it is a hexadecimal value. + The largest Unicode value allowed is 0xFFFFFF. + """ + def __init__(self, location, character, tag): + Statement.__init__(self, location) + self.character = character + self.tag = tag + + class BaseAxis(Statement): def __init__(self, bases, scripts, vertical, location=None): Statement.__init__(self, location) diff --git a/Lib/fontTools/feaLib/parser.py b/Lib/fontTools/feaLib/parser.py index 022a837a0..7430419c7 100644 --- a/Lib/fontTools/feaLib/parser.py +++ b/Lib/fontTools/feaLib/parser.py @@ -1310,6 +1310,16 @@ class Parser(object): self.expect_symbol_(";") return block + def parse_cvCharacter_(self, tag): + assert self.cur_token_ == "Character", self.cur_token_ + location, character = self.cur_token_location_, self.expect_decimal_or_hexadecimal_() + self.expect_symbol_(";") + if not (0xFFFFFF >= character >= 0): + raise FeatureLibError("Character value must be between " + "{:#x} and {:#x}".format(0, 0xFFFFFF), + location) + return self.ast.CharacterStatement(location, character, tag) + def parse_FontRevision_(self): assert self.cur_token_ == "FontRevision", self.cur_token_ location, version = self.cur_token_location_, self.expect_float_() @@ -1530,6 +1540,13 @@ class Parser(object): raise FeatureLibError("Expected an integer or floating-point number", self.cur_token_location_) + def expect_decimal_or_hexadecimal_(self): + self.advance_lexer_() + if self.cur_token_type_ is Lexer.NUMBER: + return self.cur_token_ + raise FeatureLibError("Expected a decimal or hexadecimal number", + self.cur_token_location_) + def expect_string_(self): self.advance_lexer_() if self.cur_token_type_ is Lexer.STRING: