From 69c86679824cf60bdeccb3bb71b743dc4bb87168 Mon Sep 17 00:00:00 2001 From: Marc Foley Date: Mon, 12 Oct 2020 12:37:11 +0100 Subject: [PATCH] instancer: sort axisValues so format 4 are dominant for constructing names --- Lib/fontTools/varLib/instancer.py | 25 +++++++++++++++++++++++-- Tests/varLib/instancer_test.py | 27 +++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/Lib/fontTools/varLib/instancer.py b/Lib/fontTools/varLib/instancer.py index 042309d2a..d88cb38c9 100644 --- a/Lib/fontTools/varLib/instancer.py +++ b/Lib/fontTools/varLib/instancer.py @@ -1366,8 +1366,29 @@ def axisValuesFromAxisLimits(stat, axisLimits): raise ValueError(f"Cannot find AxisValue for {', '.join(missing)}") # filter out Elidable axisValues axisValues = [a for a in axisValues if a.Flags & ELIDABLE_AXIS_VALUE_NAME != 2] - # TODO sort and remove duplicates so format 4 axisValues are dominant - return axisValues + return sortedAxisValues(axisValues) + + +def sortedAxisValues(axisValues): + # Sort and remove duplicates so format 4 axisValues are dominant + results, seenAxes = [], set() + format4 = sorted( + [a for a in axisValues if a.Format == 4], + key=lambda k: len(k.AxisValueRecord), reverse=True + ) + nonFormat4 = [a for a in axisValues if a not in format4] + + for axisValue in format4: + axes = set([r.AxisIndex for r in axisValue.AxisValueRecord]) + if seenAxes - axes == seenAxes: + seenAxes |= axes + results.append((tuple(axes), axisValue)) + + for axisValue in nonFormat4: + axisIndex = axisValue.AxisIndex + if axisIndex not in seenAxes: + results.append(((axisIndex,), axisValue)) + return [v for k, v in sorted(results)] def updateNameTable(varfont, axisLimits): diff --git a/Tests/varLib/instancer_test.py b/Tests/varLib/instancer_test.py index f0725e1a1..d148a8c45 100644 --- a/Tests/varLib/instancer_test.py +++ b/Tests/varLib/instancer_test.py @@ -2032,6 +2032,33 @@ def test_updateNameTable_vf_with_italic_attribute(varfont): assert names[(17, 3, 1, 0x409)] == "Black Condensed Italic" +def test_updateNameTable_format4_axisValues(varfont): + # format 4 axisValues should dominate the other axisValues + stat = varfont["STAT"].table + + axisValue = otTables.AxisValue() + axisValue.Format = 4 + axisValue.Flags = 0 + varfont["name"].setName("Dominant Value", 297, 3, 1, 0x409) + axisValue.ValueNameID = 297 + axisValue.AxisValueRecord = [] + for tag, value in (("wght", 900), ("wdth", 79)): + rec = otTables.AxisValueRecord() + rec.AxisIndex = next( + i for i, a in enumerate(stat.DesignAxisRecord.Axis) if a.AxisTag == tag + ) + rec.Value = value + axisValue.AxisValueRecord.append(rec) + stat.AxisValueArray.AxisValue.append(axisValue) + + instancer.updateNameTable(varfont, {"wdth": 79, "wght": 900}) + names = _get_name_records(varfont) + assert names[(1, 3, 1, 0x409)] == "Test Variable Font Dominant Value" + assert names[(2, 3, 1, 0x409)] == "Regular" + assert names[(16, 3, 1, 0x409)] == "Test Variable Font" + assert names[(17, 3, 1, 0x409)] == "Dominant Value" + + def test_sanityCheckVariableTables(varfont): font = ttLib.TTFont() with pytest.raises(ValueError, match="Missing required table fvar"):