def buildAccentedGlyphs(junk,object): # """Get the names of the selected glyphs in a font. # # Call the composing function for every glyph that has an entry # in the dictionary.""" # componentsByFontname(font, font.fontname) font_file = os.path.normpath(fontforge.activeFont().path) top_level = os.path.split(os.path.split(font_file)[0])[0] tool_path = os.path.join(top_level, "tools") try: sys.path.append(tool_path) from glyphcomponents import glyphComponents if type(object).__name__ == "font": for glyph in object.selection.byGlyphs: if glyph.glyphname in glyphComponents.keys(): composeAccented(glyph) else: continue else: if object.glyphname in glyphComponents.keys(): composeAccented(object) else: logWarning('This glyph has no entry in the dictionary') except ImportError: fontforge.postError("Cannot import Python module glyphcomponents", "This script is made to work with the SFDs residing in top_level/SFD and the module in top_level/tools.")
def add_guides (glyph, direction): f = fontforge.activeFont() guides = f.guide l = glyph.layers[glyph.activeLayer] for c in l: for p in selected_points(c): if direction != 'h' and direction != 'v' and direction != 'hv': return False if direction == 'h' or direction == 'hv': guide = fontforge.contour() #place an horizontal guideline using point position guide.moveTo (-1000, p.y) guide.lineTo (2000, p.y) guides += guide if direction == 'v' or direction == 'hv': guide = fontforge.contour() #place a vertical guideline using point position guide.moveTo (p.x, -2000) guide.lineTo (p.x, 3000) guides += guide f.guide = guides glyph.layers[glyph.activeLayer]=l #Is there a better way to refresh the screen? print 'done' return True
def add_guides(glyph, direction): f = fontforge.activeFont() guides = f.guide l = glyph.layers[glyph.activeLayer] for c in l: for p in selected_points(c): if direction != "h" and direction != "v" and direction != "hv": return False if direction == "h" or direction == "hv": guide = fontforge.contour() # place an horizontal guideline using point position guide.moveTo(-1000, p.y) guide.lineTo(2000, p.y) guides += guide if direction == "v" or direction == "hv": guide = fontforge.contour() # place a vertical guideline using point position guide.moveTo(p.x, -2000) guide.lineTo(p.x, 3000) guides += guide f.guide = guides glyph.layers[glyph.activeLayer] = l # Is there a better way to refresh the screen? print "done" return True
def genTestOTF(arg, ft): localFontdir='/.fonts/'; fDir=os.path.expanduser("~")+localFontdir; ftActive=fontforge.activeFont(); ftActive.save('temp.sfd'); ft=fontforge.open('temp.sfd'); aLayer=ft.layers[ft.activeLayer].name; ft.encoding='UnicodeBMP'; ft.selection.all(); for g in ft.selection.byGlyphs: g.removeOverlap(); g.correctDirection(); g.canonicalStart(); g.canonicalContours(); testname = 'test-' + time.strftime("%H-%M-%m-%d-%Y") + "-" + ft.fontname; ft.familyname = testname; ft.fullname = testname; ft.fontname = testname; # uniqueID # Fullname ft.appendSFNTName('English (US)', 'Version', testname); ft.appendSFNTName('English (US)', 'Descriptor', 'this is just a test version generated on' + time.strftime("%H-%M-%m-%d-%Y")); ft.appendSFNTName('English (US)', 'Compatible Full', testname ); ft.appendSFNTName('English (US)', 'Preferred Family', testname ); ft.appendSFNTName('English (US)', 'Fullname', testname ); target=testname +'.otf'; ft.generate(target, flags=('opentype','dummy-dsig','apple','no-hints','no-flex'),layer=aLayer) shutil.copy(target,fDir+target); ft.close(); os.remove(target); os.remove('temp.sfd'); print target + " generated and installed in ~/.fonts/ ";
def sniffwindow(self, w): '''sniff key presses for a gtk window''' print "sniffwindow w", w print "sniff active font:", fontforge.activeFont() w.connect("key-release-event", self._do_main) fontforge.addGtkWindowToMainEventLoop(w.window.xid) fd = fontforge.getGtkWindowMainEventLoopFD(w.window.xid) w.connect('destroy', self.OnDestroyWindow, fd)
def sniffwindow(self, w): """sniff key presses for a gtk window""" print "sniffwindow w", w print "sniff active font:", fontforge.activeFont() w.connect("key-release-event", self._do_main) fontforge.addGtkWindowToMainEventLoop(w.window.xid) fd = fontforge.getGtkWindowMainEventLoopFD(w.window.xid) w.connect("destroy", self.OnDestroyWindow, fd)
def shouldWeAppear(registerobject, font): font = fontforge.activeFont() glyphs = [] for g in font.selection.byGlyphs: glyphs.append(g) if len(glyphs) == 2: return True else: return False
def main(argv): font_in = argv[0] font = fontforge.open(font_in) ymin = 0 ymax = 0 for g in fontforge.activeFont().glyphs(): bbox = g.boundingBox() print str(g.glyphname), print str(bbox[1]), print str(bbox[3])
"""def integralPoints(): font = fontforge.activeFont() for glyph in font.glyphs(): noRoundErrors = False while noRoundErrors == False: errors = glyph.validate(True) noRoundErrors = True if errors & 0x80000 == 0x80000: noRoundErrors = False glyph.round()
def main(): args = parser.parse_args() font_in = args.font[0] font = fontforge.open(font_in) for g in fontforge.activeFont().glyphs(): bbox = g.boundingBox() print str(g.glyphname), print str(bbox[0]), print str(bbox[1]), print str(bbox[2]), print str(bbox[3])
def extremaForce(): font = fontforge.activeFont() for glyph in font.glyphs(): noExtremaErrors = False while noExtremaErrors == False: errors = glyph.validate(True) noExtremaErrors = True if e & 0x20 == 0x20: noExtremaErrors = False glyph.addExtrema('only_good_rm') if noExtremaErrors == False: glyph.simplify(0, 'setstarttoextrema')
def simplepolateFonts(registerobject, font): # Ask user how many children to create, default is 5 amount = 5 s = fontforge.askString("Simple Font Interpolation", "How many children?", str(amount)) try: amount = int(s) except: fontforge.postError("Bad value", "Expected whole number") # figure out the interpolation amount floats based on how many children the user requested interpolationamount = [0.0] calcamount = amount + 1 x = 1.0 / calcamount for y in range(1, calcamount): interpolationamount.append(x * y) interpolationamount.append(1.0) # TODO: This should ask the user to choose which is source1 and source2 # get the souce fonts from the 2 currently open (check for only 2 open is in shouldWeAppear()) fonts = fontforge.fonts() source1 = fonts[0] source2 = fonts[1] # get a name for the children - font-name-generator.py supplies gibberish() so if we have that available, lets use it name = source1.familyname + " Simp" newName = fontforge.askString("Simplepolate Fonts", "Base family name?", str(name)) # create all the children for x in range(amount + 2): # TODO I thought this would work but it doesn't # newFont = source1.interpolateFonts(interpolationamount[x],source2.path) # TODO and I thought this would work because it does on its own, but if its even just repeated twice right next to each other, it doesn't work!! :( source1.interpolateFonts(interpolationamount[x], source2.path) newFontName = newName + ' ' + str(int( interpolationamount[x] * 100)).zfill(3) newFont = fontforge.activeFont() # Set PostScript Style Name (FamilyName-Style) newFont.weight = "Regular" newFont.fontname = newFontName.replace(' ', '') + '-' + newFont.weight # Set PostScript Family Name (Family Name) newFont.familyname = newFontName # Set PostScript Full Name (Family Name Style) newFont.fullname = newFontName + ' ' + font.weight # let folks know what we did message = "Simplepolated %s: %s%%/%s%% %s/%s" % ( newFont.fullname, int(100 - interpolationamount[x] * 100), int(interpolationamount[x] * 100), source1.fontname, source2.fontname) note(message)
def colGlyphs(data,fontname) : # data and fontname are values passed automatically when called as a menu item - see docs for registerMenuItem # They are not used by the function font = fontforge.activeFont() print "Toggling colour of glyphs with LtnCapA in their name" # Output from print statements will only appear when FF is called via a terminal window for glyph in font: g = font[glyph] if glyph.find('LtnCapA') >= 0: # Selects all glyphs with the string in their name #print glyph if g.color == 0x00FF00: g.color = 0xFF0000 else : g.color = 0x0000FF print "Glyph's coloured"
def simplepolateFonts(registerobject, font): # Ask user how many children to create, default is 5 amount = 5 s = fontforge.askString("Simple Font Interpolation", "How many children?", str(amount)) try: amount = int(s) except: fontforge.postError("Bad value", "Expected whole number") # figure out the interpolation amount floats based on how many children the user requested interpolationamount = [0.0] calcamount = amount +1 x = 1.0 / calcamount for y in range(1, calcamount): interpolationamount.append(x*y) interpolationamount.append(1.0) # TODO: This should ask the user to choose which is source1 and source2 # get the souce fonts from the 2 currently open (check for only 2 open is in shouldWeAppear()) fonts = fontforge.fonts() source1 = fonts[0] source2 = fonts[1] # get a name for the children - font-name-generator.py supplies gibberish() so if we have that available, lets use it name = source1.familyname + " Simp" newName = fontforge.askString("Simplepolate Fonts", "Base family name?", str(name)) # create all the children for x in range(amount+2): # TODO I thought this would work but it doesn't # newFont = source1.interpolateFonts(interpolationamount[x],source2.path) # TODO and I thought this would work because it does on its own, but if its even just repeated twice right next to each other, it doesn't work!! :( source1.interpolateFonts(interpolationamount[x],source2.path) newFontName = newName + ' ' + str(int(interpolationamount[x]*100)).zfill(3) newFont = fontforge.activeFont() # Set PostScript Style Name (FamilyName-Style) newFont.weight = "Regular" newFont.fontname = newFontName.replace(' ', '') + '-' + newFont.weight # Set PostScript Family Name (Family Name) newFont.familyname = newFontName # Set PostScript Full Name (Family Name Style) newFont.fullname = newFontName + ' ' + font.weight # let folks know what we did message = "Simplepolated %s: %s%%/%s%% %s/%s" % (newFont.fullname, int(100-interpolationamount[x]*100), int(interpolationamount[x]*100), source1.fontname, source2.fontname) note(message)
def dessiner_glyphe(donnees, input_glyphe): '''Dessine dans un glyphe donné les points correspondant aux données en entrées. Objet, Glyphe -> Void ''' # on sélectionne la police police = fontforge.activeFont() # on créer une plume pour dessiner glyphe = police[input_glyphe]; plume = glyphe.glyphPen() # pour chaque contour for contour in donnees['contours']: # on déplace la plume au niveau du premier point plume.moveTo((float(contour['points'][0]['x']),float(contour['points'][0]['y']))); # pour les points suivants for point in contour['points'][1:]: # on trace des lignes plume.lineTo((float(point['x']),float(point['y']))); # on finit par clore le tracé plume.closePath(); # on supprime la plume pour forcer le rafraîchissement plume = None;
def main(argv): font_in = argv[0] font = fontforge.open(font_in) ymin = 0 ymax = 0 for g in fontforge.activeFont().glyphs(): bbox = g.boundingBox() if bbox[3] > ymax: ymax = bbox[3] if bbox[1] < ymin: ymin = bbox[1] data = file(font_in, 'rb').read() sfnt = Sfnt(data) hhea = sfnt.hhea() os2 = sfnt.os2() print "MaxGlyph ", ymax print "WinAscent ", os2['usWinAscender'] print "TypoAscent ", os2['sTypoAscender'] print "HHeadAscent ", hhea['Ascender'] print "MinGlyph ", ymin print "WinDescent ", os2['usWinDescender'] print "TypoDescent ", os2['sTypoDescender'] print "HHeadDescent", hhea['Descender'] print "TypoLineGap ", os2['sTypoLineGap'] print "HHeadLineGap ", hhea['LineGap']
def main(argv): for font_in in argv: print font_in, font = fontforge.open(font_in) print "checked:", ymin = 0 ymax = 0 for g in fontforge.activeFont().glyphs(): bbox = g.boundingBox() if bbox[3] > ymax: ymax = int(bbox[3]) if bbox[1] < ymin: ymin = int(bbox[1]) data = file(font_in, 'rb').read() sfnt = Sfnt(data) hhea = sfnt.hhea() os2 = sfnt.os2() if ymax != os2['usWinAscender']: print "Change WinAscent to", ymax elif ymax != os2['sTypoAscender']: print "Change TypoAscent to", ymax elif ymax != hhea['Ascender']: print "Change HHeadAscent to", ymax elif ymin != -os2['usWinDescender']: print "Change WinDescent to", -ymin elif ymin != os2['sTypoDescender']: print "Change TypoDescent to", ymin elif ymin != hhea['Descender']: print "Change HHeadDescent to", ymin elif 0 != os2['sTypoLineGap']: print "Change TypoLineGap to 0" elif 0 != hhea['LineGap']: print "Change HHeadLineGap to 0" else: print "OK"
def main(argv): # open up a temp file to push FF native scripting into pe_fn = "/tmp/script.pe" pe = file(pe_fn, 'w') # open up the font specified on the command line font_in = argv[0] font = fontforge.open(font_in) # open the font file in the native script too print >> pe, 'Open("' + font_in + '")' # initialise these values ymin = 0 ymax = 0 # for each glyph in the font, find the bounding box for g in fontforge.activeFont().glyphs(): bbox = g.boundingBox() # store the max and min vertical values if bbox[3] > ymax: ymax = int(bbox[3]) if bbox[1] < ymin: ymin = int(bbox[1]) # read the vertical metrics directly from the font file data = file(font_in, 'rb').read() sfnt = Sfnt(data) hhea = sfnt.hhea() os2 = sfnt.os2() # check the metrics are correct, and if not, push a native # script command to correct it if ymax != os2['usWinAscender']: print "WinAscent should be", ymax, "but is", os2['usWinAscender'] set_os2_vert(pe, "WinAscent", ymax) if ymax != os2['sTypoAscender']: print "TypoAscent should be", ymax, "but is", os2['sTypoAscender'] set_os2_vert(pe, "TypoAscent", ymax) if ymax != hhea['Ascender']: print "HHeadAscent should be", ymax, "but is", hhea['Ascender'] set_os2_vert(pe, "HHeadAscent", ymax) if ymin != os2['usWinDescender']: print "WinDescent should be", ymin, "but is", os2['usWinDescender'] set_os2_vert(pe, "WinDescent", ymin) if ymin != os2['sTypoDescender']: print "TypoDescent should be", ymin, "but is", os2['sTypoDescender'] set_os2_vert(pe, "TypoDescent", ymin) if ymin != hhea['Descender']: print "HHeadDescent should be", ymin, "but is", hhea['Descender'] set_os2_vert(pe, "HHeadDescent", ymin) if 0 != os2['sTypoLineGap']: print "TypoLineGap should be 0 but is", os2['sTypoLineGap'] set_os2_vert(pe, "TypoLineGap", 0) if 0 != hhea['LineGap']: print "HHeadLineGap should be 0 but is", hhea['LineGap'] set_os2_vert(pe, "HHeadLineGap", 0) # push native script command to regenerate the font file print >> pe, 'Generate("' + font_in + '")' # close the script file pe.close() # run the script file print "Running a script to change these values...", os.system("fontforge -script " + pe_fn) print "Done!" # check the values are really set new_data = file(font_in, 'rb').read() new_sfnt = Sfnt(new_data) new_hhea = new_sfnt.hhea() new_os2 = new_sfnt.os2() if ymax != new_os2['usWinAscender']: print "But WinAscent is still", new_os2['usWinAscender'], " -- change it to", ymax, "by hand" if ymax != new_os2['sTypoAscender']: print "But TypoAscent is still", new_os2['sTypoAscender'], " -- change it to", ymax, "by hand" if ymax != new_hhea['Ascender']: print "But HHeadAscent is still", new_hhea['Ascender'], " -- change it to", ymax, "by hand" if ymin != new_os2['usWinDescender']: print "But WinDescent is still", new_os2['usWinDescender'], " -- change it to", ymin, "by hand" if ymin != new_os2['sTypoDescender']: print "But TypoDescent is still", new_os2['sTypoDescender'], " -- change it to", ymin, "by hand" if ymin != new_hhea['Descender']: print "But HHeadDescent is still", new_hhea['Descender'], " -- change it to", ymin, "by hand" if 0 != new_os2['sTypoLineGap']: print "But TypoLineGap is ", new_os2['sTypoLineGap'], "change it to 0 by hand" if 0 != new_hhea['LineGap']: print "But HHeadLineGap is ", new_hhea['LineGap'], "change it to 0 by hand"
usage() sys.exit() elif o in ("-o", "--output"): outfile = a elif o in ("-s", "--subtable"): kern_table = a elif o in ("-t", "--threshold"): threshold = int(a) elif o in ("-f", "--remove-fail-kern"): remfailkern = 1 if not outfile: outfile = font_name #font_name = sys.argv[1] font = fontforge.open(font_name) font = fontforge.activeFont() font.encoding = "unicode" failkerns = ('.notdef', '.notdef'), if remfailkern: import failkern for (b, c) in failkern.failkerns_u: b_u = uni2name(b) c_u = uni2name(c) if b_u and c_u: failkerns += (b_u, c_u), font.selection.all() selection = font.selection.byGlyphs for glyf in selection: if glyf.isWorthOutputting:
# fontforge.loadNamelist() # fontforge.loadNamelistDir() # fontforge.preloadCidmap() fontforge.printSetup("lpr") if (fontforge.unicodeFromName("A")!=65) or (fontforge.unicodeFromName("uni030D")!=0x30D): raise ValueError("Wrong return from unicodeFromName") foo = fontforge.version() ambrosia = sys.argv[1] fonts = fontforge.fonts() if ( len(fonts)!=0 ) : raise ValueError("Wrong return from fontforge.fonts") fontforge.activeFont() fontforge.activeGlyph() fontforge.activeLayer() fontnames= fontforge.fontsInFile(ambrosia) if len(fontnames)!=1 or fontnames[0]!='Ambrosia': raise ValueError("Wrong return from fontforge.fontsInFile") font = fontforge.open(ambrosia) morefonts = fontforge.fonts() if len(morefonts)!=1: raise ValueError("Wrong return from fontforge.fonts") instrs = fontforge.parseTTInstrs("SRP0\nMIRP[min,rnd,black]") print(fontforge.unParseTTInstrs(instrs))
# This script is to be run in FontForge to import the # images into glyphs and maybe apply other modifications to them. # FontForge has weird behaviour when importing # multiple bitmaps, so this script is necessary. srcdir = '/tmp/glyphs' from os import path import fontforge as ff font = ff.activeFont() for i in xrange(0xf000, 0xf1a3): file = path.join(srcdir, 'uni%04X.png' % i) glyph = font.createChar(i) # Import image glyph.importOutlines(file) #FIXME: fix up
#!/usr/bin/env python from os import listdir, path from fontforge import activeFont, nameFromUnicode from psMat import translate import sys # Following is needed for Unicode characters in file names reload(sys) sys.setdefaultencoding('utf8') __author__ = "Stichting z25.org <*****@*****.**>" __license__ = "MIT" font = activeFont() glyphDir = r'/home/sander/workspace/neude/src/glyphs/11-ExtraBlack' svgfiles = [ fname for fname in listdir(glyphDir) if fname[-4:].lower() == '.svg' ] src_unis = [] #TODO base all on unicode codepoints for svgfile in svgfiles: if '_alt' in svgfile or '_hor' in svgfile or '_ver' in svgfile: # print('DEBUG: skipping %s'%svgfile) #FIXME continue # print('DEBUG: svg', svgfile) try: src = svgfile.split('_')[0] uni = int(src, 16) except: print('ERROR: Invalid glyph unicode value in file name: %s' %
def genAbhaya(junk,glyph): """Roll a font forward""" myFont = fontforge.activeFont() genAbhayasamp(myFont) fontforge.logWarning("All done!")
def are_glyphs_selected(junk, font): font = fontforge.activeFont() for glyph in font.selection.byGlyphs: return True return False
def nextStep(junk,glyph): """Roll a font forward""" myFont = fontforge.activeFont() snapShot(myFont) fontforge.logWarning("All done!")
#!/usr/bin/env python 'FontForge: Demo code to paste into the "Execute Script" dialog' __url__ = 'http://github.com/silnrsi/pysilfont' __copyright__ = 'Copyright (c) 2013 SIL International (http://www.sil.org)' __license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)' __author__ = 'David Raymond' import sys, os, fontforge sys.path.append(os.path.join(os.environ['HOME'], 'src/pysilfont/scripts')) import samples.demoFunctions # Loads demoFunctions.py module from src/pysilfont/scripts/samples reload( samples.demoFunctions ) # Reload the demo module each time you execute the script to pick up any recent edits samples.demoFunctions.callFunctions("Colour Glyphs", fontforge.activeFont()) '''Demo usage: Open the "Execute Script" dialog (from the FontForge File menu or press ctrl+.), paste just the code section this (from "import..." to "samples...") into there then run it (Alt+o) and see how it pops up a dialogue with a choice of 3 functions to run. Edit demoFunctions.py and alter one of the functions. Execute the script again and see that that the function's behaviour has changed. Additional functions can be added to demoFunctions.py and, if also defined functionList() become availably immdiately. If you want to see the output from print statements, or use commands like input, (eg for degugging purposes) then start FontForge from a terminal window rather than the desktop launcher. When starting from a terminal window, you can also specify the font to use, eg $ fontforge /home/david/RFS/GenBasR.sfd'''
def newBackgroundLayer(layerName): myFont = fontforge.activeFont() myFont.layers.add(layerName,0,0)
def renameGlyph(data,fontname,old,new) : font = fontforge.activeFont() g=font[old] print g.glyphname g.glyphname=new
#!/usr/bin/env python 'FontForge: Demo code to paste into the "Execute Script" dialog' __url__ = 'http://github.com/silnrsi/pysilfont' __copyright__ = 'Copyright (c) 2013, SIL International (http://www.sil.org)' __license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)' __author__ = 'David Raymond' __version__ = '0.0.1' import sys, os, fontforge sys.path.append(os.path.join(os.environ['HOME'], 'src/pysilfont/scripts')) import samples.demoFunctions # Loads demoFunctions.py module from src/pysilfont/scripts/samples reload (samples.demoFunctions) # Reload the demo module each time you execute the script to pick up any recent edits samples.demoFunctions.callFunctions("Colour Glyphs",fontforge.activeFont()) '''Demo usage: Open the "Execute Script" dialog (from the FontForge File menu or press ctrl+.), paste just the code section this (from "import..." to "samples...") into there then run it (Alt+o) and see how it pops up a dialogue with a choice of 3 functions to run. Edit demoFunctions.py and alter one of the functions. Execute the script again and see that that the function's behaviour has changed. Additional functions can be added to demoFunctions.py and, if also defined functionList() become availably immdiately. If you want to see the output from print statements, or use commands like input, (eg for degugging purposes) then start FontForge from a terminal window rather than the desktop launcher. When starting from a terminal window, you can also specify the font to use, eg $ fontforge /home/david/RFS/GenBasR.sfd'''
def genMast(junk, glyph): """Generate Masters""" myFont = fontforge.activeFont() geMaster(myFont) fontforge.logWarning("All done!")
__email__ = "*****@*****.**" __copyright__ = "Copyright 2016, 2018 Stevan White" __date__ = "$Date:: $" __version__ = "$Revision$" __doc__ = """ For use from the FontForge Script Menu. Add it to the Scripts Menu using the Preferences dialog. Sets the OpenType glyph class of the selected range of slots to 'component' Detailed info is printed to standard output (see by launching FontForge from a console). """ import fontforge def explain_error_and_quit(e): if e: print('Error:', e) exit(1) try: glyphs = fontforge.activeFont().selection.byGlyphs for g in glyphs: print("setting", g.glyphname, 'glyph class to', 'component') g.glyphclass = 'component' except ValueError, e: explain_error_and_quit(e)
import fontforge import layermath font = fontforge.activeFont() sum, scale = layermath.operation_space (font, ['n', 'o']) layermath.add_glyphs (font, sum ('weight', 'width'), "boldext") layermath.add_glyphs (font, sum (scale ('weight', 0.4, 0.9),\ scale ('width', 0.2), scale ('square', 0.1)), \ "bold1")
def main(argv): font_in = argv[0] font = fontforge.open(font_in) for g in fontforge.activeFont().glyphs(): print "0x%0.4X" % fontforge.unicodeFromName(g.glyphname), g.glyphname
where XXXX is the n-digit hex value for the slot encoding. Careful! it changes the value whether it was previously set or not. Detailed info is printed to standard output (see by launching FontForge from a console). """ import fontforge def explain_error_and_quit( e ): if e: print( 'Error:', e ) exit( 1 ) try: glyphs = fontforge.activeFont().selection.byGlyphs for g in glyphs: if g.encoding <= 0xFFFF: newname = 'uni%0.4X' %( g.encoding ) elif g.encoding <= 0xFFFFF: newname = 'uni%0.5X' %( g.encoding ) elif g.encoding <= 0xFFFFFF: newname = 'uni%0.6X' %( g.encoding ) elif g.encoding <= 0xFFFFFFF: newname = 'uni%0.7X' %( g.encoding ) elif g.encoding <= 0xFFFFFFFF: newname = 'uni%0.8X' %( g.encoding ) print( "naming", g.glyphname, 'as', newname ) g.glyphname = newname g.unicode = g.encoding except ValueError, e:
def main(_, font): doneglyphs = list() if os.path.exists(OUTFILE): with open(OUTFILE) as f: for line in f.readlines(): doneglyphs.append(line.split("\t")[0]) font = fontforge.activeFont() font.ascent += 200 # we must write an SVG because the PNG output doesn't preserve left/right bearings when glyph overflows bearings. my fault partially lol tempf = mktemp(suffix=".svg") tempaccentf = mktemp(suffix=".svg") accent = font[ACCENT_UNI] accent.export(tempaccentf) vbdiffa = viewBox_diff(accent, tempaccentf) imaccent = svg_to_PILImage(tempaccentf) regexp = re.compile(r"^[a-zA-Z](\.[a-zA-Z0-9_]+)?$") glyphs = [ g.glyphname if g.glyphname not in REPLACEMENTS else REPLACEMENTS[g.glyphname] for g in font.glyphs() if re.match(regexp, g.glyphname) ] # makes it less boring. feel free to comment random.shuffle(glyphs) if set(doneglyphs) == set(glyphs): fontforge.logWarning( "QuickAnchors: No glyphs which match the criteria and aren't done") def process_glyph(i, glyph): nonlocal font, doneglyphs, accent, imaccent, regexp, glyphs, tempf should_exit = should_prev = False glyph = font[glyph] if glyph.glyphname in doneglyphs: print("Warning: skipping {}".format(repr(glyph)), file=sys.stderr) else: glyph.width += 300 glyph.export(tempf, pixelsize=font.em) vbdiff = viewBox_diff(glyph, tempf) im = svg_to_PILImage(tempf) (should_exit, should_prev) = pop_window_for_image(font, glyph, im, imaccent, vbdiff, vbdiffa) os.remove(tempf) glyph.width -= 300 if should_exit: return False elif should_prev and i != 0: return process_glyph(i - 1, glyphs[i - 1]) elif should_prev: return process_glyph(0, glyphs[0]) elif i + 1 == len(glyphs): return True else: return process_glyph(i + 1, glyphs[i + 1]) return True process_glyph(0, glyphs[0])