diff --git a/Lib/gftools/builder/fontc.py b/Lib/gftools/builder/fontc.py index b9b2ed1b..50cb9ede 100644 --- a/Lib/gftools/builder/fontc.py +++ b/Lib/gftools/builder/fontc.py @@ -69,13 +69,10 @@ def modify_config(self, config: dict): extra_args = config.get("extraFontmakeArgs") or "" extra_args += " --no-production-names --drop-implied-oncurves" config["extraFontmakeArgs"] = extra_args - # override config to turn not build instances if we're variable - if self.will_build_variable_font(config): - config["buildStatic"] = False # if the font doesn't explicitly request CFF, just build TT outlines # if the font _only_ wants CFF outlines, we will try to build them # ( but fail on fontc for now) (but is this even a thing?) - elif config.get("buildTTF", True): + if config.get("buildTTF", True): config["buildOTF"] = False if self.simple_output_path: output_dir = str(self.simple_output_path) diff --git a/Lib/gftools/builder/operations/__init__.py b/Lib/gftools/builder/operations/__init__.py index 24f32fcd..027cc5cf 100644 --- a/Lib/gftools/builder/operations/__init__.py +++ b/Lib/gftools/builder/operations/__init__.py @@ -178,6 +178,11 @@ def get(self, operation_name: str): return FontcAddSubset + if operation_name == "instantiateUfo": + from .fontc.fontcInstantiateUfo import FontcInstantiateUFO + + return FontcInstantiateUFO + return self.known_operations.get(operation_name) diff --git a/Lib/gftools/builder/operations/fontc/fontcInstantiateUfo.py b/Lib/gftools/builder/operations/fontc/fontcInstantiateUfo.py new file mode 100644 index 00000000..5541e58d --- /dev/null +++ b/Lib/gftools/builder/operations/fontc/fontcInstantiateUfo.py @@ -0,0 +1,70 @@ +from pathlib import Path +from typing import List +from gftools.builder.file import File +from gftools.builder.operations import FontmakeOperationBase +import glyphsLib +import os +import gftools.builder +from functools import cached_property +from glyphsLib.builder import UFOBuilder +from ninja.ninja_syntax import Writer, escape_path +from fontTools.designspaceLib import InstanceDescriptor + + +class FontcInstantiateUFO(FontmakeOperationBase): + description = "Create instance UFOs from a Glyphs or designspace file" + rule = 'fontmake -i "$instance_name" -o ufo $fontmake_type $in $args' + + def validate(self): + # Ensure there is an instance name + if "instance_name" not in self.original: + raise ValueError("No instance name specified") + # Ensure the instance is defined in the font + desired = self.original["instance_name"] + if "target" not in self.original and not self.relevant_instance: + raise ValueError( + f"Instance {desired} not found in {self.first_source.path}" + ) + + @cached_property + def relevant_instance(self): + desired = self.original["instance_name"] + relevant_instance = [ + i + for i in self.first_source.instances + if i.name == desired or i.familyName + " " + i.styleName == desired + ] + if len(relevant_instance) == 0: + return None + return relevant_instance[0] + + @property + def instance_dir(self): + return Path(self.first_source.path).parent / "instance_ufos" + + @property + def targets(self): + if "target" in self.original: + return [File(self.original["target"])] + instance = self.relevant_instance + assert instance is not None + assert instance.filename is not None + # if self.first_source.is_glyphs: + return [File(str(self.instance_dir / (os.path.basename(instance.filename))))] + # return [ File(instance.filename) ] + + @property + def variables(self): + vars = super().variables + if self.first_source.is_glyphs: + vars["args"] += f"--instance-dir {escape_path(str(self.instance_dir))}" + else: + vars["args"] += f"--output-dir {escape_path(str(self.instance_dir))}" + vars["instance_name"] = self.original["instance_name"] + if self.original.get("glyphData") is not None: + for glyphData in self.original["glyphData"]: + vars["args"] += f" --glyph-data {escape_path(glyphData)}" + return vars + + def set_target(self, target: File): + raise ValueError("Cannot set target on InstantiateUFO") diff --git a/Lib/gftools/builder/recipeproviders/googlefonts.py b/Lib/gftools/builder/recipeproviders/googlefonts.py index 350328c9..2fc7f607 100644 --- a/Lib/gftools/builder/recipeproviders/googlefonts.py +++ b/Lib/gftools/builder/recipeproviders/googlefonts.py @@ -333,22 +333,20 @@ def build_a_static(self, source: File, instance: InstanceDescriptor, output): steps = [ {"source": source.path}, ] - # if we're running fontc we skip conversion to UFO - if not source.is_ufo and not self.config.get("use_fontc", False): - instancename = instance.name - if instancename is None: - if not instance.familyName or not instance.styleName: - raise ValueError( - f"Instance {instance.filename} must have a name, or familyName and styleName" - ) - instancename = instance.familyName + " " + instance.styleName - steps.append( - { - "operation": "instantiateUfo", - "instance_name": instancename, - "glyphData": self.config.get("glyphData"), - } - ) + instancename = instance.name + if instancename is None: + if not instance.familyName or not instance.styleName: + raise ValueError( + f"Instance {instance.filename} must have a name, or familyName and styleName" + ) + instancename = instance.familyName + " " + instance.styleName + steps.append( + { + "operation": "instantiateUfo", + "instance_name": instancename, + "glyphData": self.config.get("glyphData"), + } + ) steps += ( [ { diff --git a/Lib/gftools/builder/recipeproviders/noto.py b/Lib/gftools/builder/recipeproviders/noto.py index d83d9ebc..20c8a72b 100644 --- a/Lib/gftools/builder/recipeproviders/noto.py +++ b/Lib/gftools/builder/recipeproviders/noto.py @@ -277,7 +277,7 @@ def build_a_static(self, source, instance, output): "instance_name": instance.name, "target": "full-designspace/instance_ufos/" + os.path.basename(instance.filename) - + ".json", + + ("" if self.builder.fontc_args.use_fontc else ".json"), }, { "operation": "buildTTF" if output == "ttf" else "buildOTF",