From 3c9ce8715c654d90d0bdbf6a0d6b71b6ea93b58c 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 | 28 +++++++++++++++++++++---- Lib/fontTools/ttLib/ttGlyphSet.py | 31 +++++++++++++++++++++------- 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/Lib/fontTools/ttLib/tables/otData.py b/Lib/fontTools/ttLib/tables/otData.py index 8e4800a9773..3a01f5934f8 100644 --- a/Lib/fontTools/ttLib/tables/otData.py +++ b/Lib/fontTools/ttLib/tables/otData.py @@ -3237,6 +3237,26 @@ "ConditionTableFormat2", [ ("uint16", "Format", None, None, "Format, = 2"), + ( + "int16", + "DefaultValue", + None, + None, + "Value at default instance.", + ), + ( + "uint32", + "VarIdx", + None, + None, + "Variation index to vary the value based on current designspace location.", + ), + ], + ), + ( + "ConditionTableFormat3", + [ + ("uint16", "Format", None, None, "Format, = 3"), ( "uint8", "ConditionCount", @@ -3254,9 +3274,9 @@ ], ), ( - "ConditionTableFormat3", + "ConditionTableFormat4", [ - ("uint16", "Format", None, None, "Format, = 3"), + ("uint16", "Format", None, None, "Format, = 4"), ( "uint8", "ConditionCount", @@ -3274,9 +3294,9 @@ ], ), ( - "ConditionTableFormat4", + "ConditionTableFormat5", [ - ("uint16", "Format", None, None, "Format, = 4"), + ("uint16", "Format", None, None, "Format, = 5"), ( "Offset24", "ConditionTable", diff --git a/Lib/fontTools/ttLib/ttGlyphSet.py b/Lib/fontTools/ttLib/ttGlyphSet.py index e4f035ad669..0c565bceae0 100644 --- a/Lib/fontTools/ttLib/ttGlyphSet.py +++ b/Lib/fontTools/ttLib/ttGlyphSet.py @@ -276,8 +276,9 @@ def draw(self, pen): 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 @@ def _draw(self, pen, isPointPen): 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 = {}