[dia] svg: optimize SvgRenderer::draw_object() with matrix



commit 7e7327a576fd001f03fd0fc24980d2b74ec94021
Author: Hans Breuer <hans breuer org>
Date:   Wed Sep 10 21:51:50 2014 +0200

    svg: optimize SvgRenderer::draw_object() with matrix
    
    by inlining the group drwaing we can create a single transform for the
    whole group rather than transformation groups for every object in it.

 lib/group.c               |    6 ++++
 lib/group.h               |    2 +
 lib/libdia.def            |    1 +
 plug-ins/svg/render_svg.c |   63 ++++++++++++++++++++++++++++++--------------
 4 files changed, 52 insertions(+), 20 deletions(-)
---
diff --git a/lib/group.c b/lib/group.c
index 1f59600..d3185c6 100644
--- a/lib/group.c
+++ b/lib/group.c
@@ -895,3 +895,9 @@ group_transform (Group *group, const DiaMatrix *m)
   }
   group_update_data (group);
 }
+
+const DiaMatrix *
+group_get_transform (Group *group)
+{
+  return group->matrix;
+}
diff --git a/lib/group.h b/lib/group.h
index e3022bb..ce3705e 100644
--- a/lib/group.h
+++ b/lib/group.h
@@ -34,6 +34,8 @@ GList *group_objects(DiaObject *group);
 
 void group_destroy_shallow(DiaObject *group);
 void group_transform (Group *group, const DiaMatrix *mat);
+const DiaMatrix *group_get_transform (Group *group);
+
 #define IS_GROUP(obj) ((obj)->type == &group_type)
 
 G_END_DECLS
diff --git a/lib/libdia.def b/lib/libdia.def
index 3afaa56..eed7dcd 100644
--- a/lib/libdia.def
+++ b/lib/libdia.def
@@ -486,6 +486,7 @@ EXPORTS
 
  group_create
  group_create_with_matrix
+ group_get_transform
  group_destroy_shallow
  group_objects
  group_type
diff --git a/plug-ins/svg/render_svg.c b/plug-ins/svg/render_svg.c
index 57b693d..97950cd 100644
--- a/plug-ins/svg/render_svg.c
+++ b/plug-ins/svg/render_svg.c
@@ -43,6 +43,7 @@
 #include "diagramdata.h"
 #include "dia_xml_libxml.h"
 #include "object.h"
+#include "group.h"
 #include "textline.h"
 #include "dia_svg.h"
 
@@ -333,28 +334,50 @@ draw_object(DiaRenderer *self,
   /* modifying the root pointer so everything below us gets into the new node */
   renderer->root = group = xmlNewNode (renderer->svg_name_space, (const xmlChar *)"g");
 
-  if (matrix) {
-    gchar *s = dia_svg_from_matrix (matrix, renderer->scale);
-    xmlSetProp(renderer->root, (const xmlChar *)"transform", (xmlChar *) s);
-    g_free (s);
-  }
+  if (IS_GROUP (object) && !matrix) {
+    /* group_draw() is applying it's matrix to every child, but we can do
+     * better with inline version of group drawing
+     */
+    const DiaMatrix *gm = group_get_transform ((Group *)object);
+    GList *objs = group_objects (object);
+
+    if (gm) {
+      gchar *s = dia_svg_from_matrix (gm, renderer->scale);
+      xmlSetProp(renderer->root, (const xmlChar *)"transform", (xmlChar *) s);
+      g_free (s);
+    }
+    while (objs) {
+      DiaObject *obj = (DiaObject *)objs->data;
 
-  object->ops->draw(object, DIA_RENDERER (renderer));
-  
-  /* no easy way to count? */
-  child = renderer->root->children;
-  while (child != NULL) {
-    child = child->next;
-    ++n_children;
-  }
-  renderer->root = g_queue_pop_tail (svg_renderer->parents);
-  /* if there is only one element added to the group node unpack it again  */
-  if (1 == n_children && !matrix) {
-    xmlAddChild (renderer->root, group->children);
-    xmlUnlinkNode (group); /* dont free the children */
-    xmlFree (group);
-  } else {
+      obj->ops->draw(obj, DIA_RENDERER (renderer));
+      objs = objs->next;
+    }
+    renderer->root = g_queue_pop_tail (svg_renderer->parents);
     xmlAddChild (renderer->root, group);
+  } else {
+    if (matrix) {
+      gchar *s = dia_svg_from_matrix (matrix, renderer->scale);
+      xmlSetProp(renderer->root, (const xmlChar *)"transform", (xmlChar *) s);
+      g_free (s);
+    }
+
+    object->ops->draw(object, DIA_RENDERER (renderer));
+  
+    /* no easy way to count? */
+    child = renderer->root->children;
+    while (child != NULL) {
+      child = child->next;
+      ++n_children;
+    }
+    renderer->root = g_queue_pop_tail (svg_renderer->parents);
+    /* if there is only one element added to the group node unpack it again  */
+    if (1 == n_children && !matrix) {
+      xmlAddChild (renderer->root, group->children);
+      xmlUnlinkNode (group); /* dont free the children */
+      xmlFree (group);
+    } else {
+      xmlAddChild (renderer->root, group);
+    }
   }
 }
 


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