def makeSlanted(infile, outfile, feafile, version, slant): font = makeDesktop(infile, outfile, feafile, version, False, False) # compute amout of skew, magic formula copied from fontforge sources skew = psMat.skew(-slant * math.pi/180.0) font.selection.all() punct = ("period", "guillemotleft", "guillemotright", "braceleft", "bar", "braceright", "bracketleft", "bracketright", "parenleft", "parenright", "slash", "backslash", "brokenbar", "uni061F") for name in punct: font.selection.select(("less", None), name) font.transform(skew) # fix metadata font.italicangle = slant font.fullname += " Slanted" if font.weight == "Bold": font.fontname = font.fontname.replace("Bold", "BoldSlanted") font.appendSFNTName("Arabic (Egypt)", "SubFamily", "عريض مائل") font.appendSFNTName("English (US)", "SubFamily", "Bold Slanted") else: font.fontname = font.fontname.replace("Regular", "Slanted") font.appendSFNTName("Arabic (Egypt)", "SubFamily", "مائل") mergeLatin(font, feafile, italic=skew) # we want to merge features after merging the latin font because many # referenced glyphs are in the latin font mergeFeatures(font, feafile) generateFont(font, outfile)
def makeSlanted(options): font = makeDesktop(options, False) # compute amout of skew, magic formula copied from fontforge sources import math skew = psMat.skew(-options.slant * math.pi / 180.0) # Remove Arabic math alphanumerics, they are upright-only. font.selection.select(["ranges"], "u1EE00", "u1EEFF") for glyph in font.selection.byGlyphs: font.removeGlyph(glyph) font.selection.all() punct = ("exclam", "period", "guillemotleft", "guillemotright", "braceleft", "bar", "braceright", "bracketleft", "bracketright", "parenleft", "parenright", "slash", "backslash", "brokenbar", "uni061F", "dot.1", "dot.2") for name in punct: font.selection.select(["less"], name) font.transform(skew) # fix metadata font.italicangle = options.slant font.fullname += " Slanted" if font.weight == "Bold": font.fontname = font.fontname.replace("Bold", "BoldSlanted") font.appendSFNTName("English (US)", "SubFamily", "Bold Slanted") else: font.fontname = font.fontname.replace("Regular", "Slanted") fea = mergeLatin(font, italic=skew) makeNumerators(font) generateFont(options, font, fea)
def obliqize(infont, outfont, angle, family, arfamily): font = fontforge.open(infont) import psMat skew = psMat.skew(angle) for glyph in font.glyphs(): if glyph.isWorthOutputting(): font.selection.select(("more", "singletons"), glyph.glyphname) font.selection.select(("less", "ranges"), "afii61664", "afii61575") font.unlinkReferences() font.transform(skew) font.familyname = font.fontname = font.fontname + "-Oblique" font.fullname = font.fullname + " Oblique" font.familyname = family font.appendSFNTName('Arabic (Egypt)', 'SubFamily', arfamily) font.save(outfont) font.close()
def _make_glyph(self, glyph_def): '''Creates a FontForge glyph using the given Glyph.''' font = self.font if glyph_def.char_code == -1: glyph = font.createChar(-1, '.notdef') else: glyph = font.createChar(glyph_def.char_code) glyph.clear() glyph.manualHints = True glyph_sizes = self._calc_glyph_sizes(glyph_def) self._draw_glyph_rows(glyph, glyph_def, glyph_sizes) self._add_anchors(glyph, glyph_def, glyph_sizes) for arg in glyph_def.args: if arg.startswith(u'reference:'): code = int(arg.split(u':', 1)[1].lstrip('uU+'), 16) glyph.addReference(fontforge.nameFromUnicode(code)) elif arg.startswith(u'diacritic:'): code = int(arg.split(u':', 1)[1].lstrip('uU+'), 16) glyph.appendAccent(fontforge.nameFromUnicode(code)) # if not ('oblique' in font.fontname.lower() or \ # 'bold' in font.fontname.lower()): # self._add_row_hints(glyph, glyph_def, glyph_sizes) # self._add_col_hints(glyph, glyph_def, glyph_sizes) if 'oblique' in font.fontname.lower(): glyph.transform(psMat.skew(math.pi / 180 * 10), ('partialRefs',)) if u'combining' in glyph_def.args: glyph.width = 0 else: glyph.width = glyph_sizes.square_size * 8
# Put with Kite One under the same directory and run with # fontforge -lang=py -script font-gen.py import fontforge import psMat import math font = fontforge.open('KiteOne-Regular.ttf') print(font.copyright) print(font.familyname) print(font.fontname) print(font.fullname) font.selection.all() skew_mat = psMat.skew(-7 / 180.0 * math.pi) font.transform(skew_mat) font.selection.select(('ranges', None), '0', '9') skew_mat = psMat.skew(+1.2 / 180.0 * math.pi) font.transform(skew_mat) font.copyright += "; Modified and renamed to 'Tako'" font.familyname = 'Tako Zero' font.fontname = 'TakoZero-Irregular' font.fullname = 'Tako Zero' font.generate('TakoZero-Irregular.ttf')
def m_skew(radiant): return m_compose(psMat.translate(-c_halfsize, -c_middle), psMat.skew(radiant), psMat.translate(c_halfsize, c_middle))
font.replaceWithReference() # Remove overlapped area font.selection.all() font.removeOverlap() for i in font: glyph = font[i] if len(glyph.references) > 0 and len( glyph.layers["Fore"]) > 0: # a mixed glyph glyph.unlinkRef() glyph.removeOverlap() font.selection.all() font.simplify(0.05, ("smoothcurves", "choosehv"), 0.1) #font.em = 2000 font.selection.all() font.layers["Fore"].is_quadratic = True font.transform(psMat.skew(float(sys.argv[4]) / 180 * math.pi)) font.em = 1000 font.selection.all() font.round() font.removeOverlap() font.simplify(0.01) font.selection.all() font.removeOverlap() font.canonicalContours() font.canonicalStart() font.generate(sys.argv[3], flags=("opentype"))
for nomen in sfnt: font.appendSFNTName(nomen[0], nomen[1], nomen[2]) for glyph in glyphsWorthOutputting(font): if args.action == 'scale': glyph.transform( psMat.scale(args.width / glyph.width, 1.0), ('partialRefs', 'round')) elif args.action == 'pad': glyph.transform( psMat.translate((args.width - glyph.width) / 2, 0), ('partialRefs', 'round')) glyph.width = int(args.width) if args.skew is not None: glyph.transform( psMat.skew(radians(args.skew)), ('partialRefs', 'round')) if args.merge_with is not None: for fileName in args.merge_with: font2 = fontforge.open(fileName) font.encoding = font2.encoding font2.em = font.em font.selection.none() font2.selection.none() for glyph in glyphsWorthOutputting(font2): if glyph.glyphname not in font: font2.selection.select(('more',), glyph.glyphname) font.selection.select(('more',), glyph.glyphname) font2.copy() font.paste()
base_font.generate("otf/" + base_font.fontname + ".otf") base_font.printSample("fontdisplay", 24, "", "specimens/" + base_font.fontname + ".pdf") base_font.close() print("Generated condensed") ## italic base_font = fontforge.open("sfd/14seg-gen.sfd") base_font.selection.all() matrix = psMat.skew(math.radians(12.5)) base_font.transform(matrix) base_font.italicangle = -12.5 base_font.fullname = "LCD Display: 14 Segment (Italic)" base_font.fontname = "LCD14Italic" base_font.os2_stylemap = 0b1000000001 # italic https://www.microsoft.com/typography/otspec/os2.htm base_font.save("sfd/14seg-italic.sfd") base_font.generate("otf/" + base_font.fontname + ".otf")
def skew(self, angle, offset=None): matrix = psMat.skew(angle) self._object.transform(matrix)
LATIN_WIDTH = 1000 # 未使用 JP_WIDTH = 1000 WIDTH = JP_WIDTH # Ubuntu mono と やさしさゴシックボールドV2 で同じ ASCENT = 800 DESCENT = 200 HEIGHT = ASCENT + DESCENT LATIN_ASCENT = 800 LATIN_DESCENT = 200 # 未使用 JP_ASCENT = 880 JP_DESCENT = 120 # Italic時の傾き SKEW_MAT = psMat.skew(0.25) # 罫線素片、ブロック要素 RULED_LINES = list(range(0x2500, 0x2600)) # 半角カナとかの半角幅のやつ HALFWIDTH_CJK_KANA = list(range(0xFF61, 0xFF9F)) # 全角文字 FULLWIDTH_HIRAGANA_KATAKANA = list(range(0x3040, 0x30FF)) FULLWIDTH_CJK_UNIFIED = list(range(0x4E00, 0x9FCF)) FULLWIDTH_CJK_COMPATI = list(range(0xF900, 0xFAFF)) FULLWIDTH_CJK_UNIFIED_EX_A = list(range(0x3400, 0x4DBF)) FULLWIDTH_CJK_UNIFIED_EX_B = list(range(0x20000, 0x2A6DF)) FULLWIDTH_CJK_UNIFIED_EX_C = list(range(0x2A700, 0x2B73F)) FULLWIDTH_CJK_UNIFIED_EX_D = list(range(0x2B740, 0x2B81F)) FULLWIDTH_CJK_COMPATI_SUPP = list(range(0x2F800, 0x2FA1F)) FULLWIDTH_CODES = FULLWIDTH_HIRAGANA_KATAKANA + \
def build_font(_f, emoji): hack = fontforge.open(os.path.join(SOURCE, _f.get('hack'))) log('remove_glyph_from_hack()') hack = remove_glyph_from_hack(hack) cica = fontforge.open(os.path.join(SOURCE, _f.get('mgen_plus'))) nerd = fontforge.open(os.path.join(SOURCE, 'nerd.sfd')) icons_for_devs = fontforge.open(os.path.join(SOURCE, 'iconsfordevs.ttf')) log('transform Hack') for g in hack.glyphs(): g.transform((0.42,0,0,0.42,0,0)) if _f.get('hack_weight_reduce') != 0: # g.changeWeight(_f.get('hack_weight_reduce'), 'auto', 0, 0, 'auto') g.stroke("circular", _f.get('hack_weight_reduce'), 'butt', 'round', 'removeexternal') g = align_to_center(g) hack = modify_m(hack, _f.get('weight_name')) alternate_expands = [ 0x306e, ] if _f.get('mgen_weight_add') != 0: for g in cica.glyphs(): # g.changeWeight(_f.get('mgen_weight_add'), 'auto', 0, 0, 'auto') g.stroke("caligraphic", _f.get('mgen_weight_add'), _f.get('mgen_weight_add'), 45, 'removeinternal') # g.stroke("circular", _f.get('mgen_weight_add'), 'butt', 'round', 'removeinternal') ignoring_center = [ 0x3001, 0x3002, 0x3008, 0x3009, 0x300a, 0x300b, 0x300c, 0x300d, 0x300e, 0x300f, 0x3010, 0x3011, 0x3014, 0x3015, 0x3016, 0x3017, 0x3018, 0x3019, 0x301a, 0x301b, 0x301d, 0x301e, 0x3099, 0x309a, 0x309b, 0x309c, ] log('transform Mgen+') for g in cica.glyphs(): g.transform((0.91,0,0,0.91,0,0)) full_half_threshold = 700 if _f.get('italic'): g.transform(psMat.skew(0.25)) skew_amount = g.font.ascent * 0.91 * 0.25 g.width = g.width + skew_amount full_half_threshold += skew_amount if g.width > full_half_threshold: width = 1024 else: width = 512 g.transform(psMat.translate((width - g.width)/2, 0)) g.width = width if g.encoding in ignoring_center: pass else: g = align_to_center(g) log('modify border glyphs') for g in hack.glyphs(): if g.isWorthOutputting: if _f.get('italic'): g.transform(psMat.skew(0.25)) if g.encoding >= 0x2500 and g.encoding <= 0x257f: # 全角の罫線を0xf0000以降に退避 cica.selection.select(g.encoding) cica.copy() cica.selection.select(g.encoding + 0xf0000) cica.paste() if g.encoding >= 0x2500 and g.encoding <= 0x25af: g.transform(psMat.compose(psMat.scale(1.024, 1.024), psMat.translate(0, -30))) g = align_to_center(g) hack.selection.select(g.encoding) hack.copy() cica.selection.select(g.encoding) cica.paste() log('modify nerd glyphs') for g in nerd.glyphs(): if g.encoding < 0xe0a0 or g.encoding > 0xfd46: continue g = modify_nerd(g) nerd.selection.select(g.encoding) nerd.copy() if g.encoding >= 0xf500: # Material Design IconsはNerd Fontsに従うとアラビア文字等を壊して # しまうので、0xf0000〜に配置する cica.selection.select(g.encoding + 0xf0000) cica.paste() else: cica.selection.select(g.encoding) cica.paste() log('modify icons_for_devs glyphs') for g in icons_for_devs.glyphs(): if g.encoding < 0xe900 or g.encoding > 0xe950: continue g = modify_iconsfordevs(g) icons_for_devs.selection.select(g.encoding) icons_for_devs.copy() cica.selection.select(g.encoding) cica.paste() cica = fix_box_drawings_block_elements(cica) cica = zenkaku_space(cica) cica = zero(cica) cica = modify_WM(cica) cica = vertical_line_to_broken_bar(cica) cica = emdash_to_broken_dash(cica) cica = reiwa(cica, _f.get('weight_name')) cica = add_gopher(cica) cica = modify_ellipsis(cica) if emoji: cica = add_notoemoji(cica) cica = add_smalltriangle(cica) cica = add_dejavu(cica, _f) cica = resize_supersub(cica) log("fix_overflow()") for g in cica.glyphs(): g = fix_overflow(g) log("import_svg()") cica = import_svg(cica) cica.ascent = ASCENT cica.descent = DESCENT cica.upos = 45 cica.fontname = _f.get('family') cica.familyname = _f.get('family') cica.fullname = _f.get('name') cica.weight = _f.get('weight_name') cica = set_os2_values(cica, _f) cica.appendSFNTName(0x411,0, COPYRIGHT) cica.appendSFNTName(0x411,1, _f.get('family')) cica.appendSFNTName(0x411,2, _f.get('style_name')) # cica.appendSFNTName(0x411,3, "") cica.appendSFNTName(0x411,4, _f.get('name')) cica.appendSFNTName(0x411,5, "Version " + VERSION) cica.appendSFNTName(0x411,6, _f.get('family') + "-" + _f.get('weight_name')) # cica.appendSFNTName(0x411,7, "") # cica.appendSFNTName(0x411,8, "") # cica.appendSFNTName(0x411,9, "") # cica.appendSFNTName(0x411,10, "") # cica.appendSFNTName(0x411,11, "") # cica.appendSFNTName(0x411,12, "") cica.appendSFNTName(0x411,13, LICENSE) # cica.appendSFNTName(0x411,14, "") # cica.appendSFNTName(0x411,15, "") cica.appendSFNTName(0x411,16, _f.get('family')) cica.appendSFNTName(0x411,17, _f.get('style_name')) cica.appendSFNTName(0x409,0, COPYRIGHT) cica.appendSFNTName(0x409,1, _f.get('family')) cica.appendSFNTName(0x409,2, _f.get('style_name')) cica.appendSFNTName(0x409,3, VERSION + ";" + _f.get('family') + "-" + _f.get('style_name')) cica.appendSFNTName(0x409,4, _f.get('name')) cica.appendSFNTName(0x409,5, "Version " + VERSION) cica.appendSFNTName(0x409,6, _f.get('name')) # cica.appendSFNTName(0x409,7, "") # cica.appendSFNTName(0x409,8, "") # cica.appendSFNTName(0x409,9, "") # cica.appendSFNTName(0x409,10, "") # cica.appendSFNTName(0x409,11, "") # cica.appendSFNTName(0x409,12, "") cica.appendSFNTName(0x409,13, LICENSE) # cica.appendSFNTName(0x409,14, "") # cica.appendSFNTName(0x409,15, "") cica.appendSFNTName(0x409,16, _f.get('family')) cica.appendSFNTName(0x409,17, _f.get('style_name')) if emoji: fontpath = './dist/%s' % _f.get('filename') else: fontpath = './dist/noemoji/%s' % _f.get('filename') cica.generate(fontpath) cica.close() hack.close() nerd.close() icons_for_devs.close()
font.removeOverlap() for i in font: glyph = font[i] if len(glyph.references) > 0 and len(glyph.layers["Fore"]) > 0: # a mixed glyph glyph.unlinkRef() glyph.removeOverlap() if len(sys.argv) <= 3: font.selection.all() font.replaceWithReference(2) font.selection.select(("ranges", "unicode", None), 0x20, 0x7e) font.unlinkReferences() # Outline simplify print "Simplify, pass 1: ", font.fontname font.layers["Fore"].is_quadratic = False font.selection.all() font.simplify(font.em / 1000.0 * 0.75, ("smoothcurves", "choosehv"), 0.1) print "Simplify, pass 2: ", font.fontname oldem = font.em font.em = 1000 font.layers["Fore"].is_quadratic = True font.transform(psMat.skew(-font.italicangle / 180 * math.pi)) # Feature merging and output print "Finalize: ", font.fontname font.em = oldem font.canonicalContours() font.canonicalStart() font.generate(sys.argv[2])
#!/usr/bin/env fontforge import fontforge, psMat from sys import argv, stderr from os import system from math import radians if len(argv) < 4: stderr.write("Usage: " + argv[0] + " skew-flag infile outfile\n") quit(1) fontforge.setPrefs('CoverageFormatsAllowed', 1) font = fontforge.open(argv[2]) for glyph in font.glyphs(): if glyph.isWorthOutputting(): width = glyph.width glyph.transform(psMat.translate(-font.em / 2, 0)) glyph.transform(psMat.scale(0.8, 1.0)) if int(argv[1]): glyph.transform(psMat.rotate(radians(90))) glyph.transform(psMat.skew(radians(-4))) glyph.transform(psMat.rotate(radians(-90))) glyph.transform(psMat.translate(font.em / 2, 0)) glyph.width = width font.save(argv[3]) font.close()
def italicSkew(deg): return psMat.skew(italicAngleRad(deg))
logger.addHandler(handler) # ASCENT = 850 # DESCENT = 174 ASCENT = 1638 DESCENT = 410 #ASCENT = 819 #DESCENT = 205 SOURCE = './sourceFonts' LICENSE = open('./LICENSE.font.txt').read() LICENSE_URL = "http://scripts.sil.org/OFL" COPYRIGHT = open('./COPYRIGHT.txt').read() VERSION = '2.0.1' FAMILY = 'Ocami' ITALIC_ANGLE = -9 ITALIC_SKEW = psMat.skew(-ITALIC_ANGLE / 180.0 * math.pi) ITALIC_SHIFT = math.tan(-ITALIC_ANGLE / 180.0 * math.pi) * 0.5 source_info = { "IBMPlexMono": { "base": "IBMPlexMono-", "weights": [ "Thin", "ExtraLight", "Light", "Regular", "Text", "Medium", "SemiBold", "Bold",
base_font.generate("otf/"+base_font.fontname+".otf") base_font.printSample("fontdisplay", 24, "", "specimens/"+base_font.fontname+".pdf") base_font.close() print("Generated condensed") ## italic base_font = fontforge.open("sfd/14seg-gen.sfd") base_font.selection.all() matrix = psMat.skew(math.radians(12.5)) base_font.transform(matrix) base_font.italicangle = -12.5 base_font.fullname = "LCD Display: 14 Segment (Italic)" base_font.fontname = "LCD14Italic" base_font.os2_stylemap = 0b1000000001 # italic https://www.microsoft.com/typography/otspec/os2.htm base_font.save("sfd/14seg-italic.sfd") base_font.generate("otf/"+base_font.fontname+".otf")
import psMat, math import itgFontLib sourcefile = sys.argv[1] destfile = sys.argv[2] font = fontforge.open (sourcefile) itgFontLib.fontPreProcessing( font ) font.uniqueid += 1 itgFontLib.removeRefsIf( font, itgFontLib.isFlippedOrRotatedRef ) slantAngle = 75-90 transformation = psMat.skew ( math.radians (-slantAngle) ) font.italicangle = slantAngle font.macstyle = 2 font.selection.none () font.selection.select (['more', 'unicode', 'singletons'], 0x2031, 0x20DD, 0x26AC, 0x030A, 0x2300, 0x2332, 0x2218, 0x2219, 0x2316, 0x232D, 0x23E5, 0x27C2) font.selection.select (['more', 'singletons'], 'percent', 'perthousand', 'slash', 'degree', 'copyright', 'registered', 'perpendicular') font.selection.select (['more', 'unicode', 'ranges'], 0x2500, 0x25FF) for glyph in font.selection.byGlyphs: glyph.horizontalComponentItalicCorrection = 0 glyph.italicCorrection = 0 bounds = glyph.boundingBox() dx = fontforge.point(0, bounds[3]+50).transform(transformation).x glyph.transform ( psMat.translate( dx, 0 ), ['partialRefs', None] ) font.selection.select (['more', 'singletons'], '.notdef', '.null', 'nonmarkingreturn')
def italic_skew(deg): return psMat.skew(italic_angle_rad(deg))
font.selection.select(("less", "ranges"), "lighy.fr", "lighy.cc", "ligeq.fr", "ligeq.cc") font.replaceWithReference() # Remove overlapped area font.selection.all() font.removeOverlap() for i in font: glyph = font[i] if len(glyph.references) > 0 and len(glyph.layers["Fore"]) > 0: # a mixed glyph glyph.unlinkRef() glyph.removeOverlap() font.selection.all() font.simplify(0.05, ("smoothcurves", "choosehv"), 0.1) #font.em = 2000 font.selection.all() font.layers["Fore"].is_quadratic = True font.transform(psMat.skew(float(sys.argv[4]) / 180 * math.pi)) font.em = 1000 font.selection.all() font.round() font.removeOverlap() font.simplify(0.01) font.selection.all() font.removeOverlap() font.canonicalContours() font.canonicalStart() font.generate(sys.argv[3], flags = ("opentype"))
import psMat, math import itgFontLib sourcefile = sys.argv[1] destfile = sys.argv[2] font = fontforge.open(sourcefile) itgFontLib.fontPreProcessing(font) font.uniqueid += 1 itgFontLib.removeRefsIf(font, itgFontLib.isFlippedOrRotatedRef) slantAngle = 75 - 90 transformation = psMat.skew(math.radians(-slantAngle)) font.italicangle = slantAngle font.macstyle = 2 font.selection.none() font.selection.select(['more', 'unicode', 'singletons'], 0x2031, 0x20DD, 0x26AC, 0x030A, 0x2300, 0x2332, 0x2218, 0x2219, 0x2316, 0x232D, 0x23E5, 0x27C2) font.selection.select(['more', 'singletons'], 'percent', 'perthousand', 'slash', 'degree', 'copyright', 'registered', 'perpendicular') font.selection.select(['more', 'unicode', 'ranges'], 0x2500, 0x25FF) for glyph in font.selection.byGlyphs: glyph.horizontalComponentItalicCorrection = 0 glyph.italicCorrection = 0
cyrLetters = cyrCapitalLetters + cyrSmallLetters cyrAllLetters = cyrAllCapitalLetters + cyrAllSmallLetters greekCapitalLetters = glyphNamesInRange( font, xrange( 0x0391, 0x03A9 + 1 ) ) greekAllCapitalLetters = greekCapitalLetters greekSmallLetters = glyphNamesInRange( font, xrange( 0x03B1, 0x03C9 + 1 ) ) greekAllSmallLetters = greekSmallLetters greekLetters = greekCapitalLetters + greekSmallLetters greekAllLetters = greekAllCapitalLetters + greekAllSmallLetters allLetters = cyrAllLetters + latinAllLetters + greekAllLetters punctuation = [ 'period', 'comma' ] italicangle = font.italicangle deitalize = psMat.skew ( math.radians( italicangle ) ) for glyph in font.glyphs(): glyph.unlinkRef () glyph.transform ( deitalize ) glyph.italicCorrection = 0 glyph.horizontalComponentItalicCorrection = 0 font.italicangle = 0 font.addKerningClass( kernLookup, 'numbers_kerning', kernSize, classDiff, allDigits + digitSeparators, allDigits + digitSeparators + allDigitsSub + allDigitsSup + ordGlyphs + percents + degree + primes + rightBrackets, onlyCloser, True ) font.addKerningClass( kernLookup, 'latin_kerning', kernSize, classDiff,
#!/usr/bin/env fontforge import fontforge, psMat from sys import argv, stderr from os import system from math import radians if len(argv) < 4: stderr.write("Usage: "+argv[0]+" skew-flag infile outfile\n") quit(1) fontforge.setPrefs('CoverageFormatsAllowed', 1) font = fontforge.open(argv[2]) for glyph in font.glyphs(): if glyph.isWorthOutputting(): width = glyph.width glyph.transform(psMat.translate(-font.em / 2, 0)) glyph.transform(psMat.scale(0.8, 1.0)) if int(argv[1]): glyph.transform(psMat.rotate(radians(90))) glyph.transform(psMat.skew(radians(-4))) glyph.transform(psMat.rotate(radians(-90))) glyph.transform(psMat.translate(font.em / 2, 0)) glyph.width = width font.save(argv[3]) font.close()
cyrLetters = cyrCapitalLetters + cyrSmallLetters cyrAllLetters = cyrAllCapitalLetters + cyrAllSmallLetters greekCapitalLetters = glyphNamesInRange(font, xrange(0x0391, 0x03A9 + 1)) greekAllCapitalLetters = greekCapitalLetters greekSmallLetters = glyphNamesInRange(font, xrange(0x03B1, 0x03C9 + 1)) greekAllSmallLetters = greekSmallLetters greekLetters = greekCapitalLetters + greekSmallLetters greekAllLetters = greekAllCapitalLetters + greekAllSmallLetters allLetters = cyrAllLetters + latinAllLetters + greekAllLetters punctuation = ['period', 'comma'] italicangle = font.italicangle deitalize = psMat.skew(math.radians(italicangle)) for glyph in font.glyphs(): glyph.unlinkRef() glyph.transform(deitalize) glyph.italicCorrection = 0 glyph.horizontalComponentItalicCorrection = 0 font.italicangle = 0 font.addKerningClass( kernLookup, 'numbers_kerning', kernSize, classDiff, allDigits + digitSeparators, allDigits + digitSeparators + allDigitsSub + allDigitsSup + ordGlyphs + percents + degree + primes + rightBrackets, onlyCloser, True) font.addKerningClass( kernLookup, 'latin_kerning', kernSize, classDiff, latinAllLetters, latinAllLetters + punctuation + allDigits + allDigitsSub + allDigitsSup +
def build_font(_f, emoji): log('Generating %s ...' % _f.get('weight_name')) hack = fontforge.open('./sourceFonts/%s' % _f.get('hack')) hack = remove_glyph_from_hack(hack) cica = fontforge.open('./sourceFonts/%s' % _f.get('mgen_plus')) nerd = fontforge.open('./sourceFonts/nerd.ttf') for g in hack.glyphs(): g.transform((0.42, 0, 0, 0.42, 0, 0)) if _f.get('hack_weight_reduce') != 0: # g.changeWeight(_f.get('hack_weight_reduce'), 'auto', 0, 0, 'auto') g.stroke("circular", _f.get('hack_weight_reduce'), 'butt', 'round', 'removeexternal') g = align_to_center(g) hack = modify_m(hack, _f.get('weight_name')) alternate_expands = [ 0x306e, ] if _f.get('mgen_weight_add') != 0: for g in cica.glyphs(): # g.changeWeight(_f.get('mgen_weight_add'), 'auto', 0, 0, 'auto') g.stroke("caligraphic", _f.get('mgen_weight_add'), _f.get('mgen_weight_add'), 45, 'removeinternal') # g.stroke("circular", _f.get('mgen_weight_add'), 'butt', 'round', 'removeinternal') ignoring_center = [ 0x3001, 0x3002, 0x3008, 0x3009, 0x300a, 0x300b, 0x300c, 0x300d, 0x300e, 0x300f, 0x3010, 0x3011, 0x3014, 0x3015, 0x3016, 0x3017, 0x3018, 0x3019, 0x301a, 0x301b, 0x301d, 0x301e, 0x3099, 0x309a, 0x309b, 0x309c, ] for g in cica.glyphs(): g.transform((0.91, 0, 0, 0.91, 0, 0)) full_half_threshold = 700 if _f.get('italic'): g.transform(psMat.skew(0.25)) skew_amount = g.font.ascent * 0.91 * 0.25 g.width = g.width + skew_amount full_half_threshold += skew_amount if g.width > full_half_threshold: width = 1024 else: width = 512 g.transform(psMat.translate((width - g.width) / 2, 0)) g.width = width if g.encoding in ignoring_center: pass else: g = align_to_center(g) for g in hack.glyphs(): if g.isWorthOutputting: if _f.get('italic'): g.transform(psMat.skew(0.25)) if g.encoding >= 0x2500 and g.encoding <= 0x25af: g.transform( psMat.compose(psMat.scale(1.024, 1.024), psMat.translate(0, -30))) g = align_to_center(g) hack.selection.select(g.encoding) hack.copy() cica.selection.select(g.encoding) cica.paste() for g in nerd.glyphs(): if g.encoding < 0xe0a0 or g.encoding > 0xf4ff: continue g = modify_nerd(g) nerd.selection.select(g.encoding) nerd.copy() cica.selection.select(g.encoding) cica.paste() cica = fix_box_drawings(cica) cica = zenkaku_space(cica) cica = zero(cica) cica = modify_WM(cica) cica = vertical_line_to_broken_bar(cica) cica = emdash_to_broken_dash(cica) cica = add_gopher(cica) if emoji: cica = add_notoemoji(cica) cica = add_smalltriangle(cica) cica = add_dejavu(cica, _f) cica = resize_supersub(cica) cica.ascent = ASCENT cica.descent = DESCENT cica.upos = 45 cica.fontname = _f.get('family') cica.familyname = _f.get('family') cica.fullname = _f.get('name') cica.weight = _f.get('weight_name') cica = set_os2_values(cica, _f) cica.appendSFNTName(0x411, 0, COPYRIGHT) cica.appendSFNTName(0x411, 1, _f.get('family')) cica.appendSFNTName(0x411, 2, _f.get('style_name')) # cica.appendSFNTName(0x411,3, "") cica.appendSFNTName(0x411, 4, _f.get('name')) cica.appendSFNTName(0x411, 5, "Version " + VERSION) cica.appendSFNTName(0x411, 6, _f.get('family') + "-" + _f.get('weight_name')) # cica.appendSFNTName(0x411,7, "") # cica.appendSFNTName(0x411,8, "") # cica.appendSFNTName(0x411,9, "") # cica.appendSFNTName(0x411,10, "") # cica.appendSFNTName(0x411,11, "") # cica.appendSFNTName(0x411,12, "") cica.appendSFNTName(0x411, 13, LICENSE) # cica.appendSFNTName(0x411,14, "") # cica.appendSFNTName(0x411,15, "") cica.appendSFNTName(0x411, 16, _f.get('family')) cica.appendSFNTName(0x411, 17, _f.get('style_name')) cica.appendSFNTName(0x409, 0, COPYRIGHT) cica.appendSFNTName(0x409, 1, _f.get('family')) cica.appendSFNTName(0x409, 2, _f.get('style_name')) cica.appendSFNTName( 0x409, 3, VERSION + ";" + _f.get('family') + "-" + _f.get('style_name')) cica.appendSFNTName(0x409, 4, _f.get('name')) cica.appendSFNTName(0x409, 5, "Version " + VERSION) cica.appendSFNTName(0x409, 6, _f.get('name')) # cica.appendSFNTName(0x409,7, "") # cica.appendSFNTName(0x409,8, "") # cica.appendSFNTName(0x409,9, "") # cica.appendSFNTName(0x409,10, "") # cica.appendSFNTName(0x409,11, "") # cica.appendSFNTName(0x409,12, "") cica.appendSFNTName(0x409, 13, LICENSE) # cica.appendSFNTName(0x409,14, "") # cica.appendSFNTName(0x409,15, "") cica.appendSFNTName(0x409, 16, _f.get('family')) cica.appendSFNTName(0x409, 17, _f.get('style_name')) if emoji: fontpath = './dist/%s' % _f.get('filename') else: fontpath = './dist/noemoji/%s' % _f.get('filename') cica.generate(fontpath) cica.close() hack.close() nerd.close()
def skew(radiant): return compose(psMat.translate(-halfsize, -middle), psMat.skew(radiant), psMat.translate(halfsize, middle))
def _make_oblique(font): mat = psMat.skew(OBLIQUE_SKEW) font.selection.all() font.transform(mat) font.removeOverlap()
# if g.unicode not in unique_unicodes: # unique_unicodes[g.unicode] = 0 # continue #glyph_decimal_code = unique_unicodes[g.unicode] print("unicode = ", g.unicode) #Only include the glyphs unicodes in the 22 classes if g.unicode not in include_list: continue intrinsic_glyph_decimal_code = g.unicode list_of_files = [] #Export the unicode glyph as bmp file g.export(path + os.path.basename(i) + '-orig-' + str(g.unicode) + '.bmp') #Perform the transformations like skew rotate and translate g.transform( psMat.skew(.0523599)).export(path + os.path.basename(i) + '-skew-' + str(g.unicode) + '.bmp') list_of_files.append(path + os.path.basename(i) + '-orig-' + str(g.unicode) + '.bmp') list_of_files.append(path + os.path.basename(i) + '-skew-' + str(g.unicode) + '.bmp') g.transform(psMat.rotate(.0523599)).export(path + os.path.basename(i) + '-rotate-' + str(g.unicode) + '.bmp') list_of_files.append(path + os.path.basename(i) + '-rotate-' + str(g.unicode) + '.bmp') g.transform(psMat.translate( 1, 1)).export(path + os.path.basename(i) + '-translate-' + str(g.unicode) + '.bmp')