[dia] pydia: Renderer:draw_object() and Object::draw() via Python
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] pydia: Renderer:draw_object() and Object::draw() via Python
- Date: Fri, 7 Jan 2011 21:34:10 +0000 (UTC)
commit 3cf5a400d9924a7dc6fc5e67cec166a466885887
Author: Hans Breuer <hans breuer org>
Date: Fri Jan 7 22:09:01 2011 +0100
pydia: Renderer:draw_object() and Object::draw() via Python
Allows to interweave additional object information with the rendering.
See diasvg.py for an example. Basic idea from dia-list:
http://mail.gnome.org/archives/dia-list/2010-November/msg00019.html
plug-ins/python/diasvg.py | 4 +++
plug-ins/python/pydia-object.c | 32 ++++++++++++++++++++++++++-
plug-ins/python/pydia-render.c | 47 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 82 insertions(+), 1 deletions(-)
---
diff --git a/plug-ins/python/diasvg.py b/plug-ins/python/diasvg.py
index 9aac0db..cd79de8 100644
--- a/plug-ins/python/diasvg.py
+++ b/plug-ins/python/diasvg.py
@@ -46,6 +46,10 @@ class SvgRenderer :
def end_render (self) :
self.f.write('</svg>')
self.f.close()
+ def draw_object (self, object, matrix) :
+ self.f.write("<!-- " + object.type.name + " -->\n")
+ # don't forget to render the object
+ object.draw (self)
def set_linewidth (self, width) :
if width < 0.001 : # zero line width is invisble ?
self.line_width = 0.001
diff --git a/plug-ins/python/pydia-object.c b/plug-ins/python/pydia-object.c
index 28adc7c..d9d289e 100644
--- a/plug-ins/python/pydia-object.c
+++ b/plug-ins/python/pydia-object.c
@@ -24,6 +24,7 @@
#include "pydia-handle.h"
#include "pydia-geometry.h"
#include "pydia-properties.h"
+#include "pydia-render.h"
#include <structmember.h> /* PyMemberDef */
@@ -87,7 +88,33 @@ PyDiaObject_Destroy(PyDiaObject *self, PyObject *args)
return Py_None;
}
-/* draw */
+static PyObject *
+PyDiaObject_Draw(PyDiaObject *self, PyObject *args)
+{
+ PyObject* renderer;
+ DiaRenderer *wrapper;
+
+ if (!PyArg_ParseTuple(args, "O:Object.draw", &renderer))
+ return NULL;
+
+ /* We need to create the PythonRenderer wrapper to provide the gobject interface.
+ * This could be done much more efficient if it would somehow be cached for the
+ * whole rendering pass ...
+ */
+ wrapper = PyDia_new_renderer_wrapper (renderer);
+
+ if (!self->object->ops->draw) {
+ PyErr_SetString(PyExc_RuntimeError,"object does not implement method");
+ return NULL;
+ }
+
+ self->object->ops->draw(self->object, wrapper);
+
+ g_object_unref (wrapper);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
static PyObject *
PyDiaObject_DistanceFrom(PyDiaObject *self, PyObject *args)
@@ -189,6 +216,9 @@ static PyMethodDef PyDiaObject_Methods[] = {
" Calculate the object's distance from the given point." },
{ "copy", (PyCFunction)PyDiaObject_Copy, METH_VARARGS,
"copy() -> Object. Create a new object copy." },
+ { "draw", (PyCFunction)PyDiaObject_Draw, METH_VARARGS,
+ "draw(dia.Renderer: r) -> None."
+ " Draw the object with the given renderer" },
{ "move", (PyCFunction)PyDiaObject_Move, METH_VARARGS,
"move(real: x, real: y) -> None."
" Move the entire object. The given point is the new object.obj_pos." },
diff --git a/plug-ins/python/pydia-render.c b/plug-ins/python/pydia-render.c
index d43a8e0..74707a5 100644
--- a/plug-ins/python/pydia-render.c
+++ b/plug-ins/python/pydia-render.c
@@ -37,6 +37,7 @@
#include "pydia-font.h"
#include "pydia-image.h"
#include "pydia-error.h"
+#include "pydia-render.h"
/*
* The PyDiaRenderer is currently defined in Python only. The
@@ -328,6 +329,39 @@ set_font(DiaRenderer *renderer, DiaFont *font, real height)
static gpointer parent_class = NULL;
static void
+draw_object (DiaRenderer *renderer, DiaObject *object, DiaMatrix *matrix)
+{
+ PyObject *func, *res, *arg, *self = PYDIA_RENDERER (renderer);
+
+ func = PyObject_GetAttrString (self, "draw_object");
+ if (func && PyCallable_Check(func)) {
+ PyObject *mat = NULL;
+
+ Py_INCREF(self);
+ Py_INCREF(func);
+ if (matrix)
+ mat = PyDiaMatrix_New (matrix);
+ else {
+ Py_INCREF(Py_None);
+ mat = Py_None;
+ }
+ arg = Py_BuildValue ("(OO)", PyDiaObject_New (object), mat );
+ if (arg) {
+ res = PyEval_CallObject (func, arg);
+ ON_RES(res, FALSE);
+ }
+ Py_XDECREF (arg);
+ Py_XDECREF (mat);
+ Py_DECREF(func);
+ Py_DECREF(self);
+ } else { /* member optional */
+ PyErr_Clear();
+ /* but should still call the base class */
+ DIA_RENDERER_CLASS (parent_class)->draw_object (renderer, object, matrix);
+ }
+}
+
+static void
draw_line(DiaRenderer *renderer,
Point *start, Point *end,
Color *line_colour)
@@ -798,6 +832,17 @@ PyDia_export_data(DiagramData *data, const gchar *filename,
g_object_unref(renderer);
}
+DiaRenderer *
+PyDia_new_renderer_wrapper (PyObject *self)
+{
+ DiaPyRenderer *wrapper;
+
+ wrapper = g_object_new (DIA_TYPE_PY_RENDERER, NULL);
+ wrapper->self = self;
+
+ return DIA_RENDERER (wrapper);
+}
+
/*
* GObject boiler plate
*/
@@ -857,6 +902,8 @@ dia_py_renderer_class_init (DiaPyRendererClass *klass)
renderer_class->begin_render = begin_render;
renderer_class->end_render = end_render;
+ renderer_class->draw_object = draw_object;
+
renderer_class->set_linewidth = set_linewidth;
renderer_class->set_linecaps = set_linecaps;
renderer_class->set_linejoin = set_linejoin;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]