2 * (GLABELS) Label and Business Card Creation program for GNOME
4 * label.c: GLabels xml label module
6 * Copyright (C) 2001-2002 Jim Evins <evins@snaught.com>.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include <libxml/tree.h>
28 #include <libxml/parser.h>
29 #include <gdk-pixbuf/gdk-pixdata.h>
32 #include "label-object.h"
33 #include "label-text.h"
34 #include "label-box.h"
35 #include "label-line.h"
36 #include "label-ellipse.h"
37 #include "label-image.h"
38 #include "label-barcode.h"
40 #include "xml-label.h"
41 #include "xml-label-04.h"
42 #include "xml-label-191.h"
43 #include <libglabels/template.h>
44 #include <libglabels/xml-template.h>
45 #include <libglabels/xml.h>
50 /*========================================================*/
51 /* Private macros and constants. */
52 /*========================================================*/
53 #define COMPAT01_NAME_SPACE "http://snaught.com/glabels/0.1/"
54 #define COMPAT04_NAME_SPACE "http://snaught.com/glabels/0.4/"
55 #define COMPAT191_NAME_SPACE "http://snaught.com/glabels/1.92/"
57 /*========================================================*/
59 /*========================================================*/
61 /*========================================================*/
62 /* Private globals. */
63 /*========================================================*/
65 /*========================================================*/
66 /* Private function prototypes. */
67 /*========================================================*/
69 static glLabel *xml_doc_to_label (xmlDocPtr doc,
70 glXMLLabelStatus *status);
72 static glLabel *xml_parse_label (xmlNodePtr root,
73 glXMLLabelStatus *status);
75 static void xml_parse_objects (xmlNodePtr node,
78 static void xml_parse_object_text (xmlNodePtr node,
81 static void xml_parse_object_box (xmlNodePtr node,
84 static void xml_parse_object_ellipse (xmlNodePtr node,
87 static void xml_parse_object_line (xmlNodePtr node,
90 static void xml_parse_object_image (xmlNodePtr node,
93 static void xml_parse_object_barcode (xmlNodePtr node,
96 static void xml_parse_merge_fields (xmlNodePtr node,
99 static void xml_parse_data (xmlNodePtr node,
102 static void xml_parse_pixdata (xmlNodePtr node,
105 static void xml_parse_toplevel_span (xmlNodePtr node,
106 glLabelObject *object);
109 static xmlDocPtr xml_label_to_doc (glLabel *label,
110 glXMLLabelStatus *status);
112 static void xml_create_objects (xmlNodePtr root,
116 static void xml_create_object_text (xmlNodePtr root,
118 glLabelObject *object);
120 static void xml_create_object_box (xmlNodePtr root,
122 glLabelObject *object);
124 static void xml_create_object_line (xmlNodePtr root,
126 glLabelObject *object);
128 static void xml_create_object_ellipse(xmlNodePtr root,
130 glLabelObject *object);
132 static void xml_create_object_image (xmlNodePtr root,
134 glLabelObject *object);
136 static void xml_create_object_barcode(xmlNodePtr root,
138 glLabelObject *object);
140 static void xml_create_merge_fields (xmlNodePtr root,
144 static void xml_create_data (xmlNodePtr root,
148 static void xml_create_pixdata (xmlNodePtr root,
153 static void xml_create_toplevel_span (xmlNodePtr node,
155 glLabelText *object_text);
158 /****************************************************************************/
159 /* Open and read label from xml file. */
160 /****************************************************************************/
162 gl_xml_label_open (const gchar *utf8_filename,
163 glXMLLabelStatus *status)
169 gl_debug (DEBUG_XML, "START");
171 filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
172 g_return_val_if_fail (filename, NULL);
174 doc = xmlParseFile (filename);
176 g_warning (_("xmlParseFile error"));
177 *status = XML_LABEL_ERROR_OPEN_PARSE;
181 xmlXIncludeProcess (doc);
182 xmlReconciliateNs (doc, xmlDocGetRootElement (doc));
184 label = xml_doc_to_label (doc, status);
189 gl_label_set_filename (label, utf8_filename);
190 gl_label_clear_modified (label);
194 gl_debug (DEBUG_XML, "END");
199 /****************************************************************************/
200 /* Read label from xml buffer. */
201 /****************************************************************************/
203 gl_xml_label_open_buffer (const gchar *buffer,
204 glXMLLabelStatus *status)
209 gl_debug (DEBUG_XML, "START");
211 doc = xmlParseDoc ((xmlChar *) buffer);
213 g_warning (_("xmlParseFile error"));
214 *status = XML_LABEL_ERROR_OPEN_PARSE;
218 label = xml_doc_to_label (doc, status);
223 gl_label_clear_modified (label);
226 gl_debug (DEBUG_XML, "END");
231 /*--------------------------------------------------------------------------*/
232 /* PRIVATE. Parse xml doc structure and create label. */
233 /*--------------------------------------------------------------------------*/
235 xml_doc_to_label (xmlDocPtr doc,
236 glXMLLabelStatus *status)
238 xmlNodePtr root, node;
242 gl_debug (DEBUG_XML, "START");
246 *status = XML_LABEL_OK;
248 root = xmlDocGetRootElement (doc);
249 if (!root || !root->name) {
250 g_warning (_("No document root"));
251 *status = XML_LABEL_ERROR_OPEN_PARSE;
255 ns = xmlSearchNsByHref (doc, root, GL_XML_NAME_SPACE);
257 label = xml_parse_label (root, status);
259 gl_label_set_compression (label, xmlGetDocCompressMode (doc));
261 /* Try compatability mode 0.1 */
262 ns = xmlSearchNsByHref (doc, root, COMPAT01_NAME_SPACE);
264 g_warning (_("Importing from glabels 0.1 format"));
266 label = NULL; /* TODO */
268 /* Try compatability mode 0.4 */
269 ns = xmlSearchNsByHref (doc, root,
270 COMPAT04_NAME_SPACE);
272 g_warning (_("Importing from glabels 0.4 format"));
273 label = gl_xml_label_04_parse (root, status);
275 /* Try compatability mode 1.91 */
276 ns = xmlSearchNsByHref (doc, root,
277 COMPAT191_NAME_SPACE);
279 g_warning (_("Importing from glabels 1.91 format"));
280 label = gl_xml_label_191_parse (root, status);
282 g_warning (_("bad document, unknown glabels Namespace"));
283 *status = XML_LABEL_ERROR_OPEN_PARSE;
290 gl_debug (DEBUG_XML, "END");
295 /*--------------------------------------------------------------------------*/
296 /* PRIVATE. Parse xml root node and create label. */
297 /*--------------------------------------------------------------------------*/
299 xml_parse_label (xmlNodePtr root,
300 glXMLLabelStatus *status)
302 xmlNodePtr child_node;
304 glTemplate *template;
306 gl_debug (DEBUG_XML, "START");
308 *status = XML_LABEL_OK;
310 if (!xmlStrEqual (root->name, "Glabels-document")) {
311 g_warning (_("Bad root node = \"%s\""), root->name);
312 *status = XML_LABEL_ERROR_OPEN_PARSE;
316 label = GL_LABEL(gl_label_new ());
318 /* Pass 1, extract data nodes to pre-load cache. */
319 for (child_node = root->xmlChildrenNode; child_node != NULL; child_node = child_node->next) {
320 if (xmlStrEqual (child_node->name, "Data")) {
321 xml_parse_data (child_node, label);
325 /* Pass 2, now extract everything else. */
326 for (child_node = root->xmlChildrenNode;
328 child_node = child_node->next) {
330 if (xmlStrEqual (child_node->name, "Template")) {
331 template = gl_xml_template_parse_template_node (child_node);
333 g_object_unref (label);
334 *status = XML_LABEL_UNKNOWN_MEDIA;
337 gl_template_register (template);
338 gl_label_set_template (label, template);
339 gl_template_free (template);
340 } else if (xmlStrEqual (child_node->name, "Objects")) {
341 xml_parse_objects (child_node, label);
342 } else if (xmlStrEqual (child_node->name, "Merge")) {
343 xml_parse_merge_fields (child_node, label);
344 } else if (xmlStrEqual (child_node->name, "Data")) {
345 /* Handled in pass 1. */
347 if (!xmlNodeIsText (child_node)) {
348 g_warning (_("bad node in Document node = \"%s\""),
350 g_object_unref (label);
351 *status = XML_LABEL_ERROR_OPEN_PARSE;
357 gl_debug (DEBUG_XML, "END");
362 /*--------------------------------------------------------------------------*/
363 /* PRIVATE. Parse Objects node. */
364 /*--------------------------------------------------------------------------*/
366 xml_parse_objects (xmlNodePtr node,
369 gboolean rotate_flag;
372 gl_debug (DEBUG_XML, "START");
374 rotate_flag = gl_xml_get_prop_boolean (node, "rotate", FALSE);
375 gl_label_set_rotate_flag (label, rotate_flag);
377 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
379 if (xmlStrEqual (child->name, "Object-text")) {
380 xml_parse_object_text (child, label);
381 } else if (xmlStrEqual (child->name, "Object-box")) {
382 xml_parse_object_box (child, label);
383 } else if (xmlStrEqual (child->name, "Object-ellipse")) {
384 xml_parse_object_ellipse (child, label);
385 } else if (xmlStrEqual (child->name, "Object-line")) {
386 xml_parse_object_line (child, label);
387 } else if (xmlStrEqual (child->name, "Object-image")) {
388 xml_parse_object_image (child, label);
389 } else if (xmlStrEqual (child->name, "Object-barcode")) {
390 xml_parse_object_barcode (child, label);
392 if (!xmlNodeIsText (child)) {
393 g_warning (_("bad node = \"%s\""), child->name);
399 gl_debug (DEBUG_XML, "END");
402 /*--------------------------------------------------------------------------*/
403 /* PRIVATE. Parse XML Objects->Object-text Node */
404 /*--------------------------------------------------------------------------*/
406 xml_parse_object_text (xmlNodePtr node,
413 GtkJustification just;
414 gboolean auto_shrink;
418 gl_debug (DEBUG_XML, "START");
420 object = gl_label_text_new (label);
423 x = gl_xml_get_prop_length (node, "x", 0.0);
424 y = gl_xml_get_prop_length (node, "y", 0.0);
425 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
427 /* implied size attrs */
428 w = gl_xml_get_prop_length (node, "w", 0);
429 h = gl_xml_get_prop_length (node, "h", 0);
430 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
433 string = xmlGetProp (node, "justify");
434 just = gl_util_string_to_just (string);
436 gl_label_object_set_text_alignment (GL_LABEL_OBJECT(object), just);
438 /* auto_shrink attr */
439 auto_shrink = gl_xml_get_prop_boolean (node, "auto_shrink", FALSE);
440 gl_label_text_set_auto_shrink (GL_LABEL_TEXT(object), auto_shrink);
443 affine[0] = gl_xml_get_prop_double (node, "a0", 0.0);
444 affine[1] = gl_xml_get_prop_double (node, "a1", 0.0);
445 affine[2] = gl_xml_get_prop_double (node, "a2", 0.0);
446 affine[3] = gl_xml_get_prop_double (node, "a3", 0.0);
447 affine[4] = gl_xml_get_prop_double (node, "a4", 0.0);
448 affine[5] = gl_xml_get_prop_double (node, "a5", 0.0);
449 gl_label_object_set_affine (GL_LABEL_OBJECT(object), affine);
451 /* Process children */
452 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
453 if (xmlStrEqual (child->name, "Span")) {
454 xml_parse_toplevel_span (child, GL_LABEL_OBJECT(object));
457 if (!xmlNodeIsText (child)) {
458 g_warning ("Unexpected Object-text child: \"%s\"",
464 gl_debug (DEBUG_XML, "END");
467 /*--------------------------------------------------------------------------*/
468 /* PRIVATE. Parse XML Objects->Object-box Node */
469 /*--------------------------------------------------------------------------*/
471 xml_parse_object_box (xmlNodePtr node,
478 glColorNode *line_color_node;
481 glColorNode *fill_color_node;
483 gl_debug (DEBUG_XML, "START");
485 object = gl_label_box_new (label);
488 x = gl_xml_get_prop_length (node, "x", 0.0);
489 y = gl_xml_get_prop_length (node, "y", 0.0);
490 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
493 w = gl_xml_get_prop_length (node, "w", 0);
494 h = gl_xml_get_prop_length (node, "h", 0);
495 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
498 line_width = gl_xml_get_prop_length (node, "line_width", 1.0);
499 gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width);
501 line_color_node = gl_color_node_new_default ();
502 string = xmlGetProp (node, "line_color_field");
504 line_color_node->field_flag = TRUE;
505 line_color_node->key = string;
507 line_color_node->color = gl_xml_get_prop_uint (node, "line_color", 0);
509 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color_node);
510 gl_color_node_free (&line_color_node);
514 fill_color_node = gl_color_node_new_default ();
515 string = xmlGetProp (node, "fill_color_field");
517 fill_color_node->field_flag = TRUE;
518 fill_color_node->key = string;
520 fill_color_node->color = gl_xml_get_prop_uint (node, "fill_color", 0);
522 gl_label_object_set_fill_color (GL_LABEL_OBJECT(object), fill_color_node);
523 gl_color_node_free (&fill_color_node);
526 affine[0] = gl_xml_get_prop_double (node, "a0", 0.0);
527 affine[1] = gl_xml_get_prop_double (node, "a1", 0.0);
528 affine[2] = gl_xml_get_prop_double (node, "a2", 0.0);
529 affine[3] = gl_xml_get_prop_double (node, "a3", 0.0);
530 affine[4] = gl_xml_get_prop_double (node, "a4", 0.0);
531 affine[5] = gl_xml_get_prop_double (node, "a5", 0.0);
532 gl_label_object_set_affine (GL_LABEL_OBJECT(object), affine);
534 gl_debug (DEBUG_XML, "END");
537 /*--------------------------------------------------------------------------*/
538 /* PRIVATE. Parse XML Objects->Object-ellipse Node */
539 /*--------------------------------------------------------------------------*/
541 xml_parse_object_ellipse (xmlNodePtr node,
548 glColorNode *line_color_node;
551 glColorNode *fill_color_node;
553 gl_debug (DEBUG_XML, "START");
555 object = gl_label_ellipse_new (label);
558 x = gl_xml_get_prop_length (node, "x", 0.0);
559 y = gl_xml_get_prop_length (node, "y", 0.0);
560 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
563 w = gl_xml_get_prop_length (node, "w", 0);
564 h = gl_xml_get_prop_length (node, "h", 0);
565 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
568 line_width = gl_xml_get_prop_length (node, "line_width", 1.0);
569 gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width);
571 line_color_node = gl_color_node_new_default ();
572 string = xmlGetProp (node, "line_color_field");
574 line_color_node->field_flag = TRUE;
575 line_color_node->key = string;
577 line_color_node->color = gl_xml_get_prop_uint (node, "line_color", 0);
579 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color_node);
580 gl_color_node_free (&line_color_node);
584 fill_color_node = gl_color_node_new_default ();
585 string = xmlGetProp (node, "fill_color_field");
587 fill_color_node->field_flag = TRUE;
588 fill_color_node->key = string;
590 fill_color_node->color = gl_xml_get_prop_uint (node, "fill_color", 0);
592 gl_label_object_set_fill_color (GL_LABEL_OBJECT(object), fill_color_node);
593 gl_color_node_free (&fill_color_node);
596 affine[0] = gl_xml_get_prop_double (node, "a0", 0.0);
597 affine[1] = gl_xml_get_prop_double (node, "a1", 0.0);
598 affine[2] = gl_xml_get_prop_double (node, "a2", 0.0);
599 affine[3] = gl_xml_get_prop_double (node, "a3", 0.0);
600 affine[4] = gl_xml_get_prop_double (node, "a4", 0.0);
601 affine[5] = gl_xml_get_prop_double (node, "a5", 0.0);
602 gl_label_object_set_affine (GL_LABEL_OBJECT(object), affine);
604 gl_debug (DEBUG_XML, "END");
607 /*--------------------------------------------------------------------------*/
608 /* PRIVATE. Parse XML Objects->Object-line Node */
609 /*--------------------------------------------------------------------------*/
611 xml_parse_object_line (xmlNodePtr node,
618 glColorNode *line_color_node;
622 gl_debug (DEBUG_XML, "START");
624 object = gl_label_line_new (label);
627 x = gl_xml_get_prop_length (node, "x", 0.0);
628 y = gl_xml_get_prop_length (node, "y", 0.0);
629 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
632 dx = gl_xml_get_prop_length (node, "dx", 0);
633 dy = gl_xml_get_prop_length (node, "dy", 0);
634 gl_label_object_set_size (GL_LABEL_OBJECT(object), dx, dy);
637 line_width = gl_xml_get_prop_length (node, "line_width", 1.0);
638 gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width);
640 line_color_node = gl_color_node_new_default ();
641 string = xmlGetProp (node, "line_color_field");
643 line_color_node->field_flag = TRUE;
644 line_color_node->key = string;
646 line_color_node->color = gl_xml_get_prop_uint (node, "line_color", 0);
648 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color_node);
649 gl_color_node_free (&line_color_node);
652 affine[0] = gl_xml_get_prop_double (node, "a0", 0.0);
653 affine[1] = gl_xml_get_prop_double (node, "a1", 0.0);
654 affine[2] = gl_xml_get_prop_double (node, "a2", 0.0);
655 affine[3] = gl_xml_get_prop_double (node, "a3", 0.0);
656 affine[4] = gl_xml_get_prop_double (node, "a4", 0.0);
657 affine[5] = gl_xml_get_prop_double (node, "a5", 0.0);
658 gl_label_object_set_affine (GL_LABEL_OBJECT(object), affine);
660 gl_debug (DEBUG_XML, "END");
663 /*--------------------------------------------------------------------------*/
664 /* PRIVATE. Parse XML Objects->Object-image Node */
665 /*--------------------------------------------------------------------------*/
667 xml_parse_object_image (xmlNodePtr node,
674 glTextNode *filename;
677 gl_debug (DEBUG_XML, "START");
679 object = gl_label_image_new (label);
682 x = gl_xml_get_prop_length (node, "x", 0.0);
683 y = gl_xml_get_prop_length (node, "y", 0.0);
684 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
686 /* src or field attr */
687 string = xmlGetProp (node, "src");
689 filename = g_new0 (glTextNode, 1);
690 filename->field_flag = FALSE;
691 filename->data = string;
692 gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename);
693 gl_text_node_free (&filename);
695 string = xmlGetProp (node, "field");
697 filename = g_new0 (glTextNode, 1);
698 filename->field_flag = TRUE;
699 filename->data = string;
700 gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename);
701 gl_text_node_free (&filename);
703 g_warning ("Missing Object-image src or field attr");
708 w = gl_xml_get_prop_length (node, "w", 0);
709 h = gl_xml_get_prop_length (node, "h", 0);
710 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
713 affine[0] = gl_xml_get_prop_double (node, "a0", 0.0);
714 affine[1] = gl_xml_get_prop_double (node, "a1", 0.0);
715 affine[2] = gl_xml_get_prop_double (node, "a2", 0.0);
716 affine[3] = gl_xml_get_prop_double (node, "a3", 0.0);
717 affine[4] = gl_xml_get_prop_double (node, "a4", 0.0);
718 affine[5] = gl_xml_get_prop_double (node, "a5", 0.0);
719 gl_label_object_set_affine (GL_LABEL_OBJECT(object), affine);
721 gl_debug (DEBUG_XML, "END");
724 /*--------------------------------------------------------------------------*/
725 /* PRIVATE. Parse XML Objects->Object-barcode Node */
726 /*--------------------------------------------------------------------------*/
728 xml_parse_object_barcode (xmlNodePtr node,
735 glTextNode *text_node;
738 gboolean checksum_flag;
739 glColorNode *color_node;
743 gl_debug (DEBUG_XML, "START");
745 object = gl_label_barcode_new (label);
748 x = gl_xml_get_prop_length (node, "x", 0.0);
749 y = gl_xml_get_prop_length (node, "y", 0.0);
750 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
753 w = gl_xml_get_prop_length (node, "w", 0);
754 h = gl_xml_get_prop_length (node, "h", 0);
755 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
758 id = xmlGetProp (node, "style");
759 text_flag = gl_xml_get_prop_boolean (node, "text", FALSE);
760 checksum_flag = gl_xml_get_prop_boolean (node, "checksum", TRUE);
761 format_digits = gl_xml_get_prop_uint (node, "format", 10);
762 gl_label_barcode_set_props (GL_LABEL_BARCODE(object),
763 id, text_flag, checksum_flag, format_digits);
766 color_node = gl_color_node_new_default ();
767 string = xmlGetProp (node, "color_field");
769 color_node->field_flag = TRUE;
770 color_node->key = string;
772 color_node->color = gl_xml_get_prop_uint (node, "color", 0);
774 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), color_node);
775 gl_color_node_free (&color_node);
777 /* data or field attr */
778 string = xmlGetProp (node, "data");
780 text_node = g_new0 (glTextNode, 1);
781 text_node->field_flag = FALSE;
782 text_node->data = string;
783 gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node);
784 gl_text_node_free (&text_node);
786 string = xmlGetProp (node, "field");
788 text_node = g_new0 (glTextNode, 1);
789 text_node->field_flag = TRUE;
790 text_node->data = string;
791 gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node);
792 gl_text_node_free (&text_node);
794 g_warning ("Missing Object-barcode data or field attr");
799 affine[0] = gl_xml_get_prop_double (node, "a0", 0.0);
800 affine[1] = gl_xml_get_prop_double (node, "a1", 0.0);
801 affine[2] = gl_xml_get_prop_double (node, "a2", 0.0);
802 affine[3] = gl_xml_get_prop_double (node, "a3", 0.0);
803 affine[4] = gl_xml_get_prop_double (node, "a4", 0.0);
804 affine[5] = gl_xml_get_prop_double (node, "a5", 0.0);
805 gl_label_object_set_affine (GL_LABEL_OBJECT(object), affine);
807 gl_debug (DEBUG_XML, "END");
810 /*--------------------------------------------------------------------------*/
811 /* PRIVATE. Parse XML merge fields tag. */
812 /*--------------------------------------------------------------------------*/
814 xml_parse_merge_fields (xmlNodePtr node,
821 gl_debug (DEBUG_XML, "START");
823 string = xmlGetProp (node, "type");
824 merge = gl_merge_new (string);
827 string = xmlGetProp (node, "src");
828 gl_merge_set_src (merge, string);
831 gl_label_set_merge (label, merge);
833 g_object_unref (G_OBJECT(merge));
835 gl_debug (DEBUG_XML, "END");
838 /*--------------------------------------------------------------------------*/
839 /* PRIVATE. Parse XML data tag. */
840 /*--------------------------------------------------------------------------*/
842 xml_parse_data (xmlNodePtr node,
847 gl_debug (DEBUG_XML, "START");
849 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
851 if (xmlStrEqual (child->name, "Pixdata")) {
852 xml_parse_pixdata (child, label);
854 if (!xmlNodeIsText (child)) {
855 g_warning (_("bad node in Data node = \"%s\""),
861 gl_debug (DEBUG_XML, "END");
864 /*--------------------------------------------------------------------------*/
865 /* PRIVATE. Parse XML pixbuf data tag. */
866 /*--------------------------------------------------------------------------*/
868 xml_parse_pixdata (xmlNodePtr node,
871 gchar *name, *base64;
877 GHashTable *pixbuf_cache;
879 gl_debug (DEBUG_XML, "START");
881 name = xmlGetProp (node, "name");
882 base64 = xmlNodeGetContent (node);
884 stream = gl_base64_decode (base64, &stream_length);
885 pixdata = g_new0 (GdkPixdata, 1);
886 ret = gdk_pixdata_deserialize (pixdata, stream_length, stream, NULL);
889 pixbuf = gdk_pixbuf_from_pixdata (pixdata, TRUE, NULL);
891 pixbuf_cache = gl_label_get_pixbuf_cache (label);
892 gl_pixbuf_cache_add_pixbuf (pixbuf_cache, name, pixbuf);
900 gl_debug (DEBUG_XML, "END");
903 /*--------------------------------------------------------------------------*/
904 /* PRIVATE. Parse top-level Span tag. */
905 /*--------------------------------------------------------------------------*/
907 xml_parse_toplevel_span (xmlNodePtr node,
908 glLabelObject *object)
912 GnomeFontWeight font_weight;
913 gboolean font_italic_flag;
914 glColorNode *color_node;
915 gdouble text_line_spacing;
917 GList *lines, *text_nodes;
919 glTextNode *text_node;
921 gl_debug (DEBUG_XML, "START");
923 /* Font family attr */
924 font_family = xmlGetProp (node, "font_family");
925 gl_label_object_set_font_family (object, font_family);
926 g_free (font_family);
929 font_size = gl_xml_get_prop_double (node, "font_size", 0.0);
930 gl_label_object_set_font_size (object, font_size);
932 /* Font weight attr */
933 string = xmlGetProp (node, "font_weight");
934 font_weight = gl_util_string_to_weight (string);
936 gl_label_object_set_font_weight (object, font_weight);
938 /* Font italic flag attr */
939 font_italic_flag = gl_xml_get_prop_boolean (node, "font_italic", FALSE);
940 gl_label_object_set_font_italic_flag (object, font_italic_flag);
942 /* Text color attr */
943 color_node = gl_color_node_new_default ();
944 string = xmlGetProp (node, "color_field");
946 color_node->field_flag = TRUE;
947 color_node->key = string;
949 color_node->color = gl_xml_get_prop_uint (node, "color", 0);
951 gl_label_object_set_text_color (object, color_node);
952 gl_color_node_free (&color_node);
955 /* Text line spacing attr */
956 text_line_spacing = gl_xml_get_prop_double (node, "line_spacing", 1.0);
957 gl_label_object_set_text_line_spacing (object, text_line_spacing);
959 /* Now descend children, and build lines of text nodes */
962 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
964 if (xmlNodeIsText (child)) {
965 gchar *data = xmlNodeGetContent (child);
967 /* Hack: if the first char is LF, it's a xml formatting string */
968 if (data[0] != '\n') {
970 text_node = g_new0 (glTextNode, 1);
971 text_node->field_flag = FALSE;
972 text_node->data = data;
973 text_nodes = g_list_append (text_nodes, text_node);
978 } else if (xmlStrEqual (child->name, "Span")) {
980 g_warning ("Unexpected rich text (not supported, yet!)");
982 } else if (xmlStrEqual (child->name, "Field")) {
985 text_node = g_new0 (glTextNode, 1);
986 text_node->field_flag = TRUE;
987 text_node->data = xmlGetProp (child, "name");
988 text_nodes = g_list_append (text_nodes, text_node);
990 } else if (xmlStrEqual (child->name, "NL")) {
993 lines = g_list_append (lines, text_nodes);
997 g_warning ("Unexpected Span child: \"%s\"", child->name);
1002 /* Store last line. */
1003 lines = g_list_append (lines, text_nodes);
1006 gl_label_text_set_lines (GL_LABEL_TEXT(object), lines);
1007 gl_text_node_lines_free (&lines);
1009 gl_debug (DEBUG_XML, "END");
1012 /****************************************************************************/
1013 /* Save label to xml label file. */
1014 /****************************************************************************/
1016 gl_xml_label_save (glLabel *label,
1017 const gchar *utf8_filename,
1018 glXMLLabelStatus *status)
1024 gl_debug (DEBUG_XML, "START");
1026 doc = xml_label_to_doc (label, status);
1028 filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
1030 g_warning (_("Utf8 conversion error."));
1032 xmlSetDocCompressMode (doc, gl_label_get_compression (label));
1033 xml_ret = xmlSaveFormatFile (filename, doc, TRUE);
1035 if (xml_ret == -1) {
1037 g_warning (_("Problem saving xml file."));
1038 *status = XML_LABEL_ERROR_SAVE_FILE;
1042 gl_label_set_filename (label, utf8_filename);
1043 gl_label_clear_modified (label);
1049 gl_debug (DEBUG_XML, "END");
1052 /****************************************************************************/
1053 /* Save label to xml buffer. */
1054 /****************************************************************************/
1056 gl_xml_label_save_buffer (glLabel *label,
1057 glXMLLabelStatus *status)
1063 gl_debug (DEBUG_XML, "START");
1065 doc = xml_label_to_doc (label, status);
1067 xmlDocDumpMemory (doc, (xmlChar **)&buffer, &size);
1070 gl_label_clear_modified (label);
1072 gl_debug (DEBUG_XML, "END");
1077 /*--------------------------------------------------------------------------*/
1078 /* PRIVATE. Convert label to xml doc structure. */
1079 /*--------------------------------------------------------------------------*/
1081 xml_label_to_doc (glLabel *label,
1082 glXMLLabelStatus *status)
1086 glTemplate *template;
1089 gl_debug (DEBUG_XML, "START");
1091 LIBXML_TEST_VERSION;
1093 doc = xmlNewDoc ("1.0");
1094 doc->xmlRootNode = xmlNewDocNode (doc, NULL, "Glabels-document", NULL);
1096 ns = xmlNewNs (doc->xmlRootNode, GL_XML_NAME_SPACE, NULL);
1097 xmlSetNs (doc->xmlRootNode, ns);
1099 template = gl_label_get_template (label);
1100 gl_xml_template_create_template_node (template, doc->xmlRootNode, ns);
1102 xml_create_objects (doc->xmlRootNode, ns, label);
1104 merge = gl_label_get_merge (label);
1105 gl_debug (DEBUG_XML, "merge=%p", merge);
1106 if (merge != NULL) {
1107 xml_create_merge_fields (doc->xmlRootNode, ns, label);
1108 g_object_unref (G_OBJECT(merge));
1111 xml_create_data (doc->xmlRootNode, ns, label);
1113 gl_debug (DEBUG_XML, "END");
1115 *status = XML_LABEL_OK;
1119 /*--------------------------------------------------------------------------*/
1120 /* PRIVATE. Add XML Objects Node */
1121 /*--------------------------------------------------------------------------*/
1123 xml_create_objects (xmlNodePtr root,
1128 gboolean rotate_flag;
1130 glLabelObject *object;
1132 gl_debug (DEBUG_XML, "START");
1134 rotate_flag = gl_label_get_rotate_flag (label);
1136 node = xmlNewChild (root, ns, "Objects", NULL);
1137 xmlSetProp (node, "id", "0");
1138 gl_xml_set_prop_boolean (node, "rotate", rotate_flag);
1140 for (p = label->objects; p != NULL; p = p->next) {
1142 object = GL_LABEL_OBJECT(p->data);
1144 if ( GL_IS_LABEL_TEXT(object) ) {
1145 xml_create_object_text (node, ns, object);
1146 } else if ( GL_IS_LABEL_BOX(object) ) {
1147 xml_create_object_box (node, ns, object);
1148 } else if ( GL_IS_LABEL_ELLIPSE(object) ) {
1149 xml_create_object_ellipse (node, ns, object);
1150 } else if ( GL_IS_LABEL_LINE(object) ) {
1151 xml_create_object_line (node, ns, object);
1152 } else if ( GL_IS_LABEL_IMAGE(object) ) {
1153 xml_create_object_image (node, ns, object);
1154 } else if ( GL_IS_LABEL_BARCODE(object) ) {
1155 xml_create_object_barcode (node, ns, object);
1157 g_warning ("Unknown label object");
1162 gl_debug (DEBUG_XML, "END");
1165 /*--------------------------------------------------------------------------*/
1166 /* PRIVATE. Add XML Objects->Object-text Node */
1167 /*--------------------------------------------------------------------------*/
1169 xml_create_object_text (xmlNodePtr root,
1171 glLabelObject *object)
1176 GtkJustification just;
1177 gboolean auto_shrink;
1180 gl_debug (DEBUG_XML, "START");
1182 node = xmlNewChild (root, ns, "Object-text", NULL);
1184 /* position attrs */
1185 gl_label_object_get_position (object, &x, &y);
1186 gl_xml_set_prop_length (node, "x", x);
1187 gl_xml_set_prop_length (node, "y", y);
1190 gl_label_text_get_box ( GL_LABEL_TEXT(object), &w, &h);
1191 gl_xml_set_prop_length (node, "w", w);
1192 gl_xml_set_prop_length (node, "h", h);
1195 just = gl_label_object_get_text_alignment (object);
1196 xmlSetProp (node, "justify", gl_util_just_to_string (just));
1198 /* auto_shrink attr */
1199 auto_shrink = gl_label_text_get_auto_shrink (GL_LABEL_TEXT (object));
1200 gl_xml_set_prop_boolean (node, "auto_shrink", auto_shrink);
1203 gl_label_object_get_affine (object, affine);
1204 gl_xml_set_prop_double (node, "a0", affine[0]);
1205 gl_xml_set_prop_double (node, "a1", affine[1]);
1206 gl_xml_set_prop_double (node, "a2", affine[2]);
1207 gl_xml_set_prop_double (node, "a3", affine[3]);
1208 gl_xml_set_prop_double (node, "a4", affine[4]);
1209 gl_xml_set_prop_double (node, "a5", affine[5]);
1212 xml_create_toplevel_span (node, ns, GL_LABEL_TEXT(object));
1214 gl_debug (DEBUG_XML, "END");
1217 /*--------------------------------------------------------------------------*/
1218 /* PRIVATE. Add XML Objects->Object-box Node */
1219 /*--------------------------------------------------------------------------*/
1221 xml_create_object_box (xmlNodePtr root,
1223 glLabelObject *object)
1229 glColorNode *line_color_node;
1231 glColorNode *fill_color_node;
1233 gl_debug (DEBUG_XML, "START");
1235 node = xmlNewChild (root, ns, "Object-box", NULL);
1237 /* position attrs */
1238 gl_label_object_get_position (object, &x, &y);
1239 gl_xml_set_prop_length (node, "x", x);
1240 gl_xml_set_prop_length (node, "y", y);
1243 gl_label_object_get_size (object, &w, &h);
1244 gl_xml_set_prop_length (node, "w", w);
1245 gl_xml_set_prop_length (node, "h", h);
1248 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1249 gl_xml_set_prop_length (node, "line_width", line_width);
1251 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1252 if (line_color_node->field_flag)
1254 xmlSetProp (node, "line_color_field", line_color_node->key);
1258 gl_xml_set_prop_uint_hex (node, "line_color", line_color_node->color);
1260 gl_color_node_free (&line_color_node);
1262 /* fill attrs (color or field) */
1263 fill_color_node = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
1264 if (fill_color_node->field_flag)
1266 xmlSetProp (node, "fill_color_field", fill_color_node->key);
1270 gl_xml_set_prop_uint_hex (node, "fill_color", fill_color_node->color);
1272 gl_color_node_free (&fill_color_node);
1275 gl_label_object_get_affine (object, affine);
1276 gl_xml_set_prop_double (node, "a0", affine[0]);
1277 gl_xml_set_prop_double (node, "a1", affine[1]);
1278 gl_xml_set_prop_double (node, "a2", affine[2]);
1279 gl_xml_set_prop_double (node, "a3", affine[3]);
1280 gl_xml_set_prop_double (node, "a4", affine[4]);
1281 gl_xml_set_prop_double (node, "a5", affine[5]);
1283 gl_debug (DEBUG_XML, "END");
1286 /*--------------------------------------------------------------------------*/
1287 /* PRIVATE. Add XML Objects->Object-ellipse Node */
1288 /*--------------------------------------------------------------------------*/
1290 xml_create_object_ellipse (xmlNodePtr root,
1292 glLabelObject *object)
1298 glColorNode *line_color_node;
1300 glColorNode *fill_color_node;
1302 gl_debug (DEBUG_XML, "START");
1304 node = xmlNewChild (root, ns, "Object-ellipse", NULL);
1306 /* position attrs */
1307 gl_label_object_get_position (object, &x, &y);
1308 gl_xml_set_prop_length (node, "x", x);
1309 gl_xml_set_prop_length (node, "y", y);
1312 gl_label_object_get_size (object, &w, &h);
1313 gl_xml_set_prop_length (node, "w", w);
1314 gl_xml_set_prop_length (node, "h", h);
1317 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1318 gl_xml_set_prop_length (node, "line_width", line_width);
1320 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1321 if (line_color_node->field_flag)
1323 xmlSetProp (node, "line_color_field", line_color_node->key);
1327 gl_xml_set_prop_uint_hex (node, "line_color", line_color_node->color);
1329 gl_color_node_free (&line_color_node);
1332 /* fill attrs (color or field) */
1333 fill_color_node = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
1334 if (fill_color_node->field_flag)
1336 xmlSetProp (node, "fill_color_field", fill_color_node->key);
1340 gl_xml_set_prop_uint_hex (node, "fill_color", fill_color_node->color);
1342 gl_color_node_free (&fill_color_node);
1345 gl_label_object_get_affine (object, affine);
1346 gl_xml_set_prop_double (node, "a0", affine[0]);
1347 gl_xml_set_prop_double (node, "a1", affine[1]);
1348 gl_xml_set_prop_double (node, "a2", affine[2]);
1349 gl_xml_set_prop_double (node, "a3", affine[3]);
1350 gl_xml_set_prop_double (node, "a4", affine[4]);
1351 gl_xml_set_prop_double (node, "a5", affine[5]);
1353 gl_debug (DEBUG_XML, "END");
1356 /*--------------------------------------------------------------------------*/
1357 /* PRIVATE. Add XML Objects->Object-line Node */
1358 /*--------------------------------------------------------------------------*/
1360 xml_create_object_line (xmlNodePtr root,
1362 glLabelObject *object)
1368 glColorNode *line_color_node;
1371 gl_debug (DEBUG_XML, "START");
1373 node = xmlNewChild (root, ns, "Object-line", NULL);
1375 /* position attrs */
1376 gl_label_object_get_position (object, &x, &y);
1377 gl_xml_set_prop_length (node, "x", x);
1378 gl_xml_set_prop_length (node, "y", y);
1381 gl_label_object_get_size (object, &dx, &dy);
1382 gl_xml_set_prop_length (node, "dx", dx);
1383 gl_xml_set_prop_length (node, "dy", dy);
1386 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1387 gl_xml_set_prop_length (node, "line_width", line_width);
1389 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1390 if (line_color_node->field_flag)
1392 xmlSetProp (node, "line_color_field", line_color_node->key);
1396 gl_xml_set_prop_uint_hex (node, "line_color", line_color_node->color);
1398 gl_color_node_free (&line_color_node);
1402 gl_label_object_get_affine (object, affine);
1403 gl_xml_set_prop_double (node, "a0", affine[0]);
1404 gl_xml_set_prop_double (node, "a1", affine[1]);
1405 gl_xml_set_prop_double (node, "a2", affine[2]);
1406 gl_xml_set_prop_double (node, "a3", affine[3]);
1407 gl_xml_set_prop_double (node, "a4", affine[4]);
1408 gl_xml_set_prop_double (node, "a5", affine[5]);
1410 gl_debug (DEBUG_XML, "END");
1413 /*--------------------------------------------------------------------------*/
1414 /* PRIVATE. Add XML Objects->Object-image Node */
1415 /*--------------------------------------------------------------------------*/
1417 xml_create_object_image (xmlNodePtr root,
1419 glLabelObject *object)
1424 glTextNode *filename;
1427 gl_debug (DEBUG_XML, "START");
1429 node = xmlNewChild (root, ns, "Object-image", NULL);
1431 /* position attrs */
1432 gl_label_object_get_position (object, &x, &y);
1433 gl_xml_set_prop_length (node, "x", x);
1434 gl_xml_set_prop_length (node, "y", y);
1437 gl_label_object_get_size (object, &w, &h);
1438 gl_xml_set_prop_length (node, "w", w);
1439 gl_xml_set_prop_length (node, "h", h);
1441 /* src OR field attr */
1442 filename = gl_label_image_get_filename (GL_LABEL_IMAGE(object));
1443 if (filename->field_flag) {
1444 xmlSetProp (node, "field", filename->data);
1446 xmlSetProp (node, "src", filename->data);
1448 gl_text_node_free (&filename);
1451 gl_label_object_get_affine (object, affine);
1452 gl_xml_set_prop_double (node, "a0", affine[0]);
1453 gl_xml_set_prop_double (node, "a1", affine[1]);
1454 gl_xml_set_prop_double (node, "a2", affine[2]);
1455 gl_xml_set_prop_double (node, "a3", affine[3]);
1456 gl_xml_set_prop_double (node, "a4", affine[4]);
1457 gl_xml_set_prop_double (node, "a5", affine[5]);
1459 gl_debug (DEBUG_XML, "END");
1462 /*--------------------------------------------------------------------------*/
1463 /* PRIVATE. Add XML Objects->Object-barcode Node */
1464 /*--------------------------------------------------------------------------*/
1466 xml_create_object_barcode (xmlNodePtr root,
1468 glLabelObject *object)
1473 glTextNode *text_node;
1476 gboolean checksum_flag;
1477 glColorNode *color_node;
1478 guint format_digits;
1481 gl_debug (DEBUG_XML, "START");
1483 node = xmlNewChild (root, ns, "Object-barcode", NULL);
1485 /* position attrs */
1486 gl_label_object_get_position (object, &x, &y);
1487 gl_xml_set_prop_length (node, "x", x);
1488 gl_xml_set_prop_length (node, "y", y);
1491 gl_label_object_get_size (object, &w, &h);
1492 gl_xml_set_prop_length (node, "w", w);
1493 gl_xml_set_prop_length (node, "h", h);
1495 /* Barcode properties attrs */
1496 gl_label_barcode_get_props (GL_LABEL_BARCODE(object),
1497 &id, &text_flag, &checksum_flag, &format_digits);
1498 xmlSetProp (node, "style", id);
1499 gl_xml_set_prop_boolean (node, "text", text_flag);
1500 gl_xml_set_prop_boolean (node, "checksum", checksum_flag);
1504 color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1505 if (color_node->field_flag)
1507 xmlSetProp (node, "color_field", color_node->key);
1511 gl_xml_set_prop_uint_hex (node, "color", color_node->color);
1513 gl_color_node_free (&color_node);
1516 /* data OR field attr */
1517 text_node = gl_label_barcode_get_data (GL_LABEL_BARCODE(object));
1518 if (text_node->field_flag) {
1519 xmlSetProp (node, "field", text_node->data);
1520 gl_xml_set_prop_int (node, "format", format_digits);
1522 xmlSetProp (node, "data", text_node->data);
1524 gl_text_node_free (&text_node);
1527 gl_label_object_get_affine (object, affine);
1528 gl_xml_set_prop_double (node, "a0", affine[0]);
1529 gl_xml_set_prop_double (node, "a1", affine[1]);
1530 gl_xml_set_prop_double (node, "a2", affine[2]);
1531 gl_xml_set_prop_double (node, "a3", affine[3]);
1532 gl_xml_set_prop_double (node, "a4", affine[4]);
1533 gl_xml_set_prop_double (node, "a5", affine[5]);
1535 gl_debug (DEBUG_XML, "END");
1538 /*--------------------------------------------------------------------------*/
1539 /* PRIVATE. Add XML Label Merge Fields Node */
1540 /*--------------------------------------------------------------------------*/
1542 xml_create_merge_fields (xmlNodePtr root,
1546 xmlNodePtr node, child;
1551 gl_debug (DEBUG_XML, "START");
1553 merge = gl_label_get_merge (label);
1555 node = xmlNewChild (root, ns, "Merge", NULL);
1557 string = gl_merge_get_name (merge);
1558 xmlSetProp (node, "type", string);
1561 string = gl_merge_get_src (merge);
1562 xmlSetProp (node, "src", string);
1565 g_object_unref (G_OBJECT(merge));
1567 gl_debug (DEBUG_XML, "END");
1570 /*--------------------------------------------------------------------------*/
1571 /* PRIVATE. Add XML Label Data Node */
1572 /*--------------------------------------------------------------------------*/
1574 xml_create_data (xmlNodePtr root,
1579 GList *name_list, *p;
1580 GHashTable *pixbuf_cache;
1582 gl_debug (DEBUG_XML, "START");
1584 node = xmlNewChild (root, ns, "Data", NULL);
1586 pixbuf_cache = gl_label_get_pixbuf_cache (label);
1587 name_list = gl_pixbuf_cache_get_name_list (pixbuf_cache);
1589 for (p = name_list; p != NULL; p=p->next) {
1590 xml_create_pixdata (node, ns, label, p->data);
1593 gl_pixbuf_cache_free_name_list (name_list);
1596 gl_debug (DEBUG_XML, "END");
1599 /*--------------------------------------------------------------------------*/
1600 /* PRIVATE. Add XML Label Data Pixbuf Node */
1601 /*--------------------------------------------------------------------------*/
1603 xml_create_pixdata (xmlNodePtr root,
1609 GHashTable *pixbuf_cache;
1611 GdkPixdata *pixdata;
1613 guint stream_length;
1616 gl_debug (DEBUG_XML, "START");
1618 pixbuf_cache = gl_label_get_pixbuf_cache (label);
1620 pixbuf = gl_pixbuf_cache_get_pixbuf (pixbuf_cache, name);
1621 if ( pixbuf != NULL ) {
1623 pixdata = g_new0 (GdkPixdata, 1);
1624 gdk_pixdata_from_pixbuf (pixdata, pixbuf, FALSE);
1625 stream = gdk_pixdata_serialize (pixdata, &stream_length);
1626 base64 = gl_base64_encode (stream, stream_length);
1628 node = xmlNewChild (root, ns, "Pixdata", base64);
1629 xmlSetProp (node, "name", name);
1630 xmlSetProp (node, "encoding", "Base64");
1632 gl_pixbuf_cache_remove_pixbuf (pixbuf_cache, name);
1640 gl_debug (DEBUG_XML, "END");
1643 /*--------------------------------------------------------------------------*/
1644 /* PRIVATE. Create top-level Span node. */
1645 /*--------------------------------------------------------------------------*/
1647 xml_create_toplevel_span (xmlNodePtr root,
1649 glLabelText *object_text)
1654 GnomeFontWeight font_weight;
1655 gboolean font_italic_flag;
1656 glColorNode *color_node;
1657 GtkJustification just;
1658 gdouble text_line_spacing;
1659 GList *lines, *p_line, *p_node;
1660 glTextNode *text_node;
1663 node = xmlNewChild (root, ns, "Span", NULL);
1665 /* All span attrs at top level. */
1666 font_family = gl_label_object_get_font_family (GL_LABEL_OBJECT(object_text));
1667 font_size = gl_label_object_get_font_size (GL_LABEL_OBJECT(object_text));
1668 text_line_spacing = gl_label_object_get_text_line_spacing (GL_LABEL_OBJECT(object_text));
1669 font_weight = gl_label_object_get_font_weight (GL_LABEL_OBJECT(object_text));
1670 font_italic_flag = gl_label_object_get_font_italic_flag (GL_LABEL_OBJECT(object_text));
1672 color_node = gl_label_object_get_text_color (GL_LABEL_OBJECT(object_text));
1673 if (color_node->field_flag)
1675 xmlSetProp (node, "color_field", color_node->key);
1679 gl_xml_set_prop_uint_hex (node, "color", color_node->color);
1681 gl_color_node_free (&color_node);
1683 just = gl_label_object_get_text_alignment (GL_LABEL_OBJECT(object_text));
1684 xmlSetProp (node, "font_family", font_family);
1685 gl_xml_set_prop_double (node, "font_size", font_size);
1686 xmlSetProp (node, "font_weight", gl_util_weight_to_string (font_weight));
1687 gl_xml_set_prop_boolean (node, "font_italic", font_italic_flag);
1689 gl_xml_set_prop_double (node, "line_spacing", text_line_spacing);
1691 /* Build children. */
1692 lines = gl_label_text_get_lines (GL_LABEL_TEXT(object_text));
1693 for (p_line = lines; p_line != NULL; p_line = p_line->next) {
1695 for (p_node = (GList *) p_line->data; p_node != NULL;
1696 p_node = p_node->next) {
1697 text_node = (glTextNode *) p_node->data;
1699 if (text_node->field_flag) {
1700 child = xmlNewChild (node, ns, "Field", NULL);
1701 xmlSetProp (child, "name", text_node->data);
1703 xmlNodeAddContent (node, text_node->data);
1708 if ( p_line->next ) {
1709 child = xmlNewChild (node, ns, "NL", NULL);
1714 gl_text_node_lines_free (&lines);
1715 g_free (font_family);