From 973072b25932b5cb455558ab979bd09f070338fc Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Apr 2024 12:57:14 -0600 Subject: [PATCH] [Condition] Implement ConditionValue Shift other Condition format numbers. Implements https://github.com/adobe-type-tools/opentype-spec-drafts/blob/main/condvalue_spec.md --- Lib/fontTools/ttLib/tables/otData.py | 38 +++++++++++++++++++++------- Lib/fontTools/ttLib/ttGlyphSet.py | 31 ++++++++++++++++++----- 2 files changed, 53 insertions(+), 16 deletions(-) diff --git a/Lib/fontTools/ttLib/tables/otData.py b/Lib/fontTools/ttLib/tables/otData.py index 8e4800a97..3a01f5934 100644 --- a/Lib/fontTools/ttLib/tables/otData.py +++ b/Lib/fontTools/ttLib/tables/otData.py @@ -3238,18 +3238,18 @@ otData = [ [ ("uint16", "Format", None, None, "Format, = 2"), ( - "uint8", - "ConditionCount", + "int16", + "DefaultValue", None, None, - "Index for the variation axis within the fvar table, base 0.", + "Value at default instance.", ), ( - "Offset24", - "ConditionTable", - "ConditionCount", - 0, - "Array of condition tables for this conjunction (AND) expression.", + "uint32", + "VarIdx", + None, + None, + "Variation index to vary the value based on current designspace location.", ), ], ), @@ -3269,7 +3269,7 @@ otData = [ "ConditionTable", "ConditionCount", 0, - "Array of condition tables for this disjunction (OR) expression.", + "Array of condition tables for this conjunction (AND) expression.", ), ], ), @@ -3277,6 +3277,26 @@ otData = [ "ConditionTableFormat4", [ ("uint16", "Format", None, None, "Format, = 4"), + ( + "uint8", + "ConditionCount", + None, + None, + "Index for the variation axis within the fvar table, base 0.", + ), + ( + "Offset24", + "ConditionTable", + "ConditionCount", + 0, + "Array of condition tables for this disjunction (OR) expression.", + ), + ], + ), + ( + "ConditionTableFormat5", + [ + ("uint16", "Format", None, None, "Format, = 5"), ( "Offset24", "ConditionTable", diff --git a/Lib/fontTools/ttLib/ttGlyphSet.py b/Lib/fontTools/ttLib/ttGlyphSet.py index e4f035ad6..0c565bcea 100644 --- a/Lib/fontTools/ttLib/ttGlyphSet.py +++ b/Lib/fontTools/ttLib/ttGlyphSet.py @@ -276,8 +276,9 @@ class _TTGlyphCFF(_TTGlyph): self.glyphSet.charStrings[self.name].draw(pen, self.glyphSet.blender) -def _evaluateCondition(condition, fvarAxes, location): +def _evaluateCondition(condition, fvarAxes, location, instancer): if condition.Format == 1: + # ConditionAxisRange axisIndex = condition.AxisIndex axisTag = fvarAxes[axisIndex].axisTag axisValue = location.get(axisTag, 0) @@ -285,20 +286,27 @@ def _evaluateCondition(condition, fvarAxes, location): maxValue = condition.FilterRangeMaxValue return minValue <= axisValue <= maxValue elif condition.Format == 2: + # ConditionValue + value = condition.DefaultValue + value += instancer[condition.VarIdx] + return value > 0 + elif condition.Format == 3: # ConditionAnd for subcondition in condition.ConditionTable: - if not _evaluateCondition(subcondition, fvarAxes, location): + if not _evaluateCondition(subcondition, fvarAxes, location, instancer): return False return True - elif condition.Format == 3: + elif condition.Format == 4: # ConditionOr for subcondition in condition.ConditionTable: - if _evaluateCondition(subcondition, fvarAxes, location): + if _evaluateCondition(subcondition, fvarAxes, location, instancer): return True return False - elif condition.Format == 4: + elif condition.Format == 5: # ConditionNegate - return not _evaluateCondition(condition.conditionTable, fvarAxes, location) + return not _evaluateCondition( + condition.conditionTable, fvarAxes, location, instancer + ) else: return False # Unkonwn condition format @@ -319,17 +327,26 @@ class _TTGlyphVARC(_TTGlyph): glyph = varc.VarCompositeGlyphs.VarCompositeGlyph[idx] from fontTools.varLib.multiVarStore import MultiVarStoreInstancer + from fontTools.varLib.varStore import VarStoreInstancer fvarAxes = glyphSet.font["fvar"].axes instancer = MultiVarStoreInstancer( varc.MultiVarStore, fvarAxes, self.glyphSet.location ) + gdef = glyphSet.font.get("GDEF") if "GDEF" in glyphSet.font else None + gdefInstancer = VarStoreInstancer( + getattr(gdef.table, "VarStore") if gdef is not None else None, + fvarAxes, + self.glyphSet.location, + ) for comp in glyph.components: if comp.flags & VarComponentFlags.HAVE_CONDITION: condition = varc.ConditionList.ConditionTable[comp.conditionIndex] - if not _evaluateCondition(condition, fvarAxes, self.glyphSet.location): + if not _evaluateCondition( + condition, fvarAxes, self.glyphSet.location, gdefInstancer + ): continue location = {}