def build_variable_font( self, designspace, output_path=None, output_dir=None, ttf=True, optimize_gvar=True, optimize_cff=CFFOptimization.SPECIALIZE, use_production_names=None, reverse_direction=True, conversion_error=None, feature_writers=None, cff_round_tolerance=None, debug_feature_file=None, flatten_components=False, filters=None, **kwargs, ): """Build OpenType variable font from masters in a designspace.""" assert not (output_path and output_dir), "mutually exclusive args" designspace = self._load_designspace_sources(designspace) if output_path is None: output_path = ( os.path.splitext(os.path.basename(designspace.path))[0] + "-VF" ) ext = "ttf" if ttf else "otf" output_path = self._output_path( output_path, ext, is_variable=True, output_dir=output_dir ) logger.info("Building variable font " + output_path) if ttf: font = ufo2ft.compileVariableTTF( designspace, featureWriters=feature_writers, useProductionNames=use_production_names, cubicConversionError=conversion_error, reverseDirection=reverse_direction, optimizeGvar=optimize_gvar, flattenComponents=flatten_components, debugFeatureFile=debug_feature_file, filters=filters, inplace=True, ) else: font = ufo2ft.compileVariableCFF2( designspace, featureWriters=feature_writers, useProductionNames=use_production_names, roundTolerance=cff_round_tolerance, debugFeatureFile=debug_feature_file, optimizeCFF=optimize_cff, filters=filters, inplace=True, ) font.save(output_path)
def test_compileVariableCFF2(self, designspace, useProductionNames): varfont = compileVariableCFF2(designspace, useProductionNames=useProductionNames) expectTTX( varfont, "TestVariableFont-CFF2{}.ttx".format( "-useProductionNames" if useProductionNames else ""), )
def build_variable_fonts(designspace, *steps): sourceFonts = [ ufoLib2.Font.open(INPUT_DIR / designspace.sources[0].filename), ufoLib2.Font.open(INPUT_DIR / designspace.sources[1].filename), ufoLib2.Font.open(INPUT_DIR / designspace.sources[2].filename) ] for source in sourceFonts: set_font_metaData(source, "var") designspace.sources[0].font = sourceFonts[0] #ExtraLight designspace.sources[1].font = sourceFonts[1] #Regular designspace.sources[2].font = sourceFonts[2] #Bold for font in sourceFonts: for step in steps: step(font) familyName = sourceFonts[1].info.familyName file_stem = sourceFonts[1].info.familyName.replace(" ", "") file_path = (OUTPUT_DIR / file_stem).with_suffix(f".ttf") print(f"[{familyName}] Compiling") varFont = ufo2ft.compileVariableTTF(designspace) print(f"[{familyName}] Adding STAT table") styleSpace = classes.Stylespace.from_file(INPUT_DIR / "STAT.plist") lib.apply_stylespace_to_variable_font(styleSpace, varFont, {}) print(f"[{familyName}] Merging VTT") vttLib.transfer.merge_from_file(varFont, VTT_DATA_FILE) print(f"[{familyName}] Saving") varFont.save(file_path) print(f"[{familyName}] Done: {file_path}") print(f"[{familyName}] Compiling CFF2") file_path_cff2 = (OUTPUT_DIR / file_stem).with_suffix(f".otf") #Do not optimize, because we have to do it again after autohinting. varFontCFF2 = ufo2ft.compileVariableCFF2( designspace, inplace=True, useProductionNames=True, optimizeCFF=ufo2ft.CFFOptimization.NONE, ) print(f"[{familyName}] Adding STAT table") styleSpace = classes.Stylespace.from_file(INPUT_DIR / "STAT.plist") lib.apply_stylespace_to_variable_font(styleSpace, varFontCFF2, {}) print(f"[{familyName}] Saving") varFontCFF2.save(file_path_cff2) print(f"[{familyName}] Done: {file_path_cff2}")
def buildVariable( self, designspace, # designspace filename string or DesignSpaceDocument object outputFilename, # output filename string cff=False, # if true, builds CFF-2 font, else TTF **kwargs, # passed along to ufo2ft.compileVariable*() ): designspace = self._loadDesignspace(designspace) # check in the designspace's <lib> element if user supplied a custom featureWriters # configuration; if so, use that for all the UFOs built from this designspace. featureWriters = None if ufo2ft.featureWriters.FEATURE_WRITERS_KEY in designspace.lib: featureWriters = ufo2ft.featureWriters.loadFeatureWriters( designspace) compilerOptions = dict( useProductionNames=True, featureWriters=featureWriters, inplace=True, # avoid extra copy **kwargs) if log.isEnabledFor(logging.INFO): log.info("compiling %s -> %s (%s)", designspace.path, outputFilename, "OTF/CFF-2" if cff else "TTF") if cff: font = ufo2ft.compileVariableCFF2(designspace, **compilerOptions) else: font = ufo2ft.compileVariableTTF(designspace, **compilerOptions) # Rename fullName record to familyName (VF only). # Note: Even though we set openTypeNameCompatibleFullName it seems that the fullName # record is still computed by fonttools, so we override it here. setFullName(font, getFamilyName(font)) # rebuild STAT table to correct VF instance information rebuildStatTable(font, designspace) log.debug("writing %s", outputFilename) font.save(outputFilename)
def test_compileVariableCFF2_subroutinized(self, designspace): varfont = compileVariableCFF2(designspace, optimizeCFF=2) expectTTX(varfont, "TestVariableFont-CFF2-cffsubr.ttx")
# 1. Load Designspace and filter out instances that are marked as non-exportable. designspace = fontTools.designspaceLib.DesignSpaceDocument.fromfile( designspace_path) designspace.loadSourceFonts(ufoLib2.Font.open) designspace.instances = [ s for s in designspace.instances if s.lib.get("com.schriftgestaltung.export", True) ] # 2. Compile variable OTF from the masters. Do not optimize, because we have to do # it again after autohinting. varfont = ufo2ft.compileVariableCFF2( designspace, inplace=True, useProductionNames=True, optimizeCFF=ufo2ft.CFFOptimization.NONE, ) # 3. Generate STAT table. stylespace = statmake.classes.Stylespace.from_file(stylespace_path) statmake.lib.apply_stylespace_to_variable_font(stylespace, varfont, {}) # 4. Save. External tools after this point. varfont.save(output_path) # 5. Autohint subprocess.check_call( [os.fspath(args.psautohint_path), os.fspath(output_path)])