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
25 #include "xml-label.h"
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-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, (xmlChar *)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, (xmlChar *)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 (xmlChar *)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 (xmlChar *)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, (xmlChar *)"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, (xmlChar *)"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, (xmlChar *)"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, (xmlChar *)"Objects")) {
341 xml_parse_objects (child_node, label);
342 } else if (xmlStrEqual (child_node->name, (xmlChar *)"Merge")) {
343 xml_parse_merge_fields (child_node, label);
344 } else if (xmlStrEqual (child_node->name, (xmlChar *)"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, (xmlChar *)"Object-text")) {
380 xml_parse_object_text (child, label);
381 } else if (xmlStrEqual (child->name, (xmlChar *)"Object-box")) {
382 xml_parse_object_box (child, label);
383 } else if (xmlStrEqual (child->name, (xmlChar *)"Object-ellipse")) {
384 xml_parse_object_ellipse (child, label);
385 } else if (xmlStrEqual (child->name, (xmlChar *)"Object-line")) {
386 xml_parse_object_line (child, label);
387 } else if (xmlStrEqual (child->name, (xmlChar *)"Object-image")) {
388 xml_parse_object_image (child, label);
389 } else if (xmlStrEqual (child->name, (xmlChar *)"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, (xmlChar *)"justify");
434 just = gl_util_string_to_just ((gchar *)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,(xmlChar *) "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, (xmlChar *)"line_color_field");
504 line_color_node->field_flag = TRUE;
505 line_color_node->key = g_strdup ((gchar *)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, (xmlChar *)"fill_color_field");
518 fill_color_node->field_flag = TRUE;
519 fill_color_node->key = g_strdup ((gchar *)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, (xmlChar *)"line_color_field");
575 line_color_node->field_flag = TRUE;
576 line_color_node->key = g_strdup ((gchar *)string);
579 line_color_node->color = gl_xml_get_prop_uint (node, "line_color", 0);
581 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color_node);
582 gl_color_node_free (&line_color_node);
586 fill_color_node = gl_color_node_new_default ();
587 string = xmlGetProp (node, (xmlChar *)"fill_color_field");
589 fill_color_node->field_flag = TRUE;
590 fill_color_node->key = g_strdup ((gchar *)string);
593 fill_color_node->color = gl_xml_get_prop_uint (node, "fill_color", 0);
595 gl_label_object_set_fill_color (GL_LABEL_OBJECT(object), fill_color_node);
596 gl_color_node_free (&fill_color_node);
599 affine[0] = gl_xml_get_prop_double (node, "a0", 0.0);
600 affine[1] = gl_xml_get_prop_double (node, "a1", 0.0);
601 affine[2] = gl_xml_get_prop_double (node, "a2", 0.0);
602 affine[3] = gl_xml_get_prop_double (node, "a3", 0.0);
603 affine[4] = gl_xml_get_prop_double (node, "a4", 0.0);
604 affine[5] = gl_xml_get_prop_double (node, "a5", 0.0);
605 gl_label_object_set_affine (GL_LABEL_OBJECT(object), affine);
607 gl_debug (DEBUG_XML, "END");
610 /*--------------------------------------------------------------------------*/
611 /* PRIVATE. Parse XML Objects->Object-line Node */
612 /*--------------------------------------------------------------------------*/
614 xml_parse_object_line (xmlNodePtr node,
621 glColorNode *line_color_node;
625 gl_debug (DEBUG_XML, "START");
627 object = gl_label_line_new (label);
630 x = gl_xml_get_prop_length (node, "x", 0.0);
631 y = gl_xml_get_prop_length (node, "y", 0.0);
632 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
635 dx = gl_xml_get_prop_length (node, "dx", 0);
636 dy = gl_xml_get_prop_length (node, "dy", 0);
637 gl_label_object_set_size (GL_LABEL_OBJECT(object), dx, dy);
640 line_width = gl_xml_get_prop_length (node, "line_width", 1.0);
641 gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width);
643 line_color_node = gl_color_node_new_default ();
644 string = xmlGetProp (node, (xmlChar *)"line_color_field");
646 line_color_node->field_flag = TRUE;
647 line_color_node->key = g_strdup ((gchar *)string);
650 line_color_node->color = gl_xml_get_prop_uint (node, "line_color", 0);
652 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color_node);
653 gl_color_node_free (&line_color_node);
656 affine[0] = gl_xml_get_prop_double (node, "a0", 0.0);
657 affine[1] = gl_xml_get_prop_double (node, "a1", 0.0);
658 affine[2] = gl_xml_get_prop_double (node, "a2", 0.0);
659 affine[3] = gl_xml_get_prop_double (node, "a3", 0.0);
660 affine[4] = gl_xml_get_prop_double (node, "a4", 0.0);
661 affine[5] = gl_xml_get_prop_double (node, "a5", 0.0);
662 gl_label_object_set_affine (GL_LABEL_OBJECT(object), affine);
664 gl_debug (DEBUG_XML, "END");
667 /*--------------------------------------------------------------------------*/
668 /* PRIVATE. Parse XML Objects->Object-image Node */
669 /*--------------------------------------------------------------------------*/
671 xml_parse_object_image (xmlNodePtr node,
678 glTextNode *filename;
681 gl_debug (DEBUG_XML, "START");
683 object = gl_label_image_new (label);
686 x = gl_xml_get_prop_length (node, "x", 0.0);
687 y = gl_xml_get_prop_length (node, "y", 0.0);
688 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
690 /* src or field attr */
691 string = xmlGetProp (node, (xmlChar *)"src");
693 filename = g_new0 (glTextNode, 1);
694 filename->field_flag = FALSE;
695 filename->data = g_strdup ((gchar *)string);
696 gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename);
697 gl_text_node_free (&filename);
700 string = xmlGetProp (node, (xmlChar *)"field");
702 filename = g_new0 (glTextNode, 1);
703 filename->field_flag = TRUE;
704 filename->data = g_strdup ((gchar *)string);
705 gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename);
706 gl_text_node_free (&filename);
709 g_warning ("Missing Object-image src or field attr");
714 w = gl_xml_get_prop_length (node, "w", 0);
715 h = gl_xml_get_prop_length (node, "h", 0);
716 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
719 affine[0] = gl_xml_get_prop_double (node, "a0", 0.0);
720 affine[1] = gl_xml_get_prop_double (node, "a1", 0.0);
721 affine[2] = gl_xml_get_prop_double (node, "a2", 0.0);
722 affine[3] = gl_xml_get_prop_double (node, "a3", 0.0);
723 affine[4] = gl_xml_get_prop_double (node, "a4", 0.0);
724 affine[5] = gl_xml_get_prop_double (node, "a5", 0.0);
725 gl_label_object_set_affine (GL_LABEL_OBJECT(object), affine);
727 gl_debug (DEBUG_XML, "END");
730 /*--------------------------------------------------------------------------*/
731 /* PRIVATE. Parse XML Objects->Object-barcode Node */
732 /*--------------------------------------------------------------------------*/
734 xml_parse_object_barcode (xmlNodePtr node,
741 glTextNode *text_node;
744 gboolean checksum_flag;
745 glColorNode *color_node;
749 gl_debug (DEBUG_XML, "START");
751 object = gl_label_barcode_new (label);
754 x = gl_xml_get_prop_length (node, "x", 0.0);
755 y = gl_xml_get_prop_length (node, "y", 0.0);
756 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
759 w = gl_xml_get_prop_length (node, "w", 0);
760 h = gl_xml_get_prop_length (node, "h", 0);
761 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
764 id = xmlGetProp (node, (xmlChar *)"style");
765 text_flag = gl_xml_get_prop_boolean (node, "text", FALSE);
766 checksum_flag = gl_xml_get_prop_boolean (node, "checksum", TRUE);
767 format_digits = gl_xml_get_prop_uint (node, "format", 10);
768 gl_label_barcode_set_props (GL_LABEL_BARCODE(object),
769 (gchar *)id, text_flag, checksum_flag, format_digits);
772 color_node = gl_color_node_new_default ();
773 string = xmlGetProp (node, (xmlChar *)"color_field");
775 color_node->field_flag = TRUE;
776 color_node->key = g_strdup ((gchar *)string);
779 color_node->color = gl_xml_get_prop_uint (node, "color", 0);
781 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), color_node);
782 gl_color_node_free (&color_node);
784 /* data or field attr */
785 string = xmlGetProp (node, (xmlChar *)"data");
787 text_node = g_new0 (glTextNode, 1);
788 text_node->field_flag = FALSE;
789 text_node->data = g_strdup ((gchar *)string);
790 gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node);
791 gl_text_node_free (&text_node);
794 string = xmlGetProp (node, (xmlChar *)"field");
796 text_node = g_new0 (glTextNode, 1);
797 text_node->field_flag = TRUE;
798 text_node->data = g_strdup ((gchar *)string);
799 gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node);
800 gl_text_node_free (&text_node);
803 g_warning ("Missing Object-barcode data or field attr");
808 affine[0] = gl_xml_get_prop_double (node, "a0", 0.0);
809 affine[1] = gl_xml_get_prop_double (node, "a1", 0.0);
810 affine[2] = gl_xml_get_prop_double (node, "a2", 0.0);
811 affine[3] = gl_xml_get_prop_double (node, "a3", 0.0);
812 affine[4] = gl_xml_get_prop_double (node, "a4", 0.0);
813 affine[5] = gl_xml_get_prop_double (node, "a5", 0.0);
814 gl_label_object_set_affine (GL_LABEL_OBJECT(object), affine);
816 gl_debug (DEBUG_XML, "END");
819 /*--------------------------------------------------------------------------*/
820 /* PRIVATE. Parse XML merge fields tag. */
821 /*--------------------------------------------------------------------------*/
823 xml_parse_merge_fields (xmlNodePtr node,
830 gl_debug (DEBUG_XML, "START");
832 string = xmlGetProp (node, (xmlChar *)"type");
833 merge = gl_merge_new ((gchar *)string);
836 string = xmlGetProp (node, (xmlChar *)"src");
837 gl_merge_set_src (merge, (gchar *)string);
840 gl_label_set_merge (label, merge);
842 g_object_unref (G_OBJECT(merge));
844 gl_debug (DEBUG_XML, "END");
847 /*--------------------------------------------------------------------------*/
848 /* PRIVATE. Parse XML data tag. */
849 /*--------------------------------------------------------------------------*/
851 xml_parse_data (xmlNodePtr node,
856 gl_debug (DEBUG_XML, "START");
858 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
860 if (xmlStrEqual (child->name, (xmlChar *)"Pixdata")) {
861 xml_parse_pixdata (child, label);
863 if (!xmlNodeIsText (child)) {
864 g_warning (_("bad node in Data node = \"%s\""),
870 gl_debug (DEBUG_XML, "END");
873 /*--------------------------------------------------------------------------*/
874 /* PRIVATE. Parse XML pixbuf data tag. */
875 /*--------------------------------------------------------------------------*/
877 xml_parse_pixdata (xmlNodePtr node,
880 xmlChar *name, *base64;
886 GHashTable *pixbuf_cache;
888 gl_debug (DEBUG_XML, "START");
890 name = xmlGetProp (node, (xmlChar *)"name");
891 base64 = xmlNodeGetContent (node);
893 stream = gl_base64_decode ((gchar *)base64, &stream_length);
894 pixdata = g_new0 (GdkPixdata, 1);
895 ret = gdk_pixdata_deserialize (pixdata, stream_length, stream, NULL);
898 pixbuf = gdk_pixbuf_from_pixdata (pixdata, TRUE, NULL);
900 pixbuf_cache = gl_label_get_pixbuf_cache (label);
901 gl_pixbuf_cache_add_pixbuf (pixbuf_cache, (gchar *)name, pixbuf);
910 gl_debug (DEBUG_XML, "END");
913 /*--------------------------------------------------------------------------*/
914 /* PRIVATE. Parse top-level Span tag. */
915 /*--------------------------------------------------------------------------*/
917 xml_parse_toplevel_span (xmlNodePtr node,
918 glLabelObject *object)
920 xmlChar *font_family;
922 GnomeFontWeight font_weight;
923 gboolean font_italic_flag;
924 glColorNode *color_node;
925 gdouble text_line_spacing;
927 GList *lines, *text_nodes;
929 glTextNode *text_node;
931 gl_debug (DEBUG_XML, "START");
933 /* Font family attr */
934 font_family = xmlGetProp (node, (xmlChar *)"font_family");
935 gl_label_object_set_font_family (object, (gchar *)font_family);
936 xmlFree (font_family);
939 font_size = gl_xml_get_prop_double (node, "font_size", 0.0);
940 gl_label_object_set_font_size (object, font_size);
942 /* Font weight attr */
943 string = xmlGetProp (node, (xmlChar *)"font_weight");
944 font_weight = gl_util_string_to_weight ((gchar *)string);
946 gl_label_object_set_font_weight (object, font_weight);
948 /* Font italic flag attr */
949 font_italic_flag = gl_xml_get_prop_boolean (node, "font_italic", FALSE);
950 gl_label_object_set_font_italic_flag (object, font_italic_flag);
952 /* Text color attr */
953 color_node = gl_color_node_new_default ();
954 string = xmlGetProp (node, (xmlChar *)"color_field");
956 color_node->field_flag = TRUE;
957 color_node->key = g_strdup ((gchar *)string);
960 color_node->color = gl_xml_get_prop_uint (node, "color", 0);
962 gl_label_object_set_text_color (object, color_node);
963 gl_color_node_free (&color_node);
966 /* Text line spacing attr */
967 text_line_spacing = gl_xml_get_prop_double (node, "line_spacing", 1.0);
968 gl_label_object_set_text_line_spacing (object, text_line_spacing);
970 /* Now descend children, and build lines of text nodes */
973 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
975 if (xmlNodeIsText (child)) {
976 xmlChar *data = xmlNodeGetContent (child);
978 /* Hack: if the first char is LF, it's a xml formatting string */
979 if (data[0] != '\n') {
981 text_node = g_new0 (glTextNode, 1);
982 text_node->field_flag = FALSE;
983 text_node->data = g_strdup ((gchar *)data);
984 text_nodes = g_list_append (text_nodes, text_node);
988 } else if (xmlStrEqual (child->name, (xmlChar *)"Span")) {
990 g_warning ("Unexpected rich text (not supported, yet!)");
992 } else if (xmlStrEqual (child->name, (xmlChar *)"Field")) {
995 string = xmlGetProp (child, (xmlChar *)"name");
996 text_node = g_new0 (glTextNode, 1);
997 text_node->field_flag = TRUE;
998 text_node->data = g_strdup ((gchar *)string);
999 text_nodes = g_list_append (text_nodes, text_node);
1002 } else if (xmlStrEqual (child->name, (xmlChar *)"NL")) {
1005 lines = g_list_append (lines, text_nodes);
1009 g_warning ("Unexpected Span child: \"%s\"", child->name);
1014 /* Store last line. */
1015 lines = g_list_append (lines, text_nodes);
1018 gl_label_text_set_lines (GL_LABEL_TEXT(object), lines);
1019 gl_text_node_lines_free (&lines);
1021 gl_debug (DEBUG_XML, "END");
1024 /****************************************************************************/
1025 /* Save label to xml label file. */
1026 /****************************************************************************/
1028 gl_xml_label_save (glLabel *label,
1029 const gchar *utf8_filename,
1030 glXMLLabelStatus *status)
1036 gl_debug (DEBUG_XML, "START");
1038 doc = xml_label_to_doc (label, status);
1040 filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
1042 g_warning (_("Utf8 conversion error."));
1044 xmlSetDocCompressMode (doc, gl_label_get_compression (label));
1045 xml_ret = xmlSaveFormatFile (filename, doc, TRUE);
1047 if (xml_ret == -1) {
1049 g_warning (_("Problem saving xml file."));
1050 *status = XML_LABEL_ERROR_SAVE_FILE;
1054 gl_label_set_filename (label, utf8_filename);
1055 gl_label_clear_modified (label);
1061 gl_debug (DEBUG_XML, "END");
1064 /****************************************************************************/
1065 /* Save label to xml buffer. */
1066 /****************************************************************************/
1068 gl_xml_label_save_buffer (glLabel *label,
1069 glXMLLabelStatus *status)
1075 gl_debug (DEBUG_XML, "START");
1077 doc = xml_label_to_doc (label, status);
1079 xmlDocDumpMemory (doc, (xmlChar **)&buffer, &size);
1082 gl_label_clear_modified (label);
1084 gl_debug (DEBUG_XML, "END");
1089 /*--------------------------------------------------------------------------*/
1090 /* PRIVATE. Convert label to xml doc structure. */
1091 /*--------------------------------------------------------------------------*/
1093 xml_label_to_doc (glLabel *label,
1094 glXMLLabelStatus *status)
1098 glTemplate *template;
1101 gl_debug (DEBUG_XML, "START");
1103 LIBXML_TEST_VERSION;
1105 doc = xmlNewDoc ((xmlChar *)"1.0");
1106 doc->xmlRootNode = xmlNewDocNode (doc, NULL, (xmlChar *)"Glabels-document", NULL);
1108 ns = xmlNewNs (doc->xmlRootNode, (xmlChar *)GL_XML_NAME_SPACE, NULL);
1109 xmlSetNs (doc->xmlRootNode, ns);
1111 template = gl_label_get_template (label);
1112 gl_xml_template_create_template_node (template, doc->xmlRootNode, ns);
1114 xml_create_objects (doc->xmlRootNode, ns, label);
1116 merge = gl_label_get_merge (label);
1117 gl_debug (DEBUG_XML, "merge=%p", merge);
1118 if (merge != NULL) {
1119 xml_create_merge_fields (doc->xmlRootNode, ns, label);
1120 g_object_unref (G_OBJECT(merge));
1123 xml_create_data (doc->xmlRootNode, ns, label);
1125 gl_debug (DEBUG_XML, "END");
1127 *status = XML_LABEL_OK;
1131 /*--------------------------------------------------------------------------*/
1132 /* PRIVATE. Add XML Objects Node */
1133 /*--------------------------------------------------------------------------*/
1135 xml_create_objects (xmlNodePtr root,
1140 gboolean rotate_flag;
1142 glLabelObject *object;
1144 gl_debug (DEBUG_XML, "START");
1146 rotate_flag = gl_label_get_rotate_flag (label);
1148 node = xmlNewChild (root, ns, (xmlChar *)"Objects", NULL);
1149 xmlSetProp (node, (xmlChar *)"id", (xmlChar *)"0");
1150 gl_xml_set_prop_boolean (node, "rotate", rotate_flag);
1152 for (p = label->objects; p != NULL; p = p->next) {
1154 object = GL_LABEL_OBJECT(p->data);
1156 if ( GL_IS_LABEL_TEXT(object) ) {
1157 xml_create_object_text (node, ns, object);
1158 } else if ( GL_IS_LABEL_BOX(object) ) {
1159 xml_create_object_box (node, ns, object);
1160 } else if ( GL_IS_LABEL_ELLIPSE(object) ) {
1161 xml_create_object_ellipse (node, ns, object);
1162 } else if ( GL_IS_LABEL_LINE(object) ) {
1163 xml_create_object_line (node, ns, object);
1164 } else if ( GL_IS_LABEL_IMAGE(object) ) {
1165 xml_create_object_image (node, ns, object);
1166 } else if ( GL_IS_LABEL_BARCODE(object) ) {
1167 xml_create_object_barcode (node, ns, object);
1169 g_warning ("Unknown label object");
1174 gl_debug (DEBUG_XML, "END");
1177 /*--------------------------------------------------------------------------*/
1178 /* PRIVATE. Add XML Objects->Object-text Node */
1179 /*--------------------------------------------------------------------------*/
1181 xml_create_object_text (xmlNodePtr root,
1183 glLabelObject *object)
1188 GtkJustification just;
1189 gboolean auto_shrink;
1192 gl_debug (DEBUG_XML, "START");
1194 node = xmlNewChild (root, ns, (xmlChar *)"Object-text", NULL);
1196 /* position attrs */
1197 gl_label_object_get_position (object, &x, &y);
1198 gl_xml_set_prop_length (node, "x", x);
1199 gl_xml_set_prop_length (node, "y", y);
1202 gl_label_text_get_box ( GL_LABEL_TEXT(object), &w, &h);
1203 gl_xml_set_prop_length (node, "w", w);
1204 gl_xml_set_prop_length (node, "h", h);
1207 just = gl_label_object_get_text_alignment (object);
1208 xmlSetProp (node, (xmlChar *)"justify", (xmlChar *)gl_util_just_to_string (just));
1210 /* auto_shrink attr */
1211 auto_shrink = gl_label_text_get_auto_shrink (GL_LABEL_TEXT (object));
1212 gl_xml_set_prop_boolean (node, "auto_shrink", auto_shrink);
1215 gl_label_object_get_affine (object, affine);
1216 gl_xml_set_prop_double (node, "a0", affine[0]);
1217 gl_xml_set_prop_double (node, "a1", affine[1]);
1218 gl_xml_set_prop_double (node, "a2", affine[2]);
1219 gl_xml_set_prop_double (node, "a3", affine[3]);
1220 gl_xml_set_prop_double (node, "a4", affine[4]);
1221 gl_xml_set_prop_double (node, "a5", affine[5]);
1224 xml_create_toplevel_span (node, ns, GL_LABEL_TEXT(object));
1226 gl_debug (DEBUG_XML, "END");
1229 /*--------------------------------------------------------------------------*/
1230 /* PRIVATE. Add XML Objects->Object-box Node */
1231 /*--------------------------------------------------------------------------*/
1233 xml_create_object_box (xmlNodePtr root,
1235 glLabelObject *object)
1241 glColorNode *line_color_node;
1243 glColorNode *fill_color_node;
1245 gl_debug (DEBUG_XML, "START");
1247 node = xmlNewChild (root, ns, (xmlChar *)"Object-box", NULL);
1249 /* position attrs */
1250 gl_label_object_get_position (object, &x, &y);
1251 gl_xml_set_prop_length (node, "x", x);
1252 gl_xml_set_prop_length (node, "y", y);
1255 gl_label_object_get_size (object, &w, &h);
1256 gl_xml_set_prop_length (node, "w", w);
1257 gl_xml_set_prop_length (node, "h", h);
1260 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1261 gl_xml_set_prop_length (node, "line_width", line_width);
1263 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1264 if (line_color_node->field_flag)
1266 xmlSetProp (node, (xmlChar *)"line_color_field", (xmlChar *)line_color_node->key);
1270 gl_xml_set_prop_uint_hex (node, "line_color", line_color_node->color);
1272 gl_color_node_free (&line_color_node);
1274 /* fill attrs (color or field) */
1275 fill_color_node = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
1276 if (fill_color_node->field_flag)
1278 xmlSetProp (node, (xmlChar *)"fill_color_field", (xmlChar *)fill_color_node->key);
1282 gl_xml_set_prop_uint_hex (node, "fill_color", fill_color_node->color);
1284 gl_color_node_free (&fill_color_node);
1287 gl_label_object_get_affine (object, affine);
1288 gl_xml_set_prop_double (node, "a0", affine[0]);
1289 gl_xml_set_prop_double (node, "a1", affine[1]);
1290 gl_xml_set_prop_double (node, "a2", affine[2]);
1291 gl_xml_set_prop_double (node, "a3", affine[3]);
1292 gl_xml_set_prop_double (node, "a4", affine[4]);
1293 gl_xml_set_prop_double (node, "a5", affine[5]);
1295 gl_debug (DEBUG_XML, "END");
1298 /*--------------------------------------------------------------------------*/
1299 /* PRIVATE. Add XML Objects->Object-ellipse Node */
1300 /*--------------------------------------------------------------------------*/
1302 xml_create_object_ellipse (xmlNodePtr root,
1304 glLabelObject *object)
1310 glColorNode *line_color_node;
1312 glColorNode *fill_color_node;
1314 gl_debug (DEBUG_XML, "START");
1316 node = xmlNewChild (root, ns, (xmlChar *)"Object-ellipse", NULL);
1318 /* position attrs */
1319 gl_label_object_get_position (object, &x, &y);
1320 gl_xml_set_prop_length (node, "x", x);
1321 gl_xml_set_prop_length (node, "y", y);
1324 gl_label_object_get_size (object, &w, &h);
1325 gl_xml_set_prop_length (node, "w", w);
1326 gl_xml_set_prop_length (node, "h", h);
1329 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1330 gl_xml_set_prop_length (node, "line_width", line_width);
1332 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1333 if (line_color_node->field_flag)
1335 xmlSetProp (node, (xmlChar *)"line_color_field", (xmlChar *)line_color_node->key);
1339 gl_xml_set_prop_uint_hex (node, "line_color", line_color_node->color);
1341 gl_color_node_free (&line_color_node);
1344 /* fill attrs (color or field) */
1345 fill_color_node = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
1346 if (fill_color_node->field_flag)
1348 xmlSetProp (node, (xmlChar *)"fill_color_field", (xmlChar *)fill_color_node->key);
1352 gl_xml_set_prop_uint_hex (node, "fill_color", fill_color_node->color);
1354 gl_color_node_free (&fill_color_node);
1357 gl_label_object_get_affine (object, affine);
1358 gl_xml_set_prop_double (node, "a0", affine[0]);
1359 gl_xml_set_prop_double (node, "a1", affine[1]);
1360 gl_xml_set_prop_double (node, "a2", affine[2]);
1361 gl_xml_set_prop_double (node, "a3", affine[3]);
1362 gl_xml_set_prop_double (node, "a4", affine[4]);
1363 gl_xml_set_prop_double (node, "a5", affine[5]);
1365 gl_debug (DEBUG_XML, "END");
1368 /*--------------------------------------------------------------------------*/
1369 /* PRIVATE. Add XML Objects->Object-line Node */
1370 /*--------------------------------------------------------------------------*/
1372 xml_create_object_line (xmlNodePtr root,
1374 glLabelObject *object)
1380 glColorNode *line_color_node;
1383 gl_debug (DEBUG_XML, "START");
1385 node = xmlNewChild (root, ns, (xmlChar *)"Object-line", NULL);
1387 /* position attrs */
1388 gl_label_object_get_position (object, &x, &y);
1389 gl_xml_set_prop_length (node, "x", x);
1390 gl_xml_set_prop_length (node, "y", y);
1393 gl_label_object_get_size (object, &dx, &dy);
1394 gl_xml_set_prop_length (node, "dx", dx);
1395 gl_xml_set_prop_length (node, "dy", dy);
1398 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1399 gl_xml_set_prop_length (node, "line_width", line_width);
1401 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1402 if (line_color_node->field_flag)
1404 xmlSetProp (node, (xmlChar *)"line_color_field", (xmlChar *)line_color_node->key);
1408 gl_xml_set_prop_uint_hex (node, "line_color", line_color_node->color);
1410 gl_color_node_free (&line_color_node);
1414 gl_label_object_get_affine (object, affine);
1415 gl_xml_set_prop_double (node, "a0", affine[0]);
1416 gl_xml_set_prop_double (node, "a1", affine[1]);
1417 gl_xml_set_prop_double (node, "a2", affine[2]);
1418 gl_xml_set_prop_double (node, "a3", affine[3]);
1419 gl_xml_set_prop_double (node, "a4", affine[4]);
1420 gl_xml_set_prop_double (node, "a5", affine[5]);
1422 gl_debug (DEBUG_XML, "END");
1425 /*--------------------------------------------------------------------------*/
1426 /* PRIVATE. Add XML Objects->Object-image Node */
1427 /*--------------------------------------------------------------------------*/
1429 xml_create_object_image (xmlNodePtr root,
1431 glLabelObject *object)
1436 glTextNode *filename;
1439 gl_debug (DEBUG_XML, "START");
1441 node = xmlNewChild (root, ns, (xmlChar *)"Object-image", NULL);
1443 /* position attrs */
1444 gl_label_object_get_position (object, &x, &y);
1445 gl_xml_set_prop_length (node, "x", x);
1446 gl_xml_set_prop_length (node, "y", y);
1449 gl_label_object_get_size (object, &w, &h);
1450 gl_xml_set_prop_length (node, "w", w);
1451 gl_xml_set_prop_length (node, "h", h);
1453 /* src OR field attr */
1454 filename = gl_label_image_get_filename (GL_LABEL_IMAGE(object));
1455 if (filename->field_flag) {
1456 xmlSetProp (node, (xmlChar *)"field", (xmlChar *)filename->data);
1458 xmlSetProp (node, (xmlChar *)"src", (xmlChar *)filename->data);
1460 gl_text_node_free (&filename);
1463 gl_label_object_get_affine (object, affine);
1464 gl_xml_set_prop_double (node, "a0", affine[0]);
1465 gl_xml_set_prop_double (node, "a1", affine[1]);
1466 gl_xml_set_prop_double (node, "a2", affine[2]);
1467 gl_xml_set_prop_double (node, "a3", affine[3]);
1468 gl_xml_set_prop_double (node, "a4", affine[4]);
1469 gl_xml_set_prop_double (node, "a5", affine[5]);
1471 gl_debug (DEBUG_XML, "END");
1474 /*--------------------------------------------------------------------------*/
1475 /* PRIVATE. Add XML Objects->Object-barcode Node */
1476 /*--------------------------------------------------------------------------*/
1478 xml_create_object_barcode (xmlNodePtr root,
1480 glLabelObject *object)
1485 glTextNode *text_node;
1488 gboolean checksum_flag;
1489 glColorNode *color_node;
1490 guint format_digits;
1493 gl_debug (DEBUG_XML, "START");
1495 node = xmlNewChild (root, ns, (xmlChar *)"Object-barcode", NULL);
1497 /* position attrs */
1498 gl_label_object_get_position (object, &x, &y);
1499 gl_xml_set_prop_length (node, "x", x);
1500 gl_xml_set_prop_length (node, "y", y);
1503 gl_label_object_get_size (object, &w, &h);
1504 gl_xml_set_prop_length (node, "w", w);
1505 gl_xml_set_prop_length (node, "h", h);
1507 /* Barcode properties attrs */
1508 gl_label_barcode_get_props (GL_LABEL_BARCODE(object),
1509 &id, &text_flag, &checksum_flag, &format_digits);
1510 xmlSetProp (node, (xmlChar *)"style", (xmlChar *)id);
1511 gl_xml_set_prop_boolean (node, "text", text_flag);
1512 gl_xml_set_prop_boolean (node, "checksum", checksum_flag);
1516 color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1517 if (color_node->field_flag)
1519 xmlSetProp (node, (xmlChar *)"color_field", (xmlChar *)color_node->key);
1523 gl_xml_set_prop_uint_hex (node, "color", color_node->color);
1525 gl_color_node_free (&color_node);
1528 /* data OR field attr */
1529 text_node = gl_label_barcode_get_data (GL_LABEL_BARCODE(object));
1530 if (text_node->field_flag) {
1531 xmlSetProp (node, (xmlChar *)"field", (xmlChar *)text_node->data);
1532 gl_xml_set_prop_int (node, "format", format_digits);
1534 xmlSetProp (node, (xmlChar *)"data", (xmlChar *)text_node->data);
1536 gl_text_node_free (&text_node);
1539 gl_label_object_get_affine (object, affine);
1540 gl_xml_set_prop_double (node, "a0", affine[0]);
1541 gl_xml_set_prop_double (node, "a1", affine[1]);
1542 gl_xml_set_prop_double (node, "a2", affine[2]);
1543 gl_xml_set_prop_double (node, "a3", affine[3]);
1544 gl_xml_set_prop_double (node, "a4", affine[4]);
1545 gl_xml_set_prop_double (node, "a5", affine[5]);
1547 gl_debug (DEBUG_XML, "END");
1550 /*--------------------------------------------------------------------------*/
1551 /* PRIVATE. Add XML Label Merge Fields Node */
1552 /*--------------------------------------------------------------------------*/
1554 xml_create_merge_fields (xmlNodePtr root,
1558 xmlNodePtr node, child;
1563 gl_debug (DEBUG_XML, "START");
1565 merge = gl_label_get_merge (label);
1567 node = xmlNewChild (root, ns, (xmlChar *)"Merge", NULL);
1569 string = gl_merge_get_name (merge);
1570 xmlSetProp (node, (xmlChar *)"type", (xmlChar *)string);
1573 string = gl_merge_get_src (merge);
1574 xmlSetProp (node, (xmlChar *)"src", (xmlChar *)string);
1577 g_object_unref (G_OBJECT(merge));
1579 gl_debug (DEBUG_XML, "END");
1582 /*--------------------------------------------------------------------------*/
1583 /* PRIVATE. Add XML Label Data Node */
1584 /*--------------------------------------------------------------------------*/
1586 xml_create_data (xmlNodePtr root,
1591 GList *name_list, *p;
1592 GHashTable *pixbuf_cache;
1594 gl_debug (DEBUG_XML, "START");
1596 node = xmlNewChild (root, ns, (xmlChar *)"Data", NULL);
1598 pixbuf_cache = gl_label_get_pixbuf_cache (label);
1599 name_list = gl_pixbuf_cache_get_name_list (pixbuf_cache);
1601 for (p = name_list; p != NULL; p=p->next) {
1602 xml_create_pixdata (node, ns, label, p->data);
1605 gl_pixbuf_cache_free_name_list (name_list);
1608 gl_debug (DEBUG_XML, "END");
1611 /*--------------------------------------------------------------------------*/
1612 /* PRIVATE. Add XML Label Data Pixbuf Node */
1613 /*--------------------------------------------------------------------------*/
1615 xml_create_pixdata (xmlNodePtr root,
1621 GHashTable *pixbuf_cache;
1623 GdkPixdata *pixdata;
1625 guint stream_length;
1628 gl_debug (DEBUG_XML, "START");
1630 pixbuf_cache = gl_label_get_pixbuf_cache (label);
1632 pixbuf = gl_pixbuf_cache_get_pixbuf (pixbuf_cache, name);
1633 if ( pixbuf != NULL ) {
1635 pixdata = g_new0 (GdkPixdata, 1);
1636 gdk_pixdata_from_pixbuf (pixdata, pixbuf, FALSE);
1637 stream = gdk_pixdata_serialize (pixdata, &stream_length);
1638 base64 = gl_base64_encode (stream, stream_length);
1640 node = xmlNewChild (root, ns, (xmlChar *)"Pixdata", (xmlChar *)base64);
1641 xmlSetProp (node, (xmlChar *)"name", (xmlChar *)name);
1642 xmlSetProp (node, (xmlChar *)"encoding", (xmlChar *)"Base64");
1644 gl_pixbuf_cache_remove_pixbuf (pixbuf_cache, name);
1652 gl_debug (DEBUG_XML, "END");
1655 /*--------------------------------------------------------------------------*/
1656 /* PRIVATE. Create top-level Span node. */
1657 /*--------------------------------------------------------------------------*/
1659 xml_create_toplevel_span (xmlNodePtr root,
1661 glLabelText *object_text)
1666 GnomeFontWeight font_weight;
1667 gboolean font_italic_flag;
1668 glColorNode *color_node;
1669 GtkJustification just;
1670 gdouble text_line_spacing;
1671 GList *lines, *p_line, *p_node;
1672 glTextNode *text_node;
1675 node = xmlNewChild (root, ns, (xmlChar *)"Span", NULL);
1677 /* All span attrs at top level. */
1678 font_family = gl_label_object_get_font_family (GL_LABEL_OBJECT(object_text));
1679 font_size = gl_label_object_get_font_size (GL_LABEL_OBJECT(object_text));
1680 text_line_spacing = gl_label_object_get_text_line_spacing (GL_LABEL_OBJECT(object_text));
1681 font_weight = gl_label_object_get_font_weight (GL_LABEL_OBJECT(object_text));
1682 font_italic_flag = gl_label_object_get_font_italic_flag (GL_LABEL_OBJECT(object_text));
1684 color_node = gl_label_object_get_text_color (GL_LABEL_OBJECT(object_text));
1685 if (color_node->field_flag)
1687 xmlSetProp (node, (xmlChar *)"color_field", (xmlChar *)color_node->key);
1691 gl_xml_set_prop_uint_hex (node, "color", color_node->color);
1693 gl_color_node_free (&color_node);
1695 just = gl_label_object_get_text_alignment (GL_LABEL_OBJECT(object_text));
1696 xmlSetProp (node, (xmlChar *)"font_family", (xmlChar *)font_family);
1697 gl_xml_set_prop_double (node, "font_size", font_size);
1698 xmlSetProp (node, (xmlChar *)"font_weight", (xmlChar *)gl_util_weight_to_string (font_weight));
1699 gl_xml_set_prop_boolean (node, "font_italic", font_italic_flag);
1701 gl_xml_set_prop_double (node, "line_spacing", text_line_spacing);
1703 /* Build children. */
1704 lines = gl_label_text_get_lines (GL_LABEL_TEXT(object_text));
1705 for (p_line = lines; p_line != NULL; p_line = p_line->next) {
1707 for (p_node = (GList *) p_line->data; p_node != NULL;
1708 p_node = p_node->next) {
1709 text_node = (glTextNode *) p_node->data;
1711 if (text_node->field_flag) {
1712 child = xmlNewChild (node, ns, (xmlChar *)"Field", NULL);
1713 xmlSetProp (child, (xmlChar *)"name", (xmlChar *)text_node->data);
1715 xmlNodeAddContent (node, (xmlChar *)text_node->data);
1720 if ( p_line->next ) {
1721 child = xmlNewChild (node, ns, (xmlChar *)"NL", NULL);
1726 gl_text_node_lines_free (&lines);
1727 g_free (font_family);