• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Keine Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

作図ソフト dia の改良版


Commit MetaInfo

Revisionbff01fbb04ee217407f2cd7514c011651f156ce2 (tree)
Zeit2012-10-07 22:01:19
AutorHans Breuer <hans@breu...>
CommiterHans Breuer

Log Message

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).

Ändern Zusammenfassung

Diff

--- a/lib/dia_svg.c
+++ b/lib/dia_svg.c
@@ -30,10 +30,23 @@
3030
3131 #include "dia_svg.h"
3232
33-/** Initialize a style object from another style object or defaults.
33+/*!
34+ * \defgroup DiaSvg Services for SVG parsing and generation
35+ * \ingroup Plugins
36+ * \brief Services for SVG parsing and generation
37+ * The Dia application supports various variants of SVG. There are
38+ * at least two importers of SVG dialects, namely \ref Shapes and
39+ * the standard SVG importer \ref Plugins. Both are using theses
40+ * serivces to a large extend, but they are also doing there own
41+ * thing regarding the SVG dialect interpretation.
42+ */
43+
44+/*!
45+ * \brief Initialize a style object from another style object or defaults.
3446 * @param gs An SVG style object to initialize.
3547 * @param parent_style An SVG style object to copy values from, or NULL,
3648 * in which case defaults will be used.
49+ * \ingroup DiaSvg
3750 */
3851 void
3952 dia_svg_style_init(DiaSvgStyle *gs, DiaSvgStyle *parent_style)
@@ -54,9 +67,11 @@ dia_svg_style_init(DiaSvgStyle *gs, DiaSvgStyle *parent_style)
5467 gs->alignment = parent_style ? parent_style->alignment : ALIGN_LEFT;
5568 }
5669
57-/** Copy style values from one SVG style object to another.
70+/*!
71+ * \brief Copy style values from one SVG style object to another.
5872 * @param dest SVG style object to copy to.
5973 * @param src SVG style object to copy from.
74+ * \ingroup DiaSvg
6075 */
6176 void
6277 dia_svg_style_copy(DiaSvgStyle *dest, DiaSvgStyle *src)
@@ -77,15 +92,74 @@ dia_svg_style_copy(DiaSvgStyle *dest, DiaSvgStyle *src)
7792 dest->alignment = src->alignment;
7893 }
7994
80-/** Parse an SVG color description.
95+static const struct _SvgNamedColor {
96+ const char *name;
97+ const gint value;
98+} _svg_named_colors [] = {
99+ { "maroon", 0x800000 },
100+ { "red", 0xff0000 },
101+ { "orange", 0xffA500 },
102+ { "yellow", 0xffff00 },
103+ { "olive", 0x808000 },
104+ { "purple", 0x800080 },
105+ { "fuchsia", 0xff00ff },
106+ { "white", 0xffffff },
107+ { "lime", 0x00ff00 },
108+ { "green", 0x008000 },
109+ { "navy", 0x000080 },
110+ { "blue", 0x0000ff },
111+ { "aqua", 0x00ffff },
112+ { "teal", 0x008080 },
113+ { "black", 0x000000 },
114+ { "silver", 0xc0c0c0 },
115+ { "gray", 0x808080 }
116+
117+};
118+
119+/*!
120+ * \brief Get an SVG color value by name
121+ *
122+ * The list of named SVG colors has only 17 entries according to
123+ * http://www.w3.org/TR/CSS21/syndata.html#color-units
124+ * Still pango_color_parse() does not support seven of them including
125+ * 'white'. This function supports all of them.
126+ *
127+ * \ingroup DiaSvg
128+ */
129+static gboolean
130+svg_named_color (const char *name, gint32 *color)
131+{
132+ int i;
133+
134+ g_return_val_if_fail (name != NULL && color != NULL, FALSE);
135+
136+ for (i = 0; i < G_N_ELEMENTS(_svg_named_colors); i++) {
137+ if (strncmp (name, _svg_named_colors[i].name, strlen(_svg_named_colors[i].name)) == 0) {
138+ *color = _svg_named_colors[i].value;
139+ return TRUE;
140+ }
141+ }
142+ return FALSE;
143+}
144+/*!
145+ * \brief Parse an SVG color description.
146+ *
81147 * @param color A place to store the color information (0RGB)
82148 * @param str An SVG color description string to parse.
83149 * @return TRUE if parsing was successful.
84- * Shouldn't we use an actual Dia Color object as return value?
150+ *
151+ * This function is rather tolerant compared to the SVG specification.
152+ * It supports special names like 'fg', 'bg', 'foregroumd', 'background';
153+ * three numeric representations: '#FF0000', 'rgb(1.0,0.0,0.0), 'rgb(100%,0%,0%)'
154+ * and named colors from two domains: SVG and Pango.
155+ *
156+ * \note Shouldn't we use an actual Dia Color object as return value?
85157 * Would require that the DiaSvgStyle object uses that, too. If we did that,
86158 * we could even return the color object directly, and we would be able to use
87159 * >8 bits per channel.
88160 * But we would not be able to handle named colors anymore ...
161+ *
162+ * \ingroup DiaSvg
89163 */
90164 static gboolean
91165 _parse_color(gint32 *color, const char *str)
@@ -126,6 +200,8 @@ _parse_color(gint32 *color, const char *str)
126200 *color = ((a<<24) & 0xFF000000) | ((r<<16) & 0xFF0000) | ((g<<8) & 0xFF00) | (b & 0xFF);
127201 else
128202 return FALSE;
203+ } else if (svg_named_color (str, color)) {
204+ return TRUE;
129205 } else {
130206 /* Pango needs null terminated strings, so we just use it as a fallback */
131207 PangoColor pc;
@@ -222,12 +298,15 @@ _parse_dasharray (DiaSvgStyle *s, real user_scale, gchar *str, gchar **end)
222298 *end = ptr;
223299 }
224300
225-/** This function not only parses the style attribute of the given node
226- * it also extracts some of the style properties directly.
301+/*
302+ * \brief Parse SVG style properties
303+ * This function not only parses the style attribute of the given node
304+ * it also extracts some of the style properties directly.
227305 * @param node An XML node to parse a style from.
228306 * @param s The SVG style object to fill out. This should previously be
229307 * initialized to some default values.
230308 * @param user_scale, if >0 scalable values (font-size, stroke-width, ...) are divided by this, otherwise ignored
309+ * \ingroup DiaSvg
231310 */
232311 void
233312 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)
487566 }
488567 }
489568
490-/** Parse a SVG description of an arc segment.
569+/*!
570+ * \brief Parse a SVG description of an arc segment.
491571 * Code stolen from (and adapted)
492572 * http://www.inkscape.org/doc/doxygen/html/svg-path_8cpp.php#a7
493573 * which may have got it from rsvg, hope it is correct ;)
494- * @param points
495- * @param xc
496- * @param yc
497- * @param th0
498- * @param th1
499- * @param rx
500- * @param ry
501- * @param x_axis_rotation
502- * @param last_p2
503- * If you want the description of the algorithm read the SVG specs.
574+ * @param points destination array of _BezPoint
575+ * @param xc center x
576+ * @param yc center y
577+ * @param th0 first angle
578+ * @param th1 second angle
579+ * @param rx radius x
580+ * @param ry radius y
581+ * @param x_axis_rotation rotation of the axis
582+ * @param last_p2 the resulting current point
583+ * If you want the description of the algorithm read the SVG specs:
584+ * http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands
504585 */
505586 static void
506587 _path_arc_segment(GArray* points,
--- /dev/null
+++ b/samples/svg-colors.svg
@@ -0,0 +1,142 @@
1+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
3+<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">
4+ <g id="Background">
5+ <g>
6+ <rect style="fill: maroon; fill-opacity: 1" x="40" y="20" width="80" height="80"/>
7+ <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #800000" x="40" y="20" width="80" height="80"/>
8+ <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">
9+ <tspan x="80" y="55.9">maroon</tspan>
10+ <tspan x="80" y="71.9">#800000</tspan>
11+ </text>
12+ </g>
13+ <g>
14+ <rect style="fill: red; fill-opacity: 1" x="120" y="20" width="80" height="80"/>
15+ <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #ff0000" x="120" y="20" width="80" height="80"/>
16+ <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">
17+ <tspan x="160" y="55.9">red</tspan>
18+ <tspan x="160" y="71.9">#FF0000</tspan>
19+ </text>
20+ </g>
21+ <g>
22+ <rect style="fill: orange; fill-opacity: 1" x="200" y="20" width="80" height="80"/>
23+ <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #ffa500" x="200" y="20" width="80" height="80"/>
24+ <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">
25+ <tspan x="240" y="55.9">orange</tspan>
26+ <tspan x="240" y="71.9">#FFA500</tspan>
27+ </text>
28+ </g>
29+ <g>
30+ <rect style="fill: yellow; fill-opacity: 1" x="280" y="20" width="80" height="80"/>
31+ <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #ffff00" x="280" y="20" width="80" height="80"/>
32+ <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">
33+ <tspan x="320" y="55.9">yellow</tspan>
34+ <tspan x="320" y="71.9">#FFFF00</tspan>
35+ </text>
36+ </g>
37+ <g>
38+ <rect style="fill: olive; fill-opacity: 1" x="360" y="20" width="80" height="80"/>
39+ <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #808000" x="360" y="20" width="80" height="80"/>
40+ <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">
41+ <tspan x="400" y="55.9">olive</tspan>
42+ <tspan x="400" y="71.9">#808000</tspan>
43+ </text>
44+ </g>
45+ <g>
46+ <rect style="fill: purple; fill-opacity: 1" x="40" y="100" width="80" height="80"/>
47+ <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #800080" x="40" y="100" width="80" height="80"/>
48+ <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">
49+ <tspan x="80" y="135.9">purple</tspan>
50+ <tspan x="80" y="151.9">#800080</tspan>
51+ </text>
52+ </g>
53+ <g>
54+ <rect style="fill: fuchsia; fill-opacity: 1" x="120" y="100" width="80" height="80"/>
55+ <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #ff00ff" x="120" y="100" width="80" height="80"/>
56+ <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">
57+ <tspan x="160" y="135.9">fuchsia</tspan>
58+ <tspan x="160" y="151.9">#FF00FF</tspan>
59+ </text>
60+ </g>
61+ <g>
62+ <rect style="fill: #ffffff; fill-opacity: 1" x="200" y="100" width="80" height="80"/>
63+ <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #ffffff" x="200" y="100" width="80" height="80"/>
64+ <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">
65+ <tspan x="240" y="135.9">white</tspan>
66+ <tspan x="240" y="151.9">#FFFFFF</tspan>
67+ </text>
68+ </g>
69+ <g>
70+ <rect style="fill: lime; fill-opacity: 1" x="280" y="100" width="80" height="80"/>
71+ <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #00ff00" x="280" y="100" width="80" height="80"/>
72+ <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">
73+ <tspan x="320" y="135.9">lime</tspan>
74+ <tspan x="320" y="151.9">#00FF00</tspan>
75+ </text>
76+ </g>
77+ <g>
78+ <rect style="fill: green; fill-opacity: 1" x="360" y="100" width="80" height="80"/>
79+ <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #008000" x="360" y="100" width="80" height="80"/>
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">
81+ <tspan x="400" y="135.9">green</tspan>
82+ <tspan x="400" y="151.9">#008000</tspan>
83+ </text>
84+ </g>
85+ <g>
86+ <rect style="fill: navy; fill-opacity: 1" x="80" y="180" width="80" height="80"/>
87+ <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #000080" x="80" y="180" width="80" height="80"/>
88+ <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">
89+ <tspan x="120" y="215.9">navy</tspan>
90+ <tspan x="120" y="231.9">#000080</tspan>
91+ </text>
92+ </g>
93+ <g>
94+ <rect style="fill: blue; fill-opacity: 1" x="160" y="180" width="80" height="80"/>
95+ <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #0000ff" x="160" y="180" width="80" height="80"/>
96+ <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">
97+ <tspan x="200" y="215.9">blue</tspan>
98+ <tspan x="200" y="231.9">#00FF00</tspan>
99+ </text>
100+ </g>
101+ <g>
102+ <rect style="fill: aqua; fill-opacity: 1" x="240" y="180" width="80" height="80"/>
103+ <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #00ffff" x="240" y="180" width="80" height="80"/>
104+ <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">
105+ <tspan x="280" y="215.9">aqua</tspan>
106+ <tspan x="280" y="231.9">#00FFFF</tspan>
107+ </text>
108+ </g>
109+ <g>
110+ <rect style="fill: teal; fill-opacity: 1" x="320" y="180" width="80" height="80"/>
111+ <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #008080" x="320" y="180" width="80" height="80"/>
112+ <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">
113+ <tspan x="360" y="215.9">teal</tspan>
114+ <tspan x="360" y="231.9">#008080</tspan>
115+ </text>
116+ </g>
117+ <g>
118+ <rect style="fill: black; fill-opacity: 1" x="120" y="260" width="80" height="80"/>
119+ <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #000000" x="120" y="260" width="80" height="80"/>
120+ <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">
121+ <tspan x="160" y="295.9">black</tspan>
122+ <tspan x="160" y="311.9">#000000</tspan>
123+ </text>
124+ </g>
125+ <g>
126+ <rect style="fill: silver; fill-opacity: 1" x="200" y="260" width="80" height="80"/>
127+ <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #c0c0c0" x="200" y="260" width="80" height="80"/>
128+ <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">
129+ <tspan x="240" y="295.9">silver</tspan>
130+ <tspan x="240" y="311.9">#C0C0C0</tspan>
131+ </text>
132+ </g>
133+ <g>
134+ <rect style="fill: gray; fill-opacity: 1" x="280" y="260" width="80" height="80"/>
135+ <rect style="fill: none; stroke-opacity: 1; stroke-width: 2.35099e-037; stroke: #808080" x="280" y="260" width="80" height="80"/>
136+ <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">
137+ <tspan x="320" y="295.9">gray</tspan>
138+ <tspan x="320" y="311.9">#808080</tspan>
139+ </text>
140+ </g>
141+ </g>
142+</svg>