def main(): # 縦書き対応 fontforge.setPrefs('CoverageFormatsAllowed', 1) # バージョンを今日の日付から生成する today = date.today() version = "Lettering-{0}".format(today.strftime("%Y%m%d")) for (se, om, weight) in font_list: se_path = "{0}/{1}".format(special_elite_path, se) om_path = "{0}/{1}".format(oradano_mincho_path, om) le_path = "{0}/Lettering-{1}.ttf".format(lettering_path, weight) generate_lettering(se_path, om_path, le_path, weight, version)
def main(): # 縦書き対応 fontforge.setPrefs('CoverageFormatsAllowed', 1) # バージョンを時刻から生成する version = "Kazesawa-{0}".format(datetime.utcnow().strftime("%Y%m%d%H%M%S")) for (op, mp, weight) in font_list: op_path = "{0}/{1}".format(sourcesans_path, op) mp_path = "{0}/{1}".format(mplus_path, mp) ko_path = "{0}/Kazesawa-{1}.ttf".format(kazesawa_path, weight) sf_path = "{0}/Kazesawa-{1}".format(sfd_path, weight) generate_kazesawa(op_path, mp_path, ko_path, sf_path, weight, version)
def main(): # 縦書き対応 fontforge.setPrefs('CoverageFormatsAllowed', 1) # バージョンを今日の日付から生成する today = date.today() version = "Koruri-{0}".format(today.strftime("%Y%m%d")) for (op, rb, mp, weight) in font_list: op_path = "{0}/{1}".format(opensans_path, op) rb_path = "{0}/{1}".format(roboto_path, rb) mp_path = "{0}/{1}".format(mplus_path, mp) ko_path = "{0}/Koruri-{1}.ttf".format(koruri_path, weight) generate_koruri(op_path, rb_path, mp_path, ko_path, weight, version)
def fontAnalysis(): # x = PdfReader("/home/hasan/Desktop/ClearScan/book[t1][ClearScan].pdf") ## x = PdfReader("/home/hasan/1-5-1[t4].pdf") # print "Pagecount= %i "% (len(x.Root.Pages)) # print "Kids[0] ", x.Root.Pages.Kids[0] # return print "Testing fontforge" fontforge.setPrefs("PreferPotrace", 1) fontforge.setPrefs("AutotraceAsk", "-O 0.5 -u 1 -t 1") font = fontforge.open("/home/hasan/Desktop/ClearScan/fnt179.cff") for i in font.glyphs(): print "encoding %s"% unichr(i.encoding) # if i.encoding >=0x30 and i.encoding <= 0x80: i.export("/home/hasan/Desktop/ClearScan/chr/"+unichr(i.encoding)+".png") # print font.ndEncodingSlot() return glyphA = font["C"] foreground = glyphA.foreground for i in range(len(foreground)): # print "background[%i] = %s"%(i, glyphA.background,) print "foreground[%i] = %s"%(i, foreground[i],) print "len(foreground[%i]) = %s"%(i, len(foreground[i])) print "foreground[%i].closed = %s"%(i, str(foreground[i].closed==True)) print "foreground[%i].spiro = %s\n"%(i, str(foreground[i].spiro)) print "foreground[%i].spiro[0] = %s\n"%(i, str(foreground[i].spiro[0])) glyphA.export("/home/hasan/Desktop/C.png") # spiro = foreground[i].spiro[0] # spiro = (spiro[0]+1,spiro[1], spiro[2], spiro[3]) # foreground[i]= foreground[i] # print "foreground[%i].spiro[0] = %s\n"%(i, str(foreground[i].spiro[0])) # contour = fontforge.contour() # glyphA.autoTrace() # glyphA.simplify(0.1, ("ignoreextrema", "ignoreslopes", "nearlyhvlines", "forcelines", "setstarttoextremum")) # glyphB = font["B"] # glyphB.simplify(0.1, ("ignoreextrema", "ignoreslopes", "nearlyhvlines", "forcelines", "setstarttoextremum")) font.save("/home/hasan/Desktop/font01.ttf") #########################################################3 x = PdfReader("/home/hasan/ClearScan/book[t1][ClearScan].pdf") print "Pagecount= %i "% (len(x.Root.Pages)) print "Kids[0] ", x.Root.Pages.Kids[0] return
panose_base = (2, 11, 6, 9, 2, 2, 3, 2, 2, 7) panose_base_bold = (2, 11, 8, 9, 2, 2, 3, 2, 2, 7) ######################################## # setting ######################################## import os import sys import fontforge import psMat import unicodedata # 縦書きのために指定する fontforge.setPrefs('CoverageFormatsAllowed', 1) # 大変更時に命令を消去 0:オフ 1:オン fontforge.setPrefs('ClearInstrsBigChanges', 0) # TrueType命令をコピー 0:オフ 1:オン fontforge.setPrefs('CopyTTFInstrs', 1) ######################################## # pre-process ######################################## print("Juglans generator " + newfont_version) print("This script is for generating 'Juglans' font") if len(sys.argv) > 1 and sys.argv[1] == "bold": print("Generate Juglans-Bold") newfont_name = newfont_name_bold
#!/usr/bin/env fontforge import fontforge, psMat from sys import argv, stderr from re import search from math import pi if len(argv) < 4: stderr.write("Usage: " + argv[0] + " encloser enclosed [...] outfile\n") quit(1) fontforge.setPrefs('CoverageFormatsAllowed', 1) srcFont = fontforge.open(argv[1]) addFonts = [] for i in range(2, len(argv) - 1): addFonts += [fontforge.open(argv[i])] proportionalFlag = (search('proportional', argv[0]) is not None) verticalFlag = (search('vert', argv[0]) is not None) for srcGlyph in srcFont.glyphs(): if srcGlyph.isWorthOutputting(): gNum = srcGlyph.unicode for addFont in addFonts: try: if addFont[gNum + 0x8000].isWorthOutputting(): addFont.selection.select(("encoding", ), gNum + 0x8000) addFont.copy() srcFont.selection.select(("encoding", ), gNum) srcFont.pasteInto()
generate_flags = ('opentype', 'PfEd-lookups', 'TeX-table') panoseBase = (2, 11, 5, 9, 2, 2, 3, 2, 2, 7) ######################################## # setting ######################################## import copy import os import sys import shutil import fontforge import psMat # 縦書きのために指定する fontforge.setPrefs('CoverageFormatsAllowed', 1) # 大変更時に命令を消去 0:オフ 1:オン fontforge.setPrefs('ClearInstrsBigChanges', 0) # TrueType命令をコピー 0:オフ 1:オン fontforge.setPrefs('CopyTTFInstrs', 1) ######################################## # pre-process ######################################## print print print "myrica generator " + newfont_version print print "This script is for generating 'myrica' font" print
caliban.generate("Caliban.ttf",bitmap_type="apple") print("...Generated ttf w/ apple bitmaps") caliban.generate("Caliban.otf",bitmap_type="ms") print("...Generated otf w/ ms bitmaps") caliban.generate("Caliban.otf",bitmap_type="ttf",flags=("apple","opentype")) print("...Generated otf w/ both apple and ot modes set (& bitmaps)") caliban.generate("Caliban.dfont",bitmap_type="sbit") print("...Generated sbit") caliban.generate("Caliban.",bitmap_type="otb") print("...Generated X11 opentype bitmap") caliban.generate("Caliban.dfont",bitmap_type="dfont") print("...Generated dfont w/ apple bitmaps") caliban.layers["Fore"].is_quadratic = 1 caliban.setTableData("cvt ","") caliban.selection.all() fontforge.setPrefs("DetectDiagonalStems",1) caliban.autoHint() caliban.autoInstr() print("...AutoInstructed") caliban.generate("Caliban.ttf",bitmap_type="apple") print("...Generated ttf w/ apple bitmaps (again) and instructions") caliban.close() caliban = fontforge.open("Caliban.sfd") print("...Read sfd") caliban.close() caliban = fontforge.open("Caliban.sfdir") print("...Read sfdir") caliban.close() caliban = fontforge.open("Caliban.ps") print("...Read type0 (if PfaEdit didn't understand /CalibanBase that's ok)")
# font generation flags: # omit-instructions => do not include TT instructions (for experimental typefaces) # opentype => include OpenType tables # glyph-comments => generate a 'PfEd' table and store glyph comments # glyph-colors => generate a 'PfEd' table and store glyph colors # old-kern => generate old fashioned kern tables. # - this one is important because it generates correct kerning tables for legacy # applications def_gen_flags = ("opentype", "glyph-comments", "glyph-colors", "old-kern") exp_gen_flags = def_gen_flags + ("omit-instructions", ) if fontforge.version() < required_version: print("Your version of FontForge is too old - %s or newer is required" % (required_version)) # FoundryName is not used in TTF generation fontforge.setPrefs("FoundryName", "DejaVu") # first 4 characters of TTFFoundry are used for achVendId fontforge.setPrefs("TTFFoundry", "DejaVu") i = 1 while i < len(sys.argv): font = fontforge.open(sys.argv[i]) gen_flags = def_gen_flags # Serif Italic and Serif Bold Italic are experimental if font.fontname.rfind("Serif") > -1 and font.fontname.rfind( "Italic") > -1: gen_flags = exp_gen_flags if font.fontname.rfind("Condensed") > -1: gen_flags = exp_gen_flags if font.fontname.rfind("ExtraLight") > -1: gen_flags = exp_gen_flags
import fontforge import sys import itgFontLib sourcefile = sys.argv[2] destfile = sys.argv[1] font = fontforge.open (sourcefile) itgFontLib.fontPreProcessing( font ) itgFontLib.removeRefsIf( font, itgFontLib.isFlippedRef ) itgFontLib.resetGlyphNames( font ) itgFontLib.scaleEM ( font, 1000 ) fontforge.setPrefs ('FoundryName', 'NCSM'); fontforge.setPrefs ('GenerateHintWidthEqualityTolerance', 4) fontforge.setPrefs ('StandardSlopeError', 3) fontforge.setPrefs ('HintBoundingBoxes', 1) fontforge.setPrefs ('HintDiagonalEnds', 1) fontforge.setPrefs ('DetectDiagonalStems', 1) fontforge.setPrefs ('InterpolateStrongPoints', 0) fontforge.setPrefs ('CounterControl', 1) font.selection.all () font.round () font.autoHint () font.generate ( destfile, flags = [ 'afm', 'composites-in-afm', 'pfm', 'tfm', 'round' ] )
#!/usr/bin/python import sys import fontforge if len(sys.argv) != 3: print("Usage: %s <input> <output>" % sys.argv[0]) sys.exit(1) infilename = sys.argv[1] outfilename = sys.argv[2] fontforge.setPrefs("FoundryName", "Jebudo") fontforge.setPrefs("TTFFoundry", "Jebudo") font = fontforge.open(infilename) font.generate(outfilename, flags = ('opentype')) font.close
args is an argparse.Namespace. font is a fontforge.font. """ for argName in _argNameFontAttrMap: argValue = getattr(args, argName) if argValue is not None: # User gave a new value for this font attribute. setattr(font, _argNameFontAttrMap[argName], argValue) # Parse the command line arguments. args = initArgumentParser().parse_args() # Set FontForge options. fontforge.setPrefs("PreferPotrace", not args.prefer_autotrace) fontforge.setPrefs("AutotraceArgs", args.tracer_args) # Good, can we open the base font? try: baseFont = fontforge.open(args.bdf_file[0]) except EnvironmentError as e: sys.exit("Could not open base font `%s'!" % args.bdf_file[0]) # Now import all the bitmaps from the other BDF files into this font. print('Importing bitmaps from %d additional fonts...' % (len(args.bdf_file) - 1)) for fontFile in args.bdf_file[1:]: try: baseFont.importBitmaps(fontFile) except EnvironmentError as e:
for argName in _argNameFontAttrMap: argValue = getattr(args, argName) if argValue is not None: # User gave a new value for this font attribute. setattr( font, _argNameFontAttrMap[argName], argValue ) # Parse the command line arguments. args = initArgumentParser().parse_args() # Set FontForge options. fontforge.setPrefs("PreferPotrace", not args.prefer_autotrace) fontforge.setPrefs("AutotraceArgs", args.tracer_args) # Good, can we open the base font? try: baseFont = fontforge.open(args.bdf_file[0]) except EnvironmentError as e: sys.exit("Could not open base font `%s'!" % args.bdf_file[0]) # Now import all the bitmaps from the other BDF files into this font. print('Importing bitmaps from %d additional fonts...' % (len(args.bdf_file) - 1)) for fontFile in args.bdf_file[1:]: try: baseFont.importBitmaps(fontFile) except EnvironmentError as e: sys.exit("Could not import additional font `%s'!" % fontFile)
""" Usage: python %s path argv[1] ... path eg. python removebitmap.py ~/Downloads/fonts """ import sys import glob import fontforge import tempfile import os import shutil import subprocess # fontforge setting. fontforge.setPrefs('CoverageFormatsAllowed', 1) fontforge.setPrefs('UndoDepth', 0) # TTF flags flags = ('opentype', 'round') """ antialias: Hints are not applied, use grayscale smoothing. gridfit: Use hinting in Windows. gridfit+smoothing: ClearType GridFitting; (hinting with ClearType). symmetric-smoothing: ClearType Antialiasing; (ClearType smoothing only). gridfit is hinting on Windows. So gridfit is unnecessary for me. """
#!/usr/bin/env python # -*- coding: utf-8 -*- # # Usage: python %s step{1|3} font-file-name prefix # # argv[1] ... step1 or step3 # argv[2] ... font file name # argv[3] ... temporary file prefix # # eg. python pyFFctrl.py step1 meiryo.ttc rbf-tmp-ttf import sys import glob import fontforge fontforge.setPrefs('CoverageFormatsAllowed', 1) fontforge.setPrefs("AutoHint", False) # TTF flags # flags = ('opentype', 'TeX-table', 'round', 'dummy-dsig') flags = ('opentype', 'old-kern', 'dummy-dsig', 'round', 'no-hints', 'PfEd-colors', 'PfEd-lookups', 'PfEd-guidelines', 'PfEd-background') # – antialias: Hints are not applied, use grayscale smoothing. # – gridfit: Use hints. # – gridfit+smoothing: ClearType GridFitting. # – symmetric-smoothing: ClearType Antialiasing. def gasp(): return ( # (8, ('antialias',)), # (16, ('antialias', 'symmetric-smoothing')), (65535, ('antialias', 'gridfit', 'symmetric-smoothing', 'gridfit+smoothing')),
import fontforge; ## ## THIS FILE IS A FONTFORGE SCRIPT THAT GENERATES THE HIRMOS PONOMAR FONT FAMILY ## ## base_name = "IndictionUnicode" full_name = "Indiction Unicode" fontforge.setPrefs ("AutoHint", False) #fontforge.setPrefs ("ClearInstrsBigChanges",False ) #fontforge.setPrefs ( "CopyTTFInstrs",False ) ## open up the font font = fontforge.open(base_name + ".sfd") ## Evidently, this can break Evince, so it may need to be commented out font.head_optimized_for_cleartype = True ## not sure if we need this #font.encoding = "mac" ttnames = list( font.sfnt_names ) for ttname in ttnames: if ttname[1] == 'SubFamil': ttnames.append( ( ttname[0],'Fullname',"%s %s" % ( full_name,ttname[2] ) ) ) font.sfnt_names = tuple( ttnames ) font.generate( base_name + ".otf", flags=( "opentype", "PfEd-colors", "PfEd-lookups"), layer="Fore" )
import fontforge import sys import itgFontLib sourcefile = sys.argv[2] destfile = sys.argv[1] font = fontforge.open (sourcefile) itgFontLib.fontPreProcessing( font ) itgFontLib.removeRefsIf( font, itgFontLib.isFlippedRef ) itgFontLib.resetGlyphNames( font ) itgFontLib.scaleEM ( font, 1000 ) fontforge.setPrefs ('FoundryName', 'NCSM'); fontforge.setPrefs ('AutoHint', 0) font.selection.all () font.round () font.generate ( destfile, flags=[ 'afm', 'composites-in-afm', 'short-post', 'opentype', 'TeX-table' ] )
import fontforge import sys import itgFontLib sourcefile = sys.argv[2] destfile = sys.argv[1] font = fontforge.open(sourcefile) itgFontLib.fontPreProcessing(font) itgFontLib.removeRefsIf(font, itgFontLib.isFlippedRef) itgFontLib.resetGlyphNames(font) itgFontLib.scaleEM(font, 1000) fontforge.setPrefs('FoundryName', 'NCSM') fontforge.setPrefs('AutoHint', 0) font.selection.all() font.round() font.generate( destfile, flags=['afm', 'composites-in-afm', 'short-post', 'opentype', 'TeX-table'])
def initFontForge(): fontforge.setPrefs("PreferPotrace", 1) fontforge.setPrefs("AutotraceAsk", "-O 0.5 -u 1 -t 1") return
""" Usage: python %s path argv[1] ... path eg. python removebitmap.py ~/Downloads/fonts """ import sys import glob import fontforge import tempfile import os import shutil import subprocess # fontforge setting. fontforge.setPrefs('CoverageFormatsAllowed', 1) fontforge.setPrefs('UndoDepth', 0) # TTF flags flags = ('opentype', 'round') """ antialias: Hints are not applied, use grayscale smoothing. gridfit: Use hinting in Windows. gridfit+smoothing: ClearType GridFitting; (hinting with ClearType). symmetric-smoothing: ClearType Antialiasing; (ClearType smoothing only). gridfit is hinting on Windows. So gridfit is unnecessary for me. """ def gasp():
def execute(tool, fn, argspec, chain = None): # Function to handle parameter parsing, font and file opening etc in command-line scripts # Supports opening (and saving) fonts using FontForge (FF), PysilFont UFO (UFO) or fontTools (FT) # Special handling for: # -d variation on -h to print extra info about defaults # -q quiet mode - suppresses progress messages and sets screen logging to errors only # -l opens log file and also creates a logger function to write to the log file # -p other parameters. Includes backup settings and loglevel/scrlevel settings for logger # for UFOlib scripts, also includes all outparams keys and ufometadata settings # infont and returnfont are used when chaining calls to execute together, passing ifont on without writing to disk params = chain["params"] if chain else parameters() logger = chain["logger"] if chain else params.logger # paramset has already created a basic logger argv = chain["argv"] if chain else sys.argv if tool == "FF": import fontforge if fontforge.hasUserInterface(): return # Execute is for command-line use fontforge.loadPrefs() fontforge.setPrefs("PreserveTables", "DSIG,Feat,Glat,Gloc,LTSH,Silf,Sill,Silt,VDMX,hdmx") ## Perhaps should be a parameter and check for existing values elif tool == "UFO": from silfont.ufo import Ufont elif tool == "FT": from fontTools import ttLib elif tool == "" or tool is None: tool = None else: logger.log("Invalid tool in call to execute()", "X") return basemodule = sys.modules[fn.__module__] poptions = {} poptions['prog'] = splitfn(argv[0])[1] poptions['description'] = basemodule.__doc__ poptions['formatter_class'] = argparse.RawDescriptionHelpFormatter epilog = "For more help see https://github.com/silnrsi/pysilfont/blob/master/docs/scripts.md#" + poptions['prog'] + "\n\n" poptions['epilog'] = epilog + "Version: " + params.sets['default']['version'] + "\n" + params.sets['default']['copyright'] parser = argparse.ArgumentParser(**poptions) parser._optionals.title = "other arguments" # Add standard arguments standardargs = [ ('-d', '--defaults', {'help': 'Display help with info on default values', 'action': 'store_true'}, {}), ('-q', '--quiet', {'help': 'Quiet mode - only display errors', 'action': 'store_true'}, {}), ('-l', '--log', {'help': 'Log file'}, {'type': 'outfile'}), ('-p', '--params', {'help': 'Other parameters', 'action': 'append'}, {'type': 'optiondict'})] standardargsindex = ['defaults', 'quiet', 'log', 'params'] suppliedargs = [] for a in argspec: argn = a[:-2][-1] # [:-2] will give either 1 or 2, the last of which is the full argument name if argn[0:2] == "--": argn = argn[2:] # Will start with -- for options suppliedargs.append(argn) for i, arg in enumerate(standardargsindex): if arg not in suppliedargs: argspec.append(standardargs[i]) # Special handling for "-d" to print default value info with help text defhelp = False if "-d" in argv: defhelp = True pos = argv.index("-d") argv[pos] = "-h" # Set back to -h for argparse to recognise deffiles = [] defother = [] quiet = True if "-q" in argv else False if quiet: logger.scrlevel = "E" # Process the supplied argument specs, add args to parser, store other info in arginfo arginfo = [] logdef = None for a in argspec: # Process all but last tuple entry as argparse arguments nonkwds = a[:-2] kwds = a[-2] parser.add_argument(*nonkwds, **kwds) # Create dict of framework keywords using argument name argn = nonkwds[-1] # Find the argument name from first 1 or 2 tuple entries if argn[0:2] == "--": argn = argn[2:] # Will start with -- for options ainfo=a[-1] ainfo['name']=argn if argn == 'log': logdef = ainfo['def'] if 'def' in ainfo else None arginfo.append(ainfo) if defhelp: arg = nonkwds[0] if 'def' in ainfo: deffiles.append([arg, ainfo['def']]) elif 'default' in kwds: defother.append([arg, kwds['default']]) # if -d specified, change the help epilog to info about argument defaults if defhelp: if not (deffiles or defother): deftext = "No defaults for parameters/options" else: deftext = "Defaults for parameters/options - see user docs for details\n" if deffiles: deftext = deftext + "\n Font/file names\n" for (param, defv) in deffiles: deftext = deftext + ' {:<20}{}\n'.format(param, defv) if defother: deftext = deftext + "\n Other parameters\n" for (param, defv) in defother: deftext = deftext + ' {:<20}{}\n'.format(param, defv) parser.epilog = deftext + "\n\n" + parser.epilog # Parse the command-line arguments. If errors or -h used, procedure will exit here args = parser.parse_args(argv[1:]) # Process the first positional parameter to get defaults for file names fppval = getattr(args, arginfo[0]['name']) if fppval is None: fppval = "" # For scripts that can be run with no positional parameters (fppath, fpbase, fpext) = splitfn(fppval) # First pos param use for defaulting # Process parameters if chain: execparams = params.sets["main"] args.params = {} # clparams not used when chaining else: # Read config file from disk if it exists configname = os.path.join(fppath, "pysilfont.cfg") if os.path.exists(configname): params.addset("config file", configname, configfile=configname) else: params.addset("config file") # Create empty set if not quiet and "scrlevel" in params.sets["config file"]: logger.scrlevel = params.sets["config file"]["scrlevel"] # Process command-line parameters clparams = {} if 'params' in args.__dict__: if args.params is not None: for param in args.params: x = param.split("=", 1) if len(x) != 2: logger.log("params must be of the form 'param=value'", "S") if x[1] == "\\t": x[1] = "\t" # Special handling for tab characters clparams[x[0]] = x[1] args.params = clparams params.addset("command line", "command line", inputdict=clparams) if not quiet and "scrlevel" in params.sets["command line"]: logger.scrlevel = params.sets["command line"]["scrlevel"] # Create main set of parameters based on defaults then update with config file values and command line values params.addset("main", copyset="default") params.sets["main"].updatewith("config file") params.sets["main"].updatewith("command line") execparams = params.sets["main"] # Set up logging if chain: setattr(args, 'logger', logger) args.logfile = logger.logfile else: logfile = None if 'log' in args.__dict__: logname = args.log if args.log else "" if logdef is not None: (path, base, ext) = splitfn(logname) (dpath, dbase, dext) = splitfn(logdef) if not path: if base and ext: # If both specified then use cwd, ie no path path = "" else: path = (fppath if dpath is "" else os.path.join(fppath, dpath)) if not base: if dbase == "": base = fpbase elif dbase[0] == "_": # Append to font name if starts with _ base = fpbase + dbase else: base = dbase if not ext and dext: ext = dext logname = os.path.join(path, base+ext) if logname == "": logfile = None else: (logname, logpath, exists) = fullpath(logname) if not exists: logger.log("Log file directory " + logpath + " does not exist", "S") if not quiet: logger.log('Opening log file for output: ' + logname, "P") try: logfile = open(logname, "w") except Exception as e: print e sys.exit(1) args.log = logfile # Set up logger details logger.loglevel = execparams['loglevel'].upper() if not quiet: logger.scrlevel = execparams['scrlevel'].upper() logger.logfile = logfile setattr(args, 'logger', logger) # Process the argument values returned from argparse outfont = None infontlist = [] for c, ainfo in enumerate(arginfo): aval = getattr(args, ainfo['name']) if ainfo['name'] in ('params', 'log'): continue # params and log already processed atype = None adef = None if 'type' in ainfo: atype = ainfo['type'] if atype not in ('infont', 'outfont', 'infile', 'outfile', 'incsv', 'filename', 'optiondict'): logger.log("Invalid type of " + atype + " supplied in argspec", "X") if atype != 'optiondict': # All other types are file types, so adef must be set, even if just to "" adef = ainfo['def'] if 'def' in ainfo else "" if adef is None and aval is None: # If def explicitly set to None then this is optional setattr(args, ainfo['name'], None) continue if c == 0: if aval is None : logger.log("Invalid first positional parameter spec", "X") if aval[-1] in ("\\","/"): aval = aval[0:-1] # Remove trailing slashes else: #Handle defaults for all but first positional parameter if adef is not None: if not aval: aval = "" if aval == "" and adef == "": # Only valid for output font parameter if atype != "outfont": logger.log("No value suppiled for " + ainfo['name'], "S") ## Not sure why this needs to fail - we need to cope with other optional file or filename parameters (apath, abase, aext) = splitfn(aval) (dpath, dbase, dext) = splitfn(adef) # dpath should be None if not apath: if abase and aext: # If both specified then use cwd, ie no path apath = "" else: apath = fppath if not abase: if dbase == "": abase = fpbase elif dbase[0] == "_": # Append to font name if starts with _ abase = fpbase + dbase else: abase = dbase if not aext: if dext: aext = dext elif (atype == 'outfont' or atype == 'infont'): aext = fpext aval = os.path.join(apath, abase+aext) # Open files/fonts if atype == 'infont': if tool is None: logger.log("Can't specify a font without a font tool", "X") infontlist.append((ainfo['name'], aval)) # Build list of fonts to open when other args processed elif atype == 'infile': if not quiet: logger.log('Opening file for input: '+aval, "P") try: aval = open(aval, "r") except Exception as e: print e sys.exit(1) elif atype == 'incsv': if not quiet: logger.log('Opening file for input: '+aval, "P") aval = csvreader(aval) elif atype == 'outfile': (aval, path, exists) = fullpath(aval) if not exists: logger.log("Output file directory " + path + " does not exist", "S") if not quiet: logger.log('Opening file for output: ' + aval, "P") try: aval = codecs.open(aval, 'w', 'utf-8') except Exception as e: print e sys.exit(1) elif atype == 'outfont': if tool is None: logger.log("Can't specify a font without a font tool", "X") outfont = aval outfontpath = apath outfontbase = abase outfontext = aext elif atype == 'optiondict': # Turn multiple options in the form ['opt1=a', 'opt2=b'] into a dictionary avaldict={} if aval is not None: for option in aval: x = option.split("=", 1) if len(x) != 2: logger.log("options must be of the form 'param=value'", "S") if x[1] == "\\t": x[1] = "\t" # Special handling for tab characters avaldict[x[0]] = x[1] aval = avaldict setattr(args, ainfo['name'], aval) # Open fonts - needs to be done after processing other arguments so logger and params are defined for name, aval in infontlist: if chain and name == 'ifont': aval = chain["font"] else: if tool == "FF" : aval = fontforge.open(aval) if tool == "UFO": aval = Ufont(aval, params=params) if tool == "FT" : aval = ttLib.TTFont(aval) setattr(args, name, aval) # Assign the font object to args attribute # All arguments processed, now call the main function setattr(args, "paramsobj", params) setattr(args, "cmdlineargs", argv) newfont = fn(args) # If an output font is expected and one is returned, output the font if outfont and newfont is not None: if chain: # return font to be handled by chain() return newfont else: # Backup the font if output is overwriting original input font if outfont == infontlist[0][1]: backupdir = os.path.join(outfontpath, execparams['backupdir']) backupmax = int(execparams['backupkeep']) backup = str2bool(execparams['backup']) if backup: if not os.path.isdir(backupdir): # Create backup directory if not present try: os.mkdir(backupdir) except Exception as e: print e sys.exit(1) backupbase = os.path.join(backupdir, outfontbase+outfontext) # Work out backup name based on existing backups nums = sorted([int(i[len(backupbase)+1-len(i):-1]) for i in glob(backupbase+".*~")]) # Extract list of backup numbers from existing backups newnum = max(nums)+1 if nums else 1 backupname = backupbase+"."+str(newnum)+"~" # Backup the font newfont.logger.log("Backing up input font to "+backupname, "P") shutil.copytree(outfont, backupname) # Purge old backups for i in range(0, len(nums) - backupmax + 1): backupname = backupbase+"."+str(nums[i])+"~" newfont.logger.log("Purging old backup "+backupname, "I") shutil.rmtree(backupname) else: newfont.logger.log("No font backup done due to backup parameter setting", "W") # Output the font if tool == "FF": if not quiet: logger.log("Saving font to " + outfont, "P") if outfontext.lower() == ".ufo" or outfontext.lower() == '.ttf': newfont.generate(outfont) else: newfont.save(outfont) elif tool == "FT": if not quiet: logger.log("Saving font to " + outfont, "P") newfont.save(outfont) else: # Must be Pyslifont Ufont newfont.write(outfont) if logfile: logfile.close()
def execute(tool, fn, argspec, chain = None): # Function to handle parameter parsing, font and file opening etc in command-line scripts # Supports opening (and saving) fonts using FontForge (FF), PysilFont UFO (UFO) or fontTools (FT) # Special handling for: # -d variation on -h to print extra info about defaults # -q quiet mode - only output a single line with count of errors (if there are any) # -l opens log file and also creates a logger function to write to the log file # -p other parameters. Includes backup settings and loglevel/scrlevel settings for logger # for UFOlib scripts, also includes all outparams keys and ufometadata settings chainfirst = False if chain == "first": # If first call to execute has this set, only do the final return part of chaining chainfirst = True chain = None params = chain["params"] if chain else parameters() logger = chain["logger"] if chain else params.logger # paramset has already created a basic logger argv = chain["argv"] if chain else sys.argv if tool == "FF": import fontforge if fontforge.hasUserInterface(): return # Execute is for command-line use fontforge.loadPrefs() fontforge.setPrefs("PreserveTables", "DSIG,Feat,Glat,Gloc,LTSH,Silf,Sill,Silt,VDMX,hdmx") ## Perhaps should be a parameter and check for existing values elif tool == "UFO": from silfont.ufo import Ufont elif tool == "FT": from fontTools import ttLib elif tool == "" or tool is None: tool = None else: logger.log("Invalid tool in call to execute()", "X") return basemodule = sys.modules[fn.__module__] poptions = {} poptions['prog'] = splitfn(argv[0])[1] poptions['description'] = basemodule.__doc__ poptions['formatter_class'] = argparse.RawDescriptionHelpFormatter epilog = "For more help see https://github.com/silnrsi/pysilfont/blob/master/docs/scripts.md#" + poptions['prog'] + "\n\n" poptions['epilog'] = epilog + "Version: " + params.sets['default']['version'] + "\n" + params.sets['default']['copyright'] parser = argparse.ArgumentParser(**poptions) parser._optionals.title = "other arguments" # Add standard arguments standardargs = [ ('-d', '--defaults', {'help': 'Display help with info on default values', 'action': 'store_true'}, {}), ('-q', '--quiet', {'help': 'Quiet mode - only display errors', 'action': 'store_true'}, {}), ('-l', '--log', {'help': 'Log file'}, {'type': 'outfile'}), ('-p', '--params', {'help': 'Other parameters - see parameters.md for details', 'action': 'append'}, {'type': 'optiondict'})] standardargsindex = ['defaults', 'quiet', 'log', 'params'] suppliedargs = [] for a in argspec: argn = a[:-2][-1] # [:-2] will give either 1 or 2, the last of which is the full argument name if argn[0:2] == "--": argn = argn[2:] # Will start with -- for options suppliedargs.append(argn) for i, arg in enumerate(standardargsindex): if arg not in suppliedargs: argspec.append(standardargs[i]) # Special handling for "-d" to print default value info with help text defhelp = False if "-d" in argv: defhelp = True pos = argv.index("-d") argv[pos] = "-h" # Set back to -h for argparse to recognise deffiles = [] defother = [] quiet = True if "-q" in argv else False if quiet: logger.scrlevel = "S" # Process the supplied argument specs, add args to parser, store other info in arginfo arginfo = [] logdef = None for a in argspec: # Process all but last tuple entry as argparse arguments nonkwds = a[:-2] kwds = a[-2] parser.add_argument(*nonkwds, **kwds) # Create dict of framework keywords using argument name argn = nonkwds[-1] # Find the argument name from first 1 or 2 tuple entries if argn[0:2] == "--": argn = argn[2:] # Will start with -- for options ainfo=a[-1] ainfo['name']=argn if argn == 'log': logdef = ainfo['def'] if 'def' in ainfo else None arginfo.append(ainfo) if defhelp: arg = nonkwds[0] if 'def' in ainfo: deffiles.append([arg, ainfo['def']]) elif 'default' in kwds: defother.append([arg, kwds['default']]) # if -d specified, change the help epilog to info about argument defaults if defhelp: if not (deffiles or defother): deftext = "No defaults for parameters/options" else: deftext = "Defaults for parameters/options - see user docs for details\n" if deffiles: deftext = deftext + "\n Font/file names\n" for (param, defv) in deffiles: deftext = deftext + ' {:<20}{}\n'.format(param, defv) if defother: deftext = deftext + "\n Other parameters\n" for (param, defv) in defother: deftext = deftext + ' {:<20}{}\n'.format(param, defv) parser.epilog = deftext + "\n\n" + parser.epilog # Parse the command-line arguments. If errors or -h used, procedure will exit here args = parser.parse_args(argv[1:]) # Process the first positional parameter to get defaults for file names fppval = getattr(args, arginfo[0]['name']) if fppval is None: fppval = "" # For scripts that can be run with no positional parameters (fppath, fpbase, fpext) = splitfn(fppval) # First pos param use for defaulting # Process parameters if chain: execparams = params.sets["main"] args.params = {} # clparams not used when chaining else: # Read config file from disk if it exists configname = os.path.join(fppath, "pysilfont.cfg") if os.path.exists(configname): params.addset("config file", configname, configfile=configname) else: params.addset("config file") # Create empty set if not quiet and "scrlevel" in params.sets["config file"]: logger.scrlevel = params.sets["config file"]["scrlevel"] # Process command-line parameters clparams = {} if 'params' in args.__dict__: if args.params is not None: for param in args.params: x = param.split("=", 1) if len(x) != 2: logger.log("params must be of the form 'param=value'", "S") if x[1] == "\\t": x[1] = "\t" # Special handling for tab characters clparams[x[0]] = x[1] args.params = clparams params.addset("command line", "command line", inputdict=clparams) if not quiet and "scrlevel" in params.sets["command line"]: logger.scrlevel = params.sets["command line"]["scrlevel"] # Create main set of parameters based on defaults then update with config file values and command line values params.addset("main", copyset="default") params.sets["main"].updatewith("config file") params.sets["main"].updatewith("command line") execparams = params.sets["main"] # Set up logging if chain: setattr(args, 'logger', logger) args.logfile = logger.logfile else: logfile = None logname = args.log if 'log' in args.__dict__ and args.log is not None else "" if 'log' in args.__dict__: if logdef is not None: (path, base, ext) = splitfn(logname) (dpath, dbase, dext) = splitfn(logdef) if not path: if base and ext: # If both specified then use cwd, ie no path path = "" else: path = (fppath if dpath is "" else os.path.join(fppath, dpath)) if not base: if dbase == "": base = fpbase elif dbase[0] == "_": # Append to font name if starts with _ base = fpbase + dbase else: base = dbase if not ext and dext: ext = dext logname = os.path.join(path, base+ext) if logname == "": logfile = None else: (logname, logpath, exists) = fullpath(logname) if not exists: logger.log("Log file directory " + logpath + " does not exist", "S") logger.log('Opening log file for output: ' + logname, "P") try: logfile = io.open(logname, "w", encoding="utf-8") except Exception as e: print(e) sys.exit(1) args.log = logfile # Set up logger details logger.loglevel = execparams['loglevel'].upper() if not quiet: logger.scrlevel = execparams['scrlevel'].upper() logger.logfile = logfile setattr(args, 'logger', logger) # Process the argument values returned from argparse outfont = None infontlist = [] for c, ainfo in enumerate(arginfo): aval = getattr(args, ainfo['name']) if ainfo['name'] in ('params', 'log'): continue # params and log already processed atype = None adef = None if 'type' in ainfo: atype = ainfo['type'] if atype not in ('infont', 'outfont', 'infile', 'outfile', 'incsv', 'filename', 'optiondict'): logger.log("Invalid type of " + atype + " supplied in argspec", "X") if atype != 'optiondict': # All other types are file types, so adef must be set, even if just to "" adef = ainfo['def'] if 'def' in ainfo else "" if adef is None and aval is None: # If def explicitly set to None then this is optional setattr(args, ainfo['name'], None) continue if c == 0: if aval is None : logger.log("Invalid first positional parameter spec", "X") if aval[-1] in ("\\","/"): aval = aval[0:-1] # Remove trailing slashes else: #Handle defaults for all but first positional parameter if adef is not None: if not aval: aval = "" if aval == "" and adef == "": # Only valid for output font parameter if atype != "outfont": logger.log("No value suppiled for " + ainfo['name'], "S") ## Not sure why this needs to fail - we need to cope with other optional file or filename parameters (apath, abase, aext) = splitfn(aval) (dpath, dbase, dext) = splitfn(adef) # dpath should be None if not apath: if abase and aext: # If both specified then use cwd, ie no path apath = "" else: apath = fppath if not abase: if dbase == "": abase = fpbase elif dbase[0] == "_": # Append to font name if starts with _ abase = fpbase + dbase else: abase = dbase if not aext: if dext: aext = dext elif (atype == 'outfont' or atype == 'infont'): aext = fpext aval = os.path.join(apath, abase+aext) # Open files/fonts if atype == 'infont': if tool is None: logger.log("Can't specify a font without a font tool", "X") infontlist.append((ainfo['name'], aval)) # Build list of fonts to open when other args processed elif atype == 'infile': logger.log('Opening file for input: '+aval, "P") try: aval = io.open(aval, "r", encoding="utf-8") except Exception as e: print(e) sys.exit(1) elif atype == 'incsv': logger.log('Opening file for input: '+aval, "P") aval = csvreader(aval) elif atype == 'outfile': (aval, path, exists) = fullpath(aval) if not exists: logger.log("Output file directory " + path + " does not exist", "S") logger.log('Opening file for output: ' + aval, "P") try: aval = io.open(aval, 'w', encoding="utf-8") except Exception as e: print(e) sys.exit(1) elif atype == 'outfont': if tool is None: logger.log("Can't specify a font without a font tool", "X") outfont = aval outfontpath = apath outfontbase = abase outfontext = aext elif atype == 'optiondict': # Turn multiple options in the form ['opt1=a', 'opt2=b'] into a dictionary avaldict={} if aval is not None: for option in aval: x = option.split("=", 1) if len(x) != 2: logger.log("options must be of the form 'param=value'", "S") if x[1] == "\\t": x[1] = "\t" # Special handling for tab characters avaldict[x[0]] = x[1] aval = avaldict setattr(args, ainfo['name'], aval) # Open fonts - needs to be done after processing other arguments so logger and params are defined for name, aval in infontlist: if chain and name == 'ifont': aval = chain["font"] else: if tool == "FF" : aval = fontforge.open(aval) if tool == "UFO": aval = Ufont(aval, params=params) if tool == "FT" : aval = ttLib.TTFont(aval) setattr(args, name, aval) # Assign the font object to args attribute # All arguments processed, now call the main function setattr(args, "paramsobj", params) setattr(args, "cmdlineargs", argv) newfont = fn(args) # If an output font is expected and one is returned, output the font if chainfirst: chain = True # Special handling for first call of chaining if newfont: if chain: # return font to be handled by chain() return (args, newfont) else: if outfont: # Backup the font if output is overwriting original input font if outfont == infontlist[0][1]: backupdir = os.path.join(outfontpath, execparams['backupdir']) backupmax = int(execparams['backupkeep']) backup = str2bool(execparams['backup']) if backup: if not os.path.isdir(backupdir): # Create backup directory if not present try: os.mkdir(backupdir) except Exception as e: print(e) sys.exit(1) backupbase = os.path.join(backupdir, outfontbase+outfontext) # Work out backup name based on existing backups nums = sorted([int(i[len(backupbase)+1-len(i):-1]) for i in glob(backupbase+".*~")]) # Extract list of backup numbers from existing backups newnum = max(nums)+1 if nums else 1 backupname = backupbase+"."+str(newnum)+"~" # Backup the font newfont.logger.log("Backing up input font to "+backupname, "P") shutil.copytree(outfont, backupname) # Purge old backups for i in range(0, len(nums) - backupmax + 1): backupname = backupbase+"."+str(nums[i])+"~" newfont.logger.log("Purging old backup "+backupname, "I") shutil.rmtree(backupname) else: newfont.logger.log("No font backup done due to backup parameter setting", "W") # Output the font if tool == "FF": logger.log("Saving font to " + outfont, "P") if outfontext.lower() == ".ufo" or outfontext.lower() == '.ttf': newfont.generate(outfont) else: newfont.save(outfont) elif tool == "FT": logger.log("Saving font to " + outfont, "P") newfont.save(outfont) else: # Must be Pyslifont Ufont newfont.write(outfont) else: logger.log("Font returned to execute() but no output font is specified in arg spec", "X") elif chain: # ) When chaining return just args - the font can be accessed by args.ifont return (args, None) # ) assuming that the script has not changed the input font if logger.errorcount or logger.warningcount: message = "Command completed with " + str(logger.errorcount) + " errors and " + str(logger.warningcount) + " warnings" if logger.scrlevel in ("S", "E") and logname is not "": if logger.scrlevel == "S" or logger.warningcount: message = message + " - see " + logname if logger.errorcount: if quiet: logger.raisescrlevel("E") logger.log(message, "E") logger.resetscrlevel() else: logger.log(message, "P") if logger.scrlevel == "P" and logger.warningcount: logger.log("See log file for warning messages or rerun with '-p scrlevel=w'", "P") else: logger.log("Command completed with no warnings", "P") return (args, newfont)
#!/usr/bin/env fontforge import fontforge import psMat from sys import argv, stderr from GlyphComment import getfield fontforge.setPrefs('CoverageFormatsAllowed', 1) if len(argv) < 4: stderr.write("Usage: "+argv[0]+" ratio infile outfile\n") quit(1) widthScale = None widthList = {} try: widthScale = float(argv[1]) except ValueError: import csv reader = csv.reader(open(argv[1]), delimiter='\t') for data in reader: widthList[data[0]] = float(data[3]) font = fontforge.open(argv[2]) for glyph in font.glyphs(): if glyph.isWorthOutputting(): kagename = getfield(glyph, "Kage") glyphWidth = glyph.width glyphScale = widthList[kagename] if kagename in widthList else widthScale if glyphScale != 1.0: glyph.transform(psMat.scale(glyphScale, 1.0), ("partialRefs", "round"))
import fontforge; ## ## THIS FILE IS A FONTFORGE SCRIPT THAT GENERATES THE PONOMAR UNICODE FONT FAMILY ## ## base_name = "PonomarUnicode" full_name = "Ponomar Unicode" fontforge.setPrefs ("AutoHint", False) fontforge.setPrefs ("ClearInstrsBigChanges",False ) fontforge.setPrefs ( "CopyTTFInstrs",True ) ## open up the font font = fontforge.open(base_name + ".sfd") ## Evidently, this can break Evince, so it may need to be commented out. Not sure about that, though font.head_optimized_for_cleartype = True ttnames = list( font.sfnt_names ) for ttname in ttnames: if ttname[1] == 'SubFamil': ttnames.append( ( ttname[0],'Fullname',"%s %s" % ( full_name,ttname[2] ) ) ) font.sfnt_names = tuple( ttnames ) font.generate( base_name + ".otf", flags=( "opentype", "PfEd-colors", "PfEd-lookups"), layer="Fore" ) woff_meta = base_name + "-WOFF-metadata.xml" f = file( woff_meta, 'r')
import fontforge import sys import itgFontLib sourcefile = sys.argv[2] destfile = sys.argv[1] font = fontforge.open(sourcefile) itgFontLib.fontPreProcessing(font) itgFontLib.removeRefsIf(font, itgFontLib.isFlippedOrRotatedRef) itgFontLib.resetGlyphNames(font) itgFontLib.scaleEM(font, 1000) fontforge.setPrefs('FoundryName', 'NCSM') fontforge.setPrefs('TTFFoundry', 'NCSM') fontforge.setPrefs('GenerateHintWidthEqualityTolerance', 4) fontforge.setPrefs('StandardSlopeError', 3) fontforge.setPrefs('HintBoundingBoxes', 1) fontforge.setPrefs('HintDiagonalEnds', 1) fontforge.setPrefs('DetectDiagonalStems', 1) fontforge.setPrefs('InstructDiagonalStems', 1) fontforge.setPrefs('InstructSerifs', 0) fontforge.setPrefs('InstructBallTerminals', 0) fontforge.setPrefs('InterpolateStrongPoints', 0) fontforge.setPrefs('CounterControl', 0) font.selection.all() font.round() font.is_quadratic = True
# font generation flags: # omit-instructions => do not include TT instructions (for experimental typefaces) # opentype => include OpenType tables # glyph-comments => generate a 'PfEd' table and store glyph comments # glyph-colors => generate a 'PfEd' table and store glyph colors # old-kern => generate old fashioned kern tables. # - this one is important because it generates correct kerning tables for legacy # applications def_gen_flags = ("opentype", "glyph-comments", "glyph-colors", "old-kern") exp_gen_flags = def_gen_flags + ("omit-instructions",) if fontforge.version() < required_version: print ("Your version of FontForge is too old - %s or newer is required" % (required_version)); # FoundryName is not used in TTF generation fontforge.setPrefs("FoundryName", "DejaVu"); # first 4 characters of TTFFoundry are used for achVendId fontforge.setPrefs("TTFFoundry", "DejaVu") i = 1 while i < len(sys.argv): font=fontforge.open(sys.argv[i]); gen_flags = def_gen_flags # Serif Italic and Serif Bold Italic are experimental if font.fontname.rfind("Serif") > -1 and font.fontname.rfind("Italic") > -1: gen_flags = exp_gen_flags; if font.fontname.rfind("Condensed") > -1: gen_flags = exp_gen_flags; if font.fontname.rfind("ExtraLight") > -1: gen_flags = exp_gen_flags;
#!/usr/bin/env python # -*- coding: utf-8 -*- # # Usage: python %s step{1|3} font-file-name prefix # # argv[1] ... step1 or step3 # argv[2] ... font file name # argv[3] ... temporary file prefix # # eg. python pyFFctrl.py step1 meiryo.ttc rbf-tmp-ttf import sys import glob import fontforge fontforge.setPrefs('CoverageFormatsAllowed', 1) fontforge.setPrefs("AutoHint", False) # TTF flags # flags = ('opentype', 'TeX-table', 'round', 'dummy-dsig') flags = ('opentype', 'old-kern', 'dummy-dsig', 'round', 'no-hints', 'PfEd-colors', 'PfEd-lookups', 'PfEd-guidelines', 'PfEd-background') # – antialias: Hints are not applied, use grayscale smoothing. # – gridfit: Use hints. # – gridfit+smoothing: ClearType GridFitting. # – symmetric-smoothing: ClearType Antialiasing. def gasp(): return ( # (8, ('antialias',)),
caliban.generate("Caliban.ttf", bitmap_type="apple") print("...Generated ttf w/ apple bitmaps") caliban.generate("Caliban.otf", bitmap_type="ms") print("...Generated otf w/ ms bitmaps") caliban.generate("Caliban.otf", bitmap_type="ttf", flags=("apple", "opentype")) print("...Generated otf w/ both apple and ot modes set (& bitmaps)") caliban.generate("Caliban.dfont", bitmap_type="sbit") print("...Generated sbit") caliban.generate("Caliban.", bitmap_type="otb") print("...Generated X11 opentype bitmap") caliban.generate("Caliban.dfont", bitmap_type="dfont") print("...Generated dfont w/ apple bitmaps") caliban.layers["Fore"].is_quadratic = 1 caliban.setTableData("cvt ", "") caliban.selection.all() fontforge.setPrefs("DetectDiagonalStems", 1) caliban.autoHint() caliban.autoInstr() print("...AutoInstructed") caliban.generate("Caliban.ttf", bitmap_type="apple") print("...Generated ttf w/ apple bitmaps (again) and instructions") caliban.close() caliban = fontforge.open("Caliban.sfd") print("...Read sfd") caliban.close() caliban = fontforge.open("Caliban.sfdir") print("...Read sfdir") caliban.close() caliban = fontforge.open("Caliban.ps") print("...Read type0 (if PfaEdit didn't understand /CalibanBase that's ok)")
import fontforge ## ## THIS FILE IS A FONTFORGE SCRIPT THAT GENERATES WEB FONTS FAMILY ## ## base_name = "FiraSlav" fontforge.setPrefs("AutoHint", False) fontforge.setPrefs("ClearInstrsBigChanges", False) fontforge.setPrefs("CopyTTFInstrs", True) flavor = ("Regular", "Bold") for i in range(0, len(flavor)): ## open up the font font = fontforge.open(base_name + "-" + flavor[i] + ".sfd") font.head_optimized_for_cleartype = True # generate TTF fonts font.em = 1024 font.generate(base_name + "-" + flavor[i] + ".ttf", flags=("opentype", "old-kern", "PfEd-colors", "PfEd-lookups", "dummy-dsig"), layer="Fore") #generate WOFF fonts woff_meta = base_name + "-WOFF-metadata.xml" f = file(woff_meta, 'r') lines = f.readlines() f.close()
# font generation flags: # omit-instructions => do not include TT instructions (for experimental typefaces) # opentype => include OpenType tables # glyph-comments => generate a 'PfEd' table and store glyph comments # glyph-colors => generate a 'PfEd' table and store glyph colors # old-kern => generate old fashioned kern tables. # - this one is important because it generates correct kerning tables for legacy # applications def_gen_flags = ("opentype", "glyph-comments", "glyph-colors", "old-kern") exp_gen_flags = def_gen_flags + ("omit-instructions", ) if fontforge.version() < required_version: print("Your version of FontForge is too old - %s or newer is required" % (required_version)) # FoundryName is not used in TTF generation fontforge.setPrefs("FoundryName", "Brutalist") # first 4 characters of TTFFoundry are used for achVendId fontforge.setPrefs("TTFFoundry", "Brutalist") i = 1 while i < len(sys.argv): font = fontforge.open(sys.argv[i]) gen_flags = def_gen_flags # Serif Italic and Serif Bold Italic are experimental if font.fontname.rfind("Serif") > -1 and font.fontname.rfind( "Italic") > -1: gen_flags = exp_gen_flags if font.fontname.rfind("Condensed") > -1: gen_flags = exp_gen_flags if font.fontname.rfind("ExtraLight") > -1: gen_flags = exp_gen_flags