[dia] svg: finally support all SVG named colors (plus some dox)



commit bff01fbb04ee217407f2cd7514c011651f156ce2
Author: Hans Breuer <hans breuer org>
Date:   Sat Oct 6 20:59:24 2012 +0200

    svg: finally support all SVG named colors (plus some dox)
    
    The list of named SVG colors has only 17 entries according to
    http://www.w3.org/TR/CSS21/syndata.html#color-units
    Still pango_color_parse() does not support seven of them
    including 'white' (only 10 out of 17).

 lib/dia_svg.c          |  115 +++++++++++++++++++++++++++++++++------
 samples/svg-colors.svg |  142 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 240 insertions(+), 17 deletions(-)
---
diff --git a/lib/dia_svg.c b/lib/dia_svg.c
index 0980532..44e5a5c 100644
--- a/lib/dia_svg.c
+++ b/lib/dia_svg.c
@@ -30,10 +30,23 @@
 
 #include "dia_svg.h"
 
-/** Initialize a style object from another style object or defaults.
+/*!
+ * \defgroup DiaSvg Services for SVG parsing and generation
+ * \ingroup Plugins
+ * \brief Services for SVG parsing and generation
+ * The Dia application supports various variants of SVG. There are
+ * at least two importers of SVG dialects, namely \ref Shapes and
+ * the standard SVG importer \ref Plugins. Both are using theses
+ * serivces to a large extend, but they are also doing there own
+ * thing regarding the SVG dialect interpretation.
+ */
+
+/*!
+ * \brief Initialize a style object from another style object or defaults.
  * @param gs An SVG style object to initialize.
  * @param parent_style An SVG style object to copy values from, or NULL,
  *                     in which case defaults will be used.
+ * \ingroup DiaSvg
  */
 void
 dia_svg_style_init(DiaSvgStyle *gs, DiaSvgStyle *parent_style)
@@ -54,9 +67,11 @@ dia_svg_style_init(DiaSvgStyle *gs, DiaSvgStyle *parent_style)
   gs->alignment = parent_style ? parent_style->alignment : ALIGN_LEFT;
 }
 
-/** Copy style values from one SVG style object to another.
+/*!
+ * \brief Copy style values from one SVG style object to another.
  * @param dest SVG style object to copy to.
  * @param src SVG style object to copy from.
+ * \ingroup DiaSvg
  */
 void
 dia_svg_style_copy(DiaSvgStyle *dest, DiaSvgStyle *src)
@@ -77,15 +92,74 @@ dia_svg_style_copy(DiaSvgStyle *dest, DiaSvgStyle *src)
   dest->alignment = src->alignment;
 }
 
-/** Parse an SVG color description.
+static const struct _SvgNamedColor {
+  const char *name;
+  const gint  value;
+} _svg_named_colors [] = {
+  { "maroon", 0x800000 },
+  { "red", 0xff0000 },
+  { "orange", 0xffA500 },
+  { "yellow", 0xffff00 },
+  { "olive", 0x808000 },
+  { "purple", 0x800080 },
+  { "fuchsia", 0xff00ff },
+  { "white", 0xffffff },
+  { "lime", 0x00ff00 },
+  { "green", 0x008000 },
+  { "navy", 0x000080 },
+  { "blue", 0x0000ff },
+  { "aqua", 0x00ffff },
+  { "teal", 0x008080 },
+  { "black", 0x000000 },
+  { "silver", 0xc0c0c0 },
+  { "gray", 0x808080 }
+
+};
+
+/*!
+ * \brief Get an SVG color value by name
+ *
+ * The list of named SVG colors has only 17 entries according to
+ * http://www.w3.org/TR/CSS21/syndata.html#color-units
+ * Still pango_color_parse() does not support seven of them including
+ * 'white'. This function supports all of them.
+ *
+ * \ingroup DiaSvg
+ */
+static gboolean
+svg_named_color (const char *name, gint32 *color)
+{
+  int i;
+
+  g_return_val_if_fail (name != NULL && color != NULL, FALSE);
+
+  for (i = 0; i < G_N_ELEMENTS(_svg_named_colors); i++) {
+    if (strncmp (name, _svg_named_colors[i].name, strlen(_svg_named_colors[i].name)) == 0) {
+      *color = _svg_named_colors[i].value;
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+/*! 
+ * \brief Parse an SVG color description.
+ *
  * @param color A place to store the color information (0RGB)
  * @param str An SVG color description string to parse.
  * @return TRUE if parsing was successful.
- * Shouldn't we use an actual Dia Color object as return value?
+ *
+ * This function is rather tolerant compared to the SVG specification.
+ * It supports special names like 'fg', 'bg', 'foregroumd', 'background';
+ * three numeric representations: '#FF0000', 'rgb(1.0,0.0,0.0), 'rgb(100%,0%,0%)'
+ * and named colors from two domains: SVG and Pango.
+ *
+ * \note Shouldn't we use an actual Dia Color object as return value?
  * Would require that the DiaSvgStyle object uses that, too.  If we did that,
  * we could even return the color object directly, and we would be able to use
  * >8 bits per channel.
  * But we would not be able to handle named colors anymore ...
+ *
+ * \ingroup DiaSvg
  */
 static gboolean
 _parse_color(gint32 *color, const char *str)
@@ -126,6 +200,8 @@ _parse_color(gint32 *color, const char *str)
       *color = ((a<<24) & 0xFF000000) | ((r<<16) & 0xFF0000) | ((g<<8) & 0xFF00) | (b & 0xFF);
     else
       return FALSE;
+  } else if (svg_named_color (str, color)) {
+    return TRUE;
   } else {
     /* Pango needs null terminated strings, so we just use it as a fallback */
     PangoColor pc;
@@ -222,12 +298,15 @@ _parse_dasharray (DiaSvgStyle *s, real user_scale, gchar *str, gchar **end)
     *end = ptr;
 }
 
-/** This function not only parses the style attribute of the given node
- *  it also extracts some of the style properties directly.
+/*
+ * \brief Parse SVG style properties
+ * This function not only parses the style attribute of the given node
+ * it also extracts some of the style properties directly.
  * @param node An XML node to parse a style from.
  * @param s The SVG style object to fill out.  This should previously be
  *          initialized to some default values.
  * @param user_scale, if >0 scalable values (font-size, stroke-width, ...) are divided by this, otherwise ignored
+ * \ingroup DiaSvg
  */
 void
 dia_svg_parse_style(xmlNodePtr node, DiaSvgStyle *s, real user_scale)
@@ -487,20 +566,22 @@ dia_svg_parse_style(xmlNodePtr node, DiaSvgStyle *s, real user_scale)
   }
 }
 
-/** Parse a SVG description of an arc segment.
+/*!
+ * \brief Parse a SVG description of an arc segment.
  * Code stolen from (and adapted)
  * http://www.inkscape.org/doc/doxygen/html/svg-path_8cpp.php#a7
  * which may have got it from rsvg, hope it is correct ;)
- * @param points
- * @param xc
- * @param yc
- * @param th0
- * @param th1
- * @param rx
- * @param ry
- * @param x_axis_rotation
- * @param last_p2
- * If you want the description of the algorithm read the SVG specs.
+ * @param points destination array of _BezPoint
+ * @param xc center x
+ * @param yc center y
+ * @param th0 first angle
+ * @param th1 second angle
+ * @param rx radius x
+ * @param ry radius y
+ * @param x_axis_rotation rotation of the axis
+ * @param last_p2 the resulting current point
+ * If you want the description of the algorithm read the SVG specs:
+ * http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands
  */
 static void
 _path_arc_segment(GArray* points,
diff --git a/samples/svg-colors.svg b/samples/svg-colors.svg
new file mode 100644
index 0000000..f43594b
--- /dev/null
+++ b/samples/svg-colors.svg
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd";>
+<svg width="20cm" height="16cm" viewBox="40 20 400 320" xmlns="http://www.w3.org/2000/svg"; xmlns:xlink="http://www.w3.org/1999/xlink";>
+  <g id="Background">
+    <g>
+      <rect style="fill: maroon; fill-opacity: 1" x="40" y="20" width="80" height="80"/>
+      <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #800000" x="40" y="20" width="80" height="80"/>
+      <text font-size="12.8" style="fill: #ffffff; fill-opacity: 1;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="80" y="55.9">
+        <tspan x="80" y="55.9">maroon</tspan>
+        <tspan x="80" y="71.9">#800000</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: red; fill-opacity: 1" x="120" y="20" width="80" height="80"/>
+      <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #ff0000" x="120" y="20" width="80" height="80"/>
+      <text font-size="12.8" style="fill: #ffffff; fill-opacity: 1;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="160" y="55.9">
+        <tspan x="160" y="55.9">red</tspan>
+        <tspan x="160" y="71.9">#FF0000</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: orange; fill-opacity: 1" x="200" y="20" width="80" height="80"/>
+      <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #ffa500" x="200" y="20" width="80" height="80"/>
+      <text font-size="12.8" style="fill: #000000; fill-opacity: 1;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="240" y="55.9">
+        <tspan x="240" y="55.9">orange</tspan>
+        <tspan x="240" y="71.9">#FFA500</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: yellow; fill-opacity: 1" x="280" y="20" width="80" height="80"/>
+      <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #ffff00" x="280" y="20" width="80" height="80"/>
+      <text font-size="12.8" style="fill: #000000; fill-opacity: 1;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="320" y="55.9">
+        <tspan x="320" y="55.9">yellow</tspan>
+        <tspan x="320" y="71.9">#FFFF00</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: olive; fill-opacity: 1" x="360" y="20" width="80" height="80"/>
+      <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #808000" x="360" y="20" width="80" height="80"/>
+      <text font-size="12.8" style="fill: #ffffff; fill-opacity: 1;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="400" y="55.9">
+        <tspan x="400" y="55.9">olive</tspan>
+        <tspan x="400" y="71.9">#808000</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: purple; fill-opacity: 1" x="40" y="100" width="80" height="80"/>
+      <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #800080" x="40" y="100" width="80" height="80"/>
+      <text font-size="12.8" style="fill: #ffffff; fill-opacity: 1;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="80" y="135.9">
+        <tspan x="80" y="135.9">purple</tspan>
+        <tspan x="80" y="151.9">#800080</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: fuchsia; fill-opacity: 1" x="120" y="100" width="80" height="80"/>
+      <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #ff00ff" x="120" y="100" width="80" height="80"/>
+      <text font-size="12.8" style="fill: #000000; fill-opacity: 1;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="160" y="135.9">
+        <tspan x="160" y="135.9">fuchsia</tspan>
+        <tspan x="160" y="151.9">#FF00FF</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: #ffffff; fill-opacity: 1" x="200" y="100" width="80" height="80"/>
+      <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #ffffff" x="200" y="100" width="80" height="80"/>
+      <text font-size="12.8" style="fill: #000000; fill-opacity: 1;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="240" y="135.9">
+        <tspan x="240" y="135.9">white</tspan>
+        <tspan x="240" y="151.9">#FFFFFF</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: lime; fill-opacity: 1" x="280" y="100" width="80" height="80"/>
+      <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #00ff00" x="280" y="100" width="80" height="80"/>
+      <text font-size="12.8" style="fill: #000000; fill-opacity: 1;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="320" y="135.9">
+        <tspan x="320" y="135.9">lime</tspan>
+        <tspan x="320" y="151.9">#00FF00</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: green; fill-opacity: 1" x="360" y="100" width="80" height="80"/>
+      <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #008000" x="360" y="100" width="80" height="80"/>
+      <text font-size="12.8" style="fill: #ffffff; fill-opacity: 1;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="400" y="135.9">
+        <tspan x="400" y="135.9">green</tspan>
+        <tspan x="400" y="151.9">#008000</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: navy; fill-opacity: 1" x="80" y="180" width="80" height="80"/>
+      <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #000080" x="80" y="180" width="80" height="80"/>
+      <text font-size="12.8" style="fill: #ffffff; fill-opacity: 1;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="120" y="215.9">
+        <tspan x="120" y="215.9">navy</tspan>
+        <tspan x="120" y="231.9">#000080</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: blue; fill-opacity: 1" x="160" y="180" width="80" height="80"/>
+      <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #0000ff" x="160" y="180" width="80" height="80"/>
+      <text font-size="12.8" style="fill: #ffffff; fill-opacity: 1;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="200" y="215.9">
+        <tspan x="200" y="215.9">blue</tspan>
+        <tspan x="200" y="231.9">#00FF00</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: aqua; fill-opacity: 1" x="240" y="180" width="80" height="80"/>
+      <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #00ffff" x="240" y="180" width="80" height="80"/>
+      <text font-size="12.8" style="fill: #000000; fill-opacity: 1;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="280" y="215.9">
+        <tspan x="280" y="215.9">aqua</tspan>
+        <tspan x="280" y="231.9">#00FFFF</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: teal; fill-opacity: 1" x="320" y="180" width="80" height="80"/>
+      <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #008080" x="320" y="180" width="80" height="80"/>
+      <text font-size="12.8" style="fill: #ffffff; fill-opacity: 1;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="360" y="215.9">
+        <tspan x="360" y="215.9">teal</tspan>
+        <tspan x="360" y="231.9">#008080</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: black; fill-opacity: 1" x="120" y="260" width="80" height="80"/>
+      <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #000000" x="120" y="260" width="80" height="80"/>
+      <text font-size="12.8" style="fill: #ffffff; fill-opacity: 1;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="160" y="295.9">
+        <tspan x="160" y="295.9">black</tspan>
+        <tspan x="160" y="311.9">#000000</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: silver; fill-opacity: 1" x="200" y="260" width="80" height="80"/>
+      <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #c0c0c0" x="200" y="260" width="80" height="80"/>
+      <text font-size="12.8" style="fill: #000000; fill-opacity: 1;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="240" y="295.9">
+        <tspan x="240" y="295.9">silver</tspan>
+        <tspan x="240" y="311.9">#C0C0C0</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: gray; fill-opacity: 1" x="280" y="260" width="80" height="80"/>
+      <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #808080" x="280" y="260" width="80" height="80"/>
+      <text font-size="12.8" style="fill: #ffffff; fill-opacity: 1;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="320" y="295.9">
+        <tspan x="320" y="295.9">gray</tspan>
+        <tspan x="320" y="311.9">#808080</tspan>
+      </text>
+    </g>
+  </g>
+</svg>



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