def test_deprecated_arguments(self): ufo = loadUFO("TestFont.ufo") with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always", UserWarning) compileTTF(ufo, kernWriterClass=KernFeatureWriter) self.assertEqual(len(w), 1) self.assertEqual(w[-1].category, UserWarning) self.assertIn( "'kernWriterClass' is deprecated; use 'featureWriters'", str(w[-1].message)) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always", UserWarning) compileOTF(ufo, markWriterClass=MarkFeatureWriter) self.assertEqual(len(w), 1) self.assertEqual(w[-1].category, UserWarning) self.assertIn( "'markWriterClass' is deprecated; use 'featureWriters'", str(w[-1].message)) with self.assertRaises(TypeError): compileTTF(ufo, kernWriterClass=KernFeatureWriter, featureWriters=[MarkFeatureWriter])
def test_compile_without_production_names(self, testufo, prod_names_key, prod_names_value): expected = [ ".notdef", "space", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", ] result = compileTTF(testufo, useProductionNames=False) assert result.getGlyphOrder() == expected testufo.lib[prod_names_key] = prod_names_value result = compileTTF(testufo) assert result.getGlyphOrder() == expected
def DISABLED_test_check_glyphnames_max_length(): """ Check that glyph names do not exceed max length. """ from fontbakery.profiles.universal import com_google_fonts_check_glyphnames_max_length as check import defcon import ufo2ft # TTF test_font = defcon.Font(TEST_FILE("test.ufo")) test_ttf = ufo2ft.compileTTF(test_font) status, _ = list(check(test_ttf))[-1] assert status == PASS test_glyph = defcon.Glyph() test_glyph.unicode = 0x1234 test_glyph.name = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") test_font.insertGlyph(test_glyph) test_ttf = ufo2ft.compileTTF(test_font, useProductionNames=False) status, _ = list(check(test_ttf))[-1] assert status == FAIL test_ttf = ufo2ft.compileTTF(test_font, useProductionNames=True) status, _ = list(check(test_ttf))[-1] assert status == PASS # Upgrade to post format 3.0 and roundtrip data to update TTF object. test_ttf["post"].formatType = 3.0 test_file = io.BytesIO() test_ttf.save(test_file) test_ttf = TTFont(test_file) status, message = list(check(test_ttf))[-1] assert status == PASS assert "format 3.0" in message del test_font, test_ttf, test_file # Prevent copypasta errors. # CFF test_font = defcon.Font(TEST_FILE("test.ufo")) test_otf = ufo2ft.compileOTF(test_font) status, _ = list(check(test_otf))[-1] assert status == PASS test_font.insertGlyph(test_glyph) test_otf = ufo2ft.compileOTF(test_font, useProductionNames=False) status, _ = list(check(test_otf))[-1] assert status == FAIL test_otf = ufo2ft.compileOTF(test_font, useProductionNames=True) status, _ = list(check(test_otf))[-1] assert status == PASS
def test_compile_without_production_names(self): expected = [ '.notdef', 'space', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l' ] result = compileTTF(self.ufo, useProductionNames=False) self.assertEqual(result.getGlyphOrder(), expected) self.ufo.lib["com.github.googlei18n.ufo2ft.useProductionNames"] = False result = compileTTF(self.ufo) self.assertEqual(result.getGlyphOrder(), expected)
def ufo2font(directory, ufolist, output, fromInstances=False): path = os.path.abspath(os.path.join(os.pardir, "src", directory)) for i in ufolist: ufoSource = os.path.join(path, i) destination = "" ufo = Font(ufoSource) folder = os.path.join(path, "fonts") if fromInstances is True: folder = os.path.abspath(os.path.join(path, os.pardir, "fonts")) featureWriters = [KernFeatureWriter(mode="append"), MarkFeatureWriter] if "otf" in output: destination = os.path.join(folder, "OTF") if not os.path.exists(destination): os.makedirs(destination) otf = compileOTF(ufo, removeOverlaps=True, useProductionNames=False, featureWriters=featureWriters) otf.save(os.path.join(destination, i[:-4] + ".otf")) print(destination + i[:-4] + ".otf saved") if "ttf" in output: destination = os.path.join(folder, "TTF") if not os.path.exists(destination): os.makedirs(destination) ttf = compileTTF(ufo, removeOverlaps=True, useProductionNames=False, featureWriters=featureWriters) ttf.save(os.path.join(destination, i[:-4] + ".ttf")) if "woff2" in output: destination = os.path.join(folder, "WOFF2") if not os.path.exists(destination): os.makedirs(destination) if "ttf" not in output: ttf = compileTTF(ufo, removeOverlaps=True, useProductionNames=False, featureWriters=featureWriters) ttf.flavor = "woff2" ttf.save(os.path.join(destination, i[:-4] + ".woff2")) if "woff" in output: destination = os.path.join(folder, "WOFF") if not os.path.exists(destination): os.makedirs(destination) if "ttf" not in output and "woff2" not in output: ttf = compileTTF(ufo, removeOverlaps=True, useProductionNames=False, featureWriters=featureWriters) ttf.flavor = "woff" ttf.save(os.path.join(destination, i[:-4] + ".woff"))
def DISABLED_test_check_glyphnames_max_length(): """ Check that glyph names do not exceed max length. """ check = CheckTester(universal_profile, "com.google.fonts/check/glyphnames_max_length") import defcon import ufo2ft # TTF test_font = defcon.Font(TEST_FILE("test.ufo")) ttFont = ufo2ft.compileTTF(test_font) assert_PASS(check(ttFont)) test_glyph = defcon.Glyph() test_glyph.unicode = 0x1234 test_glyph.name = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") test_font.insertGlyph(test_glyph) ttFont = ufo2ft.compileTTF(test_font, useProductionNames=False) assert_results_contain(check(ttFont), FAIL, None) # FIXME: This needs a message keyword ttFont = ufo2ft.compileTTF(test_font, useProductionNames=True) assert_PASS(check(ttFont)) # Upgrade to post format 3.0 and roundtrip data to update TTF object. ttFont["post"].formatType = 3.0 _file = io.BytesIO() _file.name = ttFont.reader.file.name ttFont.save(_file) ttFont = TTFont(_file) message = assert_PASS(check(ttFont)) assert "format 3.0" in message del test_font, ttFont, _file # Prevent copypasta errors. # CFF test_font = defcon.Font(TEST_FILE("test.ufo")) ttFont = ufo2ft.compileOTF(test_font) assert_PASS(check(ttFont)) test_font.insertGlyph(test_glyph) ttFont = ufo2ft.compileOTF(test_font, useProductionNames=False) assert_results_contain(check(ttFont), FAIL, None) # FIXME: This needs a message keyword ttFont = ufo2ft.compileOTF(test_font, useProductionNames=True) assert_PASS(check(ttFont))
def test_compile_with_production_names(self): expected = [ '.notdef', 'uni0020', 'uni0061', 'uni0062', 'uni0063', 'uni0064', 'uni0065', 'uni0066', 'uni0067', 'uni0068', 'uni0069', 'uni006A', 'uni006B', 'uni006C' ] result = compileTTF(self.ufo) self.assertEqual(result.getGlyphOrder(), expected) result = compileTTF(self.ufo, useProductionNames=True) self.assertEqual(result.getGlyphOrder(), expected) self.ufo.lib["com.github.googlei18n.ufo2ft.useProductionNames"] = True result = compileTTF(self.ufo) self.assertEqual(result.getGlyphOrder(), expected)
def build_font_instance(generator, instance_descriptor, *steps): for format in ["ttf", "otf"]: instance = generator.generate_instance(instance_descriptor) for step in steps: step(instance) instance.info.openTypeOS2Panose = [2, 11, 6, 9, 2, 0, 0, 2, 0, 4] instance.info.openTypeOS2TypoAscender = 1900 instance.info.openTypeOS2TypoDescender = -480 instance.info.openTypeOS2TypoLineGap = 0 instance.info.openTypeHheaAscender = instance.info.openTypeOS2TypoAscender instance.info.openTypeHheaDescender = instance.info.openTypeOS2TypoDescender instance.info.openTypeHheaLineGap = instance.info.openTypeOS2TypoLineGap instance.info.openTypeOS2WinAscent = 2226 instance.info.openTypeOS2WinDescent = abs( instance.info.openTypeOS2TypoDescender) if format == "ttf": instance.info.openTypeGaspRangeRecords = [ { "rangeMaxPPEM": 9, "rangeGaspBehavior": [1, 3] }, { "rangeMaxPPEM": 50, "rangeGaspBehavior": [0, 1, 2, 3] }, { "rangeMaxPPEM": 65535, "rangeGaspBehavior": [1, 3] }, ] familyName = instance.info.familyName file_stem = instance.info.familyName.replace(" ", "") file_path = (OUTPUT_DIR / file_stem).with_suffix(f".{format}") print(f"[{familyName}] Compiling") if format == "ttf": instance_font = ufo2ft.compileTTF(instance, removeOverlaps=True, inplace=True) else: instance_font = ufo2ft.compileOTF(instance, removeOverlaps=True, inplace=True) if format == "ttf": print(f"[{familyName}] Merging VTT") vttLib.transfer.merge_from_file(instance_font, VTT_DATA_FILE) print(f"[{familyName}] Saving") instance_font.save(file_path) print(f"[{familyName}] Done: {file_path}")
def generate(source:Path, merge:Path) -> None: ufoSource = ufoLib2.Font.open(source) mergeSource = ufoLib2.Font.open(merge) prefix = str(source).split("/")[1] prefix = prefix.split("-")[0] for glyph in mergeSource: if glyph.name not in ufoSource: ufoSource.addGlyph(mergeSource[glyph.name]) ufoSource.lib['com.github.googlei18n.ufo2ft.filters'] = [{ # extra safe :) "name": "flattenComponents", "pre": 1, }, { "name": "decomposeTransformedComponents", "pre": 1, }] static_ttf = ufo2ft.compileTTF( ufoSource, removeOverlaps=True, overlapsBackend="pathops", useProductionNames=True, ) DSIG_modification(static_ttf) style_name = ufoSource.info.styleName print ("["+prefix+"-"+str(style_name)+"] Saving") output = "fonts/ttf/"+prefix+"-"+str(style_name)+".ttf" GASP_set(static_ttf) static_ttf.save(output)
def loadFont(fname): if fname.lower().endswith(".ufo"): ufo = Font(fname) f = compileTTF(ufo) else: f = ttLib.TTFont(fname) return f
def save_ttf(self, ufo, is_instance=False, mti_feafiles=None, kern_writer=KernFeatureWriter): """Build TTF from UFO.""" ttf_path = self._output_path(ufo, 'ttf', is_instance) ttf = compileTTF(ufo, kernWriter=kern_writer) ttf.save(ttf_path)
def build_font_instance(generator, instance_descriptor, *steps): for format in ["otf"]: # removed TTF from here instance = generator.generate_instance(instance_descriptor) for step in steps: step(instance) set_font_metaData(instance, format) familyName = instance.info.familyName fontName = familyName + " " + instance.info.styleName file_stem = instance.info.familyName.replace(" ", "") file_path = (OUTPUT_DIR / str(file_stem + "-" + instance.info.styleName)).with_suffix(f".{format}") print(f"[{fontName}] Compiling") if format == "ttf": instance_font = ufo2ft.compileTTF(instance, removeOverlaps=True, inplace=True) else: instance_font = ufo2ft.compileOTF(instance, removeOverlaps=True, inplace=True) if format == "ttf": print(f"[{fontName}] Merging VTT") vttLib.transfer.merge_from_file(instance_font, VTT_DATA_FILE) print(f"[{fontName}] Saving") instance_font.save(file_path) print(f"[{fontName}] Done: {file_path}")
def test_mti_features(self): """Checks handling of UFOs with embdedded MTI/Monotype feature files https://github.com/googlei18n/fontmake/issues/289 """ self.expectTTX(compileTTF(loadUFO("MTIFeatures.ufo")), "MTIFeatures.ttx", tables=self._layoutTables)
def compile_static_and_save(instance: ufoLib2.Font, name: str) -> None: family_name = name style_name = instance.info.styleName print(f"[{family_name}] Building static instance: {style_name}") # Use pathops backend for overlap removal because it is, at the time of this # writing, massively faster than booleanOperations and thanks to autohinting, # there is no need to keep outlines compatible to previous releases. static_ttf = ufo2ft.compileTTF(instance, removeOverlaps=True, overlapsBackend="pathops") static_otf = ufo2ft.compileOTF( instance, removeOverlaps=True, overlapsBackend="pathops", # Can do inplace now because TTF is already done. inplace=True, # Don't optimize here, will be optimized after autohinting. optimizeCFF=ufo2ft.CFFOptimization.NONE, ) file_name = f"{family_name}-{style_name}".replace(" ", "") file_path_static = (OUTPUT_STATIC_TTF_DIR / file_name).with_suffix(".ttf") file_path_static_otf = (OUTPUT_STATIC_OTF_DIR / file_name).with_suffix(".otf") file_path_static.parent.mkdir(exist_ok=True, parents=True) static_ttf.save(file_path_static) file_path_static_otf.parent.mkdir(exist_ok=True, parents=True) static_otf.save(file_path_static_otf) print(f"[{family_name}] Done: {file_path_static}, {file_path_static_otf}")
def _make_ttfont(config, ufo, color_glyphs): if config.output_format == ".ufo": return None # Use skia-pathops to remove overlaps (i.e. simplify self-overlapping # paths) because the default ("booleanOperations") does not support # quadratic bezier curves (qcurve), which may appear # when we pass through picosvg (e.g. arcs or stroked paths). ttfont = None if config.output_format == ".ttf": ttfont = ufo2ft.compileTTF(ufo, overlapsBackend="pathops") if config.output_format == ".otf": cff_version = 1 if config.color_format.startswith("cff2_"): cff_version = 2 ttfont = ufo2ft.compileOTF(ufo, cffVersion=cff_version, overlapsBackend="pathops") if not ttfont: raise ValueError( f"Unable to generate {config.color_format} {config.output_format}") # Permit fixups where we can't express something adequately in UFO _COLOR_FORMAT_GENERATORS[config.color_format].apply_ttfont( ufo, color_glyphs, ttfont) return ttfont
def test_custom_layer_compilation(layertestrgufo): ufo = layertestrgufo font_otf = compileOTF(ufo, layerName="Medium") assert font_otf.getGlyphOrder() == [".notdef", "e"] font_ttf = compileTTF(ufo, layerName="Medium") assert font_ttf.getGlyphOrder() == [".notdef", "e"]
def buildStatic( self, ufo, # input UFO as filename string or defcon.Font object outputFilename, # output filename string cff=True, # true = makes CFF outlines. false = makes TTF outlines. **kwargs, # passed along to ufo2ft.compile*() ): if isinstance(ufo, str): ufo = Font(ufo) # update version to actual, real version. Must come after any call to setFontInfo. updateFontVersion(ufo, dummy=False, isVF=False) compilerOptions = dict( useProductionNames=True, inplace=True, # avoid extra copy removeOverlaps=True, overlapsBackend='pathops', # use Skia's pathops ) log.info("compiling %s -> %s (%s)", _LazyFontName(ufo), outputFilename, "OTF/CFF-2" if cff else "TTF") if cff: font = ufo2ft.compileOTF(ufo, **compilerOptions) else: # ttf font = ufo2ft.compileTTF(ufo, **compilerOptions) log.debug("writing %s", outputFilename) font.save(outputFilename)
def test_compile_with_custom_postscript_names_notdef_preserved(self): custom_names = dict(self.CUSTOM_POSTSCRIPT_NAMES) custom_names['.notdef'] = 'defnot' self.ufo.lib['public.postscriptNames'] = custom_names result = compileTTF(self.ufo, useProductionNames=True) order = sorted(result.getGlyphOrder()) self.assertEqual(result.getGlyphOrder(), ['.notdef', 'foo', 'bar', 'baz', 'meh'])
def test_mti_features(self, FontClass): """Checks handling of UFOs with embdedded MTI/Monotype feature files https://github.com/googlei18n/fontmake/issues/289 """ ufo = FontClass(getpath("MTIFeatures.ufo")) ttf = compileTTF(ufo) expectTTX(ttf, "MTIFeatures.ttx", tables=self._layoutTables)
def test_too_long_production_name(self, testufo): name = "_".join(("a", ) * 16) testufo.newGlyph(name) result = compileTTF(testufo, useProductionNames=True).getGlyphOrder() # the production name uniXXXX would exceed the max length so the # original name is used assert name in result
def test_warn_name_exceeds_max_length(self, testufo, caplog): long_name = 64 * "a" testufo.newGlyph(long_name) with caplog.at_level(logging.WARNING, logger="ufo2ft.postProcessor"): result = compileTTF(testufo, useProductionNames=True) assert "length exceeds 63 characters" in caplog.text assert long_name in result.getGlyphOrder()
def test_no_warn_post_filter(font, caplog): font.lib["com.github.googlei18n.ufo2ft.filters"][0]["include"].append( "xxx") with caplog.at_level(logging.WARNING, logger=ufo2ft.filters.sortContours.logger.name): _ = ufo2ft.compileTTF(font, inplace=True) assert len(caplog.records) == 0
def generateFont(options, font): generateFeatures(font, options) from datetime import datetime info = font.info major, minor = options.version.split(".") info.versionMajor, info.versionMinor = int(major), int(minor) year = datetime.now().year info.copyright = f"Copyright 2010-{year} The Amiri Project Authors (https://github.com/alif-type/amiri)." info.openTypeNameLicense = "This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is available with a FAQ at: https://scripts.sil.org/OFL" info.openTypeNameLicenseURL = "https://scripts.sil.org/OFL" if options.output.endswith(".ttf"): from fontTools.ttLib import newTable from fontTools.ttLib.tables import ttProgram otf = compileTTF(font, inplace=True, removeOverlaps=True, overlapsBackend="pathops", featureWriters=[]) otf["DSIG"] = DSIG = newTable("DSIG") DSIG.ulVersion = 1 DSIG.usFlag = 0 DSIG.usNumSigs = 0 DSIG.signatureRecords = [] otf["prep"] = prep = newTable("prep") prep.program = ttProgram.Program() prep.program.fromAssembly( ['PUSHW[]', '511', 'SCANCTRL[]', 'PUSHB[]', '4', 'SCANTYPE[]']) else: import cffsubr otf = compileOTF(font, inplace=True, optimizeCFF=0, removeOverlaps=True, overlapsBackend="pathops", featureWriters=[]) cffsubr.subroutinize(otf) if info.styleMapStyleName and "italic" in info.styleMapStyleName: otf['name'].names = [n for n in otf['name'].names if n.nameID != 17] for name in otf['name'].names: if name.nameID == 2: name.string = info.styleName glyf = otf.get("glyf") if glyf: from fontTools.ttLib.tables._g_l_y_f import UNSCALED_COMPONENT_OFFSET for name, glyph in glyf.glyphs.items(): glyph.expand(glyf) if glyph.isComposite(): for component in glyph.components: component.flags |= UNSCALED_COMPONENT_OFFSET return otf
def get_test_font(): import defcon import ufo2ft test_ufo = defcon.Font(TEST_FILE("test.ufo")) glyph = test_ufo.newGlyph("acute") glyph.unicode = 0x00B4 glyph = test_ufo.newGlyph("acutecomb") glyph.unicode = 0x0301 test_ttf = ufo2ft.compileTTF(test_ufo) return test_ttf
def test_colr_cpal_raw(self, FontClass): testufo = FontClass(getpath("ColorTestRaw.ufo")) assert "com.github.googlei18n.ufo2ft.colorLayers" in testufo.lib assert "com.github.googlei18n.ufo2ft.colorPalettes" in testufo.lib result = compileTTF(testufo) palettes = [[(c.red, c.green, c.blue, c.alpha) for c in p] for p in result["CPAL"].palettes] assert palettes == [[(255, 76, 26, 255), (0, 102, 204, 255)]] layers = {gn: [(layer.name, layer.colorID) for layer in layers] for gn, layers in result["COLR"].ColorLayers.items()} assert layers == {"a": [('a.color1', 0), ('a.color2', 1)]}
def test_compile_with_production_names(self, testufo): original = [ ".notdef", "space", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", ] modified = [ ".notdef", "uni0020", "uni0061", "uni0062", "uni0063", "uni0064", "uni0065", "uni0066", "uni0067", "uni0068", "uni0069", "uni006A", "uni006B", "uni006C", ] result = compileTTF(testufo) assert result.getGlyphOrder() == original result = compileTTF(testufo, useProductionNames=True) assert result.getGlyphOrder() == modified testufo.lib[USE_PRODUCTION_NAMES] = True result = compileTTF(testufo) assert result.getGlyphOrder() == modified
def test_compile_empty_ufo(FontClass): ufo = FontClass() font = compileTTF(ufo) assert font["name"].getName(1, 3, 1).toUnicode() == "New Font" assert font["name"].getName(2, 3, 1).toUnicode() == "Regular" assert font["name"].getName(4, 3, 1).toUnicode() == "New Font Regular" assert font["head"].unitsPerEm == 1000 assert font["OS/2"].sTypoAscender == 800 assert font["OS/2"].sCapHeight == 700 assert font["OS/2"].sxHeight == 500 assert font["OS/2"].sTypoDescender == -200
def makeStaticFont(self): ufoSource = self.add_mti_features_to_master()[0] staticTTF = compileTTF(ufoSource, removeOverlaps=True, useProductionNames=False, featureCompilerClass=MtiFeatureCompiler, featureWriters=None) staticTTF.save( os.path.join(self.staticPath, os.path.basename(self.ufos[0])[:-4] + ".ttf")) print(" " + os.path.basename(self.ufos[0])[:-4] + " generated\n")
def test_warn_pre_filter(font, caplog): font.lib["com.github.googlei18n.ufo2ft.filters"][0]["pre"] = True font.lib["com.github.googlei18n.ufo2ft.filters"][0]["include"].append( "xxx") with caplog.at_level(logging.WARNING, logger=ufo2ft.filters.sortContours.logger.name): _ = ufo2ft.compileTTF(font, inplace=True) assert len(caplog.records) == 1 assert "contains components which will not be sorted" in caplog.text
def test_colr_cpal(self, FontClass): testufo = FontClass(getpath("ColorTest.ufo")) assert "com.github.googlei18n.ufo2ft.colorLayerMapping" in testufo.lib assert "com.github.googlei18n.ufo2ft.colorPalettes" in testufo.lib result = compileTTF(testufo) assert "COLR" in result assert "CPAL" in result layers = {gn: [(layer.name, layer.colorID) for layer in layers] for gn, layers in result["COLR"].ColorLayers.items()} assert layers == {'a': [('a.color1', 0), ('a.color2', 1)], 'b': [('b.color1', 1), ('b.color2', 0)], 'c': [('c.color2', 1), ('c.color1', 0)]}
def build(args): font = GSFont(args.file) # Set metadata major, minor = args.version.split(".") font.versionMajor, font.versionMinor = int(major), int(minor) font.copyright = font.copyright.format(year=datetime.now().year) builder = UFOBuilder( font, propagate_anchors=False, write_skipexportglyphs=True, store_editor_state=False, ) for master in builder.masters: if master.info.styleName == args.master: ufo = master break anchors = {} curs = [] curs.append("lookupflag RightToLeft IgnoreMarks;") for glyph in ufo: for anchor in glyph.anchors: if anchor.name in ("entry", "exit"): anchors.setdefault(glyph.name, [None, None]) anchors[glyph.name][0 if anchor.name == "entry" else 1] = anchor for glyph, (entry, exit_) in anchors.items(): curs.append( f"pos cursive {glyph} {_dumpAnchor(entry)} {_dumpAnchor(exit_)};") curs = "\n".join(curs) + "\n" ufo.features.text = ufo.features.text.replace("# Automatic Code Cursive", curs) compileTTF(ufo, inplace=True, flattenComponents=True, useProductionNames=False).save(args.out_file)
def build(args): ufo = merge(args) setInfo(ufo.info, args.version) buildExtraGlyphs(ufo) removeOverlap(ufo) if args.out_file.endswith(".ttf"): otf = compileTTF(ufo) else: otf = compileOTF(ufo) otf = subsetGlyphs(otf, ufo) return otf
def QuadraticTTFontFactory(font): ttf = compileTTF(font) return ttf
def QuadraticTTFontFactory(font, useProductionNames=False): ttf = compileTTF(font, useProductionNames=useProductionNames) return ttf