[dia] Bug 568168 - also SVG can render holes, Shape should not.



commit 7d0d7226f58f422ae3c57d9c474613526a5ba59c
Author: Hans Breuer <hans breuer org>
Date:   Fri Sep 14 19:48:45 2012 +0200

    Bug 568168 - also SVG can render holes, Shape should not.
    
    Implement SvgRenderer::is_capable_to() on par with cairo.
    Avoid code duplication in base class. Still the ShapeRenderer
    would complain on multiple move-to and keeps rendering the
    last segment.
    Actually that does not happen with e.g. render-test.dia,
    because "Standard - Outine" checks renderer capabilities
    before using them.

 lib/diasvgrenderer.c      |   88 +++++++++++++++------------------------------
 plug-ins/svg/render_svg.c |   32 ++++++++++++++---
 2 files changed, 56 insertions(+), 64 deletions(-)
---
diff --git a/lib/diasvgrenderer.c b/lib/diasvgrenderer.c
index 4d8055d..4c2b9a1 100644
--- a/lib/diasvgrenderer.c
+++ b/lib/diasvgrenderer.c
@@ -539,10 +539,11 @@ fill_ellipse(DiaRenderer *self,
 }
 
 static void
-draw_bezier(DiaRenderer *self, 
-	    BezPoint *points,
-	    int numpoints,
-	    Color *colour)
+_bezier(DiaRenderer *self, 
+	BezPoint *points,
+	int numpoints,
+	Color *colour,
+	gboolean fill)
 {
   DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
   int i;
@@ -557,7 +558,8 @@ draw_bezier(DiaRenderer *self,
 
   node = xmlNewChild(renderer->root, renderer->svg_name_space, (const xmlChar *)"path", NULL);
   
-  xmlSetProp(node, (const xmlChar *)"style", (xmlChar *) get_draw_style(renderer, colour));
+  xmlSetProp(node, (const xmlChar *)"style",
+	     (xmlChar *)(fill ? get_fill_style(renderer, colour) : get_draw_style(renderer, colour)));
 
   str = g_string_new(NULL);
 
@@ -571,10 +573,16 @@ draw_bezier(DiaRenderer *self,
   for (i = 1; i < numpoints; i++)
     switch (points[i].type) {
     case BEZ_MOVE_TO:
-      g_warning("only first BezPoint shoul be a BEZ_MOVE_TO");
-      g_string_printf(str, "M %s %s",
-		      dia_svg_dtostr(p1x_buf, (gdouble) points[i].p1.x),
-		      dia_svg_dtostr(p1y_buf, (gdouble) points[i].p1.y) );
+      if (!DIA_RENDERER_GET_CLASS (self)->is_capable_to(self, RENDER_HOLES)) {
+        g_warning("only first BezPoint should be a BEZ_MOVE_TO");
+        g_string_printf(str, "M %s %s",
+		        dia_svg_dtostr(p1x_buf, (gdouble) points[i].p1.x),
+		        dia_svg_dtostr(p1y_buf, (gdouble) points[i].p1.y) );
+      } else {
+        g_string_append_printf(str, "M %s %s",
+		        dia_svg_dtostr(p1x_buf, (gdouble) points[i].p1.x),
+		        dia_svg_dtostr(p1y_buf, (gdouble) points[i].p1.y) );
+      }
       break;
     case BEZ_LINE_TO:
       g_string_append_printf(str, " L %s,%s",
@@ -591,66 +599,28 @@ draw_bezier(DiaRenderer *self,
 			dia_svg_dtostr(p3y_buf, (gdouble) points[i].p3.y) );
       break;
     }
+  if (fill)
+    g_string_append(str, "z");
   xmlSetProp(node, (const xmlChar *)"d", (xmlChar *) str->str);
   g_string_free(str, TRUE);
 }
 
 static void
+draw_bezier(DiaRenderer *self, 
+	    BezPoint *points,
+	    int numpoints,
+	    Color *colour)
+{
+  _bezier(self, points, numpoints, colour, FALSE);
+}
+
+static void
 fill_bezier(DiaRenderer *self, 
 	    BezPoint *points, /* Last point must be same as first point */
 	    int numpoints,
 	    Color *colour)
 {
-  DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
-  int i;
-  xmlNodePtr node;
-  GString *str;
-  gchar p1x_buf[DTOSTR_BUF_SIZE];
-  gchar p1y_buf[DTOSTR_BUF_SIZE];
-  gchar p2x_buf[DTOSTR_BUF_SIZE];
-  gchar p2y_buf[DTOSTR_BUF_SIZE];
-  gchar p3x_buf[DTOSTR_BUF_SIZE];
-  gchar p3y_buf[DTOSTR_BUF_SIZE];
-
-  node = xmlNewChild(renderer->root, renderer->svg_name_space, (const xmlChar *)"path", NULL);
-  
-  xmlSetProp(node, (const xmlChar *)"style", (xmlChar *) get_fill_style(renderer, colour));
-
-  str = g_string_new(NULL);
-
-  if (points[0].type != BEZ_MOVE_TO)
-    g_warning("first BezPoint must be a BEZ_MOVE_TO");
-
-  g_string_printf(str, "M %s %s",
-		   dia_svg_dtostr(p1x_buf, (gdouble) points[0].p1.x),
-		   dia_svg_dtostr(p1y_buf, (gdouble) points[0].p1.y) );
- 
-  for (i = 1; i < numpoints; i++)
-    switch (points[i].type) {
-    case BEZ_MOVE_TO:
-      g_warning("only first BezPoint should be a BEZ_MOVE_TO");
-      g_string_printf(str, "M %s %s",
-		      dia_svg_dtostr(p1x_buf, (gdouble) points[i].p1.x),
-		      dia_svg_dtostr(p1y_buf, (gdouble) points[i].p1.y) );
-      break;
-    case BEZ_LINE_TO:
-      g_string_append_printf(str, " L %s,%s",
-			dia_svg_dtostr(p1x_buf, (gdouble) points[i].p1.x),
-			dia_svg_dtostr(p1y_buf, (gdouble) points[i].p1.y) );
-      break;
-    case BEZ_CURVE_TO:
-      g_string_append_printf(str, " C %s,%s %s,%s %s,%s",
-			dia_svg_dtostr(p1x_buf, (gdouble) points[i].p1.x),
-			dia_svg_dtostr(p1y_buf, (gdouble) points[i].p1.y),
-			dia_svg_dtostr(p2x_buf, (gdouble) points[i].p2.x),
-			dia_svg_dtostr(p2y_buf, (gdouble) points[i].p2.y),
-			dia_svg_dtostr(p3x_buf, (gdouble) points[i].p3.x),
-			dia_svg_dtostr(p3y_buf, (gdouble) points[i].p3.y) );
-      break;
-    }
-  g_string_append(str, "z");
-  xmlSetProp(node, (const xmlChar *)"d", (xmlChar *) str->str);
-  g_string_free(str, TRUE);
+  _bezier(self, points, numpoints, colour, TRUE);
 }
 
 static void
diff --git a/plug-ins/svg/render_svg.c b/plug-ins/svg/render_svg.c
index 45f3e52..54f2322 100644
--- a/plug-ins/svg/render_svg.c
+++ b/plug-ins/svg/render_svg.c
@@ -158,6 +158,27 @@ end_render (DiaRenderer *self)
   DIA_RENDERER_CLASS (parent_class)->end_render (DIA_RENDERER (self));
 }
 
+/*!
+ * \brief Advertize special capabilities
+ *
+ * Some objects drawing adapts to capabilities advertized by the respective
+ * renderer. Usually there is a fallback, but generally the real thing should
+ * be better.
+ *
+ * \memberof SvgRenderer
+ */
+static gboolean 
+is_capable_to (DiaRenderer *renderer, RenderCapability cap)
+{
+  if (RENDER_HOLES == cap)
+    return TRUE;
+  else if (RENDER_ALPHA == cap)
+    return TRUE;
+  else if (RENDER_AFFINE == cap)
+    return TRUE;
+  return FALSE;
+}
+
 /* destructor */
 static void
 svg_renderer_finalize (GObject *object)
@@ -187,6 +208,7 @@ svg_renderer_class_init (SvgRendererClass *klass)
   renderer_class->draw_string  = draw_string;
   renderer_class->draw_text  = draw_text;
   renderer_class->draw_text_line  = draw_text_line;
+  renderer_class->is_capable_to = is_capable_to;
 }
 
 /*!
@@ -255,7 +277,7 @@ new_svg_renderer(DiagramData *data, const char *filename)
  * We could try to be smart and count the objects we using for the object.
  * If it is only one the grouping is superfluous and should be removed.
  *
- * \memberof ScgRenderer
+ * \memberof SvgRenderer
  */
 static void 
 draw_object(DiaRenderer *self,
@@ -269,15 +291,15 @@ draw_object(DiaRenderer *self,
 
   g_queue_push_tail (svg_renderer->parents, renderer->root);
 
+  /* 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);
   }
 
-  /* modifying the root pointer so everything below us gets into the new node */
-  renderer->root = group = xmlNewNode (renderer->svg_name_space, (const xmlChar *)"g");
-
   object->ops->draw(object, DIA_RENDERER (renderer));
   
   /* no easy way to count? */
@@ -288,7 +310,7 @@ draw_object(DiaRenderer *self,
   }
   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) {
+  if (1 == n_children && !matrix) {
     xmlAddChild (renderer->root, group->children);
     xmlUnlinkNode (group); /* dont free the children */
     xmlFree (group);



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