summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGustavo J. A. M. Carneiro <gjc@src.gnome.org>2005-06-06 22:21:49 +0000
committerGustavo J. A. M. Carneiro <gjc@src.gnome.org>2005-06-06 22:21:49 +0000
commit26a04d153da54e1716ddecef5f2db0989ae3c0f3 (patch)
tree93b1fb3a8777ecad1127b67859c3136f0e01f8ef
parentedb54df2ef7f92519860ea867bc8a9318e33e8c3 (diff)
downloadpygtk-26a04d153da54e1716ddecef5f2db0989ae3c0f3.tar.gz
pygtk + cairo \!\!
-rw-r--r--ChangeLog29
-rw-r--r--Makefile.am16
-rw-r--r--codegen/argtypes.py16
-rw-r--r--configure.in49
-rw-r--r--examples/Makefile.am1
-rw-r--r--examples/gtk/widget.py44
-rw-r--r--examples/pango/pangocairo-simple.py58
-rw-r--r--gtk/Makefile.am4
-rw-r--r--gtk/gdk.defs7
-rw-r--r--gtk/gdk.override22
-rw-r--r--gtk/gdkcairo.override142
-rw-r--r--gtk/gtkmodule.c11
-rw-r--r--pangocairo.defs47
-rw-r--r--pangocairo.override253
-rw-r--r--pangocairomodule.c67
15 files changed, 736 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog
index c78091ee..db150361 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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");
+}
+