[featureVars] expose method to addGSUBFeatureVariations to existing VF
Fixes https://github.com/fonttools/fonttools/issues/3357
This commit is contained in:
parent
0b05cec0a3
commit
82021732ae
@ -863,7 +863,7 @@ def _add_COLR(font, model, master_fonts, axisTags, colr_layer_reuse=True):
|
||||
colr.VarIndexMap = builder.buildDeltaSetIndexMap(varIdxes)
|
||||
|
||||
|
||||
def load_designspace(designspace):
|
||||
def load_designspace(designspace, log_enabled=True):
|
||||
# TODO: remove this and always assume 'designspace' is a DesignSpaceDocument,
|
||||
# never a file path, as that's already handled by caller
|
||||
if hasattr(designspace, "sources"): # Assume a DesignspaceDocument
|
||||
@ -911,10 +911,11 @@ def load_designspace(designspace):
|
||||
axis.labelNames["en"] = tostr(axis_name)
|
||||
|
||||
axes[axis_name] = axis
|
||||
log.info("Axes:\n%s", pformat([axis.asdict() for axis in axes.values()]))
|
||||
if log_enabled:
|
||||
log.info("Axes:\n%s", pformat([axis.asdict() for axis in axes.values()]))
|
||||
|
||||
axisMappings = ds.axisMappings
|
||||
if axisMappings:
|
||||
if axisMappings and log_enabled:
|
||||
log.info("Mappings:\n%s", pformat(axisMappings))
|
||||
|
||||
# Check all master and instance locations are valid and fill in defaults
|
||||
@ -944,20 +945,23 @@ def load_designspace(designspace):
|
||||
# Normalize master locations
|
||||
|
||||
internal_master_locs = [o.getFullDesignLocation(ds) for o in masters]
|
||||
log.info("Internal master locations:\n%s", pformat(internal_master_locs))
|
||||
if log_enabled:
|
||||
log.info("Internal master locations:\n%s", pformat(internal_master_locs))
|
||||
|
||||
# TODO This mapping should ideally be moved closer to logic in _add_fvar/avar
|
||||
internal_axis_supports = {}
|
||||
for axis in axes.values():
|
||||
triple = (axis.minimum, axis.default, axis.maximum)
|
||||
internal_axis_supports[axis.name] = [axis.map_forward(v) for v in triple]
|
||||
log.info("Internal axis supports:\n%s", pformat(internal_axis_supports))
|
||||
if log_enabled:
|
||||
log.info("Internal axis supports:\n%s", pformat(internal_axis_supports))
|
||||
|
||||
normalized_master_locs = [
|
||||
models.normalizeLocation(m, internal_axis_supports)
|
||||
for m in internal_master_locs
|
||||
]
|
||||
log.info("Normalized master locations:\n%s", pformat(normalized_master_locs))
|
||||
if log_enabled:
|
||||
log.info("Normalized master locations:\n%s", pformat(normalized_master_locs))
|
||||
|
||||
# Find base master
|
||||
base_idx = None
|
||||
@ -972,7 +976,8 @@ def load_designspace(designspace):
|
||||
raise VarLibValidationError(
|
||||
"Base master not found; no master at default location?"
|
||||
)
|
||||
log.info("Index of base master: %s", base_idx)
|
||||
if log_enabled:
|
||||
log.info("Index of base master: %s", base_idx)
|
||||
|
||||
return _DesignSpaceData(
|
||||
axes,
|
||||
@ -1308,6 +1313,30 @@ def _feature_variations_tags(ds):
|
||||
return sorted({t.strip() for t in raw_tags.split(",")})
|
||||
|
||||
|
||||
def addGSUBFeatureVariations(vf, designspace, featureTags=(), *, log_enabled=False):
|
||||
"""Add GSUB FeatureVariations table to variable font, based on DesignSpace rules.
|
||||
|
||||
Args:
|
||||
vf: A TTFont object representing the variable font.
|
||||
designspace: A DesignSpaceDocument object.
|
||||
featureTags: Optional feature tag(s) to use for the FeatureVariations records.
|
||||
If unset, the key 'com.github.fonttools.varLib.featureVarsFeatureTag' is
|
||||
looked up in the DS <lib> and used; otherwise the default is 'rclt' if
|
||||
the <rules processing="last"> attribute is set, else 'rvrn'.
|
||||
See <https://fonttools.readthedocs.io/en/latest/designspaceLib/xml.html#rules-element>
|
||||
log_enabled: If True, log info about DS axes and sources. Default is False, as
|
||||
the same info may have already been logged as part of varLib.build.
|
||||
"""
|
||||
ds = load_designspace(designspace, log_enabled=log_enabled)
|
||||
if not ds.rules:
|
||||
return
|
||||
if not featureTags:
|
||||
featureTags = _feature_variations_tags(ds)
|
||||
_add_GSUB_feature_variations(
|
||||
vf, ds.axes, ds.internal_axis_supports, ds.rules, featureTags
|
||||
)
|
||||
|
||||
|
||||
def main(args=None):
|
||||
"""Build variable fonts from a designspace file and masters"""
|
||||
from argparse import ArgumentParser
|
||||
|
@ -1,7 +1,13 @@
|
||||
from fontTools.colorLib.builder import buildCOLR
|
||||
from fontTools.ttLib import TTFont, newTable
|
||||
from fontTools.ttLib.tables import otTables as ot
|
||||
from fontTools.varLib import build, build_many, load_designspace, _add_COLR
|
||||
from fontTools.varLib import (
|
||||
build,
|
||||
build_many,
|
||||
load_designspace,
|
||||
_add_COLR,
|
||||
addGSUBFeatureVariations,
|
||||
)
|
||||
from fontTools.varLib.errors import VarLibValidationError
|
||||
import fontTools.varLib.errors as varLibErrors
|
||||
from fontTools.varLib.models import VariationModel
|
||||
@ -1009,6 +1015,32 @@ Expected to see .ScriptCount==1, instead saw 0""",
|
||||
save_before_dump=True,
|
||||
)
|
||||
|
||||
def test_varlib_addGSUBFeatureVariations(self):
|
||||
ttx_dir = self.get_test_input("master_ttx_interpolatable_ttf")
|
||||
|
||||
ds = DesignSpaceDocument.fromfile(
|
||||
self.get_test_input("FeatureVars.designspace")
|
||||
)
|
||||
for source in ds.sources:
|
||||
ttx_dump = TTFont()
|
||||
ttx_dump.importXML(
|
||||
os.path.join(
|
||||
ttx_dir, os.path.basename(source.filename).replace(".ufo", ".ttx")
|
||||
)
|
||||
)
|
||||
source.font = ttx_dump
|
||||
|
||||
varfont, _, _ = build(ds, exclude=["GSUB"])
|
||||
assert "GSUB" not in varfont
|
||||
|
||||
addGSUBFeatureVariations(varfont, ds)
|
||||
assert "GSUB" in varfont
|
||||
|
||||
tables = ["fvar", "GSUB"]
|
||||
expected_ttx_path = self.get_test_output("FeatureVars.ttx")
|
||||
self.expect_ttx(varfont, expected_ttx_path, tables)
|
||||
self.check_ttx_dump(varfont, expected_ttx_path, tables, ".ttf")
|
||||
|
||||
|
||||
def test_load_masters_layerName_without_required_font():
|
||||
ds = DesignSpaceDocument()
|
||||
|
Loading…
x
Reference in New Issue
Block a user