def modify_ellipsis(_f): """3点リーダーを半角にする DejaVuSansMono の U+22EF(⋯) をU+2026(…)、U+22EE(⋮)、U+22F0(⋰)、U+22F1(⋱) にコピーした上で回転させて生成 三点リーダの文字幅について · Issue #41 · miiton/Cica https://github.com/miiton/Cica/issues/41 """ _f.selection.select(0x22ef) _f.copy() _f.selection.select(0x2026) _f.paste() _f.selection.select(0x22ee) _f.paste() _f.selection.select(0x22f0) _f.paste() _f.selection.select(0x22f1) _f.paste() for g in _f.glyphs("encoding"): if g.encoding < 0x22ee: continue elif g.encoding > 0x22f1: break elif g.encoding == 0x22ee: bb = g.boundingBox() cx = (bb[2] + bb[0]) / 2 cy = (bb[3] + bb[1]) / 2 trcen = psMat.translate(-cx, -cy) rotcen = psMat.compose( trcen, psMat.compose(psMat.rotate(math.radians(90)), psMat.inverse(trcen))) g.transform(rotcen) elif g.encoding == 0x22f0: bb = g.boundingBox() cx = (bb[2] + bb[0]) / 2 cy = (bb[3] + bb[1]) / 2 trcen = psMat.translate(-cx, -cy) rotcen = psMat.compose( trcen, psMat.compose(psMat.rotate(math.radians(45)), psMat.inverse(trcen))) g.transform(rotcen) elif g.encoding == 0x22f1: bb = g.boundingBox() cx = (bb[2] + bb[0]) / 2 cy = (bb[3] + bb[1]) / 2 trcen = psMat.translate(-cx, -cy) rotcen = psMat.compose( trcen, psMat.compose(psMat.rotate(math.radians(-45)), psMat.inverse(trcen))) g.transform(rotcen) return _f
def geometric_triangle(rotation=0, black=True): sw = 46 xm = 37 b = bb + (bh - bw + 2 * xm) / 2.0 t = b + (bw - 2 * xm) * math.sin(math.pi / 3) contours = [] c = fontforge.contour() c.moveTo(bl + xm, b) c.lineTo(cx, t) c.lineTo(br - xm, b) c.closed = True contours.append(c) if not black: xm += sw * math.sqrt(3) c = fontforge.contour() c.moveTo(bl + xm, b + sw) c.lineTo(br - xm, b + sw) c.lineTo(cx, t - 2 * sw) c.closed = True contours.append(c) if rotation: cy = (b + t) / 2.0 rotT = psMat.compose(psMat.translate(-cx, -cy), psMat.compose(psMat.rotate(rotation), psMat.translate(cx, cy))) for c in contours: c.transform(rotT) return contours
def misc(out, noto): glyph = mvGlyph(out, noto, "℘") xform = compose( aroundCentroid(glyph, mat.scale(0.78, 1)), moveToCenter(glyph), ) glyph.transform(xform, ('round', )) glyph.width, glyph.vwidth = monosize mvGlyph(out, noto, "ϰ") mvGlyph(out, out, "ϵ", "є") mvGlyph(out, out, "⋅", "∙") glyph = mvGlyph(out, out, "∓", "±") xform = aroundCentroid(glyph, mat.scale(1, -1)) glyph.transform(xform, ('round', )) glyph = mvGlyph(out, out, "⅋", "&") xform = aroundCentroid(glyph, mat.rotate(math.pi)) glyph.transform(xform, ('round', )) glyph = mvGlyph(out, out, "⊥", "⊤") xform = aroundCentroid(glyph, mat.scale(1, -1)) glyph.transform(xform, ('round', )) glyph = mvGlyph(out, out, "∇", "Δ") xform = aroundCentroid(glyph, mat.scale(1, -1)) glyph.transform(xform, ('round', )) glyph = mvGlyph(out, out, "≕", "≔") xform = aroundCentroid(glyph, mat.scale(-1, 1)) glyph.transform(xform, ('round', )) mvGlyph(out, noto, "⋈") mvGlyph(out, noto, "⋉") mvGlyph(out, noto, "⋊")
def modify_WM(_f): _f.selection.select(0x57) _f.transform(psMat.scale(0.95, 1.0)) _f.copy() _f.selection.select(0x4d) _f.paste() _f.transform(psMat.compose(psMat.rotate(math.radians(180)), psMat.translate(0, 627))) for g in _f.selection.byGlyphs: g = align_to_center(g) return _f
def dozenal(font, scp): scp.selection.select(("ranges", ), ord("2"), ord("3")) scp.copy() font.selection.select(("ranges", ), ord("↊"), ord("↋")) font.paste() # rotate two to dek dek = font[ord('↊')] xform = aroundCentroid(dek, mat.rotate(math.pi)) dek.transform(compose( xform, mat.scale(1, 0.96), mat.translate(0, -12), ), ('round', )) dek.width, dek.vwidth = monosize # rotate three to el el = font[ord('↋')] xform = aroundCentroid(el, mat.rotate(math.pi)) el.transform(compose( xform, mat.scale(1, 0.96), ), ('round', )) el.width, el.vwidth = monosize
def add_smalltriangle(_f): _f.selection.select(0x25bc) _f.copy() _f.selection.select(0x25be) _f.paste() _f.transform(psMat.compose(psMat.scale(0.64), psMat.translate(0, 68))) _f.copy() _f.selection.select(0x25b8) _f.paste() _f.transform(psMat.rotate(math.radians(90))) for g in _f.glyphs(): if g.encoding == 0x25be or g.encoding == 0x25b8: g.width = 512 g = align_to_center(g) return _f
def add_smalltriangle(_font): _font.selection.select(0x25bc) # ▼ BLACK DOWN-POINTING TRIANGLE _font.copy() _font.selection.select(0x25be) # ▾ BLACK DOWN-POINTING SMALL TRIANGLE _font.paste() _font.transform(psMat.compose(psMat.scale(0.64), psMat.translate(0, 68))) _font.copy() _font.selection.select(0x25b8) # ▸ BLACK RIGHT-POINTING SMALL TRIANGLE _font.paste() _font.transform(psMat.rotate(math.radians(90))) for g in _font.glyphs(): if g.encoding == 0x25be or g.encoding == 0x25b8: g.width = WIDTH // 2 g.left_side_bearing = g.right_side_bearing = int( (g.left_side_bearing + g.right_side_bearing) / 2) g.width = WIDTH // 2 return _font
def set_vbearings_line(line): splitted = line.split() ch, method = splitted[0:2] h2v_shift = splitted[2:] c = get_glyph_by_name(ch) f.selection.select(c) f.copy() tag = 'vert' name = c.glyphname tagged_name = "%s.%s" % (name, tag) n = get_glyph_by_name(tagged_name) f.selection.select(n) alt_path = "../../../splitted/%s/%s/vert/u%04X.svg" % ( weight, mod, c.unicode) if os.path.exists(alt_path): n.clear() n.importOutlines(alt_path, ('removeoverlap', 'correctdir')) else: f.paste() if method.find('R') >= 0: rot = psMat.compose( psMat.translate(-em / 2, -ascent + em / 2), psMat.compose(psMat.rotate(-math.pi / 2), psMat.translate(em / 2, ascent - em / 2))) n.transform(rot) if method.find('F') >= 0: flip = psMat.compose( psMat.translate(-em / 2, -ascent + em / 2), psMat.compose(psMat.scale(-1, 1), psMat.translate(em / 2, ascent - em / 2))) n.transform(flip) elif method == 'S': position = weights_position[weight] * 2 x, y = h2v_shift[position:position + 2] sht = psMat.translate(int(x), int(y)) n.transform(sht) n.width = em n.vwidth = em if not (tag in alt_glyphs): alt_glyphs[tag] = [] alt_glyphs[tag].append((name, tagged_name))
def rotate_glyph(Glyph): matrix = psMat.rotate(pi / 2) Glyph.transform(matrix)
def arrows(font, dejavu): sideArrs = "←→↔↚↛↮" \ + "⇐⇒⇔⇍⇏⇎" \ + "↜↝↭⇜⇝" \ + "↞↠↼⇀" \ + "⇤⇥⟜⊸⧟" \ + "↢↣↩↪↤↦" \ + "⤆⤇" \ + "⤙⤚⤛⤜" tallArrs = "↑↓↕⇑⇓⇕" \ + "↟↡↾⇂" \ + "⤒⤓⫯⫰↥↧" for c in sideArrs: if ord(c) in dejavu: dejavu.selection.select(("singletons", ), ord(c)) dejavu.copy() font.selection.select(("singletons", ), ord(c)) font.paste() glyph = font[ord(c)] xform = mat.scale(monosize[0] / glyph.width) glyph.transform(xform, ('round', )) xFront, _, xBack, _ = glyph.layers[1].boundingBox() xform = aroundCentroid( glyph, mat.scale(glyph.width / (xBack - xFront + 20))) # xform = mat.translate(10 - xFront) glyph.transform(xform, ('round', )) glyph.width, glyph.vwidth = monosize for c in tallArrs: if ord(c) in dejavu: dejavu.selection.select(("singletons", ), ord(c)) dejavu.copy() font.selection.select(("singletons", ), ord(c)) font.paste() glyph = font[ord(c)] _, yBot, _, yTop = glyph.layers[1].boundingBox() xform = mat.scale(monosize[0] / (yTop - yBot)) glyph.transform(xform, ('round', )) xform = moveToCenter(glyph) glyph.transform(xform, ('round', )) glyph.width, glyph.vwidth = monosize glyph = mvGlyph(font, font, '⫯', '⊸') xform = aroundCentroid(glyph, mat.rotate(math.pi / 2)) glyph.transform(xform, ('round', )) glyph = mvGlyph(font, font, '⫰', '⫯') xform = aroundCentroid(glyph, mat.scale(1, -1)) glyph.transform(xform, ('round', )) glyph = mvGlyph(font, font, '⤓', '⤒') xform = aroundCentroid(glyph, mat.scale(1, -1)) glyph.transform(xform, ('round', )) glyph.width, glyph.vwidth = monosize glyph = mvGlyph(font, font, '⤆', '⤇') xform = aroundCentroid(glyph, mat.scale(-1, 1)) glyph.transform(xform, ('round', )) glyph = mvGlyph(font, font, '⤙', '⤚') xform = aroundCentroid(glyph, mat.scale(-1, 1)) glyph.transform(xform, ('round', )) glyph.width, glyph.vwidth = monosize glyph = mvGlyph(font, font, '⤛', '⤜') xform = aroundCentroid(glyph, mat.scale(-1, 1)) glyph.transform(xform, ('round', )) glyph.width, glyph.vwidth = monosize
html.write('<tr>\n') html.write('<td><i class="fa fa-' + options[0] + ' fa-2x"></i></td>\n') circle = font['minus'] font.selection.select('minus') font.copy() font.selection.select(("unicode", None), workbench_char) font.paste() x = (font[icon].boundingBox()[2] - font[icon].boundingBox()[0]) / 2.0 y = (font[icon].boundingBox()[3] - font[icon].boundingBox()[1]) / 2.0 s = psMat.scale(1.7, 0.5) font[workbench_char].transform(s) r = psMat.rotate(3.1415926535 / 4.0) font[workbench_char].transform(r) t = psMat.translate(x - 500, y - 1400) font[workbench_char].transform(t) font.selection.select(("unicode", None), workbench_char) font.copy() font.selection.select(("unicode", None), cur_unicode) font.paste() t = psMat.translate(-160, 120) font[workbench_char].transform(t) font.selection.select(("unicode", None), workbench_char) font.copy()
pfote.comment = u'Gerne den Vorschlag von Christine Fraunhofer hier umgesetzt!' pen = pfote.glyphPen() for i, cnts in enumerate(contours): for x, cnt in enumerate(cnts): if x == 0: pen.moveTo(cnt[0], cnt[1]) else: pen.curveTo((cnt[0], cnt[1]), (cnt[2], cnt[3]), (cnt[4], cnt[5])) if x == (len(cnts) - 1): pen.closePath() pen = None # Nun Einzelpfote kopieren, drehen ändern und ein weiteres Zeichen erstellen. pfote.left_side_bearing = pfote.right_side_bearing = 120 t1 = psMat.compose(psMat.rotate(math.radians(2)), psMat.translate(0, -50)) t2 = psMat.compose(psMat.scale(0.95), psMat.translate(-1500, -500)) t3 = psMat.compose(psMat.scale(0.9), psMat.translate(-3000, -100)) t4 = psMat.compose(psMat.scale(0.85), psMat.translate(-4500, -600)) pfotelig = font.createChar(0xF2740, 'pfote.lig') pfotelig.addReference("pfote", t1) pfotelig.addReference("pfote", t2) pfotelig.addReference("pfote", t3) pfotelig.addReference("pfote", t4) pfotelig.unlinkRef pfotelig.left_side_bearing = pfotelig.right_side_bearing = 240 pfotelig.comment = u'Hier wurde die Pfote aus "pfote" übernommen, vervielfältigt und transformiert.' # Weitere Methode zur Einbettung eines Zeichens: # SVG inline + tempfile svg_notdef = '''<?xml version="1.0" encoding="UTF-8"?>
#!/usr/bin/env fontforge from sys import argv, stderr import fontforge, psMat, math if len(argv) < 3: stderr.write("Usage: %s in-sfd out-sfd\n" % argv[0]) exit(1) fontforge.setPrefs('CoverageFormatsAllowed', 1) font = fontforge.open(argv[1]) font.hasvmetrics = True for glyph in font.glyphs(): if glyph.isWorthOutputting(): w = glyph.width glyph.transform(psMat.rotate(-(math.pi / 2.0))) glyph.transform(psMat.translate(font.descent, font.ascent)) glyph.width = font.em glyph.vwidth = w glyph.round() font.save(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 m_rotate(radiant): return m_compose(psMat.translate(-c_halfsize, -c_middle), psMat.rotate(radiant), psMat.translate(c_halfsize, c_middle))
def resize_supersub(_f): superscripts = [ { "src": 0x0031, "dest": 0x00b9 }, { "src": 0x0032, "dest": 0x00b2 }, { "src": 0x0033, "dest": 0x00b3 }, { "src": 0x0030, "dest": 0x2070 }, { "src": 0x0069, "dest": 0x2071 }, { "src": 0x0034, "dest": 0x2074 }, { "src": 0x0037, "dest": 0x2077 }, { "src": 0x0038, "dest": 0x2078 }, { "src": 0x0039, "dest": 0x2079 }, { "src": 0x002b, "dest": 0x207a }, { "src": 0x002d, "dest": 0x207b }, { "src": 0x003d, "dest": 0x207c }, { "src": 0x0028, "dest": 0x207d }, { "src": 0x0029, "dest": 0x207e }, { "src": 0x006e, "dest": 0x207f }, # ↓上付きの大文字 { "src": 0x0041, "dest": 0x1d2c }, { "src": 0x00c6, "dest": 0x1d2d }, { "src": 0x0042, "dest": 0x1d2e }, { "src": 0x0044, "dest": 0x1d30 }, { "src": 0x0045, "dest": 0x1d31 }, { "src": 0x018e, "dest": 0x1d32 }, { "src": 0x0047, "dest": 0x1d33 }, { "src": 0x0048, "dest": 0x1d34 }, { "src": 0x0049, "dest": 0x1d35 }, { "src": 0x004a, "dest": 0x1d36 }, { "src": 0x004b, "dest": 0x1d37 }, { "src": 0x004c, "dest": 0x1d38 }, { "src": 0x004d, "dest": 0x1d39 }, { "src": 0x004e, "dest": 0x1d3a }, ## ↓REVERSED N なのでNを左右反転させる必要あり { "src": 0x004e, "dest": 0x1d3b, "reversed": True }, { "src": 0x004f, "dest": 0x1d3c }, { "src": 0x0222, "dest": 0x1d3d }, { "src": 0x0050, "dest": 0x1d3e }, { "src": 0x0052, "dest": 0x1d3f }, { "src": 0x0054, "dest": 0x1d40 }, { "src": 0x0055, "dest": 0x1d41 }, { "src": 0x0057, "dest": 0x1d42 }, # ↓上付きの小文字 { "src": 0x0061, "dest": 0x1d43 }, { "src": 0x0250, "dest": 0x1d44 }, { "src": 0x0251, "dest": 0x1d45 }, { "src": 0x1d02, "dest": 0x1d46 }, { "src": 0x0062, "dest": 0x1d47 }, { "src": 0x0064, "dest": 0x1d48 }, { "src": 0x0065, "dest": 0x1d49 }, { "src": 0x0259, "dest": 0x1d4a }, { "src": 0x025b, "dest": 0x1d4b }, { "src": 0x025c, "dest": 0x1d4c }, { "src": 0x0067, "dest": 0x1d4d }, ## ↓TURNED i なので 180度回す必要あり { "src": 0x0069, "dest": 0x1d4e, "turned": True }, { "src": 0x006b, "dest": 0x1d4f }, { "src": 0x006d, "dest": 0x1d50 }, { "src": 0x014b, "dest": 0x1d51 }, { "src": 0x006f, "dest": 0x1d52 }, { "src": 0x0254, "dest": 0x1d53 }, { "src": 0x1d16, "dest": 0x1d54 }, { "src": 0x1d17, "dest": 0x1d55 }, { "src": 0x0070, "dest": 0x1d56 }, { "src": 0x0074, "dest": 0x1d57 }, { "src": 0x0075, "dest": 0x1d58 }, { "src": 0x1d1d, "dest": 0x1d59 }, { "src": 0x026f, "dest": 0x1d5a }, { "src": 0x0076, "dest": 0x1d5b }, { "src": 0x1d25, "dest": 0x1d5c }, { "src": 0x03b2, "dest": 0x1d5d }, { "src": 0x03b3, "dest": 0x1d5e }, { "src": 0x03b4, "dest": 0x1d5f }, { "src": 0x03c6, "dest": 0x1d60 }, { "src": 0x03c7, "dest": 0x1d61 }, { "src": 0x0056, "dest": 0x2c7d }, { "src": 0x0068, "dest": 0x02b0 }, { "src": 0x0266, "dest": 0x02b1 }, { "src": 0x006a, "dest": 0x02b2 }, { "src": 0x006c, "dest": 0x02e1 }, { "src": 0x0073, "dest": 0x02e2 }, { "src": 0x0078, "dest": 0x02e3 }, { "src": 0x0072, "dest": 0x02b3 }, { "src": 0x0077, "dest": 0x02b7 }, { "src": 0x0079, "dest": 0x02b8 }, { "src": 0x0063, "dest": 0x1d9c }, { "src": 0x0066, "dest": 0x1da0 }, { "src": 0x007a, "dest": 0x1dbb }, { "src": 0x0061, "dest": 0x00aa }, { "src": 0x0252, "dest": 0x1d9b }, { "src": 0x0255, "dest": 0x1d9d }, { "src": 0x00f0, "dest": 0x1d9e }, { "src": 0x025c, "dest": 0x1d9f }, { "src": 0x025f, "dest": 0x1da1 }, { "src": 0x0261, "dest": 0x1da2 }, { "src": 0x0265, "dest": 0x1da3 }, { "src": 0x0268, "dest": 0x1da4 }, { "src": 0x0269, "dest": 0x1da5 }, { "src": 0x026a, "dest": 0x1da6 }, { "src": 0x1d7b, "dest": 0x1da7 }, { "src": 0x029d, "dest": 0x1da8 }, { "src": 0x026d, "dest": 0x1da9 }, { "src": 0x1d85, "dest": 0x1daa }, { "src": 0x029f, "dest": 0x1dab }, { "src": 0x0271, "dest": 0x1dac }, { "src": 0x0270, "dest": 0x1dad }, { "src": 0x0272, "dest": 0x1dae }, { "src": 0x0273, "dest": 0x1daf }, { "src": 0x0274, "dest": 0x1db0 }, { "src": 0x0275, "dest": 0x1db1 }, { "src": 0x0278, "dest": 0x1db2 }, { "src": 0x0282, "dest": 0x1db3 }, { "src": 0x0283, "dest": 0x1db4 }, { "src": 0x01ab, "dest": 0x1db5 }, { "src": 0x0289, "dest": 0x1db6 }, { "src": 0x028a, "dest": 0x1db7 }, { "src": 0x1d1c, "dest": 0x1db8 }, { "src": 0x028b, "dest": 0x1db9 }, { "src": 0x028c, "dest": 0x1dba }, { "src": 0x0290, "dest": 0x1dbc }, { "src": 0x0291, "dest": 0x1dbd }, { "src": 0x0292, "dest": 0x1dbe }, { "src": 0x03b8, "dest": 0x1dbf }, ] subscripts = [{ "src": 0x0069, "dest": 0x1d62 }, { "src": 0x0072, "dest": 0x1d63 }, { "src": 0x0075, "dest": 0x1d64 }, { "src": 0x0076, "dest": 0x1d65 }, { "src": 0x03b2, "dest": 0x1d66 }, { "src": 0x03b3, "dest": 0x1d67 }, { "src": 0x03c1, "dest": 0x1d68 }, { "src": 0x03c6, "dest": 0x1d69 }, { "src": 0x03c7, "dest": 0x1d6a }, { "src": 0x006a, "dest": 0x2c7c }, { "src": 0x0030, "dest": 0x2080 }, { "src": 0x0031, "dest": 0x2081 }, { "src": 0x0032, "dest": 0x2082 }, { "src": 0x0033, "dest": 0x2083 }, { "src": 0x0034, "dest": 0x2084 }, { "src": 0x0035, "dest": 0x2085 }, { "src": 0x0036, "dest": 0x2086 }, { "src": 0x0037, "dest": 0x2087 }, { "src": 0x0038, "dest": 0x2088 }, { "src": 0x0039, "dest": 0x2089 }, { "src": 0x002b, "dest": 0x208a }, { "src": 0x002d, "dest": 0x208b }, { "src": 0x003d, "dest": 0x208c }, { "src": 0x0028, "dest": 0x208d }, { "src": 0x0029, "dest": 0x208e }, { "src": 0x0061, "dest": 0x2090 }, { "src": 0x0065, "dest": 0x2091 }, { "src": 0x006f, "dest": 0x2092 }, { "src": 0x0078, "dest": 0x2093 }, { "src": 0x0259, "dest": 0x2094 }, { "src": 0x0068, "dest": 0x2095 }, { "src": 0x006b, "dest": 0x2096 }, { "src": 0x006c, "dest": 0x2097 }, { "src": 0x006d, "dest": 0x2098 }, { "src": 0x006e, "dest": 0x2099 }, { "src": 0x0070, "dest": 0x209a }, { "src": 0x0073, "dest": 0x209b }, { "src": 0x0074, "dest": 0x209c }] for g in superscripts: _f.selection.select(g["src"]) _f.copy() _f.selection.select(g["dest"]) _f.paste() for g in subscripts: _f.selection.select(g["src"]) _f.copy() _f.selection.select(g["dest"]) _f.paste() for g in _f.glyphs("encoding"): if g.encoding > 0x2c7d: continue elif in_scripts(g.encoding, superscripts): if g.encoding == 0x1d5d or g.encoding == 0x1d61: g.transform(psMat.scale(0.70, 0.70)) elif g.encoding == 0x1d3b: g.transform(psMat.scale(0.75, 0.75)) g.transform( psMat.compose(psMat.scale(-1, 1), psMat.translate(g.width, 0))) elif g.encoding == 0x1d4e: g.transform(psMat.scale(0.75, 0.75)) g.transform(psMat.rotate(3.14159)) g.transform(psMat.translate(0, 512)) else: g.transform(psMat.scale(0.75, 0.75)) bb = g.boundingBox() g.transform(psMat.translate(0, 244)) align_to_center(g) elif in_scripts(g.encoding, subscripts): if g.encoding == 0x1d66 or g.encoding == 0x1d6a: g.transform(psMat.scale(0.70, 0.70)) else: g.transform(psMat.scale(0.75, 0.75)) bb = g.boundingBox() y = -144 if bb[1] < -60: # DESCENT - 144 y = -60 g.transform(psMat.translate(0, y)) align_to_center(g) return _f
#!/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 rotate(self, angle, offset=None): matrix = psMat.rotate(angle) self._object.transform(matrix)
def merge(args): arabic = fontforge.open(args.arabicfile) arabic.encoding = "Unicode" arabic.mergeFeature(args.feature_file) latin = fontforge.open(args.latinfile) latin.encoding = "Unicode" latin.em = arabic.em latin_locl = "" for glyph in latin.glyphs(): if glyph.color == 0xff0000: latin.removeGlyph(glyph) else: if glyph.glyphname in arabic: name = glyph.glyphname glyph.unicode = -1 glyph.glyphname = name + ".latin" if not latin_locl: latin_locl = "feature locl {lookupflag IgnoreMarks; script latn;" latin_locl += "sub %s by %s;" % (name, glyph.glyphname) arabic.mergeFonts(latin) if latin_locl: latin_locl += "} locl;" arabic.mergeFeatureString(latin_locl) for ch in [(ord(u'،'), "comma"), (ord(u'؛'), "semicolon")]: ar = arabic.createChar(ch[0], fontforge.nameFromUnicode(ch[0])) en = arabic[ch[1]] colon = arabic["colon"] ar.addReference(en.glyphname, psMat.rotate(math.radians(180))) delta = colon.boundingBox()[1] - ar.boundingBox()[1] ar.transform(psMat.translate(0, delta)) ar.left_side_bearing = en.right_side_bearing ar.right_side_bearing = en.left_side_bearing question_ar = arabic.createChar(ord(u'؟'), "uni061F") question_ar.addReference("question", psMat.scale(-1, 1)) question_ar.left_side_bearing = arabic["question"].right_side_bearing question_ar.right_side_bearing = arabic["question"].left_side_bearing # Set metadata arabic.version = args.version years = datetime.now().year == 2015 and 2015 or "2015-%s" % datetime.now().year arabic.copyright = ". ".join(["Portions copyright © %s, Khaled Hosny (<*****@*****.**>)", "Portions " + latin.copyright[0].lower() + latin.copyright[1:].replace("(c)", "©")]) arabic.copyright = arabic.copyright % years handle_cloned_glyphs(arabic) en = "English (US)" arabic.appendSFNTName(en, "Designer", "Khaled Hosny") arabic.appendSFNTName(en, "License URL", "http://scripts.sil.org/OFL") arabic.appendSFNTName(en, "License", 'This Font Software is licensed under the SIL Open Font License, Version 1.1. \ This Font Software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR \ CONDITIONS OF ANY KIND, either express or implied. See the SIL Open Font License \ for the specific language, permissions and limitations governing your use of \ this Font Software.') arabic.appendSFNTName(en, "Descriptor", "Mada is a geometric, unmodulted Arabic display typeface inspired by Cairo road signage.") arabic.appendSFNTName(en, "Sample Text", "صف خلق خود كمثل ٱلشمس إذ بزغت يحظى ٱلضجيع بها نجلاء معطار.") return arabic
def rotate_glyph(Glyph): matrix = psMat.rotate(pi/2) Glyph.transform(matrix)
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') list_of_files.append(path + os.path.basename(i) + '-translate-' + str(g.unicode) + '.bmp') g.transform(psMat.translate(1, 1)).transform( psMat.skew(.0523599)).export(path + os.path.basename(i) + '-translate-skew-' + str(g.unicode) + '.bmp')
fontName = sys.argv[1] ext = fontName.split('.')[-1] font = fontforge.open(fontName) minRads = -20 maxRads = 20 maxNrOfRandomPoints = 30 maxLength = 1000 maxWidth = 100 maxArea = 2000 minArea = -100 minScale = 10 for glyph in font.glyphs(): if random.randint(1, 10) % 3 == 0 and maxRads > minRads: matrix = psMat.rotate(math.radians(random.randint(minRads, maxRads))) glyph.transform(matrix) # glyph.nltransform('sin(x) * 500', 'y') pen = glyph.glyphPen(False) points = random.randint(1, maxNrOfRandomPoints) for p in range(points): x1 = random.randint(minArea, maxArea) y1 = random.randint(minArea, maxArea) pen.moveTo((x1, y1)) length = random.randint(int(maxLength / minScale), maxLength) width = random.randint(int(maxWidth / minScale), maxWidth) if random.randint(1, 10) % 2 == 0:
if output_html: html.write('<tr>\n') html.write('<td><i class="fa fa-'+options[0]+' fa-2x"></i></td>\n') circle = font['minus'] font.selection.select('minus') font.copy() font.selection.select(("unicode", None), workbench_char) font.paste() x = (font[icon].boundingBox()[2] - font[icon].boundingBox()[0]) / 2.0 y = (font[icon].boundingBox()[3] - font[icon].boundingBox()[1]) / 2.0 s = psMat.scale(1.7,0.5) font[workbench_char].transform(s) r = psMat.rotate(3.1415926535/4.0) font[workbench_char].transform(r) t = psMat.translate(x-500,y-1400) font[workbench_char].transform(t) font.selection.select(("unicode", None), workbench_char) font.copy() font.selection.select(("unicode", None), cur_unicode) font.paste() t = psMat.translate(-160,120) font[workbench_char].transform(t) font.selection.select(("unicode", None), workbench_char) font.copy()
def rotate(radiant): return compose(psMat.translate(-halfsize, -middle), psMat.rotate(radiant), psMat.translate(halfsize, middle))
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() srcFont.correctDirection() if proportionalFlag: for glyph in srcFont.selection.byGlyphs: if verticalFlag: glyph.transform(psMat.translate(0, srcFont.descent)) if glyph.color != 0xffff00: glyph.transform(psMat.rotate(pi / 2)) glyph.left_side_bearing = 50 glyph.right_side_bearing = 50 if verticalFlag: w = glyph.width glyph.transform(psMat.rotate(-pi / 2)) glyph.transform(psMat.translate(0, srcFont.ascent)) glyph.width = srcFont.em glyph.vwidth = w break except TypeError: pass else: stderr.write("Glyph ID " + str(gNum & 0x7fff) + " not found\n") srcGlyph.removeOverlap()
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() srcFont.correctDirection() if proportionalFlag: for glyph in srcFont.selection.byGlyphs: if verticalFlag: glyph.transform( psMat.translate(0, srcFont.descent)) if glyph.color != 0xffff00: glyph.transform(psMat.rotate(pi / 2)) try: glyph.left_side_bearing = 50 glyph.right_side_bearing = 50 except TypeError: glyph.left_side_bearing = 50L glyph.right_side_bearing = 50L if verticalFlag: w = glyph.width glyph.transform(psMat.rotate(-pi / 2)) glyph.transform( psMat.translate(0, srcFont.ascent)) glyph.width = srcFont.em glyph.vwidth = w break except TypeError:
#! /usr/bin/python """ Usage: python 2fontsin1.py fonte1.ufo fonte2.ufo fonte-out.ufo """ import fontforge import psMat import math import sys matrix = psMat.rotate(math.radians(45)) font1 = fontforge.open(sys.argv[1]) font2 = fontforge.open(sys.argv[2]) for glyph in font1.glyphs(): #glyph.wireframe(100, 300, -45) font1.selection.select(glyph.glyphname) font1.copy() font2.selection.select(glyph.glyphname) font2.pasteInto() font2.removeOverlap() font2.generate(sys.argv[3])