2 * (LIBGLABELS) Template library for GLABELS
4 * xml.c: GLabels xml utilities module
6 * Copyright (C) 2003, 2004 Jim Evins <evins@snaught.com>.
8 * This file is part of the LIBGLABELS library.
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.
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.
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,
29 #include <glib/gi18n.h>
30 #include <glib/gstrfuncs.h>
31 #include <glib/gmessages.h>
34 #include "libglabels-private.h"
37 /*========================================================*/
38 /* Private macros and constants. */
39 /*========================================================*/
41 #define POINTS_PER_POINT 1.0 /* internal units are points. */
42 #define POINTS_PER_INCH 72.0
43 #define POINTS_PER_MM 2.83464566929
44 #define POINTS_PER_CM (10.0*POINTS_PER_MM)
45 #define POINTS_PER_PICA (1.0/12.0)
47 /*========================================================*/
49 /*========================================================*/
53 gdouble points_per_unit;
56 /*========================================================*/
57 /* Private globals. */
58 /*========================================================*/
60 static UnitTableEntry unit_table[] = {
62 /* These names are identical to the absolute length units supported in
63 the CSS2 Specification (Section 4.3.2) */
65 /* This table must be sorted exactly as the enumerations in glUnitsType */
67 /* [GL_UNITS_POINT] */ {(xmlChar *)"pt", POINTS_PER_POINT},
68 /* [GL_UNITS_INCH] */ {(xmlChar *)"in", POINTS_PER_INCH},
69 /* [GL_UNITS_MM] */ {(xmlChar *)"mm", POINTS_PER_MM},
70 /* [GL_UNITS_CM] */ {(xmlChar *)"cm", POINTS_PER_CM},
71 /* [GL_UNITS_PICA] */ {(xmlChar *)"pc", POINTS_PER_PICA},
75 static glUnitsType default_units = GL_UNITS_POINT;
78 /****************************************************************************/
81 * gl_xml_get_prop_double:
82 * @node: the libxml2 #xmlNodePtr of the node
83 * @property: the property name
84 * @default_val: a default value to return if property not found
86 * Return value of property as a double.
88 * Returns: the property as a double.
92 gl_xml_get_prop_double (xmlNodePtr node,
93 const gchar *property,
99 string = xmlGetProp (node, (xmlChar *)property);
100 if ( string != NULL ) {
101 val = g_strtod ((gchar *)string, NULL);
111 * gl_xml_get_prop_boolean:
112 * @node: the libxml2 #xmlNodePtr of the node
113 * @property: the property name
114 * @default_val: a default value to return if property not found
116 * Return value of property as a boolean.
118 * Returns: the property as a boolean.
122 gl_xml_get_prop_boolean (xmlNodePtr node,
123 const gchar *property,
124 gboolean default_val)
129 string = xmlGetProp (node, (xmlChar *)property);
130 if ( string != NULL ) {
131 val = !((xmlStrcasecmp (string, (xmlChar *)"false") == 0) ||
132 xmlStrEqual (string, (xmlChar *)"0"));;
142 * gl_xml_get_prop_int:
143 * @node: the libxml2 #xmlNodePtr of the node
144 * @property: the property name
145 * @default_val: a default value to return if property not found
147 * Return value of property as an integer.
149 * Returns: the property as an integer.
153 gl_xml_get_prop_int (xmlNodePtr node,
154 const gchar *property,
160 string = xmlGetProp (node, (xmlChar *)property);
161 if ( string != NULL ) {
162 val = strtol ((char *)string, NULL, 0);
172 * gl_xml_get_prop_uint:
173 * @node: the libxml2 #xmlNodePtr of the node
174 * @property: the property name
175 * @default_val: a default value to return if property not found
177 * Return value of property (usually formatted in hex) as an unsigned integer.
179 * Returns: the property as an unsigned integer.
183 gl_xml_get_prop_uint (xmlNodePtr node,
184 const gchar *property,
190 string = xmlGetProp (node, (xmlChar *)property);
191 if ( string != NULL ) {
192 val = strtoul ((char *)string, NULL, 0);
202 * gl_xml_get_prop_length:
203 * @node: the libxml2 #xmlNodePtr of the node
204 * @property: the property name
205 * @default_val: a default value to return if property not found
207 * Return value of a length property as a double, converting to internal
208 * units (points). The property is expected to be formatted as a number
209 * followed by a units string. If there is no units string, the length
210 * is assumed to be in points. Valid units strings are "pt" for points,
211 * "in" for inches, "mm" for millimeters, "cm" for centimeters, and
214 * Returns: the length in points.
218 gl_xml_get_prop_length (xmlNodePtr node,
219 const gchar *property,
227 string = xmlGetProp (node, (xmlChar *)property);
228 if ( string != NULL ) {
230 val = g_strtod ((gchar *)string, (gchar **)&unit);
232 if (unit != string) {
233 unit = (xmlChar *)g_strchug ((gchar *)unit);
234 if (strlen ((char *)unit) > 0 ) {
235 for (i=GL_UNITS_FIRST; i<=GL_UNITS_LAST; i++) {
236 if (xmlStrcasecmp (unit, unit_table[i].name) == 0) {
237 val *= unit_table[i].points_per_unit;
241 if (i>GL_UNITS_LAST) {
242 g_warning ("Line %d, Node \"%s\", Property \"%s\": Unknown unit \"%s\", assuming points",
243 xmlGetLineNo (node), node->name, property,
261 * gl_xml_set_prop_double:
262 * @node: the libxml2 #xmlNodePtr of the node
263 * @property: the property name
264 * @val: the value to set
266 * Set a property from a double.
270 gl_xml_set_prop_double (xmlNodePtr node,
271 const gchar *property,
274 gchar *string, buffer[G_ASCII_DTOSTR_BUF_SIZE];
276 /* Guarantee "C" locale by use of g_ascii_formatd */
277 string = g_ascii_formatd (buffer, G_ASCII_DTOSTR_BUF_SIZE, "%g", val);
279 xmlSetProp (node, (xmlChar *)property, (xmlChar *)string);
284 * gl_xml_set_prop_boolean:
285 * @node: the libxml2 #xmlNodePtr of the node
286 * @property: the property name
287 * @val: the value to set
289 * Set a property from a boolean.
293 gl_xml_set_prop_boolean (xmlNodePtr node,
294 const gchar *property,
297 xmlSetProp (node, (xmlChar *)property, (xmlChar *)(val ? "True" : "False"));
301 * gl_xml_set_prop_int:
302 * @node: the libxml2 #xmlNodePtr of the node
303 * @property: the property name
304 * @val: the value to set
306 * Set a property from an integer.
310 gl_xml_set_prop_int (xmlNodePtr node,
311 const gchar *property,
316 string = g_strdup_printf ("%d", val);
317 xmlSetProp (node, (xmlChar *)property, (xmlChar *)string);
322 * gl_xml_set_prop_uint_hex:
323 * @node: the libxml2 #xmlNodePtr of the node
324 * @property: the property name
325 * @val: the value to set
327 * Set a property from an unsigned integer and format in hex.
331 gl_xml_set_prop_uint_hex (xmlNodePtr node,
332 const gchar *property,
337 string = g_strdup_printf ("0x%08x", val);
338 xmlSetProp (node, (xmlChar *)property, (xmlChar *)string);
343 * gl_xml_set_prop_length:
344 * @node: the libxml2 #xmlNodePtr of the node
345 * @property: the property name
346 * @val: the length to set in internal units (points)
348 * Set a property from a length, performing any necessary conversion.
349 * Length properties are formatted as a number followed by a units string.
350 * The units of the formatted property is determined by the most recent call to
351 * gl_xml_set_default_units().
355 gl_xml_set_prop_length (xmlNodePtr node,
356 const gchar *property,
359 gchar *string, buffer[G_ASCII_DTOSTR_BUF_SIZE];
362 /* Convert to default units */
363 val /= unit_table[default_units].points_per_unit;
365 /* Guarantee "C" locale by use of g_ascii_formatd */
366 string = g_ascii_formatd (buffer, G_ASCII_DTOSTR_BUF_SIZE, "%g", val);
368 string_unit = g_strdup_printf ("%s%s", string, unit_table[default_units].name);
369 xmlSetProp (node, (xmlChar *)property, (xmlChar *)string_unit);
370 g_free (string_unit);
374 * gl_xml_set_default_units:
375 * @units: default units selection (#glUnitsType)
377 * Set the default units when formatting lengths. See
378 * gl_xml_set_prop_length().
382 gl_xml_set_default_units (glUnitsType units)
384 g_return_if_fail ((units >= GL_UNITS_FIRST) && (units <= GL_UNITS_LAST));
386 default_units = units;