def makeQuran(options): font = makeDesktop(options, False) # fix metadata font.fontname = font.fontname.replace("-Regular", "Quran-Regular") font.familyname += " Quran" font.fullname += " Quran" sample = "بِسۡمِ ٱللَّهِ ٱلرَّحۡمَٰنِ ٱلرَّحِیمِ ١ ٱلۡحَمۡدُ لِلَّهِ رَبِّ ٱلۡعَٰلَمِینَ ٢" font.appendSFNTName('English (US)', 'Sample Text', sample) digits = ("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine") fea = mergeLatin(font, glyphs=digits, quran=True) for glyph in font.glyphs(): if glyph.glyphname.endswith(".ara"): glyph.glyphname = glyph.glyphname[:-4] glyph.unicode = fontforge.unicodeFromName(glyph.glyphname) # scale some vowel marks and dots down a bit scaleGlyph(font["uni0651"], 0.8) for mark in ("uni064B", "uni064C", "uni064E", "uni064F", "uni06E1", "uni08F0", "uni08F1", "uni08F2", "TwoDots.a", "ThreeDots.a", "vTwoDots.a"): scaleGlyph(font[mark], 0.9) # create overline glyph to be used for sajda line, it is positioned # vertically at the level of the base of waqf marks fea += makeQuranSajdaLine(font, font[0x06D7].boundingBox()[1]) unicodes = [font[n].unicode for n in digits] unicodes += ['.', '(', ')', '[', ']', '{', '}', '|', ' ', '/', '\\', 0x00AB, 0x00BB, 0x0305, 0x030A, 0x0325, 0x060C, 0x0615, 0x0617, 0x0618, 0x0619, 0x061A, 0x061B, 0x061E, 0x061F, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x0651, 0x0652, 0x0653, 0x0654, 0x0655, 0x0656, 0x0657, 0x0658, 0x065C, 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, 0x0668, 0x0669, 0x066E, 0x066F, 0x0670, 0x0671, 0x067A, 0x06A1, 0x06BA, 0x06CC, 0x06D6, 0x06D7, 0x06D8, 0x06D9, 0x06DA, 0x06DB, 0x06DC, 0x06DD, 0x06DE, 0x06DF, 0x06E0, 0x06E1, 0x06E2, 0x06E3, 0x06E4, 0x06E5, 0x06E6, 0x06E7, 0x06E8, 0x06E9, 0x06EA, 0x06EB, 0x06EC, 0x06ED, 0x06F0, 0x06F1, 0x06F2, 0x06F3, 0x06F4, 0x06F5, 0x06F6, 0x06F7, 0x06F8, 0x06F9, 0x08F0, 0x08F1, 0x08F2, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x200B, 0x200C, 0x200D, 0x200E, 0x200F, 0x2028, 0x2029, 0x202A, 0x202B, 0x202C, 0x202D, 0x202E, 0x202F, 0x25CC, 0xFD3E, 0xFD3F, 0xFDFA, 0xFDFD] unicodes = [isinstance(u, str) and ord(u) or u for u in unicodes] generateFont(options, font, fea) subsetFontFT(options.output, unicodes, quran=True)
def ligname_tuple(ligname): returns = {'name': None, 'parts': None, 'chars': None} for atom in ligname.split(' '): if atom.endswith('.liga'): returns['name'] = atom try: parts = atom.split('.')[0].split('_') chars = ''.join([chr(ff.unicodeFromName(c)) for c in parts]) if not returns['parts']: returns['parts'] = parts if not returns['chars']: returns['chars'] = chars except: pass else: returns['chars'] = atom try: parts = [ff.nameFromUnicode(ord(c)) for c in atom] ligname = '_'.join(parts) + '.liga' returns['parts'] = parts if not returns['name']: returns['name'] = ligname except: pass return tuple(returns.values())
def str2glyphName(char): if char == ".point": char = "." codepoint = fontforge.unicodeFromName(char) if codepoint != -1: glyphName = fontforge.nameFromUnicode(codepoint) else: codes = codepoints.from_unicode(char) if len(codes) == 1: glyphName = fontforge.nameFromUnicode(codes[0]) else: glyphName = char return glyphName
def isValid(name): """ Return true if a name should remain in the latin font. This blocks have been removed from the existing font in the meantime: 'Arabic Presentation Forms-A': From U+FB50 to U+FDFF 'Arabic Presentation Forms-B': From U+FE70 To U+FEFF some names got created by the built process, they look like "uni076A.medi_KafLamAlf.ref1" we want to filter these 'Arabic' From U+0600 To U+06FF 'Arabic Supplement' From U+0750 To U+077F These are in both fonts but not desired in the arabic: 'Arabic Extended-A' From U+08A0 To U+08FF """ # we don't have these in our latin if re.match('^u[0-9a-f]{5}$', name, flags=re.IGNORECASE): return False for pre in ['aKaf', 'aHeh', 'aMem', 'aBaa', 'aYaa', 'aAlf' , 'aFaa', 'aLam', 'aTaa', 'hamza', 'aHaa', 'aWaw' , 'aSad', 'aAyn', 'aQaf', 'aNon', 'aGaf', 'aSen' , 'aRaa', 'aDal' , 'FourDots', 'hThreeDots', 'ThreeDots', 'dash.gaf.alt2' , 'Dot', 'TwoDots', 'vTwoDots', 'iThreeDots', 'dotbelowcomb' , 'dot.' , 'smallv', 'smalltaa', 'damma', 'ring.below', 'aTwo.above' , 'dash.gaf', 'twostrokes.below']: if name.startswith(pre): return False # we use 'fi' and 'fl' instead # the latin uni25CC is missing the anchors if name in ('f_i', 'f_l', 'uni25CC'): return False; if not name.startswith('uni'): return True; uni = fontforge.unicodeFromName(name[:len('uniXXXX')]) if 0xFB50 <= uni <= 0xFDFF \ or 0xFE70 <= uni <= 0xFEFF \ or 0x0600 <= uni <= 0x06FF \ or 0x0750 <= uni <= 0x077F \ or 0x08A0 <= uni <= 0x08FF: return False # print 'kept uni name:', name; return True
def generateAcute(font): # we will try to generate an acute from é. # é is chosen, as it's common in French, so it's probably avialable in the font glyph = font.createChar(0x00e9); layer = fontforge.layer() contour = None maxpos = -sys.maxint - 1; # we will search for the contour which has the highest point. That's probably the accent # search in foreground char = glyph.foreground for cont in char: for point in cont: if point.y > maxpos: maxpos = point.y contour = cont # search in references for ref in glyph.references: name = ref[0] mat = ref[1] char = font.createChar(fontforge.unicodeFromName(name)).foreground; for cont in char: cont.transform(mat); for point in cont: if point.y > maxpos: maxpos = point.y contour = cont # only add this contour if not contour: print "é character is invalid, accent not generated" return layer.is_quadratic = contour.is_quadratic layer += contour # save layer glyph = font.createChar(0x02ca); glyph.foreground = layer
def buildComposition(font, glyphnames): newnames = [] font.addLookup("Latin composition", 'gsub_ligature', (), (('ccmp', script_lang),)) font.addLookupSubtable("Latin composition", "Latin composition subtable") for name in glyphnames: u = fontforge.unicodeFromName(name) if 0 < u < 0xfb00: decomp = unicodedata.decomposition(unichr(u)) if decomp: base = decomp.split()[0] mark = decomp.split()[1] if not '<' in base: nmark = None nbase = None for g in font.glyphs(): if g.unicode == int(base, 16): nbase = g.glyphname if g.unicode == int(mark, 16): nmark = g.glyphname if not nbase: nbase = "uni%04X" % int(base, 16) if not nmark: nmark = "uni%04X" % int(mark, 16) if nbase in font and nmark in font: font[name].addPosSub("Latin composition subtable", (nbase, nmark)) if base not in glyphnames: newnames.append(nbase) if mark not in glyphnames: newnames.append(nmark) return newnames
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
#-*- coding: utf-8 -*- from xml.dom.minidom import parse as parseXml import sys import glob import fontforge letters = ["!", """, "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", "", "€", "", "‚", "ƒ", "„", "…", "†", "‡", "ˆ", "‰", "Š", "‹", "Œ", "", "Ž", "", "", "‘", "’", "“", "”", "•", "–", "—", "˜", "™", "š", "›", "œ", "", "ž", "Ÿ", " ", "¡", "¢", "£", "¤", "¥", "¦", "§", "¨", "©", "ª", "«", "¬", "­", "®", "¯", "°", "±", "²", "³", "´", "µ", "¶", "·", "¸", "¹", "º", "»", "¼", "½", "¾", "¿", "À", "Á", "Â", "Ã", "Ä", "Å", "Æ", "Ç", "È", "É", "Ê", "Ë", "Ì", "Í", "Î", "Ï", "Ð", "Ñ", "Ò", "Ó", "Ô", "Õ", "Ö", "×", "Ø", "Ù", "Ú", "Û", "Ü", "Ý", "Þ", "ß", "à", "á", "â", "ã", "ä", "å", "æ", "ç", "è", "é", "ê", "ë", "ì", "í", "î", "ï", "ð", "ñ", "ò", "ó", "ô", "õ", "ö", "÷", "ø", "ù", "ú", "û", "ü", "ý", "þ", "€", "Œ", "œ", "…", "–", "—", "‘", "’", "“", "”", "Ⅰ", "Ⅱ", "Ⅲ", "Ⅳ", "Ⅴ", "Ⅵ", "Ⅶ", "Ⅷ", "Ⅸ", "Ⅹ", "Ⅺ", "Ⅻ", "Ⅼ", "Ⅽ", "Ⅾ", "Ⅿ", "←", "↑", "→", "↓", "⓪", "①", "②", "③", "④", "⑤", "⑥", "⑦", "⑧", "⑨", "♩", "♪", "♫", "♬", "♭", "♮", "♯", "′", "″", "∢"] STROKE_FONT = "%s-stroke.ufo" % sys.argv[1].replace(" ", "-") GLYPH_DIR = "%s/glyphs/" % STROKE_FONT for letter in letters: letter = letter.split("/")[-1].replace(".svg", "") char = fontforge.unicodeFromName(letter) if char == -1: char = letter.replace("&#", "").replace(";", "") letter = fontforge.nameFromUnicode(int(char)) print "letter: %s" % letter print "char: %s" % char # Gets the XML of the glyph try: letter = letter.replace("&#", "").replace(";", "") letter = fontforge.nameFromUnicode(int(char)) # In UFO, capital characters have an underscore in their name: "A" -> "A_.glif" if letter[0].isupper(): if len(letter) == 1:
def makeQuran(infile, outfile, feafile, version): font = makeDesktop(infile, outfile, feafile, version, False, False) # fix metadata font.fontname = font.fontname.replace("-Regular", "Quran-Regular") font.familyname += " Quran" font.fullname += " Quran" digits = ("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine") mergeLatin(font, feafile, glyphs=digits, quran=True) punct = ("period", "guillemotleft", "guillemotright", "braceleft", "bar", "braceright", "bracketleft", "bracketright", "parenleft", "parenright", "slash", "backslash") for name in punct: if name+".ara" in font: glyph = font[name+".ara"] glyph.glyphname = name glyph.unicode = fontforge.unicodeFromName(name) # abuse U+065C as a below form of U+06EC, for Qaloon dotabove = font["uni06EC"] dotbelow = font["uni065C"] delta = dotbelow.boundingBox()[-1] - dotabove.boundingBox()[-1] dotbelow.references = [] dotbelow.addReference(dotabove.glyphname, psMat.translate(0, delta)) dotbelow.addAnchorPoint("TashkilTashkilBelow", "basemark", 220, dotbelow.boundingBox()[1] - 100) # scale some vowel marks and dots down a bit font["uni0651"].transform(psMat.scale(0.8)) for mark in ("uni064B", "uni064C", "uni064E", "uni064F", "uni06E1"): font[mark].transform(psMat.scale(0.9)) for dot in ("TwoDots.a", "ThreeDots.a", "vTwoDots.a"): font[dot].transform(psMat.scale(0.9)) quran_glyphs = [] # create dummy glyphs used for some coding hacks for i in range(1, 11): dummy = font.createChar(-1, "dummy%s" %i) dummy.width = 0 quran_glyphs.append(dummy.glyphname) mergeFeatures(font, feafile) quran_glyphs += digits quran_glyphs += punct quran_glyphs += ("space", "uni060C", "uni0615", "uni0617", "uni0618", "uni0619", "uni061A", "uni061B", "uni061E", "uni061F", "uni0621", "uni0622", "uni0623", "uni0624", "uni0625", "uni0626", "uni0627", "uni0628", "uni0629", "uni062A", "uni062B", "uni062C", "uni062D", "uni062E", "uni062F", "uni0630", "uni0631", "uni0632", "uni0633", "uni0634", "uni0635", "uni0636", "uni0637", "uni0638", "uni0639", "uni063A", "uni0640", "uni0641", "uni0642", "uni0643", "uni0644", "uni0645", "uni0646", "uni0647", "uni0648", "uni0649", "uni064A", "uni064B", "uni064C", "uni064D", "uni064E", "uni064F", "uni0650", "uni0651", "uni0652", "uni0653", "uni0654", "uni0655", "uni0656", "uni0657", "uni0658", "uni065C", "uni0660", "uni0661", "uni0662", "uni0663", "uni0664", "uni0665", "uni0666", "uni0667", "uni0668", "uni0669", "uni066E", "uni066F", "uni06A1", "uni06BA", "uni0670", "uni0671", "uni067A", "uni06CC", "uni06D6", "uni06D7", "uni06D8", "uni06D9", "uni06DA", "uni06DB", "uni06DC", "uni06DD", "uni06DE", "uni06DF", "uni06E0", "uni06E1", "uni06E2", "uni06E3", "uni06E4", "uni06E5", "uni06E6", "uni06E7", "uni06E8", "uni06E9", "uni06EA", "uni06EB", "uni06EC", "uni06ED", "uni06F0", "uni06F1", "uni06F2", "uni06F3", "uni06F4", "uni06F5", "uni06F6", "uni06F7", "uni06F8", "uni06F9", "uni08F0", "uni08F1", "uni08F2", "uni2000", "uni2001", "uni2002", "uni2003", "uni2004", "uni2005", "uni2006", "uni2007", "uni2008", "uni2009", "uni200A", "uni200B", "uni200C", "uni200D", "uni200E", "uni200F", "uni2028", "uni2029", "uni202A", "uni202B", "uni202C", "uni202D", "uni202E", "uni202F", "uni25CC", "uniFDFA", "uniFDFD") quran_glyphs += ("uni030A", "uni0325") # ring above and below subsetFont(font, quran_glyphs, True) # set font ascent to the highest glyph in the font so that waqf marks don't # get truncated # we could have set os2_typoascent_add and hhea_ascent_add, but ff makes # the offset relative to em-size in the former and font bounds in the # later, but we want both to be relative to font bounds ymax = 0 for glyph in font.glyphs(): bb = glyph.boundingBox() if bb[-1] > ymax: ymax = bb[-1] font.os2_typoascent = font.hhea_ascent = ymax # create overline glyph to be used for sajda line, it is positioned # vertically at the level of the base of waqf marks overline_pos = font[0x06D7].boundingBox()[1] makeOverUnderline(font, under=False, o_pos=overline_pos) generateFont(font, outfile)
def _byName(self, name): """Return a tuple of unicode codepoint and name or False if name was not found by fontforge.unicodeFromName.""" uni = fontforge.unicodeFromName(name) if uni > -1: return (uni, str(name)) return False
#!/usr/bin/env fontforge import fontforge from os import system from pathlib import Path FontName = Path(input("Enter Font Name: ")) FontSize = int(input("Enter Font Size: ")) FontStem = Path(FontName.stem) FontStem.mkdir(parents=True, exist_ok=True) F = fontforge.open(FontName.name, 1) for name in F: unicodeName = fontforge.unicodeFromName(name) filename = '{:05x}'.format(unicodeName) + ".png" if '-' not in filename: FullDir = str(FontStem.joinpath(filename)) print("Exporting " + filename) F[name].export(FullDir, FontSize) system('mogrify -negate -define png:color-type=0 "'+FullDir+'"')
# fontforge.savePrefs() fontforge.defaultOtherSubrs(); # fontforge.readOtherSubrsFile(); foo = fontforge.hasSpiro() # fontforge.loadEncodingFile() # fontforge.loadNamelist() # fontforge.loadNamelistDir() # fontforge.loadPlugin() # fontforge.loadPluginDir() # fontforge.preloadCidmap() fontforge.printSetup("lpr") if ( (fontforge.unicodeFromName("A")!=65) | (fontforge.unicodeFromName("uni030D")!=0x30D) ) : raise ValueError, "Wrong return from unicodeFromName" foo = fontforge.version() fonts = fontforge.fonts() if ( len(fonts)!=0 ) : raise ValueError, "Wrong return from fontforge.fonts" fontforge.activeFont() fontforge.activeGlyph() fontforge.activeLayer() fontnames= fontforge.fontsInFile("fonts/Ambrosia.sfd") if ( len(fontnames)!=1 ) | (fontnames[0]!='Ambrosia' ): raise ValueError, "Wrong return from fontforge.fontsInFile" font = fontforge.open("fonts/Ambrosia.sfd")
fontforge.setPrefs("DetectDiagonalStems",~foo) fontforge.loadPrefs() # fontforge.savePrefs() fontforge.defaultOtherSubrs() # fontforge.readOtherSubrsFile() foo = fontforge.hasSpiro() # fontforge.loadEncodingFile() # 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':
# Test for uniXXXXYYYY... ligature elif (glyphname.startswith("uni") and len(glyphname) > 7 and len(glyphname) % 4 == 3): components = ("uni" + glyphname[k:k + 4] for k in xrange(3, len(glyphname), 4)) addlig(components, glyph) # Read feature file if args.featurefile: font.mergeFeature(args.featurefile) # Add alias glyphs for glyphname in ALIASES: if glyphname in font: for name in ALIASES[glyphname]: glyph = font.createChar(fontforge.unicodeFromName(name), name) if not glyph.isWorthOutputting(): glyph.addReference(glyphname) # Amend lookup tables for glyph in font.glyphs(): for row in glyph.getPosSub("*"): if row[1] == "Substitution": for name in ALIASES.get(glyph.glyphname, ()): font[name].addPosSub(row[0], row[2]) elif row[1] in ("AltSubs", "MultSubs"): for name in ALIASES.get(glyph.glyphname, ()): font[name].addPosSub(row[0], row[2:]) elif row[1] == "Ligature": for components in product(*(ALIASES.get(name, ()) + (name,) for name in row[2:])):
if skip and glyf.glyphname in skiplist: continue #print glyf.glyphname refs = glyf.references #print len(refs), refs, len(glyf.foreground) subref = 0 cont_num = 0 point_num = 0 basedata = () accdata = () for ref in refs: tm = ref[1][0:4] # transform matrix of reference shift_x = ref[1][4] shift_y = ref[1][5] ref_cont = len(font[ref[0]].foreground) uni_index = fontforge.unicodeFromName(strip_suff.split(ref[0])[0]) #print uni_index, if ref[0] == "cyrbreve" or ref[0] == "cyrBreve": ref_type = 'Mn' elif uni_index >= 0: ref_type = unicodedata.category(unichr(uni_index)) else: break #print ref_type if ref_cont > 0: subref = 0 ref_data(ref, ref_cont, ref[0]) elif len(font[ref[0]].references) >= 1: subref = 1 point_bot = (0.0, 32768.0, 0) point_top = (0.0, -32768.0, 0)
if descriptiveglyphnames: ucchar = alias else: ucchar = ucname(alias) thefont.selection.select(char) for ref in thefont[char].references: if thefont[ref[0]].unicode > 0 and ref[0] in encoding: newrefname = encoding[ref[0]] else: newrefname = ref[0] references.append( (ucchar, newrefname, ref[1], thefont[char].width)) thefont[char].references = () thefont.copy() thefont.clear() outfont.createChar(fontforge.unicodeFromName(ucchar), ucchar).width = thefont[char].width outfont.selection.select(ucchar) outfont.paste() if ucchar in outfont: outfont[ucchar].references = () gdh.write(' ' + alias.replace('.', '_') + ' = ps("' + ucchar + '");\n') if alias in freetengenc: outfont[ucchar].unicode = freetengenc[alias] outfont.createChar(0x200B, "zwsp").width = 0 outfont.createChar(0x200C, "zwnj").width = 0 outfont.createChar(0x200D, "zwj").width = 0 gdh.write(' ZWJ = ps("zwj");\n')
def subset_font_raw(font_in, font_out, unicodes, opts): if '--namelist' in opts: # 2010-12-06 DC To allow setting namelist filenames, # change getopt.gnu_getopt from namelist to namelist= # and invert comments on following 2 lines # nam_fn = opts['--namelist'] nam_fn = font_out + '.nam' nam = file(nam_fn, 'w') else: nam = None if '--script' in opts: pe_fn = "/tmp/script.pe" pe = file(pe_fn, 'w') else: pe = None font = fontforge.open(font_in) if pe: print >> pe, 'Open("' + font_in + '")' # Note: should probably do this in the non-script case too # see http://sourceforge.net/mailarchive/forum.php?thread_name=20100906085718.GB1907%40khaled-laptop&forum_name=fontforge-users # but FontForge's python API can't toggle winasc/desc as offset, only set the offset values with font.os2_windescent and font.os2_winascent print >> pe, 'SetOS2Value("WinAscentIsOffset", 0)' print >> pe, 'SetOS2Value("WinDescentIsOffset", 0)' for i in unicodes: select_with_refs(font, i, font, pe, nam) addl_glyphs = [] if '--nmr' in opts: addl_glyphs.append('nonmarkingreturn') if '--null' in opts: addl_glyphs.append('.null') for glyph in addl_glyphs: font.selection.select(('more',), glyph) if nam: print >> nam, "0x%0.4X" % fontforge.unicodeFromName(glyph), glyph if pe: print >> pe, 'SelectMore("%s")' % glyph flags = () if '--simplify' in opts: font.simplify() font.round() flags = ('omit-instructions',) if '--strip_names' in opts: font.sfnt_names = () if '--new' in opts: font.copy() new = fontforge.font() new.encoding = font.encoding new.em = font.em new.layers['Fore'].is_quadratic = font.layers['Fore'].is_quadratic for i in unicodes: select_with_refs(font, i, new, pe, nam) new.paste() # This is a hack - it should have been taken care of above. font.selection.select('space') font.copy() new.selection.select('space') new.paste() new.sfnt_names = font.sfnt_names font = new else: font.selection.invert() print >> pe, "SelectInvert()" font.cut() print >> pe, "Clear()" if nam: print "Writing NameList", nam.close() print nam if pe: print >> pe, 'Generate("' + font_out + '")' pe.close() os.system("fontforge -script " + pe_fn) else: font.generate(font_out, flags = flags) print '\tDone' font.close() if '--roundtrip' in opts: font2 = fontforge.open(font_out) font2.generate(font_out, flags = flags) print '-------------------------------------' print '| WebFont Subset |' print '-------------------------------------' print '| Version: V1.0 2015.11 |' print '-------------------------------------'
def subset_font_raw(font_in, font_out, unicodes, opts): if '--namelist' in opts: # 2010-12-06 DC To allow setting namelist filenames, # change getopt.gnu_getopt from namelist to namelist= # and invert comments on following 2 lines # nam_fn = opts['--namelist'] nam_fn = font_out + '.nam' nam = file(nam_fn, 'w') else: nam = None if '--script' in opts: pe_fn = "/tmp/script.pe" pe = file(pe_fn, 'w') else: pe = None font = fontforge.open(font_in) if pe: print('Open("' + font_in + '")', file=pe) extract_vert_to_script(font_in, pe) for i in unicodes: select_with_refs(font, i, font, pe, nam) addl_glyphs = [] if '--nmr' in opts: addl_glyphs.append('nonmarkingreturn') if '--null' in opts: addl_glyphs.append('.null') if '--nd' in opts: addl_glyphs.append('.notdef') for glyph in addl_glyphs: font.selection.select(('more', ), glyph) if nam: print("0x%0.4X" % fontforge.unicodeFromName(glyph), glyph, file=nam) if pe: print('SelectMore("%s")' % glyph, file=pe) flags = () if '--opentype-features' in opts: flags += ('opentype', ) if '--simplify' in opts: font.simplify() font.round() flags += ('omit-instructions', ) if '--strip_names' in opts: font.sfnt_names = () if '--new' in opts: font.copy() new = fontforge.font() new.encoding = font.encoding new.em = font.em new.layers['Fore'].is_quadratic = font.layers['Fore'].is_quadratic for i in unicodes: select_with_refs(font, i, new, pe, nam) new.paste() # This is a hack - it should have been taken care of above. font.selection.select('space') font.copy() new.selection.select('space') new.paste() new.sfnt_names = font.sfnt_names font = new else: font.selection.invert() print("SelectInvert()", file=pe) font.cut() print("Clear()", file=pe) if '--move-display' in opts: print("Moving display glyphs into unicode ranges...") font.familyname += " Display" font.fullname += " Display" font.fontname += "Display" font.appendSFNTName('English (US)', 'Family', font.familyname) font.appendSFNTName('English (US)', 16, font.familyname) font.appendSFNTName('English (US)', 17, 'Display') font.appendSFNTName('English (US)', 'Fullname', font.fullname) for glname in unicodes: font.selection.none() if isinstance(glname, str): if glname.endswith('.display'): font.selection.select(glname) font.copy() font.selection.none() newgl = glname.replace('.display', '') font.selection.select(newgl) font.paste() font.selection.select(glname) font.cut() if nam: print("Writing NameList", end="") nam.close() if pe: print('Generate("' + font_out + '")', file=pe) pe.close() subprocess.call(["fontforge", "-script", pe_fn]) else: font.generate(font_out, flags=flags) font.close() if '--roundtrip' in opts: # FontForge apparently contains a bug where it incorrectly calculates # the advanceWidthMax in the hhea table, and a workaround is to open # and re-generate font2 = fontforge.open(font_out) font2.generate(font_out, flags=flags)
def subset_font_raw(font_in, font_out, unicodes, opts): if '--namelist' in opts: # 2010-12-06 DC To allow setting namelist filenames, # change getopt.gnu_getopt from namelist to namelist= # and invert comments on following 2 lines # nam_fn = opts['--namelist'] nam_fn = font_out + '.nam' nam = open(nam_fn, 'w') else: nam = None if '--script' in opts: pe_fn = "/tmp/script.pe" pe = open(pe_fn, 'w') else: pe = None font = fontforge.open(font_in) if pe: print('Open("' + font_in + '")', file=pe) extract_vert_to_script(font_in, pe) for i in unicodes: select_with_refs(font, i, font, pe, nam) addl_glyphs = [] if '--nmr' in opts: addl_glyphs.append('nonmarkingreturn') if '--null' in opts: addl_glyphs.append('.null') if '--nd' in opts: addl_glyphs.append('.notdef') for glyph in addl_glyphs: font.selection.select(('more',), glyph) if nam: print("0x%0.4X" % fontforge.unicodeFromName(glyph), glyph, file=nam) if pe: print('SelectMore("%s")' % glyph, file=pe) flags = () if '--opentype-features' in opts: flags += ('opentype',) if '--simplify' in opts: font.simplify() font.round() flags += ('omit-instructions',) if '--strip_names' in opts: font.sfnt_names = () if '--new' in opts: font.copy() new = fontforge.font() new.encoding = font.encoding new.em = font.em new.layers['Fore'].is_quadratic = font.layers['Fore'].is_quadratic for i in unicodes: select_with_refs(font, i, new, pe, nam) new.paste() # This is a hack - it should have been taken care of above. font.selection.select('space') font.copy() new.selection.select('space') new.paste() new.sfnt_names = font.sfnt_names font = new else: font.selection.invert() print("SelectInvert()", file=pe) font.cut() print("Clear()", file=pe) if '--move-display' in opts: print("Moving display glyphs into unicode ranges...") font.familyname += " Display" font.fullname += " Display" font.fontname += "Display" font.appendSFNTName('English (US)', 'Family', font.familyname) font.appendSFNTName('English (US)', 16, font.familyname) font.appendSFNTName('English (US)', 17, 'Display') font.appendSFNTName('English (US)', 'Fullname', font.fullname) for glname in unicodes: font.selection.none() if isinstance(glname, str): if glname.endswith('.display'): font.selection.select(glname) font.copy() font.selection.none() newgl = glname.replace('.display','') font.selection.select(newgl) font.paste() font.selection.select(glname) font.cut() if nam: print("Writing NameList", end="") nam.close() if pe: print('Generate("' + font_out + '")', file=pe) pe.close() subprocess.call(["fontforge", "-script", pe_fn]) else: font.generate(font_out, flags = flags) font.close() if '--roundtrip' in opts: # FontForge apparently contains a bug where it incorrectly calculates # the advanceWidthMax in the hhea table, and a workaround is to open # and re-generate font2 = fontforge.open(font_out) font2.generate(font_out, flags = flags)
def subset_font_raw(font_in, font_out, unicodes, opts): if '--namelist' in opts: # 2010-12-06 DC To allow setting namelist filenames, # change getopt.gnu_getopt from namelist to namelist= # and invert comments on following 2 lines # nam_fn = opts['--namelist'] nam_fn = font_out + '.nam' nam = file(nam_fn, 'w') else: nam = None if '--script' in opts: pe_fn = "/tmp/script.pe" pe = file(pe_fn, 'w') else: pe = None font = fontforge.open(font_in) if pe: print >> pe, 'Open("' + font_in + '")' extract_vert_to_script(font_in, pe) for i in unicodes: select_with_refs(font, i, font, pe, nam) addl_glyphs = [] if '--nmr' in opts: addl_glyphs.append('nonmarkingreturn') if '--null' in opts: addl_glyphs.append('.null') for glyph in addl_glyphs: font.selection.select(('more', ), glyph) if nam: print >> nam, "0x%0.4X" % fontforge.unicodeFromName(glyph), glyph if pe: print >> pe, 'SelectMore("%s")' % glyph flags = () if '--simplify' in opts: font.simplify() font.round() flags = ('omit-instructions', ) if '--strip_names' in opts: font.sfnt_names = () if '--new' in opts: font.copy() new = fontforge.font() new.encoding = font.encoding new.em = font.em new.layers['Fore'].is_quadratic = font.layers['Fore'].is_quadratic for i in unicodes: select_with_refs(font, i, new, pe, nam) new.paste() # This is a hack - it should have been taken care of above. font.selection.select('space') font.copy() new.selection.select('space') new.paste() new.sfnt_names = font.sfnt_names font = new else: font.selection.invert() print >> pe, "SelectInvert()" font.cut() print >> pe, "Clear()" if nam: print "Writing NameList", nam.close() if pe: print >> pe, 'Generate("' + font_out + '")' pe.close() os.system("fontforge -script " + pe_fn) else: font.generate(font_out, flags=flags) font.close() if '--roundtrip' in opts: # FontForge apparently contains a bug where it incorrectly calculates # the advanceWidthMax in the hhea table, and a workaround is to open # and re-generate font2 = fontforge.open(font_out) font2.generate(font_out, flags=flags)
def subset_font_raw(font_in, font_out, unicodes, opts): if '--namelist' in opts: # 2010-12-06 DC To allow setting namelist filenames, # change getopt.gnu_getopt from namelist to namelist= # and invert comments on following 2 lines # nam_fn = opts['--namelist'] nam_fn = font_out + '.nam' nam = file(nam_fn, 'w') else: nam = None if '--script' in opts: pe_fn = "/tmp/script.pe" pe = file(pe_fn, 'w') else: pe = None font = fontforge.open(font_in) if pe: print >> pe, 'Open("' + font_in + '")' # Note: should probably do this in the non-script case too # see http://sourceforge.net/mailarchive/forum.php?thread_name=20100906085718.GB1907%40khaled-laptop&forum_name=fontforge-users # but FontForge's python API can't toggle winasc/desc as offset, only set the offset values with font.os2_windescent and font.os2_winascent print >> pe, 'SetOS2Value("WinAscentIsOffset", 0)' print >> pe, 'SetOS2Value("WinDescentIsOffset", 0)' for i in unicodes: select_with_refs(font, i, font, pe, nam) addl_glyphs = [] if '--nmr' in opts: addl_glyphs.append('nonmarkingreturn') if '--null' in opts: addl_glyphs.append('.null') for glyph in addl_glyphs: font.selection.select(('more', ), glyph) if nam: print >> nam, "0x%0.4X" % fontforge.unicodeFromName(glyph), glyph if pe: print >> pe, 'SelectMore("%s")' % glyph flags = () if '--simplify' in opts: font.simplify() font.round() flags = ('omit-instructions', ) if '--strip_names' in opts: font.sfnt_names = () if '--new' in opts: font.copy() new = fontforge.font() new.encoding = font.encoding new.em = font.em new.layers['Fore'].is_quadratic = font.layers['Fore'].is_quadratic for i in unicodes: select_with_refs(font, i, new, pe, nam) new.paste() # This is a hack - it should have been taken care of above. font.selection.select('space') font.copy() new.selection.select('space') new.paste() new.sfnt_names = font.sfnt_names font = new else: font.selection.invert() print >> pe, "SelectInvert()" font.cut() print >> pe, "Clear()" if nam: print "Writing NameList", nam.close() print nam if pe: print >> pe, 'Generate("' + font_out + '")' pe.close() os.system("fontforge -script " + pe_fn) else: font.generate(font_out, flags=flags) print '\tDone' font.close() if '--roundtrip' in opts: font2 = fontforge.open(font_out) font2.generate(font_out, flags=flags) print '-------------------------------------' print '| WebFont Subset |' print '-------------------------------------' print '| Version: V1.0 2015.11 |' print '-------------------------------------'
uniCodePoint = fontforge.unicodeFromName("uni0308") # tréma combiné elif strglyph == "œ" or strglyph == "oe": uniCodePoint = fontforge.unicodeFromName("oe") # œ = ligature oe elif strglyph == "ç": uniCodePoint = fontforge.unicodeFromName("ccedilla") # ç et pas que la cédille elif strglyph == "fi" or strglyph == "fi": uniCodePoint = fontforge.unicodeFromName("fi") # ligature fi "uniFB01" else: # other glyphs print("non!") uniCodePoint = fontforge.unicodeFromName(strglyph) ''' #if re.match(r"",strglyph): #uniCodePoint = codepoints.from_unicode(strglyph.decode('utf-8'))[0] uniCodePoint = fontforge.unicodeFromName(glyphName) #glyphName = fontforge.nameFromUnicode(uniCodePoint) print(uniCodePoint) print(glyphName) #fontglyph = font.createMappedChar(glyphName) fontglyph = font.createChar(uniCodePoint) tmpsvg = minidom.parseString(svgModel) #print(tmpsvg.toxml()) tmpsvg.getElementsByTagName("svg")[0].appendChild(layer) pathtmpsvg = individualGlyphFolder + glyphName + ".svg" with open(pathtmpsvg, 'w') as f: print(type(tmpsvg)) tmpsvg.writexml(f) fontglyph.importOutlines(pathtmpsvg)
font.createMappedChar(letter) font.createChar(char) # Import outline file font[char].importOutlines(f) font[char].autoTrace() # Set bearings to 0 font[char].left_side_bearing = 0 font[char].right_side_bearing = 0 # AutoWidth: separation, MinBearing, MaxBearing for f in files: letter = f.split("/")[-1].replace(".png", "") char = fontforge.unicodeFromName(letter) if char == -1: char = letter.replace("&#", "").replace(";", "") letter = fontforge.nameFromUnicode(int(char)) print "letter: %s" % letter print "char: %s" % char importGlyph(f, letter, int(char)) bottom = font["h"].boundingBox()[1] top = font["h"].boundingBox()[3] height = top - bottom scale_ratio = 780 / height scale_matrix = psMat.scale(scale_ratio) translate_matrix = psMat.translate(0, font.descent * scale_ratio)
def subset_font_raw(font_in, font_out, unicodes, opts): if '--namelist' in opts: # 2010-12-06 DC To allow setting namelist filenames, # change getopt.gnu_getopt from namelist to namelist= # and invert comments on following 2 lines # nam_fn = opts['--namelist'] nam_fn = font_out + '.nam' nam = file(nam_fn, 'w') else: nam = None if '--script' in opts: pe_fn = "/tmp/script.pe" pe = file(pe_fn, 'w') else: pe = None font = fontforge.open(font_in) if pe: print >> pe, 'Open("' + font_in + '")' extract_vert_to_script(font_in, pe) for i in unicodes: select_with_refs(font, i, font, pe, nam) addl_glyphs = [] if '--nmr' in opts: addl_glyphs.append('nonmarkingreturn') if '--null' in opts: addl_glyphs.append('.null') for glyph in addl_glyphs: font.selection.select(('more',), glyph) if nam: print >> nam, "0x%0.4X" % fontforge.unicodeFromName(glyph), glyph if pe: print >> pe, 'SelectMore("%s")' % glyph flags = () if '--simplify' in opts: font.simplify() font.round() flags = ('omit-instructions',) if '--strip_names' in opts: font.sfnt_names = () if '--new' in opts: font.copy() new = fontforge.font() new.encoding = font.encoding new.em = font.em new.layers['Fore'].is_quadratic = font.layers['Fore'].is_quadratic for i in unicodes: select_with_refs(font, i, new, pe, nam) new.paste() # This is a hack - it should have been taken care of above. font.selection.select('space') font.copy() new.selection.select('space') new.paste() new.sfnt_names = font.sfnt_names font = new else: font.selection.invert() print >> pe, "SelectInvert()" font.cut() print >> pe, "Clear()" if nam: print "Writing NameList", nam.close() if pe: print >> pe, 'Generate("' + font_out + '")' pe.close() os.system("fontforge -script " + pe_fn) else: font.generate(font_out, flags = flags) font.close() if '--roundtrip' in opts: # FontForge apparently contains a bug where it incorrectly calculates # the advanceWidthMax in the hhea table, and a workaround is to open # and re-generate font2 = fontforge.open(font_out) font2.generate(font_out, flags = flags)
# fontforge.savePrefs() fontforge.defaultOtherSubrs(); # fontforge.readOtherSubrsFile(); foo = fontforge.hasSpiro() # fontforge.loadEncodingFile() # fontforge.loadNamelist() # fontforge.loadNamelistDir() # fontforge.loadPlugin() # fontforge.loadPluginDir() # fontforge.preloadCidmap() fontforge.printSetup("lpr") if ( (fontforge.unicodeFromName("A")!=65) | (fontforge.unicodeFromName("uni030D")!=0x30D) ) : raise ValueError, "Wrong return from unicodeFromName" foo = fontforge.version() ambrosia = os.path.join("/home/rakesh/pdf2htmlEX/fontforge-pdf2htmlEX/tests", "fonts", "Ambrosia.sfd") 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 ) | (fontnames[0]!='Ambrosia' ):