作図ソフト dia の改良版
Revisão | bff01fbb04ee217407f2cd7514c011651f156ce2 (tree) |
---|---|
Hora | 2012-10-07 22:01:19 |
Autor | Hans Breuer <hans@breu...> |
Commiter | Hans Breuer |
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).
@@ -30,10 +30,23 @@ | ||
30 | 30 | |
31 | 31 | #include "dia_svg.h" |
32 | 32 | |
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. | |
34 | 46 | * @param gs An SVG style object to initialize. |
35 | 47 | * @param parent_style An SVG style object to copy values from, or NULL, |
36 | 48 | * in which case defaults will be used. |
49 | + * \ingroup DiaSvg | |
37 | 50 | */ |
38 | 51 | void |
39 | 52 | dia_svg_style_init(DiaSvgStyle *gs, DiaSvgStyle *parent_style) |
@@ -54,9 +67,11 @@ dia_svg_style_init(DiaSvgStyle *gs, DiaSvgStyle *parent_style) | ||
54 | 67 | gs->alignment = parent_style ? parent_style->alignment : ALIGN_LEFT; |
55 | 68 | } |
56 | 69 | |
57 | -/** Copy style values from one SVG style object to another. | |
70 | +/*! | |
71 | + * \brief Copy style values from one SVG style object to another. | |
58 | 72 | * @param dest SVG style object to copy to. |
59 | 73 | * @param src SVG style object to copy from. |
74 | + * \ingroup DiaSvg | |
60 | 75 | */ |
61 | 76 | void |
62 | 77 | dia_svg_style_copy(DiaSvgStyle *dest, DiaSvgStyle *src) |
@@ -77,15 +92,74 @@ dia_svg_style_copy(DiaSvgStyle *dest, DiaSvgStyle *src) | ||
77 | 92 | dest->alignment = src->alignment; |
78 | 93 | } |
79 | 94 | |
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 | + * | |
81 | 147 | * @param color A place to store the color information (0RGB) |
82 | 148 | * @param str An SVG color description string to parse. |
83 | 149 | * @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? | |
85 | 157 | * Would require that the DiaSvgStyle object uses that, too. If we did that, |
86 | 158 | * we could even return the color object directly, and we would be able to use |
87 | 159 | * >8 bits per channel. |
88 | 160 | * But we would not be able to handle named colors anymore ... |
161 | + * | |
162 | + * \ingroup DiaSvg | |
89 | 163 | */ |
90 | 164 | static gboolean |
91 | 165 | _parse_color(gint32 *color, const char *str) |
@@ -126,6 +200,8 @@ _parse_color(gint32 *color, const char *str) | ||
126 | 200 | *color = ((a<<24) & 0xFF000000) | ((r<<16) & 0xFF0000) | ((g<<8) & 0xFF00) | (b & 0xFF); |
127 | 201 | else |
128 | 202 | return FALSE; |
203 | + } else if (svg_named_color (str, color)) { | |
204 | + return TRUE; | |
129 | 205 | } else { |
130 | 206 | /* Pango needs null terminated strings, so we just use it as a fallback */ |
131 | 207 | PangoColor pc; |
@@ -222,12 +298,15 @@ _parse_dasharray (DiaSvgStyle *s, real user_scale, gchar *str, gchar **end) | ||
222 | 298 | *end = ptr; |
223 | 299 | } |
224 | 300 | |
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. | |
227 | 305 | * @param node An XML node to parse a style from. |
228 | 306 | * @param s The SVG style object to fill out. This should previously be |
229 | 307 | * initialized to some default values. |
230 | 308 | * @param user_scale, if >0 scalable values (font-size, stroke-width, ...) are divided by this, otherwise ignored |
309 | + * \ingroup DiaSvg | |
231 | 310 | */ |
232 | 311 | void |
233 | 312 | 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) | ||
487 | 566 | } |
488 | 567 | } |
489 | 568 | |
490 | -/** Parse a SVG description of an arc segment. | |
569 | +/*! | |
570 | + * \brief Parse a SVG description of an arc segment. | |
491 | 571 | * Code stolen from (and adapted) |
492 | 572 | * http://www.inkscape.org/doc/doxygen/html/svg-path_8cpp.php#a7 |
493 | 573 | * 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 | |
504 | 585 | */ |
505 | 586 | static void |
506 | 587 | _path_arc_segment(GArray* points, |
@@ -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> |