Merge pull request #3042 from fonttools/conditionset-consult-avar
Conditionset: consult avar to normalize values
This commit is contained in:
commit
a55a545b12
@ -2065,7 +2065,7 @@ class ConditionsetStatement(Statement):
|
|||||||
self.conditions = conditions
|
self.conditions = conditions
|
||||||
|
|
||||||
def build(self, builder):
|
def build(self, builder):
|
||||||
builder.add_conditionset(self.name, self.conditions)
|
builder.add_conditionset(self.location, self.name, self.conditions)
|
||||||
|
|
||||||
def asFea(self, res="", indent=""):
|
def asFea(self, res="", indent=""):
|
||||||
res += indent + f"conditionset {self.name} " + "{\n"
|
res += indent + f"conditionset {self.name} " + "{\n"
|
||||||
|
@ -34,7 +34,7 @@ from fontTools.otlLib.error import OpenTypeLibError
|
|||||||
from fontTools.varLib.varStore import OnlineVarStoreBuilder
|
from fontTools.varLib.varStore import OnlineVarStoreBuilder
|
||||||
from fontTools.varLib.builder import buildVarDevTable
|
from fontTools.varLib.builder import buildVarDevTable
|
||||||
from fontTools.varLib.featureVars import addFeatureVariationsRaw
|
from fontTools.varLib.featureVars import addFeatureVariationsRaw
|
||||||
from fontTools.varLib.models import normalizeValue
|
from fontTools.varLib.models import normalizeValue, piecewiseLinearMap
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
import itertools
|
import itertools
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
@ -947,11 +947,7 @@ class Builder(object):
|
|||||||
feature_vars = {}
|
feature_vars = {}
|
||||||
has_any_variations = False
|
has_any_variations = False
|
||||||
# Sort out which lookups to build, gather their indices
|
# Sort out which lookups to build, gather their indices
|
||||||
for (
|
for (_, _, feature_tag), variations in self.feature_variations_.items():
|
||||||
script_,
|
|
||||||
language,
|
|
||||||
feature_tag,
|
|
||||||
), variations in self.feature_variations_.items():
|
|
||||||
feature_vars[feature_tag] = []
|
feature_vars[feature_tag] = []
|
||||||
for conditionset, builders in variations.items():
|
for conditionset, builders in variations.items():
|
||||||
raw_conditionset = self.conditionsets_[conditionset]
|
raw_conditionset = self.conditionsets_[conditionset]
|
||||||
@ -1572,10 +1568,11 @@ class Builder(object):
|
|||||||
def add_vhea_field(self, key, value):
|
def add_vhea_field(self, key, value):
|
||||||
self.vhea_[key] = value
|
self.vhea_[key] = value
|
||||||
|
|
||||||
def add_conditionset(self, key, value):
|
def add_conditionset(self, location, key, value):
|
||||||
if not "fvar" in self.font:
|
if "fvar" not in self.font:
|
||||||
raise FeatureLibError(
|
raise FeatureLibError(
|
||||||
"Cannot add feature variations to a font without an 'fvar' table"
|
"Cannot add feature variations to a font without an 'fvar' table",
|
||||||
|
location,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Normalize
|
# Normalize
|
||||||
@ -1592,6 +1589,18 @@ class Builder(object):
|
|||||||
for tag, (bottom, top) in value.items()
|
for tag, (bottom, top) in value.items()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# NOTE: This might result in rounding errors (off-by-ones) compared to
|
||||||
|
# rules in Designspace files, since we're working with what's in the
|
||||||
|
# `avar` table rather than the original values.
|
||||||
|
if "avar" in self.font:
|
||||||
|
mapping = self.font["avar"].segments
|
||||||
|
value = {
|
||||||
|
axis: tuple(
|
||||||
|
piecewiseLinearMap(v, mapping[axis]) for v in condition_range
|
||||||
|
)
|
||||||
|
for axis, condition_range in value.items()
|
||||||
|
}
|
||||||
|
|
||||||
self.conditionsets_[key] = value
|
self.conditionsets_[key] = value
|
||||||
|
|
||||||
def makeOpenTypeAnchor(self, location, anchor):
|
def makeOpenTypeAnchor(self, location, anchor):
|
||||||
|
@ -975,6 +975,57 @@ class BuilderTest(unittest.TestCase):
|
|||||||
f'{name}.fea:{line}:12: Ambiguous "ignore {sub}", there should be least one marked glyph'
|
f'{name}.fea:{line}:12: Ambiguous "ignore {sub}", there should be least one marked glyph'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_condition_set_avar(self):
|
||||||
|
"""Test that the `avar` table is consulted when normalizing user-space
|
||||||
|
values."""
|
||||||
|
|
||||||
|
features = """
|
||||||
|
languagesystem DFLT dflt;
|
||||||
|
|
||||||
|
lookup conditional_sub {
|
||||||
|
sub e by a;
|
||||||
|
} conditional_sub;
|
||||||
|
|
||||||
|
conditionset test {
|
||||||
|
wght 600 1000;
|
||||||
|
} test;
|
||||||
|
|
||||||
|
variation rlig test {
|
||||||
|
lookup conditional_sub;
|
||||||
|
} rlig;
|
||||||
|
"""
|
||||||
|
|
||||||
|
def make_mock_vf():
|
||||||
|
font = makeTTFont()
|
||||||
|
font["name"] = newTable("name")
|
||||||
|
addFvar(font, [("wght", 0, 0, 1000, "Weight")], [])
|
||||||
|
del font["name"]
|
||||||
|
return font
|
||||||
|
|
||||||
|
# Without `avar`:
|
||||||
|
font = make_mock_vf()
|
||||||
|
addOpenTypeFeaturesFromString(font, features)
|
||||||
|
assert (
|
||||||
|
font.tables["GSUB"]
|
||||||
|
.table.FeatureVariations.FeatureVariationRecord[0]
|
||||||
|
.ConditionSet.ConditionTable[0]
|
||||||
|
.FilterRangeMinValue
|
||||||
|
== 0.6 # user-space 600
|
||||||
|
)
|
||||||
|
|
||||||
|
# With `avar`, shifting the positive midpoint 0.5 a bit to the right:
|
||||||
|
font = make_mock_vf()
|
||||||
|
font["avar"] = newTable("avar")
|
||||||
|
font["avar"].segments = {"wght": {-1.0: -1.0, 0.0: 0.0, 0.5: 0.625, 1.0: 1.0}}
|
||||||
|
addOpenTypeFeaturesFromString(font, features)
|
||||||
|
assert (
|
||||||
|
font.tables["GSUB"]
|
||||||
|
.table.FeatureVariations.FeatureVariationRecord[0]
|
||||||
|
.ConditionSet.ConditionTable[0]
|
||||||
|
.FilterRangeMinValue
|
||||||
|
== 0.7 # user-space 600 shifted to the right,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def generate_feature_file_test(name):
|
def generate_feature_file_test(name):
|
||||||
return lambda self: self.check_feature_file(name)
|
return lambda self: self.check_feature_file(name)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user