[feaLib] make Device Table from device tuples
This commit is contained in:
parent
5644da31d2
commit
c01b956ae7
@ -316,6 +316,25 @@ class Builder(object):
|
||||
lookup.mapping[glyph] = valuerecord
|
||||
|
||||
|
||||
def _makeOpenTypeDeviceTable(deviceTable, device):
|
||||
device = tuple(sorted(device))
|
||||
deviceTable.StartSize = startSize = device[0][0]
|
||||
deviceTable.EndSize = endSize = device[-1][0]
|
||||
deviceDict = dict(device)
|
||||
deviceTable.DeltaValue = deltaValues = [
|
||||
deviceDict.get(size, 0)
|
||||
for size in range(startSize, endSize + 1)]
|
||||
maxDelta = max(deltaValues)
|
||||
minDelta = min(deltaValues)
|
||||
assert minDelta > -129 and maxDelta < 128
|
||||
if minDelta > -3 and maxDelta < 2:
|
||||
deviceTable.DeltaFormat = 1
|
||||
elif minDelta > -9 and maxDelta < 8:
|
||||
deviceTable.DeltaFormat = 2
|
||||
else:
|
||||
deviceTable.DeltaFormat = 3
|
||||
|
||||
|
||||
def makeOpenTypeValueRecord(v):
|
||||
"""ast.ValueRecord --> (otBase.ValueRecord, int ValueFormat)"""
|
||||
vr = otBase.ValueRecord()
|
||||
@ -328,18 +347,18 @@ def makeOpenTypeValueRecord(v):
|
||||
if v.yAdvance:
|
||||
vr.YAdvance = v.yAdvance
|
||||
|
||||
# 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
|
||||
if v.xPlaDevice:
|
||||
vr.XPlaDevice = otTables.XPlaDevice()
|
||||
_makeOpenTypeDeviceTable(vr.XPlaDevice, v.xPlaDevice)
|
||||
if v.yPlaDevice:
|
||||
vr.YPlaDevice = otTables.YPlaDevice()
|
||||
_makeOpenTypeDeviceTable(vr.YPlaDevice, v.yPlaDevice)
|
||||
if v.xAdvDevice:
|
||||
vr.XAdvDevice = otTables.XAdvDevice()
|
||||
_makeOpenTypeDeviceTable(vr.XAdvDevice, v.xAdvDevice)
|
||||
if v.yAdvDevice:
|
||||
vr.YAdvDevice = otTables.YAdvDevice()
|
||||
_makeOpenTypeDeviceTable(vr.YAdvDevice, v.yAdvDevice)
|
||||
|
||||
vrMask = 0
|
||||
for mask, name, _, _ in otBase.valueRecordFormat:
|
||||
|
@ -373,6 +373,17 @@ class Parser(object):
|
||||
xPlaDevice, yPlaDevice, xAdvDevice, yAdvDevice = (
|
||||
self.parse_device_(), self.parse_device_(),
|
||||
self.parse_device_(), self.parse_device_())
|
||||
allDeltas = sorted([
|
||||
delta
|
||||
for size, delta
|
||||
in (xPlaDevice if xPlaDevice else ()) +
|
||||
(yPlaDevice if yPlaDevice else ()) +
|
||||
(xAdvDevice if xAdvDevice else ()) +
|
||||
(yAdvDevice if yAdvDevice else ())])
|
||||
if allDeltas[0] < -128 or allDeltas[-1] > 127:
|
||||
raise FeatureLibError(
|
||||
"Device value out of valid range (-128..127)",
|
||||
self.cur_token_location_)
|
||||
else:
|
||||
xPlaDevice, yPlaDevice, xAdvDevice, yAdvDevice = (
|
||||
None, None, None, None)
|
||||
|
@ -479,9 +479,9 @@ class ParserTest(unittest.TestCase):
|
||||
" valueRecordDef <"
|
||||
" 1 2 3 4"
|
||||
" <device 8 88>"
|
||||
" <device 11 111, 12 222>"
|
||||
" <device 11 111, 12 112>"
|
||||
" <device NULL>"
|
||||
" <device 33 -333, 44 -444, 55 555>"
|
||||
" <device 33 -113, 44 -114, 55 115>"
|
||||
" > foo;"
|
||||
"} liga;")
|
||||
value = doc.statements[0].statements[0].value
|
||||
@ -490,9 +490,9 @@ class ParserTest(unittest.TestCase):
|
||||
self.assertEqual(value.xAdvance, 3)
|
||||
self.assertEqual(value.yAdvance, 4)
|
||||
self.assertEqual(value.xPlaDevice, ((8, 88),))
|
||||
self.assertEqual(value.yPlaDevice, ((11, 111), (12, 222)))
|
||||
self.assertEqual(value.yPlaDevice, ((11, 111), (12, 112)))
|
||||
self.assertIsNone(value.xAdvDevice)
|
||||
self.assertEqual(value.yAdvDevice, ((33, -333), (44, -444), (55, 555)))
|
||||
self.assertEqual(value.yAdvDevice, ((33, -113), (44, -114), (55, 115)))
|
||||
|
||||
def test_valuerecord_named(self):
|
||||
doc = self.parse("valueRecordDef <1 2 3 4> foo;"
|
||||
@ -518,6 +518,13 @@ class ParserTest(unittest.TestCase):
|
||||
self.assertEqual(liga.statements[0].value.xAdvance, 789)
|
||||
self.assertEqual(smcp.statements[0].value.xAdvance, 789)
|
||||
|
||||
def test_valuerecord_device_value_out_of_range(self):
|
||||
self.assertRaisesRegex(
|
||||
FeatureLibError, r"Device value out of valid range \(-128..127\)",
|
||||
self.parse,
|
||||
"valueRecordDef <1 2 3 4 <device NULL> <device NULL> "
|
||||
"<device NULL> <device 11 128>> foo;")
|
||||
|
||||
def test_languagesystem(self):
|
||||
[langsys] = self.parse("languagesystem latn DEU;").statements
|
||||
self.assertEqual(langsys.script, "latn")
|
||||
|
13
Lib/fontTools/feaLib/testdata/GPOS_1.fea
vendored
13
Lib/fontTools/feaLib/testdata/GPOS_1.fea
vendored
@ -6,13 +6,18 @@ feature kern {
|
||||
position [one two three] <-80 0 -160 0>;
|
||||
position A <
|
||||
1 2 3 4
|
||||
<device 11 111, 12 222> <device 13 333, 14 444>
|
||||
<device 16 666> <device NULL>
|
||||
<device 11 111, 12 112> <device 13 113, 14 114>
|
||||
<device 16 116> <device NULL>
|
||||
>;
|
||||
position B <
|
||||
1 2 3 4
|
||||
<device 11 111, 12 222> <device 13 333, 14 444>
|
||||
<device 16 666> <device NULL>
|
||||
<device 11 111, 12 112> <device 13 113, 14 114>
|
||||
<device 16 116> <device NULL>
|
||||
>;
|
||||
position C <
|
||||
1 2 3 4
|
||||
<device 11 -2, 14 1> <device 13 -3, 15 1>
|
||||
<device 11 -8, 14 7> <device 13 8, 15 1>
|
||||
>;
|
||||
position four 400;
|
||||
position five <-80 0 -160 0>;
|
||||
|
55
Lib/fontTools/feaLib/testdata/GPOS_1.ttx
vendored
55
Lib/fontTools/feaLib/testdata/GPOS_1.ttx
vendored
@ -53,7 +53,7 @@
|
||||
<Lookup index="0">
|
||||
<!-- LookupType=1 -->
|
||||
<LookupFlag value="0"/>
|
||||
<!-- SubTableCount=5 -->
|
||||
<!-- SubTableCount=6 -->
|
||||
<SinglePos index="0" Format="1">
|
||||
<Coverage>
|
||||
<Glyph value="one"/>
|
||||
@ -93,7 +93,58 @@
|
||||
<Glyph value="B"/>
|
||||
</Coverage>
|
||||
<ValueFormat value="15"/>
|
||||
<Value XPlacement="1" YPlacement="2" XAdvance="3" YAdvance="4"/>
|
||||
<Value XPlacement="1" YPlacement="2" XAdvance="3" YAdvance="4">
|
||||
<XPlaDevice>
|
||||
<StartSize value="11"/>
|
||||
<EndSize value="12"/>
|
||||
<DeltaFormat value="3"/>
|
||||
<DeltaValue value="[111, 112]"/>
|
||||
</XPlaDevice>
|
||||
<YPlaDevice>
|
||||
<StartSize value="13"/>
|
||||
<EndSize value="14"/>
|
||||
<DeltaFormat value="3"/>
|
||||
<DeltaValue value="[113, 114]"/>
|
||||
</YPlaDevice>
|
||||
<XAdvDevice>
|
||||
<StartSize value="16"/>
|
||||
<EndSize value="16"/>
|
||||
<DeltaFormat value="3"/>
|
||||
<DeltaValue value="[116]"/>
|
||||
</XAdvDevice>
|
||||
</Value>
|
||||
</SinglePos>
|
||||
<SinglePos index="5" Format="1">
|
||||
<Coverage>
|
||||
<Glyph value="C"/>
|
||||
</Coverage>
|
||||
<ValueFormat value="15"/>
|
||||
<Value XPlacement="1" YPlacement="2" XAdvance="3" YAdvance="4">
|
||||
<XPlaDevice>
|
||||
<StartSize value="11"/>
|
||||
<EndSize value="14"/>
|
||||
<DeltaFormat value="1"/>
|
||||
<DeltaValue value="[-2, 0, 0, 1]"/>
|
||||
</XPlaDevice>
|
||||
<YPlaDevice>
|
||||
<StartSize value="13"/>
|
||||
<EndSize value="15"/>
|
||||
<DeltaFormat value="2"/>
|
||||
<DeltaValue value="[-3, 0, 1]"/>
|
||||
</YPlaDevice>
|
||||
<XAdvDevice>
|
||||
<StartSize value="11"/>
|
||||
<EndSize value="14"/>
|
||||
<DeltaFormat value="2"/>
|
||||
<DeltaValue value="[-8, 0, 0, 7]"/>
|
||||
</XAdvDevice>
|
||||
<YAdvDevice>
|
||||
<StartSize value="13"/>
|
||||
<EndSize value="15"/>
|
||||
<DeltaFormat value="3"/>
|
||||
<DeltaValue value="[8, 0, 1]"/>
|
||||
</YAdvDevice>
|
||||
</Value>
|
||||
</SinglePos>
|
||||
</Lookup>
|
||||
<Lookup index="1">
|
||||
|
Loading…
x
Reference in New Issue
Block a user