Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add option to override FEA include directory; set it to the .glyphs directory when building from Glyphs #917

Merged
merged 3 commits into from
Oct 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Lib/fontmake/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,13 @@ def main(args=None):
"interpolating. Use if you share feature files of masters in "
"external files, as instances can end up elsewhere.",
)
outputGroup.add_argument(
"--fea-include-dir",
default=None,
help="Overrides the default directory where to search for included "
"feature files with relative paths. This only works when the input is a "
"Designspace or UFOs, not from Glyphs at the moment.",
)
outputGroup.add_argument(
"--no-generate-GDEF",
dest="generate_GDEF",
Expand Down Expand Up @@ -641,6 +648,10 @@ def main(args=None):
project = FontProject(validate_ufo=args.pop("validate_ufo"))

if inputs.glyphs_path:
# we don't support customizing include directory for .glyphs input
# for Glyphs.app does not either.
exclude_args(parser, args, ["fea_include_dir"], inputs.format_name)

with _make_tempdirs(parser, args):
project.run_from_glyphs(inputs.glyphs_path, **args)
return
Expand Down
30 changes: 27 additions & 3 deletions Lib/fontmake/font_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ def _build_interpolatable_masters(
feature_writers=None,
cff_round_tolerance=None,
debug_feature_file=None,
fea_include_dir=None,
flatten_components=False,
filters=None,
**kwargs,
Expand All @@ -307,6 +308,7 @@ def _build_interpolatable_masters(
cubicConversionError=conversion_error,
featureWriters=feature_writers,
debugFeatureFile=debug_feature_file,
feaIncludeDir=fea_include_dir,
filters=filters,
flattenComponents=flatten_components,
inplace=True,
Expand All @@ -318,6 +320,7 @@ def _build_interpolatable_masters(
roundTolerance=cff_round_tolerance,
featureWriters=feature_writers,
debugFeatureFile=debug_feature_file,
feaIncludeDir=fea_include_dir,
filters=filters,
inplace=True,
)
Expand Down Expand Up @@ -349,6 +352,7 @@ def build_variable_fonts(
feature_writers=None,
cff_round_tolerance=None,
debug_feature_file=None,
fea_include_dir=None,
flatten_components=False,
filters=None,
**kwargs,
Expand Down Expand Up @@ -408,6 +412,7 @@ def build_variable_fonts(
optimizeGvar=optimize_gvar,
flattenComponents=flatten_components,
debugFeatureFile=debug_feature_file,
feaIncludeDir=fea_include_dir,
filters=filters,
inplace=True,
variableFontNames=list(vf_name_to_output_path),
Expand All @@ -419,6 +424,7 @@ def build_variable_fonts(
useProductionNames=use_production_names,
roundTolerance=cff_round_tolerance,
debugFeatureFile=debug_feature_file,
feaIncludeDir=fea_include_dir,
optimizeCFF=optimize_cff,
filters=filters,
inplace=True,
Expand Down Expand Up @@ -486,6 +492,7 @@ def save_otfs(
flatten_components=False,
filters=None,
generate_GDEF=True,
fea_include_dir=None,
):
"""Build OpenType binaries from UFOs.

Expand Down Expand Up @@ -588,6 +595,7 @@ def save_otfs(
cubicConversionError=conversion_error,
featureWriters=feature_writers,
debugFeatureFile=debug_feature_file,
feaIncludeDir=fea_include_dir,
cffVersion=cff_version,
subroutinizer=subroutinizer,
flattenComponents=flatten_components,
Expand Down Expand Up @@ -801,8 +809,14 @@ def run_from_glyphs(
generate_GDEF=generate_GDEF,
ufo_structure=kwargs.get("ufo_structure"),
)
# 'include' statements in features.fea should be resolved relative to
# the input .glyphs path, like Glyphs.app would do, and not relative
# to the UFOs that are generated by glyphsLib.
fea_include_dir = os.path.dirname(glyphs_path)
try:
self.run_from_designspace(designspace_path, **kwargs)
self.run_from_designspace(
designspace_path, fea_include_dir=fea_include_dir, **kwargs
)
except FontmakeError as e:
e.source_trail.append(glyphs_path)
raise
Expand All @@ -813,6 +827,7 @@ def interpolate_instance_ufos(
include=None,
round_instances=False,
expand_features_to_instances=False,
fea_include_dir=None,
ufo_structure="package",
):
"""Interpolate master UFOs with Instantiator and return instance UFOs.
Expand Down Expand Up @@ -857,7 +872,9 @@ def interpolate_instance_ufos(

if expand_features_to_instances:
logger.debug("Expanding features to instance UFOs")
fea_txt = parseLayoutFeatures(subDoc.default.font).asFea()
fea_txt = parseLayoutFeatures(
subDoc.default.font, includeDir=fea_include_dir
).asFea()
generator = attr.evolve(generator, copy_feature_text=fea_txt)

for instance in subDoc.instances:
Expand Down Expand Up @@ -903,6 +920,7 @@ def interpolate_instance_ufos_mutatormath(
include=None,
round_instances=False,
expand_features_to_instances=False,
fea_include_dir=None,
):
"""Interpolate master UFOs with MutatorMath and return instance UFOs.

Expand Down Expand Up @@ -965,7 +983,9 @@ def interpolate_instance_ufos_mutatormath(
raise ValueError("No source is designated as the master for features.")
else:
master_source_font = builder.sources[master_source.name][0]
master_source_features = parseLayoutFeatures(master_source_font).asFea()
master_source_features = parseLayoutFeatures(
master_source_font, includeDir=fea_include_dir
).asFea()
for instance_ufo in instance_ufos:
instance_ufo.features.text = master_source_features
instance_ufo.save()
Expand Down Expand Up @@ -1111,6 +1131,7 @@ def _run_from_designspace_static(
round_instances=False,
feature_writers=None,
expand_features_to_instances=False,
fea_include_dir=None,
use_mutatormath=False,
ufo_structure="package",
**kwargs,
Expand All @@ -1127,6 +1148,7 @@ def _run_from_designspace_static(
include=pattern,
round_instances=round_instances,
expand_features_to_instances=expand_features_to_instances,
fea_include_dir=fea_include_dir,
)
)
else:
Expand All @@ -1136,6 +1158,7 @@ def _run_from_designspace_static(
include=pattern,
round_instances=round_instances,
expand_features_to_instances=expand_features_to_instances,
fea_include_dir=fea_include_dir,
ufo_structure=ufo_structure,
)
)
Expand All @@ -1159,6 +1182,7 @@ def _run_from_designspace_static(
interpolate_layout_from=interpolate_layout_from,
interpolate_layout_dir=interpolate_layout_dir,
feature_writers=feature_writers,
fea_include_dir=fea_include_dir,
**kwargs,
)

Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ fonttools[unicode,ufo,lxml]==4.38.0; platform_python_implementation == 'CPython'
fonttools[unicode,ufo]==4.38.0; platform_python_implementation != 'CPython'
cu2qu==1.6.7.post1
glyphsLib==6.1.0
ufo2ft==2.28.0
ufo2ft==2.29.0
MutatorMath==3.0.1
fontMath==0.9.2
defcon[lxml]==0.10.2; platform_python_implementation == 'CPython'
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"fonttools[ufo,lxml,unicode]>=4.34.0 ; implementation_name == 'cpython'",
"fonttools[ufo,unicode]>=4.34.0 ; implementation_name != 'cpython'",
"glyphsLib>=6.1.0",
"ufo2ft[compreffor]>=2.28.0",
"ufo2ft[compreffor]>=2.29.0",
"fontMath>=0.9.1",
"ufoLib2>=0.13.0",
"attrs>=19",
Expand Down
2 changes: 1 addition & 1 deletion tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1065,7 +1065,7 @@ def test_timing_logger(data_dir, tmp_path):
check=True,
)

assert re.match(
assert re.search(
r"^DEBUG:fontmake.timer:Took [\.0-9]+s to run 'save_otfs'\r?$",
result.stderr.decode(),
flags=re.MULTILINE,
Expand Down