featureVars: modify normalization using avar maps
This commit is contained in:
parent
4256e6c6bf
commit
081ca1327c
@ -4,6 +4,7 @@ from fontTools.ttLib import newTable
|
|||||||
from fontTools.ttLib.tables import otTables as ot
|
from fontTools.ttLib.tables import otTables as ot
|
||||||
from fontTools.otlLib.builder import buildLookup, buildSingleSubstSubtable
|
from fontTools.otlLib.builder import buildLookup, buildSingleSubstSubtable
|
||||||
from fontTools.varLib.models import normalizeValue
|
from fontTools.varLib.models import normalizeValue
|
||||||
|
from fontTools.varLib import _DesignspaceAxis
|
||||||
|
|
||||||
|
|
||||||
def addFeatureVariations(font, conditionalSubstitutions):
|
def addFeatureVariations(font, conditionalSubstitutions):
|
||||||
@ -21,7 +22,8 @@ def addFeatureVariations(font, conditionalSubstitutions):
|
|||||||
functionality is not compromised if they do.
|
functionality is not compromised if they do.
|
||||||
|
|
||||||
The minimum and maximum values are expressed in raw user coordinates, and
|
The minimum and maximum values are expressed in raw user coordinates, and
|
||||||
are internally normalized without going through the `avar` mapping.
|
are internally normalized using the `avar` mapping, if present, else using
|
||||||
|
the default mapping.
|
||||||
|
|
||||||
A Substitution is a dict mapping source glyph names to substitute glyph names.
|
A Substitution is a dict mapping source glyph names to substitute glyph names.
|
||||||
"""
|
"""
|
||||||
@ -38,10 +40,12 @@ def addFeatureVariations(font, conditionalSubstitutions):
|
|||||||
# >>> f.save(dstPath)
|
# >>> f.save(dstPath)
|
||||||
|
|
||||||
defaultSpace = {}
|
defaultSpace = {}
|
||||||
axisMap = {}
|
axes = {}
|
||||||
for axis in font["fvar"].axes:
|
for axis in font["fvar"].axes:
|
||||||
defaultSpace[axis.axisTag] = (axis.minValue, axis.maxValue)
|
defaultSpace[axis.axisTag] = (axis.minValue, axis.maxValue)
|
||||||
axisMap[axis.axisTag] = (axis.minValue, axis.defaultValue, axis.maxValue)
|
axes[axis.axisTag] = (axis.minValue, axis.defaultValue, axis.maxValue)
|
||||||
|
|
||||||
|
maps = font['avar'].segments if 'avar' in font else None
|
||||||
|
|
||||||
# Since the FeatureVariations table will only ever match one rule at a time,
|
# Since the FeatureVariations table will only ever match one rule at a time,
|
||||||
# we will make new rules for all possible combinations of our input, so we
|
# we will make new rules for all possible combinations of our input, so we
|
||||||
@ -62,7 +66,9 @@ def addFeatureVariations(font, conditionalSubstitutions):
|
|||||||
# Remove default values, so we don't generate redundant ConditionSets
|
# Remove default values, so we don't generate redundant ConditionSets
|
||||||
space = cleanupSpace(space, defaultSpace)
|
space = cleanupSpace(space, defaultSpace)
|
||||||
if space:
|
if space:
|
||||||
space = normalizeSpace(space, axisMap)
|
space = normalizeSpace(space, axes)
|
||||||
|
if maps is not None:
|
||||||
|
space = mapSpace(space, maps)
|
||||||
explodedConditionalSubstitutions.append((space, lookups))
|
explodedConditionalSubstitutions.append((space, lookups))
|
||||||
|
|
||||||
addFeatureVariationsRaw(font, explodedConditionalSubstitutions)
|
addFeatureVariationsRaw(font, explodedConditionalSubstitutions)
|
||||||
@ -180,14 +186,30 @@ def cleanupSpace(space, defaultSpace):
|
|||||||
return {tag: limit for tag, limit in space.items() if limit != defaultSpace[tag]}
|
return {tag: limit for tag, limit in space.items() if limit != defaultSpace[tag]}
|
||||||
|
|
||||||
|
|
||||||
def normalizeSpace(space, axisMap):
|
def normalizeSpace(space, axes):
|
||||||
"""Convert the min/max values in the `space` dict to normalized
|
"""Convert the min/max values in the `space` dict to normalized
|
||||||
design space values."""
|
design space values.
|
||||||
space = {tag: (normalizeValue(minValue, axisMap[tag]), normalizeValue(maxValue, axisMap[tag]))
|
The `axes` argument is a dictionary keyed by axis tags, containing
|
||||||
for tag, (minValue, maxValue) in space.items()}
|
(minimum, default, maximum) tuples from the fvar table.
|
||||||
|
"""
|
||||||
|
space = {tag: (normalizeValue(minValue, axes[tag]),
|
||||||
|
normalizeValue(maxValue, axes[tag]))
|
||||||
|
for tag, (minValue, maxValue) in space.items()}
|
||||||
return space
|
return space
|
||||||
|
|
||||||
|
|
||||||
|
def mapSpace(space, maps):
|
||||||
|
"""Modify normalized min/max values in the `space` dict using axis maps
|
||||||
|
from avar table.
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
tag: (
|
||||||
|
_DesignspaceAxis._map(minValue, maps[tag]),
|
||||||
|
_DesignspaceAxis._map(maxValue, maps[tag])
|
||||||
|
) for tag, (minValue, maxValue) in space.items()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Low level implementation
|
# Low level implementation
|
||||||
#
|
#
|
||||||
|
Loading…
x
Reference in New Issue
Block a user