]> git.sur5r.net Git - glabels/blob - glabels2/libglabels/xml.c
2005-02-05 Jim Evins <evins@snaught.com>
[glabels] / glabels2 / libglabels / xml.c
1 /*
2  *  (LIBGLABELS) Template library for GLABELS
3  *
4  *  xml.c:  GLabels xml utilities module
5  *
6  *  Copyright (C) 2003, 2004  Jim Evins <evins@snaught.com>.
7  *
8  *  This file is part of the LIBGLABELS library.
9  *
10  *  This library is free software; you can redistribute it and/or
11  *  modify it under the terms of the GNU Library General Public
12  *  License as published by the Free Software Foundation; either
13  *  version 2 of the License, or (at your option) any later version.
14  *
15  *  This library is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  *  Library General Public License for more details.
19  *
20  *  You should have received a copy of the GNU Library General Public
21  *  License along with this library; if not, write to the Free
22  *  Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23  *  MA 02111-1307, USA
24  */
25
26 #include "libglabels-private.h"
27
28 #include "xml.h"
29
30 /*========================================================*/
31 /* Private macros and constants.                          */
32 /*========================================================*/
33
34 #define POINTS_PER_POINT    1.0 /* internal units are points. */
35 #define POINTS_PER_INCH    72.0
36 #define POINTS_PER_MM       2.83464566929
37 #define POINTS_PER_CM       (10.0*POINTS_PER_MM)
38 #define POINTS_PER_PICA     (1.0/12.0)
39
40 /*========================================================*/
41 /* Private types.                                         */
42 /*========================================================*/
43
44 typedef struct {
45         gchar       *name;
46         gdouble      points_per_unit;
47 } UnitTableEntry;
48
49 /*========================================================*/
50 /* Private globals.                                       */
51 /*========================================================*/
52
53 static UnitTableEntry unit_table[] = {
54
55         /* These names are identical to the absolute length units supported in
56            the CSS2 Specification (Section 4.3.2) */
57
58         /* This table must be sorted exactly as the enumerations in glUnitsType */
59
60         /* [GL_UNITS_POINT] */   {"pt",      POINTS_PER_POINT},
61         /* [GL_UNITS_INCH]  */   {"in",      POINTS_PER_INCH},
62         /* [GL_UNITS_MM]    */   {"mm",      POINTS_PER_MM},
63         /* [GL_UNITS_CM]    */   {"cm",      POINTS_PER_CM},
64         /* [GL_UNITS_PICA]  */   {"pc",      POINTS_PER_PICA},
65
66 };
67
68 static glUnitsType  default_units        = GL_UNITS_POINT;
69
70 /*========================================================*/
71 /* Private function prototypes.                           */
72 /*========================================================*/
73
74 \f
75 /****************************************************************************/
76 /* Return value of property as a double.                                    */
77 /****************************************************************************/
78 gdouble
79 gl_xml_get_prop_double (xmlNodePtr   node,
80                         const gchar *property,
81                         gdouble      default_val)
82 {
83         gdouble  val;
84         gchar   *string;
85
86         string = xmlGetProp (node, property);
87         if ( string != NULL ) {
88                 val = g_strtod (string, NULL);
89                 g_free (string);
90                 return val;
91         }
92
93         return default_val;
94 }
95
96 /****************************************************************************/
97 /* Return value of property as a boolean.                                   */
98 /****************************************************************************/
99 gboolean
100 gl_xml_get_prop_boolean (xmlNodePtr   node,
101                          const gchar *property,
102                          gboolean     default_val)
103 {
104         gboolean  val;
105         gchar    *string;
106
107         string = xmlGetProp (node, property);
108         if ( string != NULL ) {
109                 val = !((xmlStrcasecmp (string, "false") == 0) ||
110                         xmlStrEqual (string, "0"));;
111                 g_free (string);
112                 return val;
113         }
114
115         return default_val;
116 }
117
118
119 /****************************************************************************/
120 /* Return value of property as an int. .                                    */
121 /****************************************************************************/
122 gint
123 gl_xml_get_prop_int (xmlNodePtr   node,
124                      const gchar *property,
125                      gint         default_val)
126 {
127         gint     val;
128         gchar   *string;
129
130         string = xmlGetProp (node, property);
131         if ( string != NULL ) {
132                 val = strtol (string, NULL, 0);
133                 g_free (string);
134                 return val;
135         }
136
137         return default_val;
138 }
139
140
141 /****************************************************************************/
142 /* Return value of hex property as an unsigned int.                         */
143 /****************************************************************************/
144 guint
145 gl_xml_get_prop_uint (xmlNodePtr   node,
146                       const gchar *property,
147                       guint        default_val)
148 {
149         guint    val;
150         gchar   *string;
151
152         string = xmlGetProp (node, property);
153         if ( string != NULL ) {
154                 val = strtoul (string, NULL, 0);
155                 g_free (string);
156                 return val;
157         }
158
159         return default_val;
160 }
161
162
163 /****************************************************************************/
164 /* Return value of length property as a double, converting to internal units*/
165 /****************************************************************************/
166 gdouble
167 gl_xml_get_prop_length (xmlNodePtr   node,
168                         const gchar *property,
169                         gdouble      default_val)
170 {
171         gdouble  val;
172         gchar   *string, *unit;
173         gint     i;
174
175         string = xmlGetProp (node, property);
176         if ( string != NULL ) {
177
178                 val = g_strtod (string, &unit);
179
180                 if (unit != string) {
181                         unit = g_strchug (unit);
182                         if (strlen (unit) > 0 ) {
183                                 for (i=GL_UNITS_FIRST; i<=GL_UNITS_LAST; i++) {
184                                         if (xmlStrcasecmp (unit, unit_table[i].name) == 0) {
185                                                 val *= unit_table[i].points_per_unit;
186                                                 break;
187                                         }
188                                 }
189                                 if (i>GL_UNITS_LAST) {
190                                         g_warning ("Line %d, Node \"%s\", Property \"%s\": Unknown unit \"%s\", assuming points",
191                                                    xmlGetLineNo (node), node->name, property,
192                                                    unit);
193                                 }
194                         }
195                 }
196                 else {
197                         val = 0.0;
198                 }
199
200                 g_free (string);
201                 return val;
202         }
203
204         return default_val;
205 }
206
207 /****************************************************************************/
208 /* Set property from double.                                                */
209 /****************************************************************************/
210 void
211 gl_xml_set_prop_double (xmlNodePtr    node,
212                         const gchar  *property,
213                         gdouble       val)
214 {
215         gchar  *string, buffer[G_ASCII_DTOSTR_BUF_SIZE];
216
217         /* Guarantee "C" locale by use of g_ascii_formatd */
218         string = g_ascii_formatd (buffer, G_ASCII_DTOSTR_BUF_SIZE, "%g", val);
219
220         xmlSetProp (node, property, string);
221 }
222
223 /****************************************************************************/
224 /* Set property from boolean.                                               */
225 /****************************************************************************/
226 void
227 gl_xml_set_prop_boolean (xmlNodePtr    node,
228                          const gchar  *property,
229                          gboolean      val)
230 {
231         xmlSetProp (node, property, (val ? "True" : "False"));
232 }
233
234 /****************************************************************************/
235 /* Set property from int.                                                   */
236 /****************************************************************************/
237 void
238 gl_xml_set_prop_int (xmlNodePtr    node,
239                      const gchar  *property,
240                      gint          val)
241 {
242         gchar  *string;
243
244         string = g_strdup_printf ("%d", val);
245         xmlSetProp (node, property, string);
246         g_free (string);
247 }
248
249 /****************************************************************************/
250 /* Set property from uint in hex.                                           */
251 /****************************************************************************/
252 void
253 gl_xml_set_prop_uint_hex (xmlNodePtr    node,
254                           const gchar  *property,
255                           guint         val)
256 {
257         gchar  *string;
258
259         string = g_strdup_printf ("0x%08x", val);
260         xmlSetProp (node, property, string);
261         g_free (string);
262 }
263
264 /****************************************************************************/
265 /* Set property from length.                                                */
266 /****************************************************************************/
267 void
268 gl_xml_set_prop_length (xmlNodePtr    node,
269                         const gchar  *property,
270                         gdouble       val)
271 {
272         gchar  *string, buffer[G_ASCII_DTOSTR_BUF_SIZE];
273         gchar  *string_unit;
274
275         /* Convert to default units */
276         val /= unit_table[default_units].points_per_unit;
277
278         /* Guarantee "C" locale by use of g_ascii_formatd */
279         string = g_ascii_formatd (buffer, G_ASCII_DTOSTR_BUF_SIZE, "%g", val);
280
281         string_unit = g_strdup_printf ("%s%s", string, unit_table[default_units].name);
282         xmlSetProp (node, property, string_unit);
283         g_free (string_unit);
284 }
285
286 /****************************************************************************/
287 /* Set default length units.                                                */
288 /****************************************************************************/
289 void
290 gl_xml_set_default_units (glUnitsType   units)
291 {
292         g_return_if_fail ((units >= GL_UNITS_FIRST) && (units <= GL_UNITS_LAST));
293
294         default_units = units;
295 }
296
297