diff options
author | Gustavo J. A. M. Carneiro <gjc@src.gnome.org> | 2005-06-06 22:21:49 +0000 |
---|---|---|
committer | Gustavo J. A. M. Carneiro <gjc@src.gnome.org> | 2005-06-06 22:21:49 +0000 |
commit | 26a04d153da54e1716ddecef5f2db0989ae3c0f3 (patch) | |
tree | 93b1fb3a8777ecad1127b67859c3136f0e01f8ef | |
parent | edb54df2ef7f92519860ea867bc8a9318e33e8c3 (diff) | |
download | pygtk-26a04d153da54e1716ddecef5f2db0989ae3c0f3.tar.gz |
pygtk + cairo \!\!
-rw-r--r-- | ChangeLog | 29 | ||||
-rw-r--r-- | Makefile.am | 16 | ||||
-rw-r--r-- | codegen/argtypes.py | 16 | ||||
-rw-r--r-- | configure.in | 49 | ||||
-rw-r--r-- | examples/Makefile.am | 1 | ||||
-rw-r--r-- | examples/gtk/widget.py | 44 | ||||
-rw-r--r-- | examples/pango/pangocairo-simple.py | 58 | ||||
-rw-r--r-- | gtk/Makefile.am | 4 | ||||
-rw-r--r-- | gtk/gdk.defs | 7 | ||||
-rw-r--r-- | gtk/gdk.override | 22 | ||||
-rw-r--r-- | gtk/gdkcairo.override | 142 | ||||
-rw-r--r-- | gtk/gtkmodule.c | 11 | ||||
-rw-r--r-- | pangocairo.defs | 47 | ||||
-rw-r--r-- | pangocairo.override | 253 | ||||
-rw-r--r-- | pangocairomodule.c | 67 |
15 files changed, 736 insertions, 30 deletions
@@ -1,5 +1,34 @@ 2005-06-06 Gustavo J. A. M. Carneiro <gjc@gnome.org> + * examples/gtk/widget.py: Render the sample widget with cairo, if + possible. + + * examples/pango/pangocairo-simple.py: cairosimple.c example + ported to python. + + * examples/Makefile.am (EXTRA_DIST): Add pango/pangocairo-simple.py. + + * codegen/argtypes.py (CairoArg.write_return): Add cairo_t* argtype. + + * gtk/Makefile.am (EXTRA_DIST): Add gdkcairo.override. + + * gtk/gdk.defs: Optionally define method cairo_create of + gtk.gdk.Drawable. + + * gtk/gdk.override (_wrap_gdk_cairo_create): Wrap gdk_cairo_create + as method cairo_create of gtk.gdk.Drawable. + + * gtk/gdkcairo.override: If pycairo is available, define type + gtk.gdk.CairoContext as a subclass of pangocairo.CairoContext with + some additional methods. + + * configure.in: Check for libraries to build pangocairo module. + Check for dependencies to optionally build gtk module with cairo + support. + + * Makefile.am, pangocairomodule.c, pangocairo.defs, + * pangocairo.override: Python bindings for the new libpangocairo. + * codegen/codegen.py (Wrapper.write_getsets): Add support for structured fields. For example, a field 'bar' inside a structure 'foo' is declared in the defs as "foo.bar" and mapped as "foo_bar" diff --git a/Makefile.am b/Makefile.am index 285aafa3..9848b3a6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,7 +19,7 @@ defs_DATA = pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = \ pygobject-$(PLATFORM_VERSION).pc - + if BUILD_GTK pkgconfig_DATA += pygtk-$(PLATFORM_VERSION).pc endif @@ -81,6 +81,20 @@ pango.c: $(COMMONDEFS) pango.override CLEANFILES += pango.c EXTRA_DIST += pango.override +# pangocairo module +if BUILD_PANGOCAIRO + pkgpyexec_LTLIBRARIES += pangocairo.la + defs_DATA += pangocairo.defs +endif +pangocairo_la_LDFLAGS = $(common_ldflags) -export-symbols-regex initpangocairo +pangocairo_la_LIBADD = $(PANGOCAIRO_LIBS) +pangocairo_la_CFLAGS = $(PANGOCAIRO_CFLAGS) +pangocairo_la_SOURCES = pangocairomodule.c +nodist_pangocairo_la_SOURCES = pangocairo.c +pangocairo.c: $(COMMONDEFS) pangocairo.override +CLEANFILES += pangocairo.c +EXTRA_DIST += pangocairo.override + # atk module atk_la_LDFLAGS = $(common_ldflags) -export-symbols-regex initatk atk_la_LIBADD = $(ATK_LIBS) diff --git a/codegen/argtypes.py b/codegen/argtypes.py index 1b3a0445..0f23e674 100644 --- a/codegen/argtypes.py +++ b/codegen/argtypes.py @@ -753,6 +753,20 @@ class PyObjectArg(ArgType): ' Py_INCREF(ret);\n' ' return ret;') +class CairoArg(ArgType): + def write_param(self, ptype, pname, pdflt, pnull, info): + info.varlist.add('PycairoContext', '*' + pname) + info.add_parselist('O!', ['&PycairoContext_Type', '&' + pname], [pname]) + info.arglist.append('%s->ctx' % pname) + def write_return(self, ptype, ownsreturn, info): + info.varlist.add("cairo_t", "*ret") + if ownsreturn: + info.codeafter.append(' return PycairoContext_FromContext(ret, NULL, NULL);') + else: + info.codeafter.append(' cairo_reference(ret);\n' + ' return PycairoContext_FromContext(ret, NULL, NULL);') + + class ArgMatcher: def __init__(self): self.argtypes = {} @@ -948,3 +962,5 @@ matcher.register('GdkNativeWindow', ULongArg()) matcher.register_object('GObject', None, 'G_TYPE_OBJECT') del arg + +matcher.register('cairo_t*', CairoArg()) diff --git a/configure.in b/configure.in index d2c34742..677e744a 100644 --- a/configure.in +++ b/configure.in @@ -13,6 +13,7 @@ m4_define(pango_required_version, 1.8.0) m4_define(atk_required_version, 1.8.0) m4_define(gtk_required_version, 2.6.0) m4_define(libglade_required_version, 2.4.0) +m4_define(pycairo_required_version, 0.5.0) AC_INIT(pygtk, pygtk_version, [http://bugzilla.gnome.org/enter_bug.cgi?product=pygtk]) @@ -116,28 +117,40 @@ if test -n "$export_dynamic"; then PANGO_LIBS=`echo $PANGO_LIBS | sed -e "s/$export_dynamic//"` fi -dnl gtk+ -AM_PATH_GTK_2_0(gtk_required_version, - build_gtk=true, build_gtk=false) +dnl pangocairo +PKG_CHECK_MODULES(PANGOCAIRO, [pangocairo >= pango_required_version + pycairo >= pycairo_required_version], + build_pangocairo=true, build_pangocairo=false) +AM_CONDITIONAL(BUILD_PANGOCAIRO, $build_pangocairo) +if test -n "$export_dynamic"; then + PANGOCAIRO_LIBS=`echo $PANGOCAIRO_LIBS | sed -e "s/$export_dynamic//"` +fi + +dnl gtk+; first try to find gtk+ and pycairo, if that fails look for gtk+ alone +PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.7, + pycairo >= pycairo_required_version], + [build_gtk=true + have_pycairo=true], + dnl no pycairo + [have_pycairo=false + PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= gtk_required_version], + build_gtk=true, [build_gtk=false])] + ) AM_CONDITIONAL(BUILD_GTK, $build_gtk) if test -n "$export_dynamic"; then GTK_LIBS=`echo $GTK_LIBS | sed -e "s/$export_dynamic//"` fi -dnl Check for newer gtk+ versions, for conditional compiling of new features PYGTK_CODEGEN_DEFINES="" -AC_SUBST(PYGTK_CODEGEN_DEFINES) - -AC_MSG_CHECKING([for GTK+ 2.4]) -if version=$(pkg-config --modversion "gtk+-2.0 >= 2.3.4" 2> /dev/null); then - PYGTK_CODEGEN_DEFINES="-DHAVE_GTK24"; - AC_MSG_RESULT([found (version $version)]) -else - AC_MSG_RESULT([not found]) +AC_SUBST([PYGTK_CODEGEN_DEFINES]) +if $have_pycairo; then + PYGTK_CODEGEN_DEFINES="-DHAVE_PYCAIRO $PYGTK_CODEGEN_DEFINES"; + AC_DEFINE([HAVE_PYCAIRO], [1], [Define to 1 if pycairo is available]) fi + dnl libglade -PKG_CHECK_MODULES(LIBGLADE, libglade-2.0 >= libglade_required_version, +PKG_CHECK_MODULES(LIBGLADE, [libglade-2.0 >= libglade_required_version], build_libglade=true, build_libglade=false) AC_SUBST(LIBGLADE_CFLAGS) AC_SUBST(LIBGLADE_LIBS) @@ -187,16 +200,22 @@ echo true && echo gobject $build_atk && echo atk $build_pango && echo pango -$build_gtk && echo gtk +$build_pangocairo && echo pangocairo +(test $build_gtk && + $have_pycairo) && echo gtk "(with cairo)" +(test $build_gtk && + ! $have_pycairo) && echo gtk "(without cairo)" $build_libglade && echo gtk.glade echo if test ! $build_atk || ! $build_pango || \ - ! $build_gtk || ! $build_libglade; then + ! $build_gtk || ! $build_libglade ||\ + ! $build_pangocairo ; then echo "The following modules will NOT be built:" echo $build_atk || echo atk $build_pango || echo pango + $build_pangocairo || echo pangocairo $build_gtk || echo gtk $build_libglade || echo gtk.glade fi diff --git a/examples/Makefile.am b/examples/Makefile.am index 1802c2dc..0a05edf1 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -54,6 +54,7 @@ EXTRA_DIST = \ neil/notebook.py \ neil/question.xpm \ pango/utf8-demo.py \ + pango/pangocairo-simple.py \ simple/README \ simple/dnd.py \ simple/dndpixmap.py \ diff --git a/examples/gtk/widget.py b/examples/gtk/widget.py index 9bb27986..51e187e3 100644 --- a/examples/gtk/widget.py +++ b/examples/gtk/widget.py @@ -5,6 +5,10 @@ import gobject import pango import gtk from gtk import gdk +try: + import cairo +except ImportError: + pass if gtk.pygtk_version < (2,3,93): print "PyGtk 2.3.93 or later required for this example" @@ -21,7 +25,6 @@ class PyGtkWidget(gtk.Widget): } def __init__(self): gtk.Widget.__init__(self) - self.draw_gc = None self.layout = self.create_pango_layout(TEXT) self.layout.set_font_description(pango.FontDescription("sans serif 16")) @@ -34,10 +37,11 @@ class PyGtkWidget(gtk.Widget): window_type=gdk.WINDOW_CHILD, wclass=gdk.INPUT_OUTPUT, event_mask=self.get_events() | gdk.EXPOSURE_MASK) - self.draw_gc = gdk.GC(self.window, - line_width=5, - line_style=gdk.SOLID, - join_style=gdk.JOIN_ROUND) + if not hasattr(self.window, "cairo_create"): + self.draw_gc = gdk.GC(self.window, + line_width=5, + line_style=gdk.SOLID, + join_style=gdk.JOIN_ROUND) self.window.set_user_data(self) self.style.attach(self.window) self.style.set_background(self.window, gtk.STATE_NORMAL) @@ -53,9 +57,7 @@ class PyGtkWidget(gtk.Widget): if self.flags() & gtk.REALIZED: self.window.move_resize(*allocation) - def do_expose_event(self, event): - self.chain(event) - + def _expose_gdk(self, event): x, y, w, h = self.allocation self.window.draw_rectangle(self.draw_gc, False, BORDER_WIDTH, BORDER_WIDTH, @@ -65,14 +67,34 @@ class PyGtkWidget(gtk.Widget): event.area, self, "label", (w - fontw) / 2, (h - fonth) / 2, self.layout) - -gobject.type_register(PyGtkWidget) + + def _expose_cairo(self, event, cr): + x, y, w, h = self.allocation + cr.set_source_color(self.style.fg[self.state]) + cr.rectangle(BORDER_WIDTH, BORDER_WIDTH, + w - 2*BORDER_WIDTH, h - 2*BORDER_WIDTH) + cr.set_line_width(5.0) + cr.set_line_join(cairo.LINE_JOIN_ROUND) + cr.stroke() + fontw, fonth = self.layout.get_pixel_size() + cr.move_to((w - fontw)/2, (h - fonth)/2) + cr.update_layout(self.layout) + cr.show_layout(self.layout) + + def do_expose_event(self, event): + self.chain(event) + try: + cr = self.window.cairo_create() + except AttributeError: + return self._expose_gdk(event) + return self._expose_cairo(event, cr) + win = gtk.Window() win.set_title(TEXT) win.connect('delete-event', gtk.main_quit) -frame = gtk.Frame("Show me a bug") +frame = gtk.Frame("Example frame") win.add(frame) w = PyGtkWidget() diff --git a/examples/pango/pangocairo-simple.py b/examples/pango/pangocairo-simple.py new file mode 100644 index 00000000..c38b8611 --- /dev/null +++ b/examples/pango/pangocairo-simple.py @@ -0,0 +1,58 @@ +#! /usr/bin/env python +import sys +import math +import pango +import cairo +import pangocairo + +RADIUS = 150 + +def draw_text(cr): + N_WORDS = 10 + FONT = "Sans Bold 27" + + # Center coordinates on the middle of the region we are drawing + cr.translate(RADIUS, RADIUS); + + # Create a PangoLayout, set the font and text */ + layout = cr.create_layout() + + layout.set_text("Text") + layout.set_font_description(pango.FontDescription(FONT)) + + # Draw the layout N_WORDS times in a circle + for i in range(N_WORDS): + angle = (360 * i) / N_WORDS; + cr.save() + + # Gradient from red at angle == 60 to blue at angle == 300 + red = (1 + math.cos((angle - 60)*math.pi/180))/2 + cr.set_source_rgb(red, 0, 1 - red) + cr.rotate(angle*math.pi/180) + + # Inform Pango to re-layout the text with the new transformation */ + cr.update_layout(layout) + + width, height = layout.get_size() + cr.move_to(-width/pango.SCALE/2, -RADIUS) + cr.show_layout(layout) + + cr.restore() + +def main(argv): + if len(argv) != 2: + print >> sys.stderr, "Usage: cairosimple OUTPUT_FILENAME.png\n" + return 1 + + filename = argv[1] + surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 2*RADIUS, 2*RADIUS) + cr = pangocairo.CairoContext(cairo.Context(surface)) + cr.set_source_rgb(1.0, 1.0, 1.0) + cr.rectangle(0, 0, 2*RADIUS, 2*RADIUS) + cr.fill() + draw_text(cr) + + surface.write_to_png(filename) + +if __name__ == '__main__': + sys.exit(main(sys.argv)) diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 2a4bd635..e0421361 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -77,11 +77,11 @@ gtk_overrides = \ gtktextview.override \ gtktreeview.override -gdk.c: $(srcdir)/gdk.defs $(COMMONDEFS) $(srcdir)/gdk.override +gdk.c: $(srcdir)/gdk.defs $(COMMONDEFS) $(srcdir)/gdk.override $(srcdir)/gdkcairo.override gtk.c: $(srcdir)/gtk.defs $(COMMONDEFS) $(gtk_overrides) $(srcdir)/gtk-extrafuncs.defs CLEANFILES += gtk.c gdk.c -EXTRA_DIST += gdk.override $(gtk_overrides) +EXTRA_DIST += gdk.override gdkcairo.override $(gtk_overrides) # libglade module if BUILD_LIBGLADE diff --git a/gtk/gdk.defs b/gtk/gdk.defs index a93843dc..ff7bbd89 100644 --- a/gtk/gdk.defs +++ b/gtk/gdk.defs @@ -4413,3 +4413,10 @@ (return-type "GdkRectangle") ) +;; From /opt/gnome-devel/include/gtk-2.0/gdk/gdkcairo.h + +(ifdef HAVE_PYCAIRO + (define-method cairo_create + (of-object "GdkDrawable") + (c-name "gdk_cairo_create") + (return-type "cairo_t*"))) diff --git a/gtk/gdk.override b/gtk/gdk.override index 7352e142..9238dc1a 100644 --- a/gtk/gdk.override +++ b/gtk/gdk.override @@ -48,6 +48,16 @@ static int have_numpy(void); extern PyTypeObject PyGtkWidget_Type; +#ifdef HAVE_PYCAIRO +# include <pycairo.h> +extern Pycairo_CAPI_t *Pycairo_CAPI; +extern PyTypeObject PyGdkCairoContext_Type; +#endif + +%% +include + gdkcairo.override + %% modulename gtk.gdk %% @@ -4747,3 +4757,15 @@ _wrap_gdk_pixbuf_get_from_drawable2(PyObject *self, /* pygobject_new handles NULL checking */ return pygobject_new((GObject *)ret); } + +%% +override gdk_cairo_create noargs +static PyObject * +_wrap_gdk_cairo_create(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + cairo_t *ret; + + ret = gdk_cairo_create(GDK_DRAWABLE(self->obj)); + return PycairoContext_FromContext(ret, &PyGdkCairoContext_Type, NULL); +} + diff --git a/gtk/gdkcairo.override b/gtk/gdkcairo.override new file mode 100644 index 00000000..9d9bbdb8 --- /dev/null +++ b/gtk/gdkcairo.override @@ -0,0 +1,142 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygtk- Python bindings for the GTK toolkit. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ +%% +body + +#ifdef HAVE_PYCAIRO + + +static PyTypeObject *_PyPangoCairoContext_Type; +#define PyPangoCairoContext_Type (*_PyPangoCairoContext_Type) + +static PyObject * +_wrap_gdk_cairo_set_source_color(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "color", NULL }; + PyObject *py_color; + GdkColor *color = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:cairo_set_source_color", kwlist, &py_color)) + return NULL; + if (pyg_boxed_check(py_color, GDK_TYPE_COLOR)) + color = pyg_boxed_get(py_color, GdkColor); + else { + PyErr_SetString(PyExc_TypeError, "color should be a GdkColor"); + return NULL; + } + gdk_cairo_set_source_color(PycairoContext_GET(self), color); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +_wrap_gdk_cairo_set_source_pixbuf(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "pixbuf", "pixbuf_x", "pixbuf_y", NULL }; + PyGObject *pixbuf; + double pixbuf_x, pixbuf_y; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!dd:cairo_set_source_pixbuf", kwlist, + &PyGdkPixbuf_Type, &pixbuf, &pixbuf_x, &pixbuf_y)) + return NULL; + gdk_cairo_set_source_pixbuf(PycairoContext_GET(self), GDK_PIXBUF(pixbuf->obj), + pixbuf_x, pixbuf_y); + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef _PyGdkCairoContext_methods[] = { + { "set_source_pixbuf", (PyCFunction)_wrap_gdk_cairo_set_source_pixbuf, METH_VARARGS|METH_KEYWORDS }, + { "set_source_color", (PyCFunction)_wrap_gdk_cairo_set_source_color, METH_VARARGS|METH_KEYWORDS }, + { NULL, NULL, 0 } +}; + + +PyTypeObject PyGdkCairoContext_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "gtk.gdk.CairoContext", /* tp_name */ + 0, /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)0, /* tp_dealloc */ + (printfunc)0, /* tp_print */ + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)0, /* tp_compare */ + (reprfunc)0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)0, /* tp_str */ + (getattrofunc)0, /* tp_getattro */ + (setattrofunc)0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "A pangocairo.CairoContext enhanced with some additional gdk methods", /* Documentation string */ + (traverseproc)0, /* tp_traverse */ + (inquiry)0, /* tp_clear */ + (richcmpfunc)0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)0, /* tp_iter */ + (iternextfunc)0, /* tp_iternext */ + _PyGdkCairoContext_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + (PyTypeObject *)0, /* tp_base */ + (PyObject *)0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + (inquiry)0, /* tp_is_gc */ + (PyObject *)0, /* tp_bases */ +}; + +#endif /* #ifdef HAVE_PYCAIRO */ + +%% +init +#ifdef HAVE_PYCAIRO + if ((module = PyImport_ImportModule("pangocairo")) != NULL) { + PyObject *moddict = PyModule_GetDict(module); + + _PyPangoCairoContext_Type = (PyTypeObject *)PyDict_GetItemString(moddict, "CairoContext"); + if (_PyPangoCairoContext_Type == NULL) { + PyErr_SetString(PyExc_ImportError, + "cannot import name CairoContext from pangocairo"); + return; + } + } else { + PyErr_SetString(PyExc_ImportError, + "could not import pangocairo"); + return; + } + + PyGdkCairoContext_Type.tp_base = &PyPangoCairoContext_Type; + if (PyType_Ready(&PyGdkCairoContext_Type) < 0) + g_return_if_reached(); + if (PyDict_SetItemString(d, "CairoContext", (PyObject *)&PyGdkCairoContext_Type) < 0) + g_return_if_reached(); +#endif diff --git a/gtk/gtkmodule.c b/gtk/gtkmodule.c index d31be5e4..b21b58ed 100644 --- a/gtk/gtkmodule.c +++ b/gtk/gtkmodule.c @@ -31,6 +31,11 @@ #include "pygtk-private.h" #include <pyerrors.h> +#ifdef HAVE_PYCAIRO +# include <pycairo.h> +Pycairo_CAPI_t *Pycairo_CAPI; +#endif + void _pygtk_register_boxed_types(PyObject *moddict); void pygtk_register_classes(PyObject *d); void pygdk_register_classes(PyObject *d); @@ -43,6 +48,7 @@ extern PyMethodDef pygdk_functions[]; PyObject *PyGtkDeprecationWarning; PyObject *PyGtkWarning; + static struct _PyGtk_FunctionStruct functions = { VERSION, @@ -118,7 +124,10 @@ init_gtk(void) char **argv; GSList *stock_ids, *cur; char buf[128]; - + +#ifdef HAVE_PYCAIRO + Pycairo_IMPORT; +#endif /* initialise gobject */ init_pygobject(); g_assert(pygobject_register_class != NULL); diff --git a/pangocairo.defs b/pangocairo.defs new file mode 100644 index 00000000..a593e395 --- /dev/null +++ b/pangocairo.defs @@ -0,0 +1,47 @@ +;; From /opt/gnome-devel/include/pango-1.0/pango/pangocairo.h + +; (define-function cairo_font_map_get_type +; (c-name "pango_cairo_font_map_get_type") +; (return-type "GType") +; ) + +(define-object CairoFontMap + (in-module "pango") + (parent "PangoFontMap") + (c-name "PangoCairoFontMap") + (gtype-id "PANGO_TYPE_CAIRO_FONT_MAP") +) + +(define-function cairo_font_map_new + (c-name "pango_cairo_font_map_new") + (is-constructor-of "PangoCairoFontMap") + (return-type "PangoCairoFontMap*") +) + +(define-function cairo_font_map_get_default + (c-name "pango_cairo_font_map_get_default") + (return-type "PangoFontMap*") +) + +(define-method set_resolution + (of-object "PangoCairoFontMap") + (c-name "pango_cairo_font_map_set_resolution") + (return-type "none") + (parameters + '("double" "dpi") + ) +) + +(define-method get_resolution + (of-object "PangoCairoFontMap") + (c-name "pango_cairo_font_map_get_resolution") + (return-type "double") +) + +(define-method create_context + (of-object "PangoCairoFontMap") + (c-name "pango_cairo_font_map_create_context") + (return-type "PangoContext*") +) + + diff --git a/pangocairo.override b/pangocairo.override new file mode 100644 index 00000000..75650c16 --- /dev/null +++ b/pangocairo.override @@ -0,0 +1,253 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- */ +%% +headers +#define NO_IMPORT_PYGOBJECT +#include <pygobject.h> +#include <pango/pangocairo.h> +#include <pycairo.h> + + +extern Pycairo_CAPI_t *Pycairo_CAPI; + +GType pypango_layout_line_type; /* See bug 305975 */ + +#ifndef PANGO_TYPE_LAYOUT_LINE +# define PANGO_TYPE_LAYOUT_LINE pypango_layout_line_type +#endif + +%% +import pango.FontMap as PyPangoFontMap_Type +import pango.Context as PyPangoContext_Type +import pango.Layout as PyPangoLayout_Type +import pango.Font as PyPangoFont_Type + +%% +body + +static PyObject * +pypango_cairo_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *o; + PycairoContext *ctx; + + if (!PyArg_ParseTuple(args, "O!:CairoContext.__new__", + &PycairoContext_Type, &ctx)) + return NULL; + + cairo_reference(ctx->ctx); + o = PycairoContext_FromContext(ctx->ctx, type, NULL); + return o; +} + +static PyObject * +_wrap_pango_cairo_update_context(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "context", NULL }; + PyGObject *context; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!:CairoContext.update_context", kwlist, + &PyPangoContext_Type, &context)) + return NULL; + pango_cairo_update_context(PycairoContext_GET(self), PANGO_CONTEXT(context->obj)); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +_wrap_pango_cairo_create_layout(PyGObject *self) +{ + PangoLayout *ret; + + ret = pango_cairo_create_layout(PycairoContext_GET(self)); + /* pygobject_new handles NULL checking */ + return pygobject_new((GObject *)ret); +} + +static PyObject * +_wrap_pango_cairo_update_layout(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "layout", NULL }; + PyGObject *layout; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!:CairoContext.update_layout", + kwlist, &PyPangoLayout_Type, &layout)) + return NULL; + pango_cairo_update_layout(PycairoContext_GET(self), PANGO_LAYOUT(layout->obj)); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +_wrap_pango_cairo_show_glyph_string(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "font", "glyphs", NULL }; + PyGObject *font; + PangoGlyphString *glyphs = NULL; + PyObject *py_glyphs; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O:CairoContext.show_glyph_string", + kwlist, &PyPangoFont_Type, &font, &py_glyphs)) + return NULL; + if (pyg_boxed_check(py_glyphs, PANGO_TYPE_GLYPH_STRING)) + glyphs = pyg_boxed_get(py_glyphs, PangoGlyphString); + else { + PyErr_SetString(PyExc_TypeError, "glyphs should be a PangoGlyphString"); + return NULL; + } + pango_cairo_show_glyph_string(PycairoContext_GET(self), PANGO_FONT(font->obj), glyphs); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +_wrap_pango_cairo_show_layout_line(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "line", NULL }; + PangoLayoutLine *line = NULL; + PyObject *py_line; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:CairoContext.show_layout_line", + kwlist, &py_line)) + return NULL; + if (pyg_boxed_check(py_line, PANGO_TYPE_LAYOUT_LINE)) + line = pyg_boxed_get(py_line, PangoLayoutLine); + else { + PyErr_SetString(PyExc_TypeError, "line should be a PangoLayoutLine"); + return NULL; + } + pango_cairo_show_layout_line(PycairoContext_GET(self), line); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +_wrap_pango_cairo_show_layout(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "layout", NULL }; + PyGObject *layout; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!:CairoContext.show_layout", + kwlist, &PyPangoLayout_Type, &layout)) + return NULL; + pango_cairo_show_layout(PycairoContext_GET(self), PANGO_LAYOUT(layout->obj)); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +_wrap_pango_cairo_glyph_string_path(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "font", "glyphs", NULL }; + PyGObject *font; + PangoGlyphString *glyphs = NULL; + PyObject *py_glyphs; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O:CairoContext.glyph_string_path", + kwlist, &PyPangoFont_Type, &font, &py_glyphs)) + return NULL; + if (pyg_boxed_check(py_glyphs, PANGO_TYPE_GLYPH_STRING)) + glyphs = pyg_boxed_get(py_glyphs, PangoGlyphString); + else { + PyErr_SetString(PyExc_TypeError, "glyphs should be a PangoGlyphString"); + return NULL; + } + pango_cairo_glyph_string_path(PycairoContext_GET(self), PANGO_FONT(font->obj), glyphs); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +_wrap_pango_cairo_layout_line_path(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "line", NULL }; + PangoLayoutLine *line = NULL; + PyObject *py_line; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:CairoContext.layout_line_path", + kwlist, &py_line)) + return NULL; + if (pyg_boxed_check(py_line, PANGO_TYPE_LAYOUT_LINE)) + line = pyg_boxed_get(py_line, PangoLayoutLine); + else { + PyErr_SetString(PyExc_TypeError, "line should be a PangoLayoutLine"); + return NULL; + } + pango_cairo_layout_line_path(PycairoContext_GET(self), line); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +_wrap_pango_cairo_layout_path(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "layout", NULL }; + PyGObject *layout; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!:CairoContext.layout_path", + kwlist, &PyPangoLayout_Type, &layout)) + return NULL; + pango_cairo_layout_path(PycairoContext_GET(self), PANGO_LAYOUT(layout->obj)); + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef _PyCairoContext_methods[] = { + { "update_context", (PyCFunction)_wrap_pango_cairo_update_context, METH_VARARGS|METH_KEYWORDS }, + { "create_layout", (PyCFunction)_wrap_pango_cairo_create_layout, METH_NOARGS }, + { "update_layout", (PyCFunction)_wrap_pango_cairo_update_layout, METH_VARARGS|METH_KEYWORDS }, + { "show_glyph_string", (PyCFunction)_wrap_pango_cairo_show_glyph_string, METH_VARARGS|METH_KEYWORDS }, + { "show_layout_line", (PyCFunction)_wrap_pango_cairo_show_layout_line, METH_VARARGS|METH_KEYWORDS }, + { "show_layout", (PyCFunction)_wrap_pango_cairo_show_layout, METH_VARARGS|METH_KEYWORDS }, + { "glyph_string_path", (PyCFunction)_wrap_pango_cairo_glyph_string_path, METH_VARARGS|METH_KEYWORDS }, + { "layout_line_path", (PyCFunction)_wrap_pango_cairo_layout_line_path, METH_VARARGS|METH_KEYWORDS }, + { "layout_path", (PyCFunction)_wrap_pango_cairo_layout_path, METH_VARARGS|METH_KEYWORDS }, + { NULL, NULL, 0 } +}; + + +PyTypeObject PyPangoCairoContext_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "pangocairo.CairoContext", /* tp_name */ + 0, /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)0, /* tp_dealloc */ + (printfunc)0, /* tp_print */ + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)0, /* tp_compare */ + (reprfunc)0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)0, /* tp_str */ + (getattrofunc)0, /* tp_getattro */ + (setattrofunc)0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "A cairo.Context enhanced with some additional pango methods", /* Documentation string */ + (traverseproc)0, /* tp_traverse */ + (inquiry)0, /* tp_clear */ + (richcmpfunc)0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)0, /* tp_iter */ + (iternextfunc)0, /* tp_iternext */ + _PyCairoContext_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + (PyTypeObject *)0, /* tp_base */ + (PyObject *)0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)0, /* tp_init */ + 0, /* tp_alloc */ + pypango_cairo_new, /* tp_new */ + 0, /* tp_free */ + (inquiry)0, /* tp_is_gc */ + (PyObject *)0, /* tp_bases */ +}; + diff --git a/pangocairomodule.c b/pangocairomodule.c new file mode 100644 index 00000000..a5eadb0f --- /dev/null +++ b/pangocairomodule.c @@ -0,0 +1,67 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygtk- Python bindings for the GTK toolkit. + * Copyright (C) 1998-2003 James Henstridge + * + * pangomodule.c: module wrapping the Pango library + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include <Python.h> +#include <pygobject.h> + +#include <pango/pangocairo.h> +#include <pycairo.h> + +/* include any extra headers needed here */ + +void pypangocairo_register_classes(PyObject *d); +void pypangocairo_add_constants(PyObject *module, const gchar *strip_prefix); + +extern PyMethodDef pypangocairo_functions[]; +extern PyTypeObject PyPangoCairoContext_Type; +extern GType pypango_layout_line_type; + +Pycairo_CAPI_t *Pycairo_CAPI; + + +DL_EXPORT(void) +initpangocairo(void) +{ + PyObject *m, *d; + + /* perform any initialisation required by the library here */ + + m = Py_InitModule("pangocairo", pypangocairo_functions); + d = PyModule_GetDict(m); + + Pycairo_IMPORT; + PyPangoCairoContext_Type.tp_base = &PycairoContext_Type; + if (PyType_Ready(&PyPangoCairoContext_Type) < 0) + g_return_if_reached(); + + init_pygobject(); + + pypangocairo_register_classes(d); + + Py_INCREF(&PyPangoCairoContext_Type); + PyModule_AddObject(m, "CairoContext", (PyObject *)&PyPangoCairoContext_Type); + + pypango_layout_line_type = g_type_from_name("PangoLayoutLine"); +} + |