instancer_test: add test for instancing GPOS with kern and mark features
This commit is contained in:
parent
7209862e89
commit
544f6aae43
@ -521,32 +521,79 @@ def makeVariableFont(masters, baseIndex, axes, masterLocations):
|
|||||||
return vf
|
return vf
|
||||||
|
|
||||||
|
|
||||||
|
def makeParametrizedVF(glyphOrder, features, values, increments):
|
||||||
|
# Create a test VF with given glyphs and parametrized OTL features.
|
||||||
|
# The VF is built from 9 masters (3 x 3 along wght and wdth), with
|
||||||
|
# locations hard-coded and base master at wght=400 and wdth=100.
|
||||||
|
# 'values' is a list of initial values that are interpolated in the
|
||||||
|
# 'features' string, and incremented for each subsequent master by the
|
||||||
|
# given 'increments' (list of 2-tuple) along the two axes.
|
||||||
|
assert values and len(values) == len(increments)
|
||||||
|
assert all(len(i) == 2 for i in increments)
|
||||||
|
masterLocations = [
|
||||||
|
{"wght": 100, "wdth": 50},
|
||||||
|
{"wght": 100, "wdth": 100},
|
||||||
|
{"wght": 100, "wdth": 150},
|
||||||
|
{"wght": 400, "wdth": 50},
|
||||||
|
{"wght": 400, "wdth": 100}, # base master
|
||||||
|
{"wght": 400, "wdth": 150},
|
||||||
|
{"wght": 700, "wdth": 50},
|
||||||
|
{"wght": 700, "wdth": 100},
|
||||||
|
{"wght": 700, "wdth": 150},
|
||||||
|
]
|
||||||
|
n = len(values)
|
||||||
|
values = list(values)
|
||||||
|
masters = []
|
||||||
|
for _ in range(3):
|
||||||
|
for _ in range(3):
|
||||||
|
master = makeTTFont(glyphOrder, features=features % tuple(values))
|
||||||
|
masters.append(master)
|
||||||
|
for i in range(n):
|
||||||
|
values[i] += increments[i][1]
|
||||||
|
for i in range(n):
|
||||||
|
values[i] += increments[i][0]
|
||||||
|
baseIndex = 4
|
||||||
|
axes = [("wght", (100, 400, 700)), ("wdth", (50, 100, 150))]
|
||||||
|
vf = makeVariableFont(masters, baseIndex, axes, masterLocations)
|
||||||
|
return vf
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def varfontGDEF():
|
def varfontGDEF():
|
||||||
glyphOrder = [".notdef", "f", "i", "f_i"]
|
glyphOrder = [".notdef", "f", "i", "f_i"]
|
||||||
masters = []
|
features = (
|
||||||
masterLocations = []
|
"feature liga { sub f i by f_i;} liga;"
|
||||||
weight = v = 100
|
"table GDEF { LigatureCaretByPos f_i %d; } GDEF;"
|
||||||
for _ in range(3):
|
)
|
||||||
width = 50
|
values = [100]
|
||||||
for _ in range(3):
|
increments = [(+30, +10)]
|
||||||
master = makeTTFont(
|
return makeParametrizedVF(glyphOrder, features, values, increments)
|
||||||
glyphOrder,
|
|
||||||
features=(
|
|
||||||
"feature liga { sub f i by f_i;} liga;"
|
@pytest.fixture
|
||||||
"table GDEF { LigatureCaretByPos f_i %d; } GDEF;" % v
|
def varfontGPOS():
|
||||||
),
|
glyphOrder = [".notdef", "V", "A"]
|
||||||
)
|
features = "feature kern { pos V A %d; } kern;"
|
||||||
masters.append(master)
|
values = [-80]
|
||||||
masterLocations.append({"wght": weight, "wdth": width})
|
increments = [(-10, -5)]
|
||||||
width += 50
|
return makeParametrizedVF(glyphOrder, features, values, increments)
|
||||||
v += 10
|
|
||||||
weight += 300
|
|
||||||
v += 30
|
@pytest.fixture
|
||||||
axes = [("wght", (100, 400, 700)), ("wdth", (50, 100, 150))]
|
def varfontGPOS2():
|
||||||
baseIndex = 4 # index of base master (wght=400, wdth=100)
|
glyphOrder = [".notdef", "V", "A", "acutecomb"]
|
||||||
vf = makeVariableFont(masters, baseIndex, axes, masterLocations)
|
features = (
|
||||||
return vf
|
"markClass [acutecomb] <anchor 150 -10> @TOP_MARKS;"
|
||||||
|
"feature mark {"
|
||||||
|
" pos base A <anchor %d 450> mark @TOP_MARKS;"
|
||||||
|
"} mark;"
|
||||||
|
"feature kern {"
|
||||||
|
" pos V A %d;"
|
||||||
|
"} kern;"
|
||||||
|
)
|
||||||
|
values = [200, -80]
|
||||||
|
increments = [(+30, +10), (-10, -5)]
|
||||||
|
return makeParametrizedVF(glyphOrder, features, values, increments)
|
||||||
|
|
||||||
|
|
||||||
class InstantiateOTLTest(object):
|
class InstantiateOTLTest(object):
|
||||||
@ -609,3 +656,152 @@ class InstantiateOTLTest(object):
|
|||||||
assert caretValue.Format == 1
|
assert caretValue.Format == 1
|
||||||
assert not hasattr(caretValue, "DeviceTable")
|
assert not hasattr(caretValue, "DeviceTable")
|
||||||
assert caretValue.Coordinate == expected
|
assert caretValue.Coordinate == expected
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"location, expected",
|
||||||
|
[
|
||||||
|
({"wght": -1.0}, -85), # +25
|
||||||
|
({"wght": 0}, -110),
|
||||||
|
({"wght": 1.0}, -135), # -25
|
||||||
|
({"wdth": -1.0}, -105), # +5
|
||||||
|
({"wdth": 0}, -110),
|
||||||
|
({"wdth": 1.0}, -115), # -5
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_pin_and_drop_axis_GPOS_kern(self, varfontGPOS, location, expected):
|
||||||
|
vf = varfontGPOS
|
||||||
|
assert "GDEF" in vf
|
||||||
|
assert "GPOS" in vf
|
||||||
|
|
||||||
|
instancer.instantiateOTL(vf, location)
|
||||||
|
|
||||||
|
gdef = vf["GDEF"].table
|
||||||
|
gpos = vf["GPOS"].table
|
||||||
|
assert gdef.Version == 0x00010003
|
||||||
|
assert gdef.VarStore
|
||||||
|
|
||||||
|
assert gpos.LookupList.Lookup[0].LookupType == 2 # PairPos
|
||||||
|
pairPos = gpos.LookupList.Lookup[0].SubTable[0]
|
||||||
|
valueRec1 = pairPos.PairSet[0].PairValueRecord[0].Value1
|
||||||
|
assert valueRec1.XAdvDevice
|
||||||
|
assert valueRec1.XAdvDevice.DeltaFormat == 0x8000
|
||||||
|
assert valueRec1.XAdvance == expected
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"location, expected",
|
||||||
|
[
|
||||||
|
({"wght": -1.0, "wdth": -1.0}, -80), # +25 + 5
|
||||||
|
({"wght": -1.0, "wdth": 0.0}, -85), # +25
|
||||||
|
({"wght": -1.0, "wdth": 1.0}, -90), # +25 - 5
|
||||||
|
({"wght": 0.0, "wdth": -1.0}, -105), # +5
|
||||||
|
({"wght": 0.0, "wdth": 0.0}, -110),
|
||||||
|
({"wght": 0.0, "wdth": 1.0}, -115), # -5
|
||||||
|
({"wght": 1.0, "wdth": -1.0}, -130), # -25 + 5
|
||||||
|
({"wght": 1.0, "wdth": 0.0}, -135), # -25
|
||||||
|
({"wght": 1.0, "wdth": 1.0}, -140), # -25 - 5
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_full_instance_GPOS_kern(self, varfontGPOS, location, expected):
|
||||||
|
vf = varfontGPOS
|
||||||
|
assert "GDEF" in vf
|
||||||
|
assert "GPOS" in vf
|
||||||
|
|
||||||
|
instancer.instantiateOTL(vf, location)
|
||||||
|
|
||||||
|
assert "GDEF" not in vf
|
||||||
|
gpos = vf["GPOS"].table
|
||||||
|
|
||||||
|
assert gpos.LookupList.Lookup[0].LookupType == 2 # PairPos
|
||||||
|
pairPos = gpos.LookupList.Lookup[0].SubTable[0]
|
||||||
|
valueRec1 = pairPos.PairSet[0].PairValueRecord[0].Value1
|
||||||
|
assert not hasattr(valueRec1, "XAdvDevice")
|
||||||
|
assert valueRec1.XAdvance == expected
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"location, expected",
|
||||||
|
[
|
||||||
|
({"wght": -1.0}, (210, -85)), # -60, +25
|
||||||
|
({"wght": 0}, (270, -110)),
|
||||||
|
({"wght": 0.5}, (300, -122)), # +30, -12
|
||||||
|
({"wght": 1.0}, (330, -135)), # +60, -25
|
||||||
|
({"wdth": -1.0}, (260, -105)), # -10, +5
|
||||||
|
({"wdth": -0.3}, (267, -108)), # -3, +2
|
||||||
|
({"wdth": 0}, (270, -110)),
|
||||||
|
({"wdth": 1.0}, (280, -115)), # +10, -5
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_pin_and_drop_axis_GPOS_mark_and_kern(
|
||||||
|
self, varfontGPOS2, location, expected
|
||||||
|
):
|
||||||
|
vf = varfontGPOS2
|
||||||
|
assert "GDEF" in vf
|
||||||
|
assert "GPOS" in vf
|
||||||
|
|
||||||
|
instancer.instantiateOTL(vf, location)
|
||||||
|
|
||||||
|
v1, v2 = expected
|
||||||
|
gdef = vf["GDEF"].table
|
||||||
|
gpos = vf["GPOS"].table
|
||||||
|
assert gdef.Version == 0x00010003
|
||||||
|
assert gdef.VarStore
|
||||||
|
assert gdef.GlyphClassDef
|
||||||
|
|
||||||
|
assert gpos.LookupList.Lookup[0].LookupType == 4 # MarkBasePos
|
||||||
|
markBasePos = gpos.LookupList.Lookup[0].SubTable[0]
|
||||||
|
baseAnchor = markBasePos.BaseArray.BaseRecord[0].BaseAnchor[0]
|
||||||
|
assert baseAnchor.Format == 3
|
||||||
|
assert baseAnchor.XDeviceTable
|
||||||
|
assert baseAnchor.XDeviceTable.DeltaFormat == 0x8000
|
||||||
|
assert not baseAnchor.YDeviceTable
|
||||||
|
assert baseAnchor.XCoordinate == v1
|
||||||
|
assert baseAnchor.YCoordinate == 450
|
||||||
|
|
||||||
|
assert gpos.LookupList.Lookup[1].LookupType == 2 # PairPos
|
||||||
|
pairPos = gpos.LookupList.Lookup[1].SubTable[0]
|
||||||
|
valueRec1 = pairPos.PairSet[0].PairValueRecord[0].Value1
|
||||||
|
assert valueRec1.XAdvDevice
|
||||||
|
assert valueRec1.XAdvDevice.DeltaFormat == 0x8000
|
||||||
|
assert valueRec1.XAdvance == v2
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"location, expected",
|
||||||
|
[
|
||||||
|
({"wght": -1.0, "wdth": -1.0}, (200, -80)), # -60 - 10, +25 + 5
|
||||||
|
({"wght": -1.0, "wdth": 0.0}, (210, -85)), # -60, +25
|
||||||
|
({"wght": -1.0, "wdth": 1.0}, (220, -90)), # -60 + 10, +25 - 5
|
||||||
|
({"wght": 0.0, "wdth": -1.0}, (260, -105)), # -10, +5
|
||||||
|
({"wght": 0.0, "wdth": 0.0}, (270, -110)),
|
||||||
|
({"wght": 0.0, "wdth": 1.0}, (280, -115)), # +10, -5
|
||||||
|
({"wght": 1.0, "wdth": -1.0}, (320, -130)), # +60 - 10, -25 + 5
|
||||||
|
({"wght": 1.0, "wdth": 0.0}, (330, -135)), # +60, -25
|
||||||
|
({"wght": 1.0, "wdth": 1.0}, (340, -140)), # +60 + 10, -25 - 5
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_full_instance_GPOS_mark_and_kern(self, varfontGPOS2, location, expected):
|
||||||
|
vf = varfontGPOS2
|
||||||
|
assert "GDEF" in vf
|
||||||
|
assert "GPOS" in vf
|
||||||
|
|
||||||
|
instancer.instantiateOTL(vf, location)
|
||||||
|
|
||||||
|
v1, v2 = expected
|
||||||
|
gdef = vf["GDEF"].table
|
||||||
|
gpos = vf["GPOS"].table
|
||||||
|
assert gdef.Version == 0x00010000
|
||||||
|
assert not hasattr(gdef, "VarStore")
|
||||||
|
assert gdef.GlyphClassDef
|
||||||
|
|
||||||
|
assert gpos.LookupList.Lookup[0].LookupType == 4 # MarkBasePos
|
||||||
|
markBasePos = gpos.LookupList.Lookup[0].SubTable[0]
|
||||||
|
baseAnchor = markBasePos.BaseArray.BaseRecord[0].BaseAnchor[0]
|
||||||
|
assert baseAnchor.Format == 1
|
||||||
|
assert not hasattr(baseAnchor, "XDeviceTable")
|
||||||
|
assert not hasattr(baseAnchor, "YDeviceTable")
|
||||||
|
assert baseAnchor.XCoordinate == v1
|
||||||
|
assert baseAnchor.YCoordinate == 450
|
||||||
|
|
||||||
|
assert gpos.LookupList.Lookup[1].LookupType == 2 # PairPos
|
||||||
|
pairPos = gpos.LookupList.Lookup[1].SubTable[0]
|
||||||
|
valueRec1 = pairPos.PairSet[0].PairValueRecord[0].Value1
|
||||||
|
assert not hasattr(valueRec1, "XAdvDevice")
|
||||||
|
assert valueRec1.XAdvance == v2
|
||||||
|
Loading…
x
Reference in New Issue
Block a user