fonttools/Tests/varLib/instancer_test.py

210 lines
7.0 KiB
Python
Raw Normal View History

from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import *
from fontTools.ttLib import TTFont
from fontTools.varLib import instancer
from fontTools.varLib.mvar import MVAR_ENTRIES
import os
import pytest
TESTDATA = os.path.join(os.path.dirname(__file__), "data")
@pytest.fixture
def varfont():
f = TTFont()
f.importXML(os.path.join(TESTDATA, "PartialInstancerTest-VF.ttx"))
return f
def _get_coordinates(varfont, glyphname):
# converts GlyphCoordinates to a list of (x, y) tuples, so that pytest's
# assert will give us a nicer diff
return list(varfont["glyf"].getCoordinates(glyphname, varfont))
class InstantiateGvarTest(object):
@pytest.mark.parametrize("glyph_name", ["hyphen"])
@pytest.mark.parametrize(
"location, expected",
[
pytest.param(
{"wdth": -1.0},
{
"hyphen": [
(27, 229),
(27, 310),
(247, 310),
(247, 229),
(0, 0),
(274, 0),
(0, 1000),
(0, 0),
]
},
id="wdth=-1.0",
),
pytest.param(
{"wdth": -0.5},
{
"hyphen": [
(33.5, 229),
(33.5, 308.5),
(264.5, 308.5),
(264.5, 229),
(0, 0),
(298, 0),
(0, 1000),
(0, 0),
]
},
id="wdth=-0.5",
),
# an axis pinned at the default normalized location (0.0) means
# the default glyf outline stays the same
pytest.param(
{"wdth": 0.0},
{
"hyphen": [
(40, 229),
(40, 307),
(282, 307),
(282, 229),
(0, 0),
(322, 0),
(0, 1000),
(0, 0),
]
},
id="wdth=0.0",
),
],
)
def test_pin_and_drop_axis(self, varfont, glyph_name, location, expected):
instancer.instantiateGvar(varfont, location)
assert _get_coordinates(varfont, glyph_name) == expected[glyph_name]
# check that the pinned axis has been dropped from gvar
assert not any(
"wdth" in t.axes
for tuples in varfont["gvar"].variations.values()
for t in tuples
)
class InstantiateCvarTest(object):
@pytest.mark.parametrize(
"location, expected",
[
pytest.param({"wght": -1.0}, [500, -400, 150, 250], id="wght=-1.0"),
pytest.param({"wdth": -1.0}, [500, -400, 180, 200], id="wdth=-1.0"),
pytest.param({"wght": -0.5}, [500, -400, 165, 250], id="wght=-0.5"),
pytest.param({"wdth": -0.3}, [500, -400, 180, 235], id="wdth=-0.3"),
],
)
def test_pin_and_drop_axis(self, varfont, location, expected):
instancer.instantiateCvar(varfont, location)
assert list(varfont["cvt "].values) == expected
# check that the pinned axis has been dropped from gvar
pinned_axes = location.keys()
assert not any(
axis in t.axes for t in varfont["cvar"].variations for axis in pinned_axes
)
def test_full_instance(self, varfont):
instancer.instantiateCvar(varfont, {"wght": -0.5, "wdth": -0.5})
assert list(varfont["cvt "].values) == [500, -400, 165, 225]
assert "cvar" not in varfont
class InstantiateMvarTest(object):
@pytest.mark.parametrize(
"location, expected",
[
pytest.param(
{"wght": 1.0}, {"strs": 100, "undo": -200, "unds": 150}, id="wght=1.0"
),
pytest.param(
{"wght": 0.5}, {"strs": 75, "undo": -150, "unds": 100}, id="wght=0.5"
),
pytest.param(
{"wght": 0.0}, {"strs": 50, "undo": -100, "unds": 50}, id="wght=0.0"
),
pytest.param(
{"wdth": -1.0}, {"strs": 20, "undo": -100, "unds": 50}, id="wdth=-1.0"
),
pytest.param(
{"wdth": -0.5}, {"strs": 35, "undo": -100, "unds": 50}, id="wdth=-0.5"
),
pytest.param(
{"wdth": 0.0}, {"strs": 50, "undo": -100, "unds": 50}, id="wdth=0.0"
),
],
)
def test_pin_and_drop_axis(self, varfont, location, expected):
mvar = varfont["MVAR"].table
# initially we have a single VarData with deltas associated with 3 regions:
# 1 with only wght, 1 with only wdth, and 1 with both wght and wdth.
assert len(mvar.VarStore.VarData) == 1
assert mvar.VarStore.VarData[0].VarRegionCount == 3
assert all(len(item) == 3 for item in mvar.VarStore.VarData[0].Item)
instancer.instantiateMvar(varfont, location)
for mvar_tag, expected_value in expected.items():
table_tag, item_name = MVAR_ENTRIES[mvar_tag]
assert getattr(varfont[table_tag], item_name) == expected_value
# check that the pinned axis does not influence any of the remaining regions
# in MVAR VarStore
pinned_axes = location.keys()
fvar = varfont["fvar"]
assert all(
peak == 0
for region in mvar.VarStore.VarRegionList.Region
for axis, (start, peak, end) in region.get_support(fvar.axes).items()
if axis in pinned_axes
)
# check that one region and accompanying deltas has been dropped
assert all(len(item) == 2 for item in mvar.VarStore.VarData[0].Item)
@pytest.mark.parametrize(
"location, expected",
[
pytest.param(
{"wght": 1.0, "wdth": 0.0},
{"strs": 100, "undo": -200, "unds": 150},
id="wght=1.0,wdth=0.0",
),
pytest.param(
{"wght": 0.0, "wdth": -1.0},
{"strs": 20, "undo": -100, "unds": 50},
id="wght=0.0,wdth=-1.0",
),
pytest.param(
{"wght": 0.5, "wdth": -0.5},
{"strs": 55, "undo": -145, "unds": 95},
id="wght=0.5,wdth=-0.5",
),
pytest.param(
{"wght": 1.0, "wdth": -1.0},
{"strs": 50, "undo": -180, "unds": 130},
id="wght=0.5,wdth=-0.5",
),
],
)
def test_full_instance(self, varfont, location, expected):
instancer.instantiateMvar(varfont, location)
for mvar_tag, expected_value in expected.items():
table_tag, item_name = MVAR_ENTRIES[mvar_tag]
assert getattr(varfont[table_tag], item_name) == expected_value
assert "MVAR" not in varfont