| #!/usr/bin/python |
| |
| import harfbuzz, optparse, sys |
| from fontconfig import fcPattern |
| |
| usage = '''usage: %prog [options] codepoints |
| Generates output of glyphs and positions. Each entry is of the form: |
| glyphid>cluster@(offsetx,offsety)+(advancex,advancey) |
| |
| codepoints is a space separated list of hex values of Unicode codepoints''' |
| p = optparse.OptionParser(usage=usage) |
| p.add_option('-s', '--size', default=32, type="int", help="point size") |
| p.add_option('-l', '--lang', help="language code") |
| p.add_option('-c', '--script', help="script code") |
| p.add_option('-F', '--feature', action='append', help="define a feature key=val") |
| p.add_option('-f', '--font', help='Font to use to render glyphs. My be a font file', default="verdana") |
| p.add_option('-b', '--bold', help='Choose bold fonts', action='store_true') |
| p.add_option('-i', '--italic', help='Choose italic fonts', action='store_true') |
| p.add_option('-d', '--debug', action='store_true', help="Output trace info") |
| p.add_option('--nogui', action='store_true', help="Don't display a gui") |
| (opts, args) = p.parse_args() |
| |
| if opts.font.lower().endswith(".ttf") : |
| fpat = ":file=" |
| else : |
| fpat = "" |
| fpat += opts.font + ":weight=" |
| fpat += "bold" if opts.bold else "medium" |
| fpat += ":slant=" |
| fpat += "italic" if opts.italic else "roman" |
| pat = fcPattern(fpat) |
| fname = pat.getString("file", 0) |
| family = pat.getString("family", 0) |
| print "Processing: " + fname |
| if opts.font.lower().endswith(".ttf") and opts.font != fname : |
| print "Failed to find font in fontconfig. Exiting" |
| sys.exit(1) |
| |
| ft = harfbuzz.ft(fname, opts.size) |
| text = "".join(unichr(int(c, 16)) for c in args) |
| bytes = text.encode('utf_8') |
| buffer = harfbuzz.buffer(bytes, len(text)) |
| if (opts.lang or opts.script) : buffer.set_scriptlang(opts.script if opts.script else "", opts.lang if opts.lang else "") |
| features = {} |
| if opts.feature : |
| for f in opts.feature : |
| k, v = f.split("=") |
| features[k] = v |
| ft.shape(buffer, features = features) |
| res = buffer.get_info(64) # scale for 26.6 |
| print res |
| |
| if not opts.nogui : |
| try: |
| import gtk |
| import gobject |
| import cairo |
| from gtk import gdk |
| except : |
| raise SystemExit |
| import pygtk |
| |
| if gtk.pygtk_version < (2, 8) : |
| print "PyGtk 2.8 or later required" |
| raise SystemExit |
| |
| class GlyphsWindow (gtk.Widget) : |
| def __init__(self, fontname, bold, italic, size, glyphs) : |
| gtk.Widget.__init__(self) |
| self.fontname = fontname |
| self.size = size |
| self.glyphs = glyphs |
| self.bold = bold |
| self.italic = italic |
| |
| def do_realize(self) : |
| self.set_flags(gtk.REALIZED) |
| self.window = gdk.Window( |
| self.get_parent_window(), |
| width = self.allocation.width, |
| height = self.allocation.height, |
| window_type = gdk.WINDOW_CHILD, |
| wclass = gdk.INPUT_OUTPUT, |
| event_mask = self.get_events() | gdk.EXPOSURE_MASK) |
| self.window.set_user_data(self) |
| self.style.attach(self.window) |
| self.style.set_background(self.window, gtk.STATE_NORMAL) |
| self.window.move_resize(*self.allocation) |
| |
| def do_unrealize(self) : |
| self.window.destroy() |
| |
| def do_expose_event(self, event) : |
| cr = self.window.cairo_create() |
| cr.set_matrix(cairo.Matrix(1, 0, 0, 1, 0, 1.5 * self.size)) |
| 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)) |
| cr.set_font_size(self.size) |
| cr.show_glyphs(self.glyphs) # [(gid, originx, originy)] |
| |
| glyphs = [] |
| org = [0, 0] |
| for g in res : |
| glyphs.append((g.gid, org[0] + g.offset[0], org[1] - g.offset[1])) |
| org[0] += g.advance[0] |
| org[1] -= g.advance[1] |
| |
| gobject.type_register(GlyphsWindow) |
| win = gtk.Window() |
| win.resize(org[0] + 10, 2 * opts.size + 40) |
| win.connect('delete-event', gtk.main_quit) |
| frame = gtk.Frame("glyphs") |
| win.add(frame) |
| w = GlyphsWindow(family, opts.bold, opts.italic, opts.size, glyphs) |
| frame.add(w) |
| win.show_all() |
| gtk.main() |