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 <glib/gi18n.h>
28 #include <libxml/tree.h>
29 #include <libxml/parser.h>
30 #include <gdk-pixbuf/gdk-pixdata.h>
33 #include "label-object.h"
34 #include "label-text.h"
35 #include "label-box.h"
36 #include "label-line.h"
37 #include "label-ellipse.h"
38 #include "label-image.h"
39 #include "label-barcode.h"
41 #include "xml-label.h"
42 #include "xml-label-04.h"
43 #include "xml-label-191.h"
44 #include <libglabels/template.h>
45 #include <libglabels/xml-template.h>
46 #include <libglabels/xml.h>
51 /*========================================================*/
52 /* Private macros and constants. */
53 /*========================================================*/
54 #define COMPAT01_NAME_SPACE "http://snaught.com/glabels/0.1/"
55 #define COMPAT04_NAME_SPACE "http://snaught.com/glabels/0.4/"
56 #define COMPAT191_NAME_SPACE "http://snaught.com/glabels/1.92/"
58 /*========================================================*/
60 /*========================================================*/
62 /*========================================================*/
63 /* Private globals. */
64 /*========================================================*/
66 /*========================================================*/
67 /* Private function prototypes. */
68 /*========================================================*/
70 static glLabel *xml_doc_to_label (xmlDocPtr doc,
71 glXMLLabelStatus *status);
73 static glLabel *xml_parse_label (xmlNodePtr root,
74 glXMLLabelStatus *status);
76 static void xml_parse_objects (xmlNodePtr node,
79 static void xml_parse_object_text (xmlNodePtr node,
82 static void xml_parse_object_box (xmlNodePtr node,
85 static void xml_parse_object_ellipse (xmlNodePtr node,
88 static void xml_parse_object_line (xmlNodePtr node,
91 static void xml_parse_object_image (xmlNodePtr node,
94 static void xml_parse_object_barcode (xmlNodePtr node,
97 static void xml_parse_merge_fields (xmlNodePtr node,
100 static void xml_parse_data (xmlNodePtr node,
103 static void xml_parse_pixdata (xmlNodePtr node,
106 static void xml_parse_toplevel_span (xmlNodePtr node,
107 glLabelObject *object);
110 static xmlDocPtr xml_label_to_doc (glLabel *label,
111 glXMLLabelStatus *status);
113 static void xml_create_objects (xmlNodePtr root,
117 static void xml_create_object_text (xmlNodePtr root,
119 glLabelObject *object);
121 static void xml_create_object_box (xmlNodePtr root,
123 glLabelObject *object);
125 static void xml_create_object_line (xmlNodePtr root,
127 glLabelObject *object);
129 static void xml_create_object_ellipse(xmlNodePtr root,
131 glLabelObject *object);
133 static void xml_create_object_image (xmlNodePtr root,
135 glLabelObject *object);
137 static void xml_create_object_barcode(xmlNodePtr root,
139 glLabelObject *object);
141 static void xml_create_merge_fields (xmlNodePtr root,
145 static void xml_create_data (xmlNodePtr root,
149 static void xml_create_pixdata (xmlNodePtr root,
154 static void xml_create_toplevel_span (xmlNodePtr node,
156 glLabelText *object_text);
159 /****************************************************************************/
160 /* Open and read label from xml file. */
161 /****************************************************************************/
163 gl_xml_label_open (const gchar *utf8_filename,
164 glXMLLabelStatus *status)
170 gl_debug (DEBUG_XML, "START");
172 filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
173 g_return_val_if_fail (filename, NULL);
175 doc = xmlParseFile (filename);
177 g_warning (_("xmlParseFile error"));
178 *status = XML_LABEL_ERROR_OPEN_PARSE;
182 xmlXIncludeProcess (doc);
183 xmlReconciliateNs (doc, xmlDocGetRootElement (doc));
185 label = xml_doc_to_label (doc, status);
190 gl_label_set_filename (label, utf8_filename);
191 gl_label_clear_modified (label);
195 gl_debug (DEBUG_XML, "END");
200 /****************************************************************************/
201 /* Read label from xml buffer. */
202 /****************************************************************************/
204 gl_xml_label_open_buffer (const gchar *buffer,
205 glXMLLabelStatus *status)
210 gl_debug (DEBUG_XML, "START");
212 doc = xmlParseDoc ((xmlChar *) buffer);
214 g_warning (_("xmlParseFile error"));
215 *status = XML_LABEL_ERROR_OPEN_PARSE;
219 label = xml_doc_to_label (doc, status);
224 gl_label_clear_modified (label);
227 gl_debug (DEBUG_XML, "END");
232 /*--------------------------------------------------------------------------*/
233 /* PRIVATE. Parse xml doc structure and create label. */
234 /*--------------------------------------------------------------------------*/
236 xml_doc_to_label (xmlDocPtr doc,
237 glXMLLabelStatus *status)
239 xmlNodePtr root, node;
243 gl_debug (DEBUG_XML, "START");
247 *status = XML_LABEL_OK;
249 root = xmlDocGetRootElement (doc);
250 if (!root || !root->name) {
251 g_warning (_("No document root"));
252 *status = XML_LABEL_ERROR_OPEN_PARSE;
256 ns = xmlSearchNsByHref (doc, root, GL_XML_NAME_SPACE);
258 label = xml_parse_label (root, status);
260 gl_label_set_compression (label, xmlGetDocCompressMode (doc));
262 /* Try compatability mode 0.1 */
263 ns = xmlSearchNsByHref (doc, root, COMPAT01_NAME_SPACE);
265 g_warning (_("Importing from glabels 0.1 format"));
267 label = NULL; /* TODO */
269 /* Try compatability mode 0.4 */
270 ns = xmlSearchNsByHref (doc, root,
271 COMPAT04_NAME_SPACE);
273 g_warning (_("Importing from glabels 0.4 format"));
274 label = gl_xml_label_04_parse (root, status);
276 /* Try compatability mode 1.91 */
277 ns = xmlSearchNsByHref (doc, root,
278 COMPAT191_NAME_SPACE);
280 g_warning (_("Importing from glabels 1.91 format"));
281 label = gl_xml_label_191_parse (root, status);
283 g_warning (_("bad document, unknown glabels Namespace"));
284 *status = XML_LABEL_ERROR_OPEN_PARSE;
291 gl_debug (DEBUG_XML, "END");
296 /*--------------------------------------------------------------------------*/
297 /* PRIVATE. Parse xml root node and create label. */
298 /*--------------------------------------------------------------------------*/
300 xml_parse_label (xmlNodePtr root,
301 glXMLLabelStatus *status)
303 xmlNodePtr child_node;
305 glTemplate *template;
307 gl_debug (DEBUG_XML, "START");
309 *status = XML_LABEL_OK;
311 if (!xmlStrEqual (root->name, "Glabels-document")) {
312 g_warning (_("Bad root node = \"%s\""), root->name);
313 *status = XML_LABEL_ERROR_OPEN_PARSE;
317 label = GL_LABEL(gl_label_new ());
319 /* Pass 1, extract data nodes to pre-load cache. */
320 for (child_node = root->xmlChildrenNode; child_node != NULL; child_node = child_node->next) {
321 if (xmlStrEqual (child_node->name, "Data")) {
322 xml_parse_data (child_node, label);
326 /* Pass 2, now extract everything else. */
327 for (child_node = root->xmlChildrenNode;
329 child_node = child_node->next) {
331 if (xmlStrEqual (child_node->name, "Template")) {
332 template = gl_xml_template_parse_template_node (child_node);
334 g_object_unref (label);
335 *status = XML_LABEL_UNKNOWN_MEDIA;
338 gl_template_register (template);
339 gl_label_set_template (label, template);
340 gl_template_free (template);
341 } else if (xmlStrEqual (child_node->name, "Objects")) {
342 xml_parse_objects (child_node, label);
343 } else if (xmlStrEqual (child_node->name, "Merge")) {
344 xml_parse_merge_fields (child_node, label);
345 } else if (xmlStrEqual (child_node->name, "Data")) {
346 /* Handled in pass 1. */
348 if (!xmlNodeIsText (child_node)) {
349 g_warning (_("bad node in Document node = \"%s\""),
351 g_object_unref (label);
352 *status = XML_LABEL_ERROR_OPEN_PARSE;
358 gl_debug (DEBUG_XML, "END");
363 /*--------------------------------------------------------------------------*/
364 /* PRIVATE. Parse Objects node. */
365 /*--------------------------------------------------------------------------*/
367 xml_parse_objects (xmlNodePtr node,
370 gboolean rotate_flag;
373 gl_debug (DEBUG_XML, "START");
375 rotate_flag = gl_xml_get_prop_boolean (node, "rotate", FALSE);
376 gl_label_set_rotate_flag (label, rotate_flag);
378 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
380 if (xmlStrEqual (child->name, "Object-text")) {
381 xml_parse_object_text (child, label);
382 } else if (xmlStrEqual (child->name, "Object-box")) {
383 xml_parse_object_box (child, label);
384 } else if (xmlStrEqual (child->name, "Object-ellipse")) {
385 xml_parse_object_ellipse (child, label);
386 } else if (xmlStrEqual (child->name, "Object-line")) {
387 xml_parse_object_line (child, label);
388 } else if (xmlStrEqual (child->name, "Object-image")) {
389 xml_parse_object_image (child, label);
390 } else if (xmlStrEqual (child->name, "Object-barcode")) {
391 xml_parse_object_barcode (child, label);
393 if (!xmlNodeIsText (child)) {
394 g_warning (_("bad node = \"%s\""), child->name);
400 gl_debug (DEBUG_XML, "END");
403 /*--------------------------------------------------------------------------*/
404 /* PRIVATE. Parse XML Objects->Object-text Node */
405 /*--------------------------------------------------------------------------*/
407 xml_parse_object_text (xmlNodePtr node,
414 GtkJustification just;
415 gboolean auto_shrink;
419 gl_debug (DEBUG_XML, "START");
421 object = gl_label_text_new (label);
424 x = gl_xml_get_prop_length (node, "x", 0.0);
425 y = gl_xml_get_prop_length (node, "y", 0.0);
426 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
428 /* implied size attrs */
429 w = gl_xml_get_prop_length (node, "w", 0);
430 h = gl_xml_get_prop_length (node, "h", 0);
431 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
434 string = xmlGetProp (node, "justify");
435 just = gl_util_string_to_just (string);
437 gl_label_object_set_text_alignment (GL_LABEL_OBJECT(object), just);
439 /* auto_shrink attr */
440 auto_shrink = gl_xml_get_prop_boolean (node, "auto_shrink", FALSE);
441 gl_label_text_set_auto_shrink (GL_LABEL_TEXT(object), auto_shrink);
444 affine[0] = gl_xml_get_prop_double (node, "a0", 0.0);
445 affine[1] = gl_xml_get_prop_double (node, "a1", 0.0);
446 affine[2] = gl_xml_get_prop_double (node, "a2", 0.0);
447 affine[3] = gl_xml_get_prop_double (node, "a3", 0.0);
448 affine[4] = gl_xml_get_prop_double (node, "a4", 0.0);
449 affine[5] = gl_xml_get_prop_double (node, "a5", 0.0);
450 gl_label_object_set_affine (GL_LABEL_OBJECT(object), affine);
452 /* Process children */
453 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
454 if (xmlStrEqual (child->name, "Span")) {
455 xml_parse_toplevel_span (child, GL_LABEL_OBJECT(object));
458 if (!xmlNodeIsText (child)) {
459 g_warning ("Unexpected Object-text child: \"%s\"",
465 gl_debug (DEBUG_XML, "END");
468 /*--------------------------------------------------------------------------*/
469 /* PRIVATE. Parse XML Objects->Object-box Node */
470 /*--------------------------------------------------------------------------*/
472 xml_parse_object_box (xmlNodePtr node,
479 glColorNode *line_color_node;
482 glColorNode *fill_color_node;
484 gl_debug (DEBUG_XML, "START");
486 object = gl_label_box_new (label);
489 x = gl_xml_get_prop_length (node, "x", 0.0);
490 y = gl_xml_get_prop_length (node, "y", 0.0);
491 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
494 w = gl_xml_get_prop_length (node, "w", 0);
495 h = gl_xml_get_prop_length (node, "h", 0);
496 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
499 line_width = gl_xml_get_prop_length (node, "line_width", 1.0);
500 gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width);
502 line_color_node = gl_color_node_new_default ();
503 string = xmlGetProp (node, "line_color_field");
505 line_color_node->field_flag = TRUE;
506 line_color_node->key = string;
508 line_color_node->color = gl_xml_get_prop_uint (node, "line_color", 0);
510 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color_node);
511 gl_color_node_free (&line_color_node);
515 fill_color_node = gl_color_node_new_default ();
516 string = xmlGetProp (node, "fill_color_field");
518 fill_color_node->field_flag = TRUE;
519 fill_color_node->key = string;
521 fill_color_node->color = gl_xml_get_prop_uint (node, "fill_color", 0);
523 gl_label_object_set_fill_color (GL_LABEL_OBJECT(object), fill_color_node);
524 gl_color_node_free (&fill_color_node);
527 affine[0] = gl_xml_get_prop_double (node, "a0", 0.0);
528 affine[1] = gl_xml_get_prop_double (node, "a1", 0.0);
529 affine[2] = gl_xml_get_prop_double (node, "a2", 0.0);
530 affine[3] = gl_xml_get_prop_double (node, "a3", 0.0);
531 affine[4] = gl_xml_get_prop_double (node, "a4", 0.0);
532 affine[5] = gl_xml_get_prop_double (node, "a5", 0.0);
533 gl_label_object_set_affine (GL_LABEL_OBJECT(object), affine);
535 gl_debug (DEBUG_XML, "END");
538 /*--------------------------------------------------------------------------*/
539 /* PRIVATE. Parse XML Objects->Object-ellipse Node */
540 /*--------------------------------------------------------------------------*/
542 xml_parse_object_ellipse (xmlNodePtr node,
549 glColorNode *line_color_node;
552 glColorNode *fill_color_node;
554 gl_debug (DEBUG_XML, "START");
556 object = gl_label_ellipse_new (label);
559 x = gl_xml_get_prop_length (node, "x", 0.0);
560 y = gl_xml_get_prop_length (node, "y", 0.0);
561 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
564 w = gl_xml_get_prop_length (node, "w", 0);
565 h = gl_xml_get_prop_length (node, "h", 0);
566 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
569 line_width = gl_xml_get_prop_length (node, "line_width", 1.0);
570 gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width);
572 line_color_node = gl_color_node_new_default ();
573 string = xmlGetProp (node, "line_color_field");
575 line_color_node->field_flag = TRUE;
576 line_color_node->key = string;
578 line_color_node->color = gl_xml_get_prop_uint (node, "line_color", 0);
580 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color_node);
581 gl_color_node_free (&line_color_node);
585 fill_color_node = gl_color_node_new_default ();
586 string = xmlGetProp (node, "fill_color_field");
588 fill_color_node->field_flag = TRUE;
589 fill_color_node->key = string;
591 fill_color_node->color = gl_xml_get_prop_uint (node, "fill_color", 0);
593 gl_label_object_set_fill_color (GL_LABEL_OBJECT(object), fill_color_node);
594 gl_color_node_free (&fill_color_node);
597 affine[0] = gl_xml_get_prop_double (node, "a0", 0.0);
598 affine[1] = gl_xml_get_prop_double (node, "a1", 0.0);
599 affine[2] = gl_xml_get_prop_double (node, "a2", 0.0);
600 affine[3] = gl_xml_get_prop_double (node, "a3", 0.0);
601 affine[4] = gl_xml_get_prop_double (node, "a4", 0.0);
602 affine[5] = gl_xml_get_prop_double (node, "a5", 0.0);
603 gl_label_object_set_affine (GL_LABEL_OBJECT(object), affine);
605 gl_debug (DEBUG_XML, "END");
608 /*--------------------------------------------------------------------------*/
609 /* PRIVATE. Parse XML Objects->Object-line Node */
610 /*--------------------------------------------------------------------------*/
612 xml_parse_object_line (xmlNodePtr node,
619 glColorNode *line_color_node;
623 gl_debug (DEBUG_XML, "START");
625 object = gl_label_line_new (label);
628 x = gl_xml_get_prop_length (node, "x", 0.0);
629 y = gl_xml_get_prop_length (node, "y", 0.0);
630 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
633 dx = gl_xml_get_prop_length (node, "dx", 0);
634 dy = gl_xml_get_prop_length (node, "dy", 0);
635 gl_label_object_set_size (GL_LABEL_OBJECT(object), dx, dy);
638 line_width = gl_xml_get_prop_length (node, "line_width", 1.0);
639 gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width);
641 line_color_node = gl_color_node_new_default ();
642 string = xmlGetProp (node, "line_color_field");
644 line_color_node->field_flag = TRUE;
645 line_color_node->key = string;
647 line_color_node->color = gl_xml_get_prop_uint (node, "line_color", 0);
649 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color_node);
650 gl_color_node_free (&line_color_node);
653 affine[0] = gl_xml_get_prop_double (node, "a0", 0.0);
654 affine[1] = gl_xml_get_prop_double (node, "a1", 0.0);
655 affine[2] = gl_xml_get_prop_double (node, "a2", 0.0);
656 affine[3] = gl_xml_get_prop_double (node, "a3", 0.0);
657 affine[4] = gl_xml_get_prop_double (node, "a4", 0.0);
658 affine[5] = gl_xml_get_prop_double (node, "a5", 0.0);
659 gl_label_object_set_affine (GL_LABEL_OBJECT(object), affine);
661 gl_debug (DEBUG_XML, "END");
664 /*--------------------------------------------------------------------------*/
665 /* PRIVATE. Parse XML Objects->Object-image Node */
666 /*--------------------------------------------------------------------------*/
668 xml_parse_object_image (xmlNodePtr node,
675 glTextNode *filename;
678 gl_debug (DEBUG_XML, "START");
680 object = gl_label_image_new (label);
683 x = gl_xml_get_prop_length (node, "x", 0.0);
684 y = gl_xml_get_prop_length (node, "y", 0.0);
685 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
687 /* src or field attr */
688 string = xmlGetProp (node, "src");
690 filename = g_new0 (glTextNode, 1);
691 filename->field_flag = FALSE;
692 filename->data = string;
693 gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename);
694 gl_text_node_free (&filename);
696 string = xmlGetProp (node, "field");
698 filename = g_new0 (glTextNode, 1);
699 filename->field_flag = TRUE;
700 filename->data = string;
701 gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename);
702 gl_text_node_free (&filename);
704 g_warning ("Missing Object-image src or field attr");
709 w = gl_xml_get_prop_length (node, "w", 0);
710 h = gl_xml_get_prop_length (node, "h", 0);
711 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
714 affine[0] = gl_xml_get_prop_double (node, "a0", 0.0);
715 affine[1] = gl_xml_get_prop_double (node, "a1", 0.0);
716 affine[2] = gl_xml_get_prop_double (node, "a2", 0.0);
717 affine[3] = gl_xml_get_prop_double (node, "a3", 0.0);
718 affine[4] = gl_xml_get_prop_double (node, "a4", 0.0);
719 affine[5] = gl_xml_get_prop_double (node, "a5", 0.0);
720 gl_label_object_set_affine (GL_LABEL_OBJECT(object), affine);
722 gl_debug (DEBUG_XML, "END");
725 /*--------------------------------------------------------------------------*/
726 /* PRIVATE. Parse XML Objects->Object-barcode Node */
727 /*--------------------------------------------------------------------------*/
729 xml_parse_object_barcode (xmlNodePtr node,
736 glTextNode *text_node;
739 gboolean checksum_flag;
740 glColorNode *color_node;
744 gl_debug (DEBUG_XML, "START");
746 object = gl_label_barcode_new (label);
749 x = gl_xml_get_prop_length (node, "x", 0.0);
750 y = gl_xml_get_prop_length (node, "y", 0.0);
751 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
754 w = gl_xml_get_prop_length (node, "w", 0);
755 h = gl_xml_get_prop_length (node, "h", 0);
756 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
759 id = xmlGetProp (node, "style");
760 text_flag = gl_xml_get_prop_boolean (node, "text", FALSE);
761 checksum_flag = gl_xml_get_prop_boolean (node, "checksum", TRUE);
762 format_digits = gl_xml_get_prop_uint (node, "format", 10);
763 gl_label_barcode_set_props (GL_LABEL_BARCODE(object),
764 id, text_flag, checksum_flag, format_digits);
767 color_node = gl_color_node_new_default ();
768 string = xmlGetProp (node, "color_field");
770 color_node->field_flag = TRUE;
771 color_node->key = string;
773 color_node->color = gl_xml_get_prop_uint (node, "color", 0);
775 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), color_node);
776 gl_color_node_free (&color_node);
778 /* data or field attr */
779 string = xmlGetProp (node, "data");
781 text_node = g_new0 (glTextNode, 1);
782 text_node->field_flag = FALSE;
783 text_node->data = string;
784 gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node);
785 gl_text_node_free (&text_node);
787 string = xmlGetProp (node, "field");
789 text_node = g_new0 (glTextNode, 1);
790 text_node->field_flag = TRUE;
791 text_node->data = string;
792 gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node);
793 gl_text_node_free (&text_node);
795 g_warning ("Missing Object-barcode data or field attr");
800 affine[0] = gl_xml_get_prop_double (node, "a0", 0.0);
801 affine[1] = gl_xml_get_prop_double (node, "a1", 0.0);
802 affine[2] = gl_xml_get_prop_double (node, "a2", 0.0);
803 affine[3] = gl_xml_get_prop_double (node, "a3", 0.0);
804 affine[4] = gl_xml_get_prop_double (node, "a4", 0.0);
805 affine[5] = gl_xml_get_prop_double (node, "a5", 0.0);
806 gl_label_object_set_affine (GL_LABEL_OBJECT(object), affine);
808 gl_debug (DEBUG_XML, "END");
811 /*--------------------------------------------------------------------------*/
812 /* PRIVATE. Parse XML merge fields tag. */
813 /*--------------------------------------------------------------------------*/
815 xml_parse_merge_fields (xmlNodePtr node,
822 gl_debug (DEBUG_XML, "START");
824 string = xmlGetProp (node, "type");
825 merge = gl_merge_new (string);
828 string = xmlGetProp (node, "src");
829 gl_merge_set_src (merge, string);
832 gl_label_set_merge (label, merge);
834 g_object_unref (G_OBJECT(merge));
836 gl_debug (DEBUG_XML, "END");
839 /*--------------------------------------------------------------------------*/
840 /* PRIVATE. Parse XML data tag. */
841 /*--------------------------------------------------------------------------*/
843 xml_parse_data (xmlNodePtr node,
848 gl_debug (DEBUG_XML, "START");
850 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
852 if (xmlStrEqual (child->name, "Pixdata")) {
853 xml_parse_pixdata (child, label);
855 if (!xmlNodeIsText (child)) {
856 g_warning (_("bad node in Data node = \"%s\""),
862 gl_debug (DEBUG_XML, "END");
865 /*--------------------------------------------------------------------------*/
866 /* PRIVATE. Parse XML pixbuf data tag. */
867 /*--------------------------------------------------------------------------*/
869 xml_parse_pixdata (xmlNodePtr node,
872 gchar *name, *base64;
878 GHashTable *pixbuf_cache;
880 gl_debug (DEBUG_XML, "START");
882 name = xmlGetProp (node, "name");
883 base64 = xmlNodeGetContent (node);
885 stream = gl_base64_decode (base64, &stream_length);
886 pixdata = g_new0 (GdkPixdata, 1);
887 ret = gdk_pixdata_deserialize (pixdata, stream_length, stream, NULL);
890 pixbuf = gdk_pixbuf_from_pixdata (pixdata, TRUE, NULL);
892 pixbuf_cache = gl_label_get_pixbuf_cache (label);
893 gl_pixbuf_cache_add_pixbuf (pixbuf_cache, name, pixbuf);
901 gl_debug (DEBUG_XML, "END");
904 /*--------------------------------------------------------------------------*/
905 /* PRIVATE. Parse top-level Span tag. */
906 /*--------------------------------------------------------------------------*/
908 xml_parse_toplevel_span (xmlNodePtr node,
909 glLabelObject *object)
913 GnomeFontWeight font_weight;
914 gboolean font_italic_flag;
915 glColorNode *color_node;
916 gdouble text_line_spacing;
918 GList *lines, *text_nodes;
920 glTextNode *text_node;
922 gl_debug (DEBUG_XML, "START");
924 /* Font family attr */
925 font_family = xmlGetProp (node, "font_family");
926 gl_label_object_set_font_family (object, font_family);
927 g_free (font_family);
930 font_size = gl_xml_get_prop_double (node, "font_size", 0.0);
931 gl_label_object_set_font_size (object, font_size);
933 /* Font weight attr */
934 string = xmlGetProp (node, "font_weight");
935 font_weight = gl_util_string_to_weight (string);
937 gl_label_object_set_font_weight (object, font_weight);
939 /* Font italic flag attr */
940 font_italic_flag = gl_xml_get_prop_boolean (node, "font_italic", FALSE);
941 gl_label_object_set_font_italic_flag (object, font_italic_flag);
943 /* Text color attr */
944 color_node = gl_color_node_new_default ();
945 string = xmlGetProp (node, "color_field");
947 color_node->field_flag = TRUE;
948 color_node->key = string;
950 color_node->color = gl_xml_get_prop_uint (node, "color", 0);
952 gl_label_object_set_text_color (object, color_node);
953 gl_color_node_free (&color_node);
956 /* Text line spacing attr */
957 text_line_spacing = gl_xml_get_prop_double (node, "line_spacing", 1.0);
958 gl_label_object_set_text_line_spacing (object, text_line_spacing);
960 /* Now descend children, and build lines of text nodes */
963 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
965 if (xmlNodeIsText (child)) {
966 gchar *data = xmlNodeGetContent (child);
968 /* Hack: if the first char is LF, it's a xml formatting string */
969 if (data[0] != '\n') {
971 text_node = g_new0 (glTextNode, 1);
972 text_node->field_flag = FALSE;
973 text_node->data = data;
974 text_nodes = g_list_append (text_nodes, text_node);
979 } else if (xmlStrEqual (child->name, "Span")) {
981 g_warning ("Unexpected rich text (not supported, yet!)");
983 } else if (xmlStrEqual (child->name, "Field")) {
986 text_node = g_new0 (glTextNode, 1);
987 text_node->field_flag = TRUE;
988 text_node->data = xmlGetProp (child, "name");
989 text_nodes = g_list_append (text_nodes, text_node);
991 } else if (xmlStrEqual (child->name, "NL")) {
994 lines = g_list_append (lines, text_nodes);
998 g_warning ("Unexpected Span child: \"%s\"", child->name);
1003 /* Store last line. */
1004 lines = g_list_append (lines, text_nodes);
1007 gl_label_text_set_lines (GL_LABEL_TEXT(object), lines);
1008 gl_text_node_lines_free (&lines);
1010 gl_debug (DEBUG_XML, "END");
1013 /****************************************************************************/
1014 /* Save label to xml label file. */
1015 /****************************************************************************/
1017 gl_xml_label_save (glLabel *label,
1018 const gchar *utf8_filename,
1019 glXMLLabelStatus *status)
1025 gl_debug (DEBUG_XML, "START");
1027 doc = xml_label_to_doc (label, status);
1029 filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
1031 g_warning (_("Utf8 conversion error."));
1033 xmlSetDocCompressMode (doc, gl_label_get_compression (label));
1034 xml_ret = xmlSaveFormatFile (filename, doc, TRUE);
1036 if (xml_ret == -1) {
1038 g_warning (_("Problem saving xml file."));
1039 *status = XML_LABEL_ERROR_SAVE_FILE;
1043 gl_label_set_filename (label, utf8_filename);
1044 gl_label_clear_modified (label);
1050 gl_debug (DEBUG_XML, "END");
1053 /****************************************************************************/
1054 /* Save label to xml buffer. */
1055 /****************************************************************************/
1057 gl_xml_label_save_buffer (glLabel *label,
1058 glXMLLabelStatus *status)
1064 gl_debug (DEBUG_XML, "START");
1066 doc = xml_label_to_doc (label, status);
1068 xmlDocDumpMemory (doc, (xmlChar **)&buffer, &size);
1071 gl_label_clear_modified (label);
1073 gl_debug (DEBUG_XML, "END");
1078 /*--------------------------------------------------------------------------*/
1079 /* PRIVATE. Convert label to xml doc structure. */
1080 /*--------------------------------------------------------------------------*/
1082 xml_label_to_doc (glLabel *label,
1083 glXMLLabelStatus *status)
1087 glTemplate *template;
1090 gl_debug (DEBUG_XML, "START");
1092 LIBXML_TEST_VERSION;
1094 doc = xmlNewDoc ("1.0");
1095 doc->xmlRootNode = xmlNewDocNode (doc, NULL, "Glabels-document", NULL);
1097 ns = xmlNewNs (doc->xmlRootNode, GL_XML_NAME_SPACE, NULL);
1098 xmlSetNs (doc->xmlRootNode, ns);
1100 template = gl_label_get_template (label);
1101 gl_xml_template_create_template_node (template, doc->xmlRootNode, ns);
1103 xml_create_objects (doc->xmlRootNode, ns, label);
1105 merge = gl_label_get_merge (label);
1106 gl_debug (DEBUG_XML, "merge=%p", merge);
1107 if (merge != NULL) {
1108 xml_create_merge_fields (doc->xmlRootNode, ns, label);
1109 g_object_unref (G_OBJECT(merge));
1112 xml_create_data (doc->xmlRootNode, ns, label);
1114 gl_debug (DEBUG_XML, "END");
1116 *status = XML_LABEL_OK;
1120 /*--------------------------------------------------------------------------*/
1121 /* PRIVATE. Add XML Objects Node */
1122 /*--------------------------------------------------------------------------*/
1124 xml_create_objects (xmlNodePtr root,
1129 gboolean rotate_flag;
1131 glLabelObject *object;
1133 gl_debug (DEBUG_XML, "START");
1135 rotate_flag = gl_label_get_rotate_flag (label);
1137 node = xmlNewChild (root, ns, "Objects", NULL);
1138 xmlSetProp (node, "id", "0");
1139 gl_xml_set_prop_boolean (node, "rotate", rotate_flag);
1141 for (p = label->objects; p != NULL; p = p->next) {
1143 object = GL_LABEL_OBJECT(p->data);
1145 if ( GL_IS_LABEL_TEXT(object) ) {
1146 xml_create_object_text (node, ns, object);
1147 } else if ( GL_IS_LABEL_BOX(object) ) {
1148 xml_create_object_box (node, ns, object);
1149 } else if ( GL_IS_LABEL_ELLIPSE(object) ) {
1150 xml_create_object_ellipse (node, ns, object);
1151 } else if ( GL_IS_LABEL_LINE(object) ) {
1152 xml_create_object_line (node, ns, object);
1153 } else if ( GL_IS_LABEL_IMAGE(object) ) {
1154 xml_create_object_image (node, ns, object);
1155 } else if ( GL_IS_LABEL_BARCODE(object) ) {
1156 xml_create_object_barcode (node, ns, object);
1158 g_warning ("Unknown label object");
1163 gl_debug (DEBUG_XML, "END");
1166 /*--------------------------------------------------------------------------*/
1167 /* PRIVATE. Add XML Objects->Object-text Node */
1168 /*--------------------------------------------------------------------------*/
1170 xml_create_object_text (xmlNodePtr root,
1172 glLabelObject *object)
1177 GtkJustification just;
1178 gboolean auto_shrink;
1181 gl_debug (DEBUG_XML, "START");
1183 node = xmlNewChild (root, ns, "Object-text", NULL);
1185 /* position attrs */
1186 gl_label_object_get_position (object, &x, &y);
1187 gl_xml_set_prop_length (node, "x", x);
1188 gl_xml_set_prop_length (node, "y", y);
1191 gl_label_text_get_box ( GL_LABEL_TEXT(object), &w, &h);
1192 gl_xml_set_prop_length (node, "w", w);
1193 gl_xml_set_prop_length (node, "h", h);
1196 just = gl_label_object_get_text_alignment (object);
1197 xmlSetProp (node, "justify", gl_util_just_to_string (just));
1199 /* auto_shrink attr */
1200 auto_shrink = gl_label_text_get_auto_shrink (GL_LABEL_TEXT (object));
1201 gl_xml_set_prop_boolean (node, "auto_shrink", auto_shrink);
1204 gl_label_object_get_affine (object, affine);
1205 gl_xml_set_prop_double (node, "a0", affine[0]);
1206 gl_xml_set_prop_double (node, "a1", affine[1]);
1207 gl_xml_set_prop_double (node, "a2", affine[2]);
1208 gl_xml_set_prop_double (node, "a3", affine[3]);
1209 gl_xml_set_prop_double (node, "a4", affine[4]);
1210 gl_xml_set_prop_double (node, "a5", affine[5]);
1213 xml_create_toplevel_span (node, ns, GL_LABEL_TEXT(object));
1215 gl_debug (DEBUG_XML, "END");
1218 /*--------------------------------------------------------------------------*/
1219 /* PRIVATE. Add XML Objects->Object-box Node */
1220 /*--------------------------------------------------------------------------*/
1222 xml_create_object_box (xmlNodePtr root,
1224 glLabelObject *object)
1230 glColorNode *line_color_node;
1232 glColorNode *fill_color_node;
1234 gl_debug (DEBUG_XML, "START");
1236 node = xmlNewChild (root, ns, "Object-box", NULL);
1238 /* position attrs */
1239 gl_label_object_get_position (object, &x, &y);
1240 gl_xml_set_prop_length (node, "x", x);
1241 gl_xml_set_prop_length (node, "y", y);
1244 gl_label_object_get_size (object, &w, &h);
1245 gl_xml_set_prop_length (node, "w", w);
1246 gl_xml_set_prop_length (node, "h", h);
1249 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1250 gl_xml_set_prop_length (node, "line_width", line_width);
1252 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1253 if (line_color_node->field_flag)
1255 xmlSetProp (node, "line_color_field", line_color_node->key);
1259 gl_xml_set_prop_uint_hex (node, "line_color", line_color_node->color);
1261 gl_color_node_free (&line_color_node);
1263 /* fill attrs (color or field) */
1264 fill_color_node = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
1265 if (fill_color_node->field_flag)
1267 xmlSetProp (node, "fill_color_field", fill_color_node->key);
1271 gl_xml_set_prop_uint_hex (node, "fill_color", fill_color_node->color);
1273 gl_color_node_free (&fill_color_node);
1276 gl_label_object_get_affine (object, affine);
1277 gl_xml_set_prop_double (node, "a0", affine[0]);
1278 gl_xml_set_prop_double (node, "a1", affine[1]);
1279 gl_xml_set_prop_double (node, "a2", affine[2]);
1280 gl_xml_set_prop_double (node, "a3", affine[3]);
1281 gl_xml_set_prop_double (node, "a4", affine[4]);
1282 gl_xml_set_prop_double (node, "a5", affine[5]);
1284 gl_debug (DEBUG_XML, "END");
1287 /*--------------------------------------------------------------------------*/
1288 /* PRIVATE. Add XML Objects->Object-ellipse Node */
1289 /*--------------------------------------------------------------------------*/
1291 xml_create_object_ellipse (xmlNodePtr root,
1293 glLabelObject *object)
1299 glColorNode *line_color_node;
1301 glColorNode *fill_color_node;
1303 gl_debug (DEBUG_XML, "START");
1305 node = xmlNewChild (root, ns, "Object-ellipse", NULL);
1307 /* position attrs */
1308 gl_label_object_get_position (object, &x, &y);
1309 gl_xml_set_prop_length (node, "x", x);
1310 gl_xml_set_prop_length (node, "y", y);
1313 gl_label_object_get_size (object, &w, &h);
1314 gl_xml_set_prop_length (node, "w", w);
1315 gl_xml_set_prop_length (node, "h", h);
1318 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1319 gl_xml_set_prop_length (node, "line_width", line_width);
1321 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1322 if (line_color_node->field_flag)
1324 xmlSetProp (node, "line_color_field", line_color_node->key);
1328 gl_xml_set_prop_uint_hex (node, "line_color", line_color_node->color);
1330 gl_color_node_free (&line_color_node);
1333 /* fill attrs (color or field) */
1334 fill_color_node = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
1335 if (fill_color_node->field_flag)
1337 xmlSetProp (node, "fill_color_field", fill_color_node->key);
1341 gl_xml_set_prop_uint_hex (node, "fill_color", fill_color_node->color);
1343 gl_color_node_free (&fill_color_node);
1346 gl_label_object_get_affine (object, affine);
1347 gl_xml_set_prop_double (node, "a0", affine[0]);
1348 gl_xml_set_prop_double (node, "a1", affine[1]);
1349 gl_xml_set_prop_double (node, "a2", affine[2]);
1350 gl_xml_set_prop_double (node, "a3", affine[3]);
1351 gl_xml_set_prop_double (node, "a4", affine[4]);
1352 gl_xml_set_prop_double (node, "a5", affine[5]);
1354 gl_debug (DEBUG_XML, "END");
1357 /*--------------------------------------------------------------------------*/
1358 /* PRIVATE. Add XML Objects->Object-line Node */
1359 /*--------------------------------------------------------------------------*/
1361 xml_create_object_line (xmlNodePtr root,
1363 glLabelObject *object)
1369 glColorNode *line_color_node;
1372 gl_debug (DEBUG_XML, "START");
1374 node = xmlNewChild (root, ns, "Object-line", NULL);
1376 /* position attrs */
1377 gl_label_object_get_position (object, &x, &y);
1378 gl_xml_set_prop_length (node, "x", x);
1379 gl_xml_set_prop_length (node, "y", y);
1382 gl_label_object_get_size (object, &dx, &dy);
1383 gl_xml_set_prop_length (node, "dx", dx);
1384 gl_xml_set_prop_length (node, "dy", dy);
1387 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1388 gl_xml_set_prop_length (node, "line_width", line_width);
1390 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1391 if (line_color_node->field_flag)
1393 xmlSetProp (node, "line_color_field", line_color_node->key);
1397 gl_xml_set_prop_uint_hex (node, "line_color", line_color_node->color);
1399 gl_color_node_free (&line_color_node);
1403 gl_label_object_get_affine (object, affine);
1404 gl_xml_set_prop_double (node, "a0", affine[0]);
1405 gl_xml_set_prop_double (node, "a1", affine[1]);
1406 gl_xml_set_prop_double (node, "a2", affine[2]);
1407 gl_xml_set_prop_double (node, "a3", affine[3]);
1408 gl_xml_set_prop_double (node, "a4", affine[4]);
1409 gl_xml_set_prop_double (node, "a5", affine[5]);
1411 gl_debug (DEBUG_XML, "END");
1414 /*--------------------------------------------------------------------------*/
1415 /* PRIVATE. Add XML Objects->Object-image Node */
1416 /*--------------------------------------------------------------------------*/
1418 xml_create_object_image (xmlNodePtr root,
1420 glLabelObject *object)
1425 glTextNode *filename;
1428 gl_debug (DEBUG_XML, "START");
1430 node = xmlNewChild (root, ns, "Object-image", NULL);
1432 /* position attrs */
1433 gl_label_object_get_position (object, &x, &y);
1434 gl_xml_set_prop_length (node, "x", x);
1435 gl_xml_set_prop_length (node, "y", y);
1438 gl_label_object_get_size (object, &w, &h);
1439 gl_xml_set_prop_length (node, "w", w);
1440 gl_xml_set_prop_length (node, "h", h);
1442 /* src OR field attr */
1443 filename = gl_label_image_get_filename (GL_LABEL_IMAGE(object));
1444 if (filename->field_flag) {
1445 xmlSetProp (node, "field", filename->data);
1447 xmlSetProp (node, "src", filename->data);
1449 gl_text_node_free (&filename);
1452 gl_label_object_get_affine (object, affine);
1453 gl_xml_set_prop_double (node, "a0", affine[0]);
1454 gl_xml_set_prop_double (node, "a1", affine[1]);
1455 gl_xml_set_prop_double (node, "a2", affine[2]);
1456 gl_xml_set_prop_double (node, "a3", affine[3]);
1457 gl_xml_set_prop_double (node, "a4", affine[4]);
1458 gl_xml_set_prop_double (node, "a5", affine[5]);
1460 gl_debug (DEBUG_XML, "END");
1463 /*--------------------------------------------------------------------------*/
1464 /* PRIVATE. Add XML Objects->Object-barcode Node */
1465 /*--------------------------------------------------------------------------*/
1467 xml_create_object_barcode (xmlNodePtr root,
1469 glLabelObject *object)
1474 glTextNode *text_node;
1477 gboolean checksum_flag;
1478 glColorNode *color_node;
1479 guint format_digits;
1482 gl_debug (DEBUG_XML, "START");
1484 node = xmlNewChild (root, ns, "Object-barcode", NULL);
1486 /* position attrs */
1487 gl_label_object_get_position (object, &x, &y);
1488 gl_xml_set_prop_length (node, "x", x);
1489 gl_xml_set_prop_length (node, "y", y);
1492 gl_label_object_get_size (object, &w, &h);
1493 gl_xml_set_prop_length (node, "w", w);
1494 gl_xml_set_prop_length (node, "h", h);
1496 /* Barcode properties attrs */
1497 gl_label_barcode_get_props (GL_LABEL_BARCODE(object),
1498 &id, &text_flag, &checksum_flag, &format_digits);
1499 xmlSetProp (node, "style", id);
1500 gl_xml_set_prop_boolean (node, "text", text_flag);
1501 gl_xml_set_prop_boolean (node, "checksum", checksum_flag);
1505 color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1506 if (color_node->field_flag)
1508 xmlSetProp (node, "color_field", color_node->key);
1512 gl_xml_set_prop_uint_hex (node, "color", color_node->color);
1514 gl_color_node_free (&color_node);
1517 /* data OR field attr */
1518 text_node = gl_label_barcode_get_data (GL_LABEL_BARCODE(object));
1519 if (text_node->field_flag) {
1520 xmlSetProp (node, "field", text_node->data);
1521 gl_xml_set_prop_int (node, "format", format_digits);
1523 xmlSetProp (node, "data", text_node->data);
1525 gl_text_node_free (&text_node);
1528 gl_label_object_get_affine (object, affine);
1529 gl_xml_set_prop_double (node, "a0", affine[0]);
1530 gl_xml_set_prop_double (node, "a1", affine[1]);
1531 gl_xml_set_prop_double (node, "a2", affine[2]);
1532 gl_xml_set_prop_double (node, "a3", affine[3]);
1533 gl_xml_set_prop_double (node, "a4", affine[4]);
1534 gl_xml_set_prop_double (node, "a5", affine[5]);
1536 gl_debug (DEBUG_XML, "END");
1539 /*--------------------------------------------------------------------------*/
1540 /* PRIVATE. Add XML Label Merge Fields Node */
1541 /*--------------------------------------------------------------------------*/
1543 xml_create_merge_fields (xmlNodePtr root,
1547 xmlNodePtr node, child;
1552 gl_debug (DEBUG_XML, "START");
1554 merge = gl_label_get_merge (label);
1556 node = xmlNewChild (root, ns, "Merge", NULL);
1558 string = gl_merge_get_name (merge);
1559 xmlSetProp (node, "type", string);
1562 string = gl_merge_get_src (merge);
1563 xmlSetProp (node, "src", string);
1566 g_object_unref (G_OBJECT(merge));
1568 gl_debug (DEBUG_XML, "END");
1571 /*--------------------------------------------------------------------------*/
1572 /* PRIVATE. Add XML Label Data Node */
1573 /*--------------------------------------------------------------------------*/
1575 xml_create_data (xmlNodePtr root,
1580 GList *name_list, *p;
1581 GHashTable *pixbuf_cache;
1583 gl_debug (DEBUG_XML, "START");
1585 node = xmlNewChild (root, ns, "Data", NULL);
1587 pixbuf_cache = gl_label_get_pixbuf_cache (label);
1588 name_list = gl_pixbuf_cache_get_name_list (pixbuf_cache);
1590 for (p = name_list; p != NULL; p=p->next) {
1591 xml_create_pixdata (node, ns, label, p->data);
1594 gl_pixbuf_cache_free_name_list (name_list);
1597 gl_debug (DEBUG_XML, "END");
1600 /*--------------------------------------------------------------------------*/
1601 /* PRIVATE. Add XML Label Data Pixbuf Node */
1602 /*--------------------------------------------------------------------------*/
1604 xml_create_pixdata (xmlNodePtr root,
1610 GHashTable *pixbuf_cache;
1612 GdkPixdata *pixdata;
1614 guint stream_length;
1617 gl_debug (DEBUG_XML, "START");
1619 pixbuf_cache = gl_label_get_pixbuf_cache (label);
1621 pixbuf = gl_pixbuf_cache_get_pixbuf (pixbuf_cache, name);
1622 if ( pixbuf != NULL ) {
1624 pixdata = g_new0 (GdkPixdata, 1);
1625 gdk_pixdata_from_pixbuf (pixdata, pixbuf, FALSE);
1626 stream = gdk_pixdata_serialize (pixdata, &stream_length);
1627 base64 = gl_base64_encode (stream, stream_length);
1629 node = xmlNewChild (root, ns, "Pixdata", base64);
1630 xmlSetProp (node, "name", name);
1631 xmlSetProp (node, "encoding", "Base64");
1633 gl_pixbuf_cache_remove_pixbuf (pixbuf_cache, name);
1641 gl_debug (DEBUG_XML, "END");
1644 /*--------------------------------------------------------------------------*/
1645 /* PRIVATE. Create top-level Span node. */
1646 /*--------------------------------------------------------------------------*/
1648 xml_create_toplevel_span (xmlNodePtr root,
1650 glLabelText *object_text)
1655 GnomeFontWeight font_weight;
1656 gboolean font_italic_flag;
1657 glColorNode *color_node;
1658 GtkJustification just;
1659 gdouble text_line_spacing;
1660 GList *lines, *p_line, *p_node;
1661 glTextNode *text_node;
1664 node = xmlNewChild (root, ns, "Span", NULL);
1666 /* All span attrs at top level. */
1667 font_family = gl_label_object_get_font_family (GL_LABEL_OBJECT(object_text));
1668 font_size = gl_label_object_get_font_size (GL_LABEL_OBJECT(object_text));
1669 text_line_spacing = gl_label_object_get_text_line_spacing (GL_LABEL_OBJECT(object_text));
1670 font_weight = gl_label_object_get_font_weight (GL_LABEL_OBJECT(object_text));
1671 font_italic_flag = gl_label_object_get_font_italic_flag (GL_LABEL_OBJECT(object_text));
1673 color_node = gl_label_object_get_text_color (GL_LABEL_OBJECT(object_text));
1674 if (color_node->field_flag)
1676 xmlSetProp (node, "color_field", color_node->key);
1680 gl_xml_set_prop_uint_hex (node, "color", color_node->color);
1682 gl_color_node_free (&color_node);
1684 just = gl_label_object_get_text_alignment (GL_LABEL_OBJECT(object_text));
1685 xmlSetProp (node, "font_family", font_family);
1686 gl_xml_set_prop_double (node, "font_size", font_size);
1687 xmlSetProp (node, "font_weight", gl_util_weight_to_string (font_weight));
1688 gl_xml_set_prop_boolean (node, "font_italic", font_italic_flag);
1690 gl_xml_set_prop_double (node, "line_spacing", text_line_spacing);
1692 /* Build children. */
1693 lines = gl_label_text_get_lines (GL_LABEL_TEXT(object_text));
1694 for (p_line = lines; p_line != NULL; p_line = p_line->next) {
1696 for (p_node = (GList *) p_line->data; p_node != NULL;
1697 p_node = p_node->next) {
1698 text_node = (glTextNode *) p_node->data;
1700 if (text_node->field_flag) {
1701 child = xmlNewChild (node, ns, "Field", NULL);
1702 xmlSetProp (child, "name", text_node->data);
1704 xmlNodeAddContent (node, text_node->data);
1709 if ( p_line->next ) {
1710 child = xmlNewChild (node, ns, "NL", NULL);
1715 gl_text_node_lines_free (&lines);
1716 g_free (font_family);