Distinguish value records format A from format B with zero values
Fixes https://github.com/fonttools/fonttools/issues/848.
This commit is contained in:
parent
1bc7053978
commit
40474f1aab
@ -973,7 +973,8 @@ class SubtableStatement(Statement):
|
|||||||
|
|
||||||
|
|
||||||
class ValueRecord(Expression):
|
class ValueRecord(Expression):
|
||||||
def __init__(self, location, vertical, xPlacement, yPlacement, xAdvance, yAdvance,
|
def __init__(self, location, vertical,
|
||||||
|
xPlacement, yPlacement, xAdvance, yAdvance,
|
||||||
xPlaDevice, yPlaDevice, xAdvDevice, yAdvDevice):
|
xPlaDevice, yPlaDevice, xAdvDevice, yAdvDevice):
|
||||||
Expression.__init__(self, location)
|
Expression.__init__(self, location)
|
||||||
self.xPlacement, self.yPlacement = (xPlacement, yPlacement)
|
self.xPlacement, self.yPlacement = (xPlacement, yPlacement)
|
||||||
@ -1008,10 +1009,10 @@ class ValueRecord(Expression):
|
|||||||
vertical = self.vertical
|
vertical = self.vertical
|
||||||
|
|
||||||
# Try format A, if possible.
|
# Try format A, if possible.
|
||||||
if x == 0 and y == 0:
|
if x is None and y is None:
|
||||||
if xAdvance == 0 and vertical:
|
if xAdvance is None and vertical:
|
||||||
return str(yAdvance)
|
return str(yAdvance)
|
||||||
elif yAdvance == 0 and not vertical:
|
elif yAdvance is None and not vertical:
|
||||||
return str(xAdvance)
|
return str(xAdvance)
|
||||||
|
|
||||||
# Try format B, if possible.
|
# Try format B, if possible.
|
||||||
|
@ -1024,10 +1024,12 @@ class Parser(object):
|
|||||||
if self.next_token_type_ is Lexer.NUMBER:
|
if self.next_token_type_ is Lexer.NUMBER:
|
||||||
number, location = self.expect_number_(), self.cur_token_location_
|
number, location = self.expect_number_(), self.cur_token_location_
|
||||||
if vertical:
|
if vertical:
|
||||||
val = self.ast.ValueRecord(location, vertical, 0, 0, 0, number,
|
val = self.ast.ValueRecord(location, vertical,
|
||||||
|
None, None, None, number,
|
||||||
None, None, None, None)
|
None, None, None, None)
|
||||||
else:
|
else:
|
||||||
val = self.ast.ValueRecord(location, vertical, 0, 0, number, 0,
|
val = self.ast.ValueRecord(location, vertical,
|
||||||
|
None, None, number, None,
|
||||||
None, None, None, None)
|
None, None, None, None)
|
||||||
return val
|
return val
|
||||||
self.expect_symbol_("<")
|
self.expect_symbol_("<")
|
||||||
|
@ -26,7 +26,6 @@ feature kern {
|
|||||||
# single adjustment positionings, provided the re-definition is using
|
# single adjustment positionings, provided the re-definition is using
|
||||||
# the same value. We replicate this behavior.
|
# the same value. We replicate this behavior.
|
||||||
pos four 400;
|
pos four 400;
|
||||||
#test-fea2fea: pos four 400;
|
|
||||||
pos four <0 0 400 0>;
|
pos four <0 0 400 0>;
|
||||||
pos nine -100;
|
pos nine -100;
|
||||||
} kern;
|
} kern;
|
||||||
|
@ -5,6 +5,5 @@
|
|||||||
languagesystem DFLT dflt;
|
languagesystem DFLT dflt;
|
||||||
|
|
||||||
feature test {
|
feature test {
|
||||||
#test-fea2fea: pos [quoteleft quotedblleft] [Y T]' 20 [quoteright quotedblright];
|
|
||||||
pos [quoteleft quotedblleft] [Y T]' <0 0 20 0> [quoteright quotedblright];
|
pos [quoteleft quotedblleft] [Y T]' <0 0 20 0> [quoteright quotedblright];
|
||||||
} test;
|
} test;
|
||||||
|
@ -529,7 +529,7 @@ class ParserTest(unittest.TestCase):
|
|||||||
[look] = liga.statements
|
[look] = liga.statements
|
||||||
[foo] = look.statements
|
[foo] = look.statements
|
||||||
self.assertEqual(foo.value.xAdvance, 123)
|
self.assertEqual(foo.value.xAdvance, 123)
|
||||||
self.assertEqual(foo.value.yAdvance, 0)
|
self.assertIsNone(foo.value.yAdvance)
|
||||||
|
|
||||||
def test_lookup_block_with_vertical_valueRecordDef(self):
|
def test_lookup_block_with_vertical_valueRecordDef(self):
|
||||||
doc = self.parse("feature vkrn {"
|
doc = self.parse("feature vkrn {"
|
||||||
@ -540,7 +540,7 @@ class ParserTest(unittest.TestCase):
|
|||||||
[vkrn] = doc.statements
|
[vkrn] = doc.statements
|
||||||
[look] = vkrn.statements
|
[look] = vkrn.statements
|
||||||
[foo] = look.statements
|
[foo] = look.statements
|
||||||
self.assertEqual(foo.value.xAdvance, 0)
|
self.assertIsNone(foo.value.xAdvance)
|
||||||
self.assertEqual(foo.value.yAdvance, 123)
|
self.assertEqual(foo.value.yAdvance, 123)
|
||||||
|
|
||||||
def test_lookup_reference(self):
|
def test_lookup_reference(self):
|
||||||
@ -1248,26 +1248,54 @@ class ParserTest(unittest.TestCase):
|
|||||||
def test_valuerecord_format_a_horizontal(self):
|
def test_valuerecord_format_a_horizontal(self):
|
||||||
doc = self.parse("feature liga {valueRecordDef 123 foo;} liga;")
|
doc = self.parse("feature liga {valueRecordDef 123 foo;} liga;")
|
||||||
value = doc.statements[0].statements[0].value
|
value = doc.statements[0].statements[0].value
|
||||||
self.assertEqual(value.xPlacement, 0)
|
self.assertIsNone(value.xPlacement)
|
||||||
self.assertEqual(value.yPlacement, 0)
|
self.assertIsNone(value.yPlacement)
|
||||||
self.assertEqual(value.xAdvance, 123)
|
self.assertEqual(value.xAdvance, 123)
|
||||||
self.assertEqual(value.yAdvance, 0)
|
self.assertIsNone(value.yAdvance)
|
||||||
self.assertIsNone(value.xPlaDevice)
|
self.assertIsNone(value.xPlaDevice)
|
||||||
self.assertIsNone(value.yPlaDevice)
|
self.assertIsNone(value.yPlaDevice)
|
||||||
self.assertIsNone(value.xAdvDevice)
|
self.assertIsNone(value.xAdvDevice)
|
||||||
self.assertIsNone(value.yAdvDevice)
|
self.assertIsNone(value.yAdvDevice)
|
||||||
|
self.assertEqual(value.makeString(vertical=False), "123")
|
||||||
|
|
||||||
def test_valuerecord_format_a_vertical(self):
|
def test_valuerecord_format_a_vertical(self):
|
||||||
doc = self.parse("feature vkrn {valueRecordDef 123 foo;} vkrn;")
|
doc = self.parse("feature vkrn {valueRecordDef 123 foo;} vkrn;")
|
||||||
value = doc.statements[0].statements[0].value
|
value = doc.statements[0].statements[0].value
|
||||||
self.assertEqual(value.xPlacement, 0)
|
self.assertIsNone(value.xPlacement)
|
||||||
self.assertEqual(value.yPlacement, 0)
|
self.assertIsNone(value.yPlacement)
|
||||||
self.assertEqual(value.xAdvance, 0)
|
self.assertIsNone(value.xAdvance)
|
||||||
self.assertEqual(value.yAdvance, 123)
|
self.assertEqual(value.yAdvance, 123)
|
||||||
self.assertIsNone(value.xPlaDevice)
|
self.assertIsNone(value.xPlaDevice)
|
||||||
self.assertIsNone(value.yPlaDevice)
|
self.assertIsNone(value.yPlaDevice)
|
||||||
self.assertIsNone(value.xAdvDevice)
|
self.assertIsNone(value.xAdvDevice)
|
||||||
self.assertIsNone(value.yAdvDevice)
|
self.assertIsNone(value.yAdvDevice)
|
||||||
|
self.assertEqual(value.makeString(vertical=True), "123")
|
||||||
|
|
||||||
|
def test_valuerecord_format_a_zero_horizontal(self):
|
||||||
|
doc = self.parse("feature liga {valueRecordDef 0 foo;} liga;")
|
||||||
|
value = doc.statements[0].statements[0].value
|
||||||
|
self.assertIsNone(value.xPlacement)
|
||||||
|
self.assertIsNone(value.yPlacement)
|
||||||
|
self.assertEqual(value.xAdvance, 0)
|
||||||
|
self.assertIsNone(value.yAdvance)
|
||||||
|
self.assertIsNone(value.xPlaDevice)
|
||||||
|
self.assertIsNone(value.yPlaDevice)
|
||||||
|
self.assertIsNone(value.xAdvDevice)
|
||||||
|
self.assertIsNone(value.yAdvDevice)
|
||||||
|
self.assertEqual(value.makeString(vertical=False), "0")
|
||||||
|
|
||||||
|
def test_valuerecord_format_a_zero_vertical(self):
|
||||||
|
doc = self.parse("feature vkrn {valueRecordDef 0 foo;} vkrn;")
|
||||||
|
value = doc.statements[0].statements[0].value
|
||||||
|
self.assertIsNone(value.xPlacement)
|
||||||
|
self.assertIsNone(value.yPlacement)
|
||||||
|
self.assertIsNone(value.xAdvance)
|
||||||
|
self.assertEqual(value.yAdvance, 0)
|
||||||
|
self.assertIsNone(value.xPlaDevice)
|
||||||
|
self.assertIsNone(value.yPlaDevice)
|
||||||
|
self.assertIsNone(value.xAdvDevice)
|
||||||
|
self.assertIsNone(value.yAdvDevice)
|
||||||
|
self.assertEqual(value.makeString(vertical=True), "0")
|
||||||
|
|
||||||
def test_valuerecord_format_a_vertical_contexts_(self):
|
def test_valuerecord_format_a_vertical_contexts_(self):
|
||||||
for tag in "vkrn vpal vhal valt".split():
|
for tag in "vkrn vpal vhal valt".split():
|
||||||
@ -1289,6 +1317,20 @@ class ParserTest(unittest.TestCase):
|
|||||||
self.assertIsNone(value.yPlaDevice)
|
self.assertIsNone(value.yPlaDevice)
|
||||||
self.assertIsNone(value.xAdvDevice)
|
self.assertIsNone(value.xAdvDevice)
|
||||||
self.assertIsNone(value.yAdvDevice)
|
self.assertIsNone(value.yAdvDevice)
|
||||||
|
self.assertEqual(value.makeString(vertical=False), "<1 2 3 4>")
|
||||||
|
|
||||||
|
def test_valuerecord_format_b_zero(self):
|
||||||
|
doc = self.parse("feature liga {valueRecordDef <0 0 0 0> foo;} liga;")
|
||||||
|
value = doc.statements[0].statements[0].value
|
||||||
|
self.assertEqual(value.xPlacement, 0)
|
||||||
|
self.assertEqual(value.yPlacement, 0)
|
||||||
|
self.assertEqual(value.xAdvance, 0)
|
||||||
|
self.assertEqual(value.yAdvance, 0)
|
||||||
|
self.assertIsNone(value.xPlaDevice)
|
||||||
|
self.assertIsNone(value.yPlaDevice)
|
||||||
|
self.assertIsNone(value.xAdvDevice)
|
||||||
|
self.assertIsNone(value.yAdvDevice)
|
||||||
|
self.assertEqual(value.makeString(vertical=False), "<0 0 0 0>")
|
||||||
|
|
||||||
def test_valuerecord_format_c(self):
|
def test_valuerecord_format_c(self):
|
||||||
doc = self.parse(
|
doc = self.parse(
|
||||||
@ -1310,6 +1352,9 @@ class ParserTest(unittest.TestCase):
|
|||||||
self.assertEqual(value.yPlaDevice, ((11, 111), (12, 112)))
|
self.assertEqual(value.yPlaDevice, ((11, 111), (12, 112)))
|
||||||
self.assertIsNone(value.xAdvDevice)
|
self.assertIsNone(value.xAdvDevice)
|
||||||
self.assertEqual(value.yAdvDevice, ((33, -113), (44, -114), (55, 115)))
|
self.assertEqual(value.yAdvDevice, ((33, -113), (44, -114), (55, 115)))
|
||||||
|
self.assertEqual(value.makeString(vertical=False),
|
||||||
|
"<1 2 3 4 <device 8 88> <device 11 111, 12 112>"
|
||||||
|
" <device NULL> <device 33 -113, 44 -114, 55 115>>")
|
||||||
|
|
||||||
def test_valuerecord_format_d(self):
|
def test_valuerecord_format_d(self):
|
||||||
doc = self.parse("feature test {valueRecordDef <NULL> foo;} test;")
|
doc = self.parse("feature test {valueRecordDef <NULL> foo;} test;")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user