[feaLib] Parse ValueRecord format C
However, not sure how to build the otTables object graph for emitting GPOS tables with device values; the current code thus silently strips off any device values. Left a TODO comment for implementing this.
This commit is contained in:
parent
b99f1c9af4
commit
46c76dbf1f
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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")
|
||||
|
@ -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;"
|
||||
|
4
Lib/fontTools/feaLib/testdata/GPOS_1.fea
vendored
4
Lib/fontTools/feaLib/testdata/GPOS_1.fea
vendored
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user