Skip to content

Commit

Permalink
[varc] Use Condition instead of ConditionSet
Browse files Browse the repository at this point in the history
  • Loading branch information
behdad committed Apr 22, 2024
1 parent 66446ce commit 7193680
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 42 deletions.
16 changes: 8 additions & 8 deletions Lib/fontTools/subset/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2693,21 +2693,21 @@ def prune_post_subset(self, font, options):
if comp.axisIndicesIndex is not None:
comp.axisIndicesIndex = mapping[comp.axisIndicesIndex]

conditionSetList = table.ConditionSetList
if conditionSetList is not None:
conditionSets = conditionSetList.ConditionSet
conditionList = table.ConditionList
if conditionList is not None:
conditionTables = conditionList.ConditionTable
usedIndices = set()

Check warning on line 2699 in Lib/fontTools/subset/__init__.py

View check run for this annotation

Codecov / codecov/patch

Lib/fontTools/subset/__init__.py#L2698-L2699

Added lines #L2698 - L2699 were not covered by tests
for glyph in table.VarCompositeGlyphs.VarCompositeGlyph:
for comp in glyph.components:
if comp.conditionSetIndex is not None:
usedIndices.add(comp.conditionSetIndex)
if comp.conditionIndex is not None:
usedIndices.add(comp.conditionIndex)
usedIndices = sorted(usedIndices)
conditionSetList.ConditionSet = _list_subset(conditionSets, usedIndices)
conditionList.ConditionTable = _list_subset(conditionTables, usedIndices)

Check warning on line 2705 in Lib/fontTools/subset/__init__.py

View check run for this annotation

Codecov / codecov/patch

Lib/fontTools/subset/__init__.py#L2703-L2705

Added lines #L2703 - L2705 were not covered by tests
mapping = {old: new for new, old in enumerate(usedIndices)}
for glyph in table.VarCompositeGlyphs.VarCompositeGlyph:
for comp in glyph.components:
if comp.conditionSetIndex is not None:
comp.conditionSetIndex = mapping[comp.conditionSetIndex]
if comp.conditionIndex is not None:
comp.conditionIndex = mapping[comp.conditionIndex]

Check warning on line 2710 in Lib/fontTools/subset/__init__.py

View check run for this annotation

Codecov / codecov/patch

Lib/fontTools/subset/__init__.py#L2710

Added line #L2710 was not covered by tests

return True

Expand Down
69 changes: 61 additions & 8 deletions Lib/fontTools/ttLib/tables/otData.py
Original file line number Diff line number Diff line change
Expand Up @@ -3169,21 +3169,21 @@
],
),
(
"ConditionSetList",
"ConditionList",
[
(
"uint32",
"ConditionSetCount",
"ConditionCount",
None,
None,
"Number of condition-set tables in the ConditionSet array",
"Number of condition tables in the ConditionTable array",
),
(
"LOffset",
"ConditionSet",
"ConditionSetCount",
"ConditionTable",
"ConditionCount",
0,
"Array of condition-set tables.",
"Array of offset to condition tables, from the beginning of the ConditionList table.",
),
],
),
Expand All @@ -3202,7 +3202,7 @@
"ConditionTable",
"ConditionCount",
0,
"Array of condition tables.",
"Array of offset to condition tables, from the beginning of the ConditionSet table.",
),
],
),
Expand Down Expand Up @@ -3233,6 +3233,59 @@
),
],
),
(
"ConditionTableFormat2",
[
("uint16", "Format", None, None, "Format, = 2"),
(
"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 conjunction (AND) expression.",
),
],
),
(
"ConditionTableFormat3",
[
("uint16", "Format", None, None, "Format, = 3"),
(
"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.",
),
],
),
(
"ConditionTableFormat4",
[
("uint16", "Format", None, None, "Format, = 4"),
(
"Offset24",
"ConditionTable",
None,
None,
"Condition to negate.",
),
],
),
(
"FeatureTableSubstitution",
[
Expand Down Expand Up @@ -3396,7 +3449,7 @@
),
("LOffset", "Coverage", None, None, ""),
("LOffset", "MultiVarStore", None, None, "(may be NULL)"),
("LOffset", "ConditionSetList", None, None, "(may be NULL)"),
("LOffset", "ConditionList", None, None, "(may be NULL)"),
("LOffset", "AxisIndicesList", None, None, "(may be NULL)"),
("LOffset", "VarCompositeGlyphs", None, None, ""),
],
Expand Down
16 changes: 8 additions & 8 deletions Lib/fontTools/ttLib/tables/otTables.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ def __init__(self):
def populateDefaults(self, propagator=None):
self.flags = 0
self.glyphName = None
self.conditionSetIndex = None
self.conditionIndex = None
self.axisIndicesIndex = None
self.axisValues = ()
self.axisValuesVarIndex = NO_VARIATION_INDEX
Expand All @@ -176,7 +176,7 @@ def decompile(self, data, font, localState):
self.glyphName = font.glyphOrder[glyphID]

if flags & VarComponentFlags.HAVE_CONDITION:
self.conditionSetIndex, i = _read_uint32var(data, i)
self.conditionIndex, i = _read_uint32var(data, i)

if flags & VarComponentFlags.HAVE_AXES:
self.axisIndicesIndex, i = _read_uint32var(data, i)
Expand Down Expand Up @@ -248,9 +248,9 @@ def compile(self, font):
flags &= ~VarComponentFlags.GID_IS_24BIT
data.append(_packer[2](glyphID))

