Tidy up hbtestfont and add README
This commit is contained in:
parent
70ae332fe6
commit
e5bed0a37f
|
@ -0,0 +1,10 @@
|
||||||
|
This contains a wrapping of harfbuzz into python. The module is dependent on pyrex. To build, type:
|
||||||
|
|
||||||
|
python setup.py build
|
||||||
|
|
||||||
|
In addition there is a test application, hbtestfont. It has GTK based gui output and for this, python modules for gtk, gobject and cairo are needed. The application may be run without gui output using the --nogui option.
|
||||||
|
|
||||||
|
Applications may be executed in the build context, without needing to install any modules or libraries, using the runpy script from the contrib/python directory. Thus one might type:
|
||||||
|
|
||||||
|
./runpy script/hbtestfont -f "Charis SIL" 0048 0069 0303
|
||||||
|
|
|
@ -3,20 +3,61 @@
|
||||||
import harfbuzz, optparse
|
import harfbuzz, optparse
|
||||||
from fontconfig import fcPattern
|
from fontconfig import fcPattern
|
||||||
|
|
||||||
try:
|
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()
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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 gtk
|
||||||
import gobject
|
import gobject
|
||||||
import cairo
|
import cairo
|
||||||
from gtk import gdk
|
from gtk import gdk
|
||||||
except :
|
except :
|
||||||
raise SystemExit
|
raise SystemExit
|
||||||
import pygtk
|
import pygtk
|
||||||
|
|
||||||
if gtk.pygtk_version < (2, 8) :
|
if gtk.pygtk_version < (2, 8) :
|
||||||
print "PyGtk 2.8 or later required"
|
print "PyGtk 2.8 or later required"
|
||||||
raise SystemExit
|
raise SystemExit
|
||||||
|
|
||||||
class GlyphsWindow (gtk.Widget) :
|
class GlyphsWindow (gtk.Widget) :
|
||||||
def __init__(self, fontname, bold, italic, size, glyphs) :
|
def __init__(self, fontname, bold, italic, size, glyphs) :
|
||||||
gtk.Widget.__init__(self)
|
gtk.Widget.__init__(self)
|
||||||
self.fontname = fontname
|
self.fontname = fontname
|
||||||
|
@ -44,66 +85,25 @@ class GlyphsWindow (gtk.Widget) :
|
||||||
|
|
||||||
def do_expose_event(self, event) :
|
def do_expose_event(self, event) :
|
||||||
cr = self.window.cairo_create()
|
cr = self.window.cairo_create()
|
||||||
cr.set_matrix(cairo.Matrix(1, 0, 0, 1, 0, 2 * self.size))
|
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_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.set_font_size(self.size)
|
||||||
cr.show_glyphs(self.glyphs) # [(gid, originx, originy)]
|
cr.show_glyphs(self.glyphs) # [(gid, originx, originy)]
|
||||||
|
|
||||||
buffer = None
|
glyphs = []
|
||||||
|
org = [0, 0]
|
||||||
def tracefn(ft, aType, index) :
|
for g in res :
|
||||||
print aType + "(" + str(index) + "): " + str(buffer.get_info())
|
|
||||||
|
|
||||||
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")
|
|
||||||
(opts, args) = p.parse_args()
|
|
||||||
|
|
||||||
fpat = opts.font + ":weight="
|
|
||||||
fpat += "bold" if opts.bold else "medium"
|
|
||||||
fpat += "italic" if opts.italic else "roman"
|
|
||||||
pat = fcPattern(fpat)
|
|
||||||
fname = pat.getString("file", 0)
|
|
||||||
family = pat.getString("family", 0)
|
|
||||||
print "Processing: " + fname
|
|
||||||
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
|
|
||||||
|
|
||||||
glyphs = []
|
|
||||||
org = [0, 0]
|
|
||||||
for g in res :
|
|
||||||
glyphs.append((g.gid, org[0] + g.offset[0], org[1] + g.offset[1]))
|
glyphs.append((g.gid, org[0] + g.offset[0], org[1] + g.offset[1]))
|
||||||
org[0] += g.advance[0]
|
org[0] += g.advance[0]
|
||||||
org[1] += g.advance[1]
|
org[1] += g.advance[1]
|
||||||
gobject.type_register(GlyphsWindow)
|
|
||||||
win = gtk.Window()
|
gobject.type_register(GlyphsWindow)
|
||||||
win.resize(org[0] + 10, 3 * opts.size + 40)
|
win = gtk.Window()
|
||||||
win.connect('delete-event', gtk.main_quit)
|
win.resize(org[0] + 10, 2 * opts.size + 40)
|
||||||
frame = gtk.Frame("glyphs")
|
win.connect('delete-event', gtk.main_quit)
|
||||||
win.add(frame)
|
frame = gtk.Frame("glyphs")
|
||||||
w = GlyphsWindow(family, opts.bold, opts.italic, opts.size, glyphs)
|
win.add(frame)
|
||||||
frame.add(w)
|
w = GlyphsWindow(family, opts.bold, opts.italic, opts.size, glyphs)
|
||||||
win.show_all()
|
frame.add(w)
|
||||||
gtk.main()
|
win.show_all()
|
||||||
|
gtk.main()
|
||||||
|
|
Loading…
Reference in New Issue