[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:
Sascha Brawer 2015-12-04 15:49:04 +01:00
parent b99f1c9af4
commit 46c76dbf1f
5 changed files with 55 additions and 16 deletions

View File

@ -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

View File

@ -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:

View File

@ -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")

View File

@ -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;"

View File

@ -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;