#!/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()
