diff --git a/Lib/fontTools/feaLib/ast.py b/Lib/fontTools/feaLib/ast.py index 23c7a3c31..d0f0c969b 100644 --- a/Lib/fontTools/feaLib/ast.py +++ b/Lib/fontTools/feaLib/ast.py @@ -197,12 +197,13 @@ class SubstitutionRule(Statement): class ValueRecord(Statement): - def __init__(self, location, xPlacement, yPlacement, xAdvance, yAdvance): + def __init__(self, location, xPlacement, yPlacement, xAdvance, yAdvance, + xPlaDevice, yPlaDevice, xAdvDevice, yAdvDevice): Statement.__init__(self, location) self.xPlacement, self.yPlacement = (xPlacement, yPlacement) self.xAdvance, self.yAdvance = (xAdvance, yAdvance) - self.xPlaDevice, self.yPlaDevice = (0, 0) - self.xAdvDevice, self.yAdvDevice = (0, 0) + self.xPlaDevice, self.yPlaDevice = (xPlaDevice, yPlaDevice) + self.xAdvDevice, self.yAdvDevice = (xAdvDevice, yAdvDevice) def __eq__(self, other): return (self.xPlacement == other.xPlacement and diff --git a/Lib/fontTools/feaLib/builder.py b/Lib/fontTools/feaLib/builder.py index 173e7fc27..4627c0891 100644 --- a/Lib/fontTools/feaLib/builder.py +++ b/Lib/fontTools/feaLib/builder.py @@ -327,14 +327,20 @@ def makeOpenTypeValueRecord(v): vr.XAdvance = v.xAdvance if v.yAdvance: vr.YAdvance = v.yAdvance - if v.xPlaDevice: - vr.XPlaDevice = v.xPlaDevice - if v.yPlaDevice: - vr.YPlaDevice = v.yPlaDevice - if v.xAdvDevice: - vr.XAdvDevice = v.xAdvDevice - if v.yAdvDevice: - vr.YAdvDevice = v.yAdvDevice + + # TODO: Implement the following. Not sure how, though. + # The commented-out lines did not work; the problem is that we need to + # construct a Device table with an array of delta values. + # if v.xPlaDevice: + # vr.XPlaDevice = otTables.XPlaDevice() + # vr.XPlaDevice.value = v.xPlaDevice + # if v.yPlaDevice: + # vr.YPlaDevice = v.yPlaDevice + # if v.xAdvDevice: + # vr.XAdvDevice = v.xAdvDevice + # if v.yAdvDevice: + # vr.YAdvDevice = v.yAdvDevice + vrMask = 0 for mask, name, _, _ in otBase.valueRecordFormat: if getattr(vr, name, 0) != 0: diff --git a/Lib/fontTools/feaLib/parser.py b/Lib/fontTools/feaLib/parser.py index f84686bf5..b1521ebd3 100644 --- a/Lib/fontTools/feaLib/parser.py +++ b/Lib/fontTools/feaLib/parser.py @@ -332,9 +332,9 @@ class Parser(object): if self.next_token_type_ is Lexer.NUMBER: number, location = self.expect_number_(), self.cur_token_location_ if vertical: - val = ast.ValueRecord(location, 0, 0, 0, number) + val = ast.ValueRecord(location, 0, 0, 0, number, 0, 0, 0, 0) else: - val = ast.ValueRecord(location, 0, 0, number, 0) + val = ast.ValueRecord(location, 0, 0, number, 0, 0, 0, 0, 0) return val self.expect_symbol_("<") location = self.cur_token_location_ @@ -351,9 +351,16 @@ class Parser(object): xPlacement, yPlacement, xAdvance, yAdvance = ( self.expect_number_(), self.expect_number_(), self.expect_number_(), self.expect_number_()) + if self.next_token_type_ is Lexer.NUMBER: + xPlaDevice, yPlaDevice, xAdvDevice, yAdvDevice = ( + self.expect_number_(), self.expect_number_(), + self.expect_number_(), self.expect_number_()) + else: + xPlaDevice, yPlaDevice, xAdvDevice, yAdvDevice = (0, 0, 0, 0) self.expect_symbol_(">") return ast.ValueRecord( - location, xPlacement, yPlacement, xAdvance, yAdvance) + location, xPlacement, yPlacement, xAdvance, yAdvance, + xPlaDevice, yPlaDevice, xAdvDevice, yAdvDevice) def parse_valuerecord_definition_(self, vertical): assert self.is_cur_keyword_("valueRecordDef") diff --git a/Lib/fontTools/feaLib/parser_test.py b/Lib/fontTools/feaLib/parser_test.py index 9cd4f8142..8c1ef3c17 100644 --- a/Lib/fontTools/feaLib/parser_test.py +++ b/Lib/fontTools/feaLib/parser_test.py @@ -444,6 +444,10 @@ class ParserTest(unittest.TestCase): self.assertEqual(value.yPlacement, 0) self.assertEqual(value.xAdvance, 123) self.assertEqual(value.yAdvance, 0) + self.assertEqual(value.xPlaDevice, 0) + self.assertEqual(value.yPlaDevice, 0) + self.assertEqual(value.xAdvDevice, 0) + self.assertEqual(value.yAdvDevice, 0) def test_valuerecord_format_a_vertical(self): doc = self.parse("feature vkrn {valueRecordDef 123 foo;} vkrn;") @@ -452,6 +456,10 @@ class ParserTest(unittest.TestCase): self.assertEqual(value.yPlacement, 0) self.assertEqual(value.xAdvance, 0) self.assertEqual(value.yAdvance, 123) + self.assertEqual(value.xPlaDevice, 0) + self.assertEqual(value.yPlaDevice, 0) + self.assertEqual(value.xAdvDevice, 0) + self.assertEqual(value.yAdvDevice, 0) def test_valuerecord_format_b(self): doc = self.parse("feature liga {valueRecordDef <1 2 3 4> foo;} liga;") @@ -460,6 +468,23 @@ class ParserTest(unittest.TestCase): self.assertEqual(value.yPlacement, 2) self.assertEqual(value.xAdvance, 3) self.assertEqual(value.yAdvance, 4) + self.assertEqual(value.xPlaDevice, 0) + self.assertEqual(value.yPlaDevice, 0) + self.assertEqual(value.xAdvDevice, 0) + self.assertEqual(value.yAdvDevice, 0) + + def test_valuerecord_format_c(self): + doc = self.parse( + "feature liga {valueRecordDef <1 2 3 4 5 6 7 8> foo;} liga;") + value = doc.statements[0].statements[0].value + self.assertEqual(value.xPlacement, 1) + self.assertEqual(value.yPlacement, 2) + self.assertEqual(value.xAdvance, 3) + self.assertEqual(value.yAdvance, 4) + self.assertEqual(value.xPlaDevice, 5) + self.assertEqual(value.yPlaDevice, 6) + self.assertEqual(value.xAdvDevice, 7) + self.assertEqual(value.yAdvDevice, 8) def test_valuerecord_named(self): doc = self.parse("valueRecordDef <1 2 3 4> foo;" diff --git a/Lib/fontTools/feaLib/testdata/GPOS_1.fea b/Lib/fontTools/feaLib/testdata/GPOS_1.fea index 4867974b5..6d27f9f65 100644 --- a/Lib/fontTools/feaLib/testdata/GPOS_1.fea +++ b/Lib/fontTools/feaLib/testdata/GPOS_1.fea @@ -4,8 +4,8 @@ languagesystem DFLT dflt; feature kern { position [one two three] <-80 0 -160 0>; - position A <1 2 3 4>; - position B <1 2 3 4>; + position A <1 2 3 4 5 6 7 8>; + position B <1 2 3 4 5 6 7 8>; position four 400; position five <-80 0 -160 0>; position six -200;