if self.conditionSetIndex is not None:
if self.conditionIndex is not None:
flags |= VarComponentFlags.HAVE_CONDITION
data.append(_write_uint32var(self.conditionSetIndex))
data.append(_write_uint32var(self.conditionIndex))

Check warning on line 253 in Lib/fontTools/ttLib/tables/otTables.py

View check run for this annotation

Codecov / codecov/patch

Lib/fontTools/ttLib/tables/otTables.py#L252-L253

Added lines #L252 - L253 were not covered by tests

numAxes = len(self.axisValues)

Expand Down Expand Up @@ -301,8 +301,8 @@ def write(name, value, attrs=()):

write("glyphName", self.glyphName)

if self.conditionSetIndex is not None:
write("conditionSetIndex", self.conditionSetIndex)
if self.conditionIndex is not None:
write("conditionIndex", self.conditionIndex)

Check warning on line 305 in Lib/fontTools/ttLib/tables/otTables.py

View check run for this annotation

Codecov / codecov/patch

Lib/fontTools/ttLib/tables/otTables.py#L305

Added line #L305 was not covered by tests
if self.axisIndicesIndex is not None:
write("axisIndicesIndex", self.axisIndicesIndex)
if (
Expand Down Expand Up @@ -342,8 +342,8 @@ def fromXML(self, name, attrs, content, ttFont):

if name == "glyphName":
self.glyphName = v
elif name == "conditionSetIndex":
self.conditionSetIndex = safeEval(v)
elif name == "conditionIndex":
self.conditionIndex = safeEval(v)

Check warning on line 346 in Lib/fontTools/ttLib/tables/otTables.py

View check run for this annotation

Codecov / codecov/patch

Lib/fontTools/ttLib/tables/otTables.py#L346

Added line #L346 was not covered by tests
elif name == "axisIndicesIndex":
self.axisIndicesIndex = safeEval(v)
elif name == "axisValues":
Expand Down
47 changes: 29 additions & 18 deletions Lib/fontTools/ttLib/ttGlyphSet.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,33 @@ def draw(self, pen):
self.glyphSet.charStrings[self.name].draw(pen, self.glyphSet.blender)


def _evaluateCondition(condition, fvarAxes, location):
if condition.Format == 1:
axisIndex = condition.AxisIndex
axisTag = fvarAxes[axisIndex].axisTag
axisValue = location.get(axisTag, 0)
minValue = condition.FilterRangeMinValue
maxValue = condition.FilterRangeMaxValue
return minValue <= axisValue <= maxValue
elif condition.Format == 2:
# ConditionAnd
for subcondition in condition.ConditionTable:
if not _evaluateCondition(subcondition, fvarAxes, location):
return False
return True

Check warning on line 292 in Lib/fontTools/ttLib/ttGlyphSet.py

View check run for this annotation

Codecov / codecov/patch

Lib/fontTools/ttLib/ttGlyphSet.py#L291-L292

Added lines #L291 - L292 were not covered by tests
elif condition.Format == 3:
# ConditionOr
for subcondition in condition.ConditionTable:
if _evaluateCondition(subcondition, fvarAxes, location):
return True
return False

Check warning on line 298 in Lib/fontTools/ttLib/ttGlyphSet.py

View check run for this annotation

Codecov / codecov/patch

Lib/fontTools/ttLib/ttGlyphSet.py#L297-L298

Added lines #L297 - L298 were not covered by tests
elif condition.Format == 4:
# ConditionNegate
return not _evaluateCondition(condition.conditionTable, fvarAxes, location)

Check warning on line 301 in Lib/fontTools/ttLib/ttGlyphSet.py

View check run for this annotation

Codecov / codecov/patch

Lib/fontTools/ttLib/ttGlyphSet.py#L301

Added line #L301 was not covered by tests
else:
return False # Unkonwn condition format

Check warning on line 303 in Lib/fontTools/ttLib/ttGlyphSet.py

View check run for this annotation

Codecov / codecov/patch

Lib/fontTools/ttLib/ttGlyphSet.py#L303

Added line #L303 was not covered by tests


class _TTGlyphVARC(_TTGlyph):
def _draw(self, pen, isPointPen):
"""Draw the glyph onto ``pen``. See fontTools.pens.basePen for details
Expand All @@ -301,24 +328,8 @@ def _draw(self, pen, isPointPen):
for comp in glyph.components:

if comp.flags & VarComponentFlags.HAVE_CONDITION:
conditionSet = varc.ConditionSetList.ConditionSet[
comp.conditionSetIndex
]
# Evaluate condition
show = True
for condition in conditionSet.ConditionTable:
if condition.Format == 1:
axisIndex = condition.AxisIndex
axisTag = fvarAxes[axisIndex].axisTag
axisValue = self.glyphSet.location.get(axisTag, 0)
minValue = condition.FilterRangeMinValue
maxValue = condition.FilterRangeMaxValue
if not (minValue <= axisValue <= maxValue):
show = False
break
else:
show = False # Unkonwn condition format
if not show:
condition = varc.ConditionList.ConditionTable[comp.conditionIndex]
if not _evaluateCondition(condition, fvarAxes, self.glyphSet.location):
continue

location = {}
Expand Down
Binary file modified Tests/ttLib/data/varc-ac01-conditional.ttf
Binary file not shown.

0 comments on commit 7193680

Please sign in to comment.