[dia] svg: finally support all SVG named colors (plus some dox)
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] svg: finally support all SVG named colors (plus some dox)
- Date: Sun, 7 Oct 2012 13:03:14 +0000 (UTC)
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]