diff --git a/Lib/fontTools/varLib/instancer.py b/Lib/fontTools/varLib/instancer.py index d8c400d76..efe30127c 100644 --- a/Lib/fontTools/varLib/instancer.py +++ b/Lib/fontTools/varLib/instancer.py @@ -1331,25 +1331,39 @@ def axisValueIsSelected(axisValue, seeker): return False +def axisValueIndexes(axisValue): + if axisValue.Format == 4: + return [r.AxisIndex for r in axisValue.AxisValueRecord] + return [axisValue.AxisIndex] + + +def axisValuesIndexes(axisValues): + res = [] + for axisValue in axisValues: + res += axisValueIndexes(axisValue) + return res + + def axisValuesFromAxisLimits(stat, axisLimits): axisValues = stat.table.AxisValueArray.AxisValue axisRecords = stat.table.DesignAxisRecord.Axis axisOrder = {a.AxisTag: a.AxisOrdering for a in axisRecords} + axisTag = {a.AxisOrdering: a.AxisTag for a in axisRecords} # Only check pinnedAxes for matching AxisValues - AxisValuesToFind = { + axisValuesToFind = { axisOrder[k]: v for k, v in axisLimits.items() \ if isinstance(v, (float, int)) } - axisValues = [a for a in axisValues if axisValueIsSelected(a, AxisValuesToFind)] - axisValuesMissing = set(AxisValuesToFind) - set(a.AxisIndex for a in axisValues) + axisValues = [a for a in axisValues if axisValueIsSelected(a, axisValuesToFind)] + axisValuesMissing = set(axisValuesToFind) - set(axisValuesIndexes(axisValues)) if axisValuesMissing: # TODO better error msg - missing = [i for i in axisValuesMissing] - raise ValueError(f"Cannot find AxisValues for {missing}") + missing = [f"{axisTag[i]}={axisValuesToFind[i]}" for i in axisValuesMissing] + raise ValueError(f"Cannot find AxisValue for {', '.join(missing)}") # filter out Elidable axisValues axisValues = [a for a in axisValues if a.Flags != 2] - # TODO sort and remove duplicates so format 4 axisValues are dominant + # TODO sort and remove duplicates so format 4 axisValues are dominant return axisValues diff --git a/Tests/varLib/instancer_test.py b/Tests/varLib/instancer_test.py index d0aa44f3f..ec3f85cfa 100644 --- a/Tests/varLib/instancer_test.py +++ b/Tests/varLib/instancer_test.py @@ -1926,7 +1926,7 @@ def _get_name_records(varfont): def test_updateNameTable_with_registered_axes(varfont): # Regular - instancer.updateNameTable(varfont, {"wght": 400, "wdth": 100}) + instancer.updateNameTable(varfont, {"wght": 400}) names = _get_name_records(varfont) assert names[(1, 3, 1, 0x409)] == "Test Variable Font" assert names[(2, 3, 1, 0x0409)] == "Regular" @@ -1935,7 +1935,7 @@ def test_updateNameTable_with_registered_axes(varfont): assert (17, 3, 1, 0x409) not in names # Black - instancer.updateNameTable(varfont, {"wght": 900, "wdth": 100}) + instancer.updateNameTable(varfont, {"wght": 900}) names = _get_name_records(varfont) assert names[(1, 3, 1, 0x409)] == "Test Variable Font Black" assert names[(2, 3, 1, 0x409)] == "Regular" @@ -1944,7 +1944,7 @@ def test_updateNameTable_with_registered_axes(varfont): assert names[(17, 3, 1, 0x409)] == "Black" # Thin - instancer.updateNameTable(varfont, {"wght": 100, "wdth": 100}) + instancer.updateNameTable(varfont, {"wght": 100}) names = _get_name_records(varfont) assert names[(1, 3, 1, 0x409)] == "Test Variable Font Thin" assert names[(2, 3, 1, 0x409)] == "Regular" @@ -1971,7 +1971,7 @@ def test_updateNameTable_with_multilingual_names(varfont): name.setName("Zhuštěné", 279, 3, 1, 0x405) # nameID 279=Condensed STAT entry # Regular | Normal - instancer.updateNameTable(varfont, {"wdth": 100, "wght": 400}) + instancer.updateNameTable(varfont, {"wght": 400}) names = _get_name_records(varfont) assert names[(1, 3, 1, 0x405)] == "Test Variable Font" assert names[(2, 3, 1, 0x405)] == "Normal" @@ -1979,7 +1979,7 @@ def test_updateNameTable_with_multilingual_names(varfont): assert (17, 3, 1, 0x405) not in names # Black | Negreta - instancer.updateNameTable(varfont, {"wdth": 100, "wght": 900}) + instancer.updateNameTable(varfont, {"wght": 900}) names = _get_name_records(varfont) assert names[(1, 3, 1, 0x405)] == "Test Variable Font Negreta" assert names[(2, 3, 1, 0x405)] == "Normal" @@ -2004,6 +2004,11 @@ def test_updateNametable_partial(varfont): assert names[(17, 3, 1, 0x409)] == "Condensed" #? maybe Condensed Regular? +def test_updateNameTable_missing_axisValues(varfont): + with pytest.raises(ValueError, match="Cannot find AxisValue for wght=200"): + instancer.updateNameTable(varfont, {"wght": 200}) + + def test_sanityCheckVariableTables(varfont): font = ttLib.TTFont() with pytest.raises(ValueError, match="Missing required table fvar"):