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"
41 #include "xml-label.h"
42 #include "xml-label-04.h"
48 /*========================================================*/
49 /* Private macros and constants. */
50 /*========================================================*/
51 #define NAME_SPACE "http://snaught.com/glabels/1.92/"
52 #define COMPAT01_NAME_SPACE "http://snaught.com/glabels/0.1/"
53 #define COMPAT04_NAME_SPACE "http://snaught.com/glabels/0.4/"
55 /*========================================================*/
57 /*========================================================*/
59 /*========================================================*/
60 /* Private globals. */
61 /*========================================================*/
63 /*========================================================*/
64 /* Private function prototypes. */
65 /*========================================================*/
67 static glLabel *xml_doc_to_label (xmlDocPtr doc,
68 glXMLLabelStatus *status);
70 static glLabel *xml_parse_label (xmlNodePtr root,
71 glXMLLabelStatus *status);
73 static void xml_parse_objects (xmlNodePtr node,
76 static void xml_parse_object (xmlNodePtr node,
79 static glLabelObject *xml_parse_text_props (xmlNodePtr node,
82 static glLabelObject *xml_parse_box_props (xmlNodePtr node,
85 static glLabelObject *xml_parse_line_props (xmlNodePtr node,
88 static glLabelObject *xml_parse_ellipse_props (xmlNodePtr node,
91 static glLabelObject *xml_parse_image_props (xmlNodePtr node,
94 static glLabelObject *xml_parse_barcode_props (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,
107 static xmlDocPtr xml_label_to_doc (glLabel *label,
108 glXMLLabelStatus *status);
110 static void xml_create_objects (xmlNodePtr root,
114 static void xml_create_object (xmlNodePtr root,
116 glLabelObject *object);
118 static void xml_create_text_props (xmlNodePtr root,
120 glLabelObject *object);
122 static void xml_create_box_props (xmlNodePtr root,
124 glLabelObject *object);
126 static void xml_create_line_props (xmlNodePtr root,
128 glLabelObject *object);
130 static void xml_create_ellipse_props (xmlNodePtr root,
132 glLabelObject *object);
134 static void xml_create_image_props (xmlNodePtr root,
136 glLabelObject *object);
138 static void xml_create_barcode_props (xmlNodePtr root,
140 glLabelObject *object);
142 static void xml_create_merge_fields (xmlNodePtr root,
146 static void xml_create_data (xmlNodePtr root,
150 static void xml_create_pixdata (xmlNodePtr root,
156 /****************************************************************************/
157 /* Open and read label from xml file. */
158 /****************************************************************************/
160 gl_xml_label_open (const gchar *filename,
161 glXMLLabelStatus *status)
166 gl_debug (DEBUG_XML, "START");
168 doc = xmlParseFile (filename);
170 g_warning (_("xmlParseFile error"));
171 *status = XML_LABEL_ERROR_OPEN_PARSE;
175 label = xml_doc_to_label (doc, status);
179 gl_label_set_filename (label, filename);
180 gl_label_clear_modified (label);
182 gl_debug (DEBUG_XML, "END");
187 /****************************************************************************/
188 /* Read label from xml buffer. */
189 /****************************************************************************/
191 gl_xml_label_open_buffer (const gchar *buffer,
192 glXMLLabelStatus *status)
197 gl_debug (DEBUG_XML, "START");
199 doc = xmlParseDoc ((xmlChar *) buffer);
201 g_warning (_("xmlParseFile error"));
202 *status = XML_LABEL_ERROR_OPEN_PARSE;
206 label = xml_doc_to_label (doc, status);
208 gl_label_clear_modified (label);
212 gl_debug (DEBUG_XML, "END");
217 /*--------------------------------------------------------------------------*/
218 /* PRIVATE. Parse xml doc structure and create label. */
219 /*--------------------------------------------------------------------------*/
221 xml_doc_to_label (xmlDocPtr doc,
222 glXMLLabelStatus *status)
224 xmlNodePtr root, node;
228 gl_debug (DEBUG_XML, "START");
232 *status = XML_LABEL_OK;
234 root = xmlDocGetRootElement (doc);
235 if (!root || !root->name) {
236 g_warning (_("No document root"));
237 *status = XML_LABEL_ERROR_OPEN_PARSE;
241 ns = xmlSearchNsByHref (doc, root, NAME_SPACE);
243 label = xml_parse_label (root, status);
245 /* Try compatability mode 0.1 */
246 ns = xmlSearchNsByHref (doc, root, COMPAT01_NAME_SPACE);
248 g_warning (_("Importing from glabels 0.1 format"));
250 label = NULL; /* TODO */
252 /* Try compatability mode 0.4 */
253 ns = xmlSearchNsByHref (doc, root,
254 COMPAT04_NAME_SPACE);
256 g_warning (_("Importing from glabels 0.4 format"));
257 label = gl_xml_label_04_parse (root, status);
259 g_warning (_("bad document, unknown glabels Namespace"));
260 *status = XML_LABEL_ERROR_OPEN_PARSE;
266 gl_debug (DEBUG_XML, "END");
271 /*--------------------------------------------------------------------------*/
272 /* PRIVATE. Parse xml root node and create label. */
273 /*--------------------------------------------------------------------------*/
275 xml_parse_label (xmlNodePtr root,
276 glXMLLabelStatus *status)
280 glTemplate *template;
282 gl_debug (DEBUG_XML, "START");
284 *status = XML_LABEL_OK;
286 if (g_strcasecmp (root->name, "Document") != 0) {
287 g_warning (_("Bad root node = \"%s\""), root->name);
288 *status = XML_LABEL_ERROR_OPEN_PARSE;
292 label = GL_LABEL(gl_label_new ());
294 /* Pass 1, extract data nodes to pre-load cache. */
295 for (node = root->xmlChildrenNode; node != NULL; node = node->next) {
296 if (g_strcasecmp (node->name, "Data") == 0) {
297 xml_parse_data (node, label);
301 /* Pass 2, now extract everything else. */
302 for (node = root->xmlChildrenNode; node != NULL; node = node->next) {
304 if (g_strcasecmp (node->name, "Sheet") == 0) {
305 template = gl_template_xml_parse_sheet (node);
307 *status = XML_LABEL_UNKNOWN_MEDIA;
310 gl_label_set_template (label, template);
311 gl_template_free (&template);
312 } else if (g_strcasecmp (node->name, "Objects") == 0) {
313 xml_parse_objects (node, label);
314 } else if (g_strcasecmp (node->name, "Merge_Fields") == 0) {
315 xml_parse_merge_fields (node, label);
316 } else if (g_strcasecmp (node->name, "Data") == 0) {
317 /* Handled in pass 1. */
319 if (!xmlNodeIsText (node)) {
320 g_warning (_("bad node in Document node = \"%s\""),
326 gl_debug (DEBUG_XML, "END");
331 /*--------------------------------------------------------------------------*/
332 /* PRIVATE. Parse Objects node. */
333 /*--------------------------------------------------------------------------*/
335 xml_parse_objects (xmlNodePtr objects_node,
338 gboolean rotate_flag;
341 gl_debug (DEBUG_XML, "START");
343 rotate_flag = gl_xml_get_prop_boolean (objects_node, "rotate", FALSE);
344 gl_label_set_rotate_flag (label, rotate_flag);
346 for (node = objects_node->xmlChildrenNode; node != NULL; node = node->next) {
348 if (g_strcasecmp (node->name, "Object") == 0) {
349 xml_parse_object (node, label);
351 if (!xmlNodeIsText (node)) {
352 g_warning (_("bad node = \"%s\""), node->name);
357 gl_debug (DEBUG_XML, "END");
360 /*--------------------------------------------------------------------------*/
361 /* PRIVATE. Parse XML Object Node */
362 /*--------------------------------------------------------------------------*/
364 xml_parse_object (xmlNodePtr object_node,
367 glLabelObject *object;
372 gl_debug (DEBUG_XML, "START");
374 string = xmlGetProp (object_node, "type");
376 if ( g_strcasecmp (string, "text") == 0 ) {
377 object = xml_parse_text_props (object_node, label);
378 } else if ( g_strcasecmp (string, "box") == 0 ) {
379 object = xml_parse_box_props (object_node, label);
380 } else if ( g_strcasecmp (string, "line") == 0 ) {
381 object = xml_parse_line_props (object_node, label);
382 } else if ( g_strcasecmp (string, "ellipse") == 0 ) {
383 object = xml_parse_ellipse_props (object_node, label);
384 } else if ( g_strcasecmp (string, "image") == 0 ) {
385 object = xml_parse_image_props (object_node, label);
386 } else if ( g_strcasecmp (string, "barcode") == 0 ) {
387 object = xml_parse_barcode_props (object_node, label);
389 g_warning ("Unknown label object type \"%s\"", string);
396 x = gl_xml_get_prop_double (object_node, "x", 0.0);
397 y = gl_xml_get_prop_double (object_node, "y", 0.0);
399 gl_label_object_set_position (object, x, y);
402 affine[0] = gl_xml_get_prop_double (object_node, "a0", 0.0);
403 affine[1] = gl_xml_get_prop_double (object_node, "a1", 0.0);
404 affine[2] = gl_xml_get_prop_double (object_node, "a2", 0.0);
405 affine[3] = gl_xml_get_prop_double (object_node, "a3", 0.0);
406 affine[4] = gl_xml_get_prop_double (object_node, "a4", 0.0);
407 affine[5] = gl_xml_get_prop_double (object_node, "a5", 0.0);
409 gl_label_object_set_affine (object, affine);
412 gl_debug (DEBUG_XML, "END");
415 /*--------------------------------------------------------------------------*/
416 /* PRIVATE. Parse XML Label->Text Node Properties */
417 /*--------------------------------------------------------------------------*/
418 static glLabelObject *
419 xml_parse_text_props (xmlNodePtr object_node,
427 GnomeFontWeight font_weight;
428 gboolean font_italic_flag;
430 GtkJustification just;
431 xmlNodePtr line_node, text_node;
432 glTextNode *node_text;
436 gl_debug (DEBUG_XML, "START");
438 object = gl_label_text_new (label);
440 w = gl_xml_get_prop_double (object_node, "w", 0);
441 h = gl_xml_get_prop_double (object_node, "h", 0);
443 font_family = xmlGetProp (object_node, "font_family");
445 font_size = gl_xml_get_prop_double (object_node, "font_size", 0.0);
447 string = xmlGetProp (object_node, "font_weight");
448 font_weight = gl_util_string_to_weight (string);
451 font_italic_flag = gl_xml_get_prop_boolean (object_node, "font_italic", FALSE);
453 string = xmlGetProp (object_node, "justify");
454 just = gl_util_string_to_just (string);
457 color = gl_xml_get_prop_uint_hex (object_node, "color", 0);
460 for (line_node = object_node->xmlChildrenNode;
462 line_node = line_node->next) {
464 if (g_strcasecmp (line_node->name, "Line") == 0) {
467 for (text_node = line_node->xmlChildrenNode;
468 text_node != NULL; text_node = text_node->next) {
470 if (g_strcasecmp (text_node->name, "Field") == 0) {
471 node_text = g_new0 (glTextNode, 1);
472 node_text->field_flag = TRUE;
473 node_text->data = xmlGetProp (text_node, "name");
474 nodes = g_list_append (nodes, node_text);
475 } else if (g_strcasecmp (text_node->name, "Literal") == 0) {
476 node_text = g_new0 (glTextNode, 1);
477 node_text->field_flag = FALSE;
479 xmlNodeGetContent (text_node);
481 g_list_append (nodes, node_text);
482 } else if (!xmlNodeIsText) {
483 g_warning ("Unexpected Text Line child: \"%s\"",
488 lines = g_list_append (lines, nodes);
490 } else if (!xmlNodeIsText (line_node)) {
491 g_warning ("Unexpected Text child: \"%s\"",
497 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
498 gl_label_text_set_lines (GL_LABEL_TEXT(object), lines);
499 gl_label_text_set_props (GL_LABEL_TEXT(object),
500 font_family, font_size, font_weight,
504 gl_text_node_lines_free (&lines);
505 g_free (font_family);
507 gl_debug (DEBUG_XML, "END");
509 return GL_LABEL_OBJECT(object);
512 /*--------------------------------------------------------------------------*/
513 /* PRIVATE. Parse XML Label->Box Node Properties */
514 /*--------------------------------------------------------------------------*/
515 static glLabelObject *
516 xml_parse_box_props (xmlNodePtr node,
521 guint line_color, fill_color;
524 gl_debug (DEBUG_XML, "START");
526 object = gl_label_box_new (label);
528 w = gl_xml_get_prop_double (node, "w", 0);
529 h = gl_xml_get_prop_double (node, "h", 0);
531 line_width = gl_xml_get_prop_double (node, "line_width", 1.0);
533 line_color = gl_xml_get_prop_uint_hex (node, "line_color", 0);
534 fill_color = gl_xml_get_prop_uint_hex (node, "fill_color", 0);
536 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
537 gl_label_box_set_line_width (GL_LABEL_BOX(object), line_width);
538 gl_label_box_set_line_color (GL_LABEL_BOX(object), line_color);
539 gl_label_box_set_fill_color (GL_LABEL_BOX(object), fill_color);
541 gl_debug (DEBUG_XML, "END");
543 return GL_LABEL_OBJECT(object);
546 /*--------------------------------------------------------------------------*/
547 /* PRIVATE. Parse XML Label->Line Node Properties */
548 /*--------------------------------------------------------------------------*/
549 static glLabelObject *
550 xml_parse_line_props (xmlNodePtr node,
558 gl_debug (DEBUG_XML, "START");
560 object = gl_label_line_new (label);
562 w = gl_xml_get_prop_double (node, "dx", 0);
563 h = gl_xml_get_prop_double (node, "dy", 0);
565 line_width = gl_xml_get_prop_double (node, "line_width", 1.0);
567 line_color = gl_xml_get_prop_uint_hex (node, "line_color", 0);
569 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
570 gl_label_line_set_line_width (GL_LABEL_LINE(object), line_width);
571 gl_label_line_set_line_color (GL_LABEL_LINE(object), line_color);
573 gl_debug (DEBUG_XML, "END");
575 return GL_LABEL_OBJECT(object);
578 /*--------------------------------------------------------------------------*/
579 /* PRIVATE. Parse XML Label->Ellipse Node Properties */
580 /*--------------------------------------------------------------------------*/
581 static glLabelObject *
582 xml_parse_ellipse_props (xmlNodePtr node,
587 guint line_color, fill_color;
590 gl_debug (DEBUG_XML, "START");
592 object = gl_label_ellipse_new (label);
594 w = gl_xml_get_prop_double (node, "w", 0);
595 h = gl_xml_get_prop_double (node, "h", 0);
597 line_width = gl_xml_get_prop_double (node, "line_width", 1.0);
599 line_color = gl_xml_get_prop_uint_hex (node, "line_color", 0);
600 fill_color = gl_xml_get_prop_uint_hex (node, "fill_color", 0);
602 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
603 gl_label_ellipse_set_line_width (GL_LABEL_ELLIPSE(object), line_width);
604 gl_label_ellipse_set_line_color (GL_LABEL_ELLIPSE(object), line_color);
605 gl_label_ellipse_set_fill_color (GL_LABEL_ELLIPSE(object), fill_color);
607 gl_debug (DEBUG_XML, "END");
609 return GL_LABEL_OBJECT(object);
612 /*--------------------------------------------------------------------------*/
613 /* PRIVATE. Parse XML Label->Image Node Properties */
614 /*--------------------------------------------------------------------------*/
615 static glLabelObject *
616 xml_parse_image_props (xmlNodePtr node,
622 glTextNode *filename;
624 gl_debug (DEBUG_XML, "START");
626 object = gl_label_image_new (label);
628 w = gl_xml_get_prop_double (node, "w", 0);
629 h = gl_xml_get_prop_double (node, "h", 0);
631 filename = g_new0 (glTextNode, 1);
632 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
633 if (g_strcasecmp (child->name, "Field") == 0) {
634 filename->field_flag = TRUE;
635 filename->data = xmlGetProp (child, "name");
636 } else if (g_strcasecmp (child->name, "File") == 0) {
637 filename->field_flag = FALSE;
638 filename->data = xmlGetProp (child, "src");
639 } else if (!xmlNodeIsText (child)) {
640 g_warning ("Unexpected Image child: \"%s\"", child->name);
644 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
645 gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename);
647 gl_text_node_free (&filename);
649 gl_debug (DEBUG_XML, "END");
651 return GL_LABEL_OBJECT(object);
654 /*--------------------------------------------------------------------------*/
655 /* PRIVATE. Parse XML Label->Barcode Node Properties */
656 /*--------------------------------------------------------------------------*/
657 static glLabelObject *
658 xml_parse_barcode_props (xmlNodePtr node,
664 glTextNode *text_node;
665 glBarcodeStyle style;
670 gl_debug (DEBUG_XML, "START");
672 object = gl_label_barcode_new (label);
674 color = gl_xml_get_prop_uint_hex (node, "color", 0);
676 string = xmlGetProp (node, "style");
677 style = gl_barcode_text_to_style (string);
680 text_flag = gl_xml_get_prop_boolean (node, "text", FALSE);
682 scale = gl_xml_get_prop_double (node, "scale", 1.0);
684 text_node = g_new0 (glTextNode, 1);
685 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
686 if (g_strcasecmp (child->name, "Field") == 0) {
687 text_node->field_flag = TRUE;
688 text_node->data = xmlGetProp (child, "name");
689 } else if (g_strcasecmp (child->name, "Literal") == 0) {
690 text_node->field_flag = FALSE;
691 text_node->data = xmlNodeGetContent (child);
692 } else if (!xmlNodeIsText (child)) {
693 g_warning ("Unexpected Barcode child: \"%s\"", child->name);
697 gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node);
698 gl_label_barcode_set_props (GL_LABEL_BARCODE(object),
699 style, text_flag, color, scale);
701 gl_text_node_free (&text_node);
703 gl_debug (DEBUG_XML, "END");
705 return GL_LABEL_OBJECT(object);
708 /*--------------------------------------------------------------------------*/
709 /* PRIVATE. Parse XML merge fields tag. */
710 /*--------------------------------------------------------------------------*/
712 xml_parse_merge_fields (xmlNodePtr node,
719 gl_debug (DEBUG_XML, "START");
721 string = xmlGetProp (node, "type");
722 merge = gl_merge_new (string);
725 string = xmlGetProp (node, "src");
726 gl_merge_set_src (merge, string);
729 gl_label_set_merge (label, merge);
731 g_object_unref (G_OBJECT(merge));
733 gl_debug (DEBUG_XML, "END");
736 /*--------------------------------------------------------------------------*/
737 /* PRIVATE. Parse XML data tag. */
738 /*--------------------------------------------------------------------------*/
740 xml_parse_data (xmlNodePtr node,
745 gl_debug (DEBUG_XML, "START");
747 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
749 if (g_strcasecmp (child->name, "Pixdata") == 0) {
750 xml_parse_pixdata (child, label);
752 if (!xmlNodeIsText (child)) {
753 g_warning (_("bad node in Data node = \"%s\""),
759 gl_debug (DEBUG_XML, "END");
762 /*--------------------------------------------------------------------------*/
763 /* PRIVATE. Parse XML pixbuf data tag. */
764 /*--------------------------------------------------------------------------*/
766 xml_parse_pixdata (xmlNodePtr node,
769 gchar *name, *base64;
775 GHashTable *pixbuf_cache;
777 gl_debug (DEBUG_XML, "START");
779 name = xmlGetProp (node, "name");
780 base64 = xmlNodeGetContent (node);
782 stream = gl_base64_decode (base64, &stream_length);
783 pixdata = g_new0 (GdkPixdata, 1);
784 ret = gdk_pixdata_deserialize (pixdata, stream_length, stream, NULL);
787 pixbuf = gdk_pixbuf_from_pixdata (pixdata, TRUE, NULL);
789 pixbuf_cache = gl_label_get_pixbuf_cache (label);
790 gl_pixbuf_cache_add_pixbuf (pixbuf_cache, name, pixbuf);
798 gl_debug (DEBUG_XML, "END");
801 /****************************************************************************/
802 /* Save label to xml label file. */
803 /****************************************************************************/
805 gl_xml_label_save (glLabel *label,
806 const gchar *filename,
807 glXMLLabelStatus *status)
812 gl_debug (DEBUG_XML, "START");
814 doc = xml_label_to_doc (label, status);
816 xmlSetDocCompressMode (doc, 9);
817 xml_ret = xmlSaveFormatFile (filename, doc, TRUE);
821 g_warning (_("Problem saving xml file."));
822 *status = XML_LABEL_ERROR_SAVE_FILE;
826 gl_label_set_filename (label, filename);
827 gl_label_clear_modified (label);
831 gl_debug (DEBUG_XML, "END");
834 /****************************************************************************/
835 /* Save label to xml buffer. */
836 /****************************************************************************/
838 gl_xml_label_save_buffer (glLabel *label,
839 glXMLLabelStatus *status)
845 gl_debug (DEBUG_XML, "START");
847 doc = xml_label_to_doc (label, status);
849 xmlDocDumpMemory (doc, (xmlChar **)&buffer, &size);
852 gl_label_clear_modified (label);
854 gl_debug (DEBUG_XML, "END");
859 /*--------------------------------------------------------------------------*/
860 /* PRIVATE. Convert label to xml doc structure. */
861 /*--------------------------------------------------------------------------*/
863 xml_label_to_doc (glLabel *label,
864 glXMLLabelStatus *status)
868 glTemplate *template;
871 gl_debug (DEBUG_XML, "START");
875 doc = xmlNewDoc ("1.0");
876 doc->xmlRootNode = xmlNewDocNode (doc, NULL, "Document", NULL);
878 ns = xmlNewNs (doc->xmlRootNode, NAME_SPACE, "glabels");
879 xmlSetNs (doc->xmlRootNode, ns);
881 template = gl_label_get_template (label);
882 gl_template_xml_add_sheet (template, doc->xmlRootNode, ns);
884 xml_create_objects (doc->xmlRootNode, ns, label);
886 merge = gl_label_get_merge (label);
887 gl_debug (DEBUG_XML, "merge=%p", merge);
889 xml_create_merge_fields (doc->xmlRootNode, ns, label);
890 g_object_unref (G_OBJECT(merge));
893 xml_create_data (doc->xmlRootNode, ns, label);
895 gl_debug (DEBUG_XML, "END");
897 *status = XML_LABEL_OK;
901 /*--------------------------------------------------------------------------*/
902 /* PRIVATE. Add XML Label->Objects Node */
903 /*--------------------------------------------------------------------------*/
905 xml_create_objects (xmlNodePtr root,
910 gboolean rotate_flag;
913 gl_debug (DEBUG_XML, "START");
915 rotate_flag = gl_label_get_rotate_flag (label);
917 node = xmlNewChild (root, ns, "Objects", NULL);
918 xmlSetProp (node, "id", "0");
919 gl_xml_set_prop_boolean (node, "rotate", rotate_flag);
921 for (p = label->objects; p != NULL; p = p->next) {
922 xml_create_object (node, ns, GL_LABEL_OBJECT(p->data));
925 gl_debug (DEBUG_XML, "END");
928 /*--------------------------------------------------------------------------*/
929 /* PRIVATE. Add XML label object Node */
930 /*--------------------------------------------------------------------------*/
932 xml_create_object (xmlNodePtr root,
934 glLabelObject *object)
936 xmlNodePtr object_node;
940 gl_debug (DEBUG_XML, "START");
942 object_node = xmlNewChild (root, ns, "Object", NULL);
944 gl_label_object_get_position (object, &x, &y);
945 gl_xml_set_prop_double (object_node, "x", x);
946 gl_xml_set_prop_double (object_node, "y", y);
948 gl_label_object_get_affine (object, affine);
949 gl_xml_set_prop_double (object_node, "a0", affine[0]);
950 gl_xml_set_prop_double (object_node, "a1", affine[1]);
951 gl_xml_set_prop_double (object_node, "a2", affine[2]);
952 gl_xml_set_prop_double (object_node, "a3", affine[3]);
953 gl_xml_set_prop_double (object_node, "a4", affine[4]);
954 gl_xml_set_prop_double (object_node, "a5", affine[5]);
956 if ( GL_IS_LABEL_TEXT(object) ) {
957 xml_create_text_props (object_node, ns, object);
958 } else if ( GL_IS_LABEL_BOX(object) ) {
959 xml_create_box_props (object_node, ns, object);
960 } else if ( GL_IS_LABEL_LINE(object) ) {
961 xml_create_line_props (object_node, ns, object);
962 } else if ( GL_IS_LABEL_ELLIPSE(object) ) {
963 xml_create_ellipse_props (object_node, ns, object);
964 } else if ( GL_IS_LABEL_IMAGE(object) ) {
965 xml_create_image_props (object_node, ns, object);
966 } else if ( GL_IS_LABEL_BARCODE(object) ) {
967 xml_create_barcode_props (object_node, ns, object);
969 g_warning ("Unknown label object");
972 gl_debug (DEBUG_XML, "END");
975 /*--------------------------------------------------------------------------*/
976 /* PRIVATE. Add XML Label->Text Node Properties */
977 /*--------------------------------------------------------------------------*/
979 xml_create_text_props (xmlNodePtr object_node,
981 glLabelObject *object)
983 xmlNodePtr line_node, field_node, literal_node;
988 GnomeFontWeight font_weight;
989 gboolean font_italic_flag;
991 GtkJustification just;
992 GList *p_line, *p_node;
993 glTextNode *node_text;
995 gl_debug (DEBUG_XML, "START");
997 xmlSetProp (object_node, "type", "Text");
999 gl_label_text_get_box ( GL_LABEL_TEXT(object), &w, &h);
1000 lines = gl_label_text_get_lines (GL_LABEL_TEXT(object));
1001 gl_label_text_get_props (GL_LABEL_TEXT(object),
1002 &font_family, &font_size, &font_weight,
1006 gl_xml_set_prop_double (object_node, "w", w);
1007 gl_xml_set_prop_double (object_node, "h", h);
1009 xmlSetProp (object_node, "font_family", font_family);
1010 gl_xml_set_prop_double (object_node, "font_size", font_size);
1011 xmlSetProp (object_node, "font_weight",
1012 gl_util_weight_to_string (font_weight));
1013 gl_xml_set_prop_boolean (object_node, "font_italic", font_italic_flag);
1015 xmlSetProp (object_node, "justify", gl_util_just_to_string (just));
1017 gl_xml_set_prop_uint_hex (object_node, "color", color);
1019 for (p_line = lines; p_line != NULL; p_line = p_line->next) {
1020 line_node = xmlNewChild (object_node, ns, "Line", NULL);
1022 for (p_node = (GList *) p_line->data; p_node != NULL;
1023 p_node = p_node->next) {
1024 node_text = (glTextNode *) p_node->data;
1026 if (node_text->field_flag) {
1028 xmlNewChild (line_node, ns, "Field", NULL);
1029 xmlSetProp (field_node, "name",
1033 xmlNewChild (line_node, ns,
1034 "Literal", node_text->data);
1041 gl_text_node_lines_free (&lines);
1042 g_free (font_family);
1044 gl_debug (DEBUG_XML, "END");
1047 /*--------------------------------------------------------------------------*/
1048 /* PRIVATE. Add XML Label->Box Node Properties */
1049 /*--------------------------------------------------------------------------*/
1051 xml_create_box_props (xmlNodePtr object_node,
1053 glLabelObject *object)
1056 guint line_color, fill_color;
1059 gl_debug (DEBUG_XML, "START");
1061 xmlSetProp (object_node, "type", "Box");
1063 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1064 line_width = gl_label_box_get_line_width (GL_LABEL_BOX(object));
1065 line_color = gl_label_box_get_line_color (GL_LABEL_BOX(object));
1066 fill_color = gl_label_box_get_fill_color (GL_LABEL_BOX(object));
1068 gl_xml_set_prop_double (object_node, "w", w);
1069 gl_xml_set_prop_double (object_node, "h", h);
1071 gl_xml_set_prop_double (object_node, "line_width", line_width);
1073 gl_xml_set_prop_uint_hex (object_node, "line_color", line_color);
1074 gl_xml_set_prop_uint_hex (object_node, "fill_color", fill_color);
1076 gl_debug (DEBUG_XML, "END");
1079 /*--------------------------------------------------------------------------*/
1080 /* PRIVATE. Add XML Label->Line Node Properties */
1081 /*--------------------------------------------------------------------------*/
1083 xml_create_line_props (xmlNodePtr object_node,
1085 glLabelObject *object)
1091 gl_debug (DEBUG_XML, "START");
1093 xmlSetProp (object_node, "type", "Line");
1095 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1096 line_width = gl_label_line_get_line_width (GL_LABEL_LINE(object));
1097 line_color = gl_label_line_get_line_color (GL_LABEL_LINE(object));
1099 gl_xml_set_prop_double (object_node, "dx", w);
1100 gl_xml_set_prop_double (object_node, "dy", h);
1102 gl_xml_set_prop_double (object_node, "line_width", line_width);
1104 gl_xml_set_prop_uint_hex (object_node, "line_color", line_color);
1106 gl_debug (DEBUG_XML, "END");
1109 /*--------------------------------------------------------------------------*/
1110 /* PRIVATE. Add XML Label->Ellipse Node Properties */
1111 /*--------------------------------------------------------------------------*/
1113 xml_create_ellipse_props (xmlNodePtr object_node,
1115 glLabelObject *object)
1118 guint line_color, fill_color;
1121 gl_debug (DEBUG_XML, "START");
1123 xmlSetProp (object_node, "type", "Ellipse");
1125 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1126 line_width = gl_label_ellipse_get_line_width (GL_LABEL_ELLIPSE(object));
1127 line_color = gl_label_ellipse_get_line_color (GL_LABEL_ELLIPSE(object));
1128 fill_color = gl_label_ellipse_get_fill_color (GL_LABEL_ELLIPSE(object));
1130 gl_xml_set_prop_double (object_node, "w", w);
1131 gl_xml_set_prop_double (object_node, "h", h);
1133 gl_xml_set_prop_double (object_node, "line_width", line_width);
1135 gl_xml_set_prop_uint_hex (object_node, "line_color", line_color);
1136 gl_xml_set_prop_uint_hex (object_node, "fill_color", fill_color);
1138 gl_debug (DEBUG_XML, "END");
1141 /*--------------------------------------------------------------------------*/
1142 /* PRIVATE. Add XML Label->Image Node Properties */
1143 /*--------------------------------------------------------------------------*/
1145 xml_create_image_props (xmlNodePtr object_node,
1147 glLabelObject *object)
1150 glTextNode *filename;
1153 gl_debug (DEBUG_XML, "START");
1155 xmlSetProp (object_node, "type", "Image");
1157 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1158 filename = gl_label_image_get_filename (GL_LABEL_IMAGE(object));
1160 gl_xml_set_prop_double (object_node, "w", w);
1161 gl_xml_set_prop_double (object_node, "h", h);
1163 if (filename->field_flag) {
1164 child = xmlNewChild (object_node, ns, "Field", NULL);
1165 xmlSetProp (child, "name", filename->data);
1167 child = xmlNewChild (object_node, ns, "File", NULL);
1168 xmlSetProp (child, "src", filename->data);
1171 gl_text_node_free (&filename);
1173 gl_debug (DEBUG_XML, "END");
1176 /*--------------------------------------------------------------------------*/
1177 /* PRIVATE. Add XML Label->Barcode Node Properties */
1178 /*--------------------------------------------------------------------------*/
1180 xml_create_barcode_props (xmlNodePtr object_node,
1182 glLabelObject *object)
1184 glTextNode *text_node;
1185 glBarcodeStyle style;
1191 gl_debug (DEBUG_XML, "START");
1193 xmlSetProp (object_node, "type", "Barcode");
1195 text_node = gl_label_barcode_get_data (GL_LABEL_BARCODE(object));
1196 gl_label_barcode_get_props (GL_LABEL_BARCODE(object),
1197 &style, &text_flag, &color, &scale);
1199 gl_xml_set_prop_uint_hex (object_node, "color", color);
1201 xmlSetProp (object_node, "style", gl_barcode_style_to_text (style));
1202 gl_xml_set_prop_boolean (object_node, "text", text_flag);
1203 gl_xml_set_prop_double (object_node, "scale", scale);
1205 if (text_node->field_flag) {
1206 child = xmlNewChild (object_node, ns, "Field", NULL);
1207 xmlSetProp (child, "name", text_node->data);
1209 child = xmlNewChild (object_node, ns, "Literal", text_node->data);
1212 gl_text_node_free (&text_node);
1214 gl_debug (DEBUG_XML, "END");
1217 /*--------------------------------------------------------------------------*/
1218 /* PRIVATE. Add XML Label Merge Fields Node */
1219 /*--------------------------------------------------------------------------*/
1221 xml_create_merge_fields (xmlNodePtr root,
1225 xmlNodePtr node, child;
1230 gl_debug (DEBUG_XML, "START");
1232 merge = gl_label_get_merge (label);
1234 node = xmlNewChild (root, ns, "Merge_Fields", NULL);
1236 string = gl_merge_get_name (merge);
1237 xmlSetProp (node, "type", string);
1240 string = gl_merge_get_src (merge);
1241 xmlSetProp (node, "src", string);
1244 g_object_unref (G_OBJECT(merge));
1246 gl_debug (DEBUG_XML, "END");
1249 /*--------------------------------------------------------------------------*/
1250 /* PRIVATE. Add XML Label Data Node */
1251 /*--------------------------------------------------------------------------*/
1253 xml_create_data (xmlNodePtr root,
1258 GList *name_list, *p;
1259 GHashTable *pixbuf_cache;
1261 gl_debug (DEBUG_XML, "START");
1263 node = xmlNewChild (root, ns, "Data", NULL);
1265 pixbuf_cache = gl_label_get_pixbuf_cache (label);
1266 name_list = gl_pixbuf_cache_get_name_list (pixbuf_cache);
1268 for (p = name_list; p != NULL; p=p->next) {
1269 xml_create_pixdata (node, ns, label, p->data);
1272 gl_pixbuf_cache_free_name_list (name_list);
1275 gl_debug (DEBUG_XML, "END");
1278 /*--------------------------------------------------------------------------*/
1279 /* PRIVATE. Add XML Label Data Pixbuf Node */
1280 /*--------------------------------------------------------------------------*/
1282 xml_create_pixdata (xmlNodePtr root,
1288 GHashTable *pixbuf_cache;
1290 GdkPixdata *pixdata;
1292 guint stream_length;
1295 gl_debug (DEBUG_XML, "START");
1297 pixbuf_cache = gl_label_get_pixbuf_cache (label);
1299 pixbuf = gl_pixbuf_cache_get_pixbuf (pixbuf_cache, name);
1300 if ( pixbuf != NULL ) {
1302 pixdata = g_new0 (GdkPixdata, 1);
1303 gdk_pixdata_from_pixbuf (pixdata, pixbuf, TRUE);
1304 stream = gdk_pixdata_serialize (pixdata, &stream_length);
1305 base64 = gl_base64_encode (stream, stream_length);
1307 node = xmlNewChild (root, ns, "Pixdata", base64);
1308 xmlSetProp (node, "name", name);
1309 xmlSetProp (node, "encoding", "base64");
1311 gl_pixbuf_cache_remove_pixbuf (pixbuf_cache, name);
1313 g_free (pixdata->pixel_data);
1320 gl_debug (DEBUG_XML, "END");