diff --git a/contrib/python/lib/fontconfig.pyx b/contrib/python/lib/fontconfig.pyx new file mode 100644 index 000000000..16e02891c --- /dev/null +++ b/contrib/python/lib/fontconfig.pyx @@ -0,0 +1,47 @@ +cdef extern from "fontconfig/fontconfig.h" : + ctypedef struct FcPattern : + pass + ctypedef struct FcConfig : + pass + cdef enum FcResult '_FcResult' : + FcResultMatch = 0, FcResultNoMatch, FcResultTypeMismatch, FcResultNoId, + FcResultOutOfMemory + + ctypedef char FcChar8 + FcPattern *FcNameParse(FcChar8 *name) + FcPattern *FcFontMatch(FcConfig *config, FcPattern *match, FcResult *res) + FcResult FcPatternGetInteger(FcPattern *pattern, char *typeid, int index, int *res) + FcResult FcPatternGetString(FcPattern *pattern, char *typeid, int index, FcChar8 **res) + void FcPatternPrint(FcPattern *pattern) + void FcPatternDestroy(FcPattern *pattern) + + FcConfig *FcConfigGetCurrent() + +cdef class fcPattern : + cdef FcPattern *_pattern + + def __init__(self, char *name) : + cdef FcPattern *temp + cdef FcResult res + + temp = FcNameParse(name) + self._pattern = FcFontMatch(FcConfigGetCurrent(), temp, &res) + if res != FcResultMatch : + print "Failed to match" + str(res) + self._pattern = 0 + + def __destroy__(self) : + FcPatternDestroy(self._pattern) + + def getInteger(self, char *typeid, int index) : + cdef int res + if self._pattern == 0 or FcPatternGetInteger(self._pattern, typeid, index, &res) != FcResultMatch : return None + return res + + def getString(self, char *typeid, int index) : + cdef FcChar8 *res + if self._pattern == 0 or FcPatternGetString(self._pattern, typeid, index, &res) != FcResultMatch : return None + return res + + def debugPrint(self) : + FcPatternPrint(self._pattern) diff --git a/contrib/python/scripts/hbtestfont b/contrib/python/scripts/hbtestfont index 30110e603..070e54939 100755 --- a/contrib/python/scripts/hbtestfont +++ b/contrib/python/scripts/hbtestfont @@ -1,6 +1,8 @@ #!/usr/bin/python import harfbuzz, optparse +from fontconfig import fcPattern + try: import gtk import gobject @@ -9,16 +11,19 @@ try: 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, size, glyphs) : + 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) @@ -40,7 +45,7 @@ class GlyphsWindow (gtk.Widget) : def do_expose_event(self, event) : cr = self.window.cairo_create() cr.set_matrix(cairo.Matrix(1, 0, 0, 1, 0, 2 * self.size)) - cr.set_font_face(cairo.ToyFontFace(self.fontname)) + 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)] @@ -49,22 +54,31 @@ buffer = None def tracefn(ft, aType, index) : print aType + "(" + str(index) + "): " + str(buffer.get_info()) -usage = '''usage: %prog [options] fontfile "codepoints" +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=12, type="int", help="point size") +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('-n', '--fontname', help='Font to use to render glyphs') +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() -ft = harfbuzz.ft(args[0], opts.size) -text = "".join(unichr(int(c, 16)) for c in args[1].split(" ")) +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 "") @@ -76,20 +90,20 @@ if opts.feature : ft.shape(buffer, features = features) res = buffer.get_info(64) # scale for 26.6 print res -if opts.fontname : - 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, 3 * opts.size + 40) - win.connect('delete-event', gtk.main_quit) - frame = gtk.Frame("glyphs") - win.add(frame) - w = GlyphsWindow(opts.fontname, opts.size, glyphs) - frame.add(w) - win.show_all() - gtk.main() + +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, 3 * 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() diff --git a/contrib/python/setup.py b/contrib/python/setup.py index ef2412b48..f59272894 100755 --- a/contrib/python/setup.py +++ b/contrib/python/setup.py @@ -13,7 +13,8 @@ setup(name='harfbuzz', maintainer_email='martin_hosken@sil.org', packages=['harfbuzz'], ext_modules = [ - Extension("harfbuzz", ["lib/harfbuzz.pyx"], libraries=["harfbuzz"], library_dirs=["../../src/.libs"], include_dirs=["/usr/include/freetype2", "../../src"]) + Extension("harfbuzz", ["lib/harfbuzz.pyx"], libraries=["harfbuzz"], library_dirs=["../../src/.libs"], include_dirs=["/usr/include/freetype2", "../../src"]), + Extension("fontconfig", ["lib/fontconfig.pyx"], libraries=["fontconfig"]) ], cmdclass = {'build_ext' : build_ext}, scripts = glob('scripts/*'),