• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python
2
3import harfbuzz, optparse, sys
4from fontconfig import fcPattern
5
6usage = '''usage: %prog [options] codepoints
7    Generates output of glyphs and positions. Each entry is of the form:
8        glyphid>cluster@(offsetx,offsety)+(advancex,advancey)
9
10    codepoints is a space separated list of hex values of Unicode codepoints'''
11p = optparse.OptionParser(usage=usage)
12p.add_option('-s', '--size', default=32, type="int", help="point size")
13p.add_option('-l', '--lang', help="language code")
14p.add_option('-c', '--script', help="script code")
15p.add_option('-F', '--feature', action='append', help="define a feature key=val")
16p.add_option('-f', '--font', help='Font to use to render glyphs. My be a font file', default="verdana")
17p.add_option('-b', '--bold', help='Choose bold fonts', action='store_true')
18p.add_option('-i', '--italic', help='Choose italic fonts', action='store_true')
19p.add_option('-d', '--debug', action='store_true', help="Output trace info")
20p.add_option('--nogui', action='store_true', help="Don't display a gui")
21(opts, args) = p.parse_args()
22
23if opts.font.lower().endswith(".ttf") :
24    fpat = ":file="
25else :
26    fpat = ""
27fpat += opts.font + ":weight="
28fpat += "bold" if opts.bold else "medium"
29fpat += ":slant="
30fpat += "italic" if opts.italic else "roman"
31pat = fcPattern(fpat)
32fname = pat.getString("file", 0)
33family = pat.getString("family", 0)
34print "Processing: " + fname
35if opts.font.lower().endswith(".ttf") and opts.font != fname :
36    print "Failed to find font in fontconfig. Exiting"
37    sys.exit(1)
38
39ft = harfbuzz.ft(fname, opts.size)
40text = "".join(unichr(int(c, 16)) for c in args)
41bytes = text.encode('utf_8')
42buffer = harfbuzz.buffer(bytes, len(text))
43if (opts.lang or opts.script) : buffer.set_scriptlang(opts.script if opts.script else "", opts.lang if opts.lang else "")
44features = {}
45if opts.feature :
46    for f in opts.feature :
47        k, v = f.split("=")
48        features[k] = v
49ft.shape(buffer, features = features)
50res = buffer.get_info(64)       # scale for 26.6
51print res
52
53if not opts.nogui :
54    try:
55        import gtk
56        import gobject
57        import cairo
58        from gtk import gdk
59    except :
60        raise SystemExit
61    import pygtk
62
63    if gtk.pygtk_version < (2, 8) :
64        print "PyGtk 2.8 or later required"
65        raise SystemExit
66
67    class GlyphsWindow (gtk.Widget) :
68        def __init__(self, fontname, bold, italic, size, glyphs) :
69            gtk.Widget.__init__(self)
70            self.fontname = fontname
71            self.size = size
72            self.glyphs = glyphs
73            self.bold = bold
74            self.italic = italic
75
76        def do_realize(self) :
77            self.set_flags(gtk.REALIZED)
78            self.window = gdk.Window(
79                    self.get_parent_window(),
80                    width = self.allocation.width,
81                    height = self.allocation.height,
82                    window_type = gdk.WINDOW_CHILD,
83                    wclass = gdk.INPUT_OUTPUT,
84                    event_mask = self.get_events() | gdk.EXPOSURE_MASK)
85            self.window.set_user_data(self)
86            self.style.attach(self.window)
87            self.style.set_background(self.window, gtk.STATE_NORMAL)
88            self.window.move_resize(*self.allocation)
89
90        def do_unrealize(self) :
91            self.window.destroy()
92
93        def do_expose_event(self, event) :
94            cr = self.window.cairo_create()
95            cr.set_matrix(cairo.Matrix(1, 0, 0, 1, 0, 1.5 * self.size))
96            cr.set_font_face(cairo.ToyFontFace(self.fontname, cairo.FONT_SLANT_ITALIC if self.italic else cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD if self.bold else cairo.FONT_WEIGHT_NORMAL))
97            cr.set_font_size(self.size)
98            cr.show_glyphs(self.glyphs)      # [(gid, originx, originy)]
99
100    glyphs = []
101    org = [0, 0]
102    for g in res :
103        glyphs.append((g.gid, org[0] + g.offset[0], org[1] - g.offset[1]))
104        org[0] += g.advance[0]
105        org[1] -= g.advance[1]
106
107    gobject.type_register(GlyphsWindow)
108    win = gtk.Window()
109    win.resize(org[0] + 10, 2 * opts.size + 40)
110    win.connect('delete-event', gtk.main_quit)
111    frame = gtk.Frame("glyphs")
112    win.add(frame)
113    w = GlyphsWindow(family, opts.bold, opts.italic, opts.size, glyphs)
114    frame.add(w)
115    win.show_all()
116    gtk.main()
117