Add fontconfig to hbtestfont
authorMartin Hosken <martin_hosken@sil.org>
Sat, 22 May 2010 18:58:00 +0000 (19:58 +0100)
committerMartin Hosken <martin_hosken@sil.org>
Sat, 22 May 2010 18:58:00 +0000 (19:58 +0100)
contrib/python/lib/fontconfig.pyx [new file with mode: 0644]
contrib/python/scripts/hbtestfont
contrib/python/setup.py

diff --git a/contrib/python/lib/fontconfig.pyx b/contrib/python/lib/fontconfig.pyx
new file mode 100644 (file)
index 0000000..16e0289
--- /dev/null
@@ -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(<FcChar8 *>name)
+        self._pattern = FcFontMatch(FcConfigGetCurrent(), temp, &res)
+        if res != FcResultMatch :
+            print "Failed to match" + str(res)
+            self._pattern = <FcPattern *>0
+
+    def __destroy__(self) :
+        FcPatternDestroy(self._pattern)
+
+    def getInteger(self, char *typeid, int index) :
+        cdef int res
+        if self._pattern == <FcPattern *>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 == <FcPattern *>0 or FcPatternGetString(self._pattern, typeid, index, &res) != FcResultMatch : return None
+        return <char *>res
+
+    def debugPrint(self) :
+        FcPatternPrint(self._pattern)
index 30110e6..070e549 100755 (executable)
@@ -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()
index ef2412b..f592728 100755 (executable)
@@ -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/*'),