[dia] pydia: Renderer:draw_layer() and Layer::render() via Python



commit 704ddded15e1a0e145ddd890f72fc0372c81e0c9
Author: Hans Breuer <hans breuer org>
Date:   Sat Jun 7 00:17:50 2014 +0200

    pydia: Renderer:draw_layer() and Layer::render() via Python
    
    Allows to interweave additional layer information with the rendering.

 plug-ins/python/diasvg.py      |    5 ++++
 plug-ins/python/pydia-layer.c  |   33 +++++++++++++++++++++++++-
 plug-ins/python/pydia-render.c |   48 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 84 insertions(+), 2 deletions(-)
---
diff --git a/plug-ins/python/diasvg.py b/plug-ins/python/diasvg.py
index ee2934f..2d5527f 100644
--- a/plug-ins/python/diasvg.py
+++ b/plug-ins/python/diasvg.py
@@ -63,6 +63,11 @@ class SvgRenderer :
                elif cap == 8 : # RENDER_PATTERN
                        return 0
                return 0
+       def draw_layer (self, layer, active, update) :
+               self.f.write ("<!-- Layer: " + layer.name + " -->\n")
+               self.f.write ('<g id="' + self._escape (layer.name) + '">\n')
+               layer.render (self)
+               self.f.write ('</g>\n')
        def draw_object (self, object, matrix) :
                self.f.write("<!-- " + object.type.name + " -->\n")
                odict = object.properties["meta"].value
diff --git a/plug-ins/python/pydia-layer.c b/plug-ins/python/pydia-layer.c
index 84ee479..90ff758 100644
--- a/plug-ins/python/pydia-layer.c
+++ b/plug-ins/python/pydia-layer.c
@@ -22,6 +22,7 @@
 #include "pydia-layer.h"
 #include "pydia-object.h"
 #include "pydia-cpoint.h"
+#include "pydia-render.h"
 
 #include <structmember.h> /* PyMemberDef */
 
@@ -186,14 +187,39 @@ PyDiaLayer_UpdateExtents(PyDiaLayer *self, PyObject *args)
     return PyInt_FromLong(layer_update_extents(self->layer));
 }
 
+static PyObject *
+PyDiaLayer_Render(PyDiaLayer *self, PyObject *args)
+{
+    PyObject* renderer;
+    DiaRenderer *wrapper;
+    Rectangle *update = NULL;
+    gboolean active = FALSE; /* could derive from layer->parent_diagram->active_layer
+                             * but not sure if it's worth the effort. */
+
+    if (!PyArg_ParseTuple(args, "O:Layer.render", &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);
+    layer_render (self->layer, wrapper, update,
+                 NULL, /* no special object renderer */
+                 NULL, /* no user data */
+                 active);
+    g_object_unref (wrapper);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
 /* missing functions:
  *  layer_add_objects
  *  layer_add_objects_first
  *  layer_remove_objects
  *  layer_replace_object_with_list
  *  layer_set_object_list
- *
- *  layer_render ???
  */
 
 static PyMethodDef PyDiaLayer_Methods[] = {
@@ -221,6 +247,9 @@ static PyMethodDef PyDiaLayer_Methods[] = {
      "  Given a point and an optional object to exclude return the distance and the closest connection point 
or None."},
     {"update_extents", (PyCFunction)PyDiaLayer_UpdateExtents, METH_VARARGS,
      "update_extents() -> None.  Force recaculation of the layer extents."},
+    { "render", (PyCFunction)PyDiaLayer_Render, METH_VARARGS,
+      "render(dia.Renderer: r) -> None."
+      "  Render the layer with the given renderer" },
     {NULL, 0, 0, NULL}
 };
 
diff --git a/plug-ins/python/pydia-render.c b/plug-ins/python/pydia-render.c
index 8988b93..1c759a4 100644
--- a/plug-ins/python/pydia-render.c
+++ b/plug-ins/python/pydia-render.c
@@ -47,6 +47,7 @@
 #include "pydia-image.h"
 #include "pydia-error.h"
 #include "pydia-render.h"
+#include "pydia-layer.h"
 
 #include "diarenderer.h"
 
@@ -415,6 +416,52 @@ is_capable_to (DiaRenderer *renderer, RenderCapability cap)
   return bRet;
 }
 
+/*! 
+ * \brief Render all the visible object in the layer
+ * @param renderer explicit this pointer
+ * @param layer    layer to draw
+ * @param active   TRUE if it is the currently active layer
+ * @param update   the update rectangle, NULL for unlimited
+ *
+ * \memberof _DiaPyRenderer
+ */
+static void
+draw_layer (DiaRenderer *renderer,
+           Layer       *layer,
+           gboolean     active,
+           Rectangle   *update)
+{
+  PyObject *func, *res, *arg, *self = PYDIA_RENDERER (renderer);
+
+  func = PyObject_GetAttrString (self, "draw_layer");
+  if (func && PyCallable_Check(func)) {
+    PyObject *olayer = PyDiaLayer_New (layer);
+    PyObject *orect;
+
+    Py_INCREF (self);
+    Py_INCREF (func);
+    if (update) {
+      orect = PyDiaRectangle_New (update, NULL);
+    } else {
+      Py_INCREF(Py_None);
+      orect = Py_None;
+    }
+    arg = Py_BuildValue ("(OiO)", olayer, active, orect);
+    if (arg) {
+      res = PyEval_CallObject (func, arg);
+      ON_RES(res, FALSE);
+    }
+    Py_XDECREF (olayer);
+    Py_XDECREF (orect);
+    Py_DECREF(func);
+    Py_DECREF(self);
+  } else { /* member optional */
+    PyErr_Clear();
+    /* have to call the base class */
+    DIA_RENDERER_CLASS (parent_class)->draw_layer (renderer, layer, active, update);
+  }
+}
+
 /*!
  * \brief Draw object
  *
@@ -1143,6 +1190,7 @@ dia_py_renderer_class_init (DiaPyRendererClass *klass)
   renderer_class->begin_render = begin_render;
   renderer_class->end_render   = end_render;
 
+  renderer_class->draw_layer = draw_layer;
   renderer_class->draw_object  = draw_object;
 
   renderer_class->set_linewidth  = set_linewidth;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]