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"
43 #include "xml-template.h"
49 /*========================================================*/
50 /* Private macros and constants. */
51 /*========================================================*/
52 #define NAME_SPACE "http://snaught.com/glabels/1.92/"
53 #define COMPAT01_NAME_SPACE "http://snaught.com/glabels/0.1/"
54 #define COMPAT04_NAME_SPACE "http://snaught.com/glabels/0.4/"
56 /*========================================================*/
58 /*========================================================*/
60 /*========================================================*/
61 /* Private globals. */
62 /*========================================================*/
64 /*========================================================*/
65 /* Private function prototypes. */
66 /*========================================================*/
68 static glLabel *xml_doc_to_label (xmlDocPtr doc,
69 glXMLLabelStatus *status);
71 static glLabel *xml_parse_label (xmlNodePtr root,
72 glXMLLabelStatus *status);
74 static void xml_parse_objects (xmlNodePtr node,
77 static void xml_parse_object (xmlNodePtr node,
80 static glLabelObject *xml_parse_text_props (xmlNodePtr node,
83 static glLabelObject *xml_parse_box_props (xmlNodePtr node,
86 static glLabelObject *xml_parse_line_props (xmlNodePtr node,
89 static glLabelObject *xml_parse_ellipse_props (xmlNodePtr node,
92 static glLabelObject *xml_parse_image_props (xmlNodePtr node,
95 static glLabelObject *xml_parse_barcode_props (xmlNodePtr node,
98 static void xml_parse_merge_fields (xmlNodePtr node,
101 static void xml_parse_data (xmlNodePtr node,
104 static void xml_parse_pixdata (xmlNodePtr node,
108 static xmlDocPtr xml_label_to_doc (glLabel *label,
109 glXMLLabelStatus *status);
111 static void xml_create_objects (xmlNodePtr root,
115 static void xml_create_object (xmlNodePtr root,
117 glLabelObject *object);
119 static void xml_create_text_props (xmlNodePtr root,
121 glLabelObject *object);
123 static void xml_create_box_props (xmlNodePtr root,
125 glLabelObject *object);
127 static void xml_create_line_props (xmlNodePtr root,
129 glLabelObject *object);
131 static void xml_create_ellipse_props (xmlNodePtr root,
133 glLabelObject *object);
135 static void xml_create_image_props (xmlNodePtr root,
137 glLabelObject *object);
139 static void xml_create_barcode_props (xmlNodePtr root,
141 glLabelObject *object);
143 static void xml_create_merge_fields (xmlNodePtr root,
147 static void xml_create_data (xmlNodePtr root,
151 static void xml_create_pixdata (xmlNodePtr root,
157 /****************************************************************************/
158 /* Open and read label from xml file. */
159 /****************************************************************************/
161 gl_xml_label_open (const gchar *filename,
162 glXMLLabelStatus *status)
167 gl_debug (DEBUG_XML, "START");
169 doc = xmlParseFile (filename);
171 g_warning (_("xmlParseFile error"));
172 *status = XML_LABEL_ERROR_OPEN_PARSE;
176 label = xml_doc_to_label (doc, status);
181 gl_label_set_filename (label, filename);
182 gl_label_clear_modified (label);
185 gl_debug (DEBUG_XML, "END");
190 /****************************************************************************/
191 /* Read label from xml buffer. */
192 /****************************************************************************/
194 gl_xml_label_open_buffer (const gchar *buffer,
195 glXMLLabelStatus *status)
200 gl_debug (DEBUG_XML, "START");
202 doc = xmlParseDoc ((xmlChar *) buffer);
204 g_warning (_("xmlParseFile error"));
205 *status = XML_LABEL_ERROR_OPEN_PARSE;
209 label = xml_doc_to_label (doc, status);
214 gl_label_clear_modified (label);
217 gl_debug (DEBUG_XML, "END");
222 /*--------------------------------------------------------------------------*/
223 /* PRIVATE. Parse xml doc structure and create label. */
224 /*--------------------------------------------------------------------------*/
226 xml_doc_to_label (xmlDocPtr doc,
227 glXMLLabelStatus *status)
229 xmlNodePtr root, node;
233 gl_debug (DEBUG_XML, "START");
237 *status = XML_LABEL_OK;
239 root = xmlDocGetRootElement (doc);
240 if (!root || !root->name) {
241 g_warning (_("No document root"));
242 *status = XML_LABEL_ERROR_OPEN_PARSE;
246 ns = xmlSearchNsByHref (doc, root, NAME_SPACE);
248 label = xml_parse_label (root, status);
250 /* Try compatability mode 0.1 */
251 ns = xmlSearchNsByHref (doc, root, COMPAT01_NAME_SPACE);
253 g_warning (_("Importing from glabels 0.1 format"));
255 label = NULL; /* TODO */
257 /* Try compatability mode 0.4 */
258 ns = xmlSearchNsByHref (doc, root,
259 COMPAT04_NAME_SPACE);
261 g_warning (_("Importing from glabels 0.4 format"));
262 label = gl_xml_label_04_parse (root, status);
264 g_warning (_("bad document, unknown glabels Namespace"));
265 *status = XML_LABEL_ERROR_OPEN_PARSE;
271 gl_debug (DEBUG_XML, "END");
276 /*--------------------------------------------------------------------------*/
277 /* PRIVATE. Parse xml root node and create label. */
278 /*--------------------------------------------------------------------------*/
280 xml_parse_label (xmlNodePtr root,
281 glXMLLabelStatus *status)
285 glTemplate *template;
287 gl_debug (DEBUG_XML, "START");
289 *status = XML_LABEL_OK;
291 if (!xmlStrEqual (root->name, "Document")) {
292 g_warning (_("Bad root node = \"%s\""), root->name);
293 *status = XML_LABEL_ERROR_OPEN_PARSE;
297 label = GL_LABEL(gl_label_new ());
299 /* Pass 1, extract data nodes to pre-load cache. */
300 for (node = root->xmlChildrenNode; node != NULL; node = node->next) {
301 if (xmlStrEqual (node->name, "Data")) {
302 xml_parse_data (node, label);
306 /* Pass 2, now extract everything else. */
307 for (node = root->xmlChildrenNode; node != NULL; node = node->next) {
309 if (xmlStrEqual (node->name, "Sheet")) {
310 template = gl_xml_template_parse_sheet (node);
312 *status = XML_LABEL_UNKNOWN_MEDIA;
315 gl_label_set_template (label, template);
316 gl_template_free (&template);
317 } else if (xmlStrEqual (node->name, "Objects")) {
318 xml_parse_objects (node, label);
319 } else if (xmlStrEqual (node->name, "Merge_Fields")) {
320 xml_parse_merge_fields (node, label);
321 } else if (xmlStrEqual (node->name, "Data")) {
322 /* Handled in pass 1. */
324 if (!xmlNodeIsText (node)) {
325 g_warning (_("bad node in Document node = \"%s\""),
331 gl_debug (DEBUG_XML, "END");
336 /*--------------------------------------------------------------------------*/
337 /* PRIVATE. Parse Objects node. */
338 /*--------------------------------------------------------------------------*/
340 xml_parse_objects (xmlNodePtr objects_node,
343 gboolean rotate_flag;
346 gl_debug (DEBUG_XML, "START");
348 rotate_flag = gl_xml_get_prop_boolean (objects_node, "rotate", FALSE);
349 gl_label_set_rotate_flag (label, rotate_flag);
351 for (node = objects_node->xmlChildrenNode; node != NULL; node = node->next) {
353 if (xmlStrEqual (node->name, "Object")) {
354 xml_parse_object (node, label);
356 if (!xmlNodeIsText (node)) {
357 g_warning (_("bad node = \"%s\""), node->name);
362 gl_debug (DEBUG_XML, "END");
365 /*--------------------------------------------------------------------------*/
366 /* PRIVATE. Parse XML Object Node */
367 /*--------------------------------------------------------------------------*/
369 xml_parse_object (xmlNodePtr object_node,
372 glLabelObject *object;
377 gl_debug (DEBUG_XML, "START");
379 string = xmlGetProp (object_node, "type");
381 if ( xmlStrEqual (string, "Text") ) {
382 object = xml_parse_text_props (object_node, label);
383 } else if ( xmlStrEqual (string, "Box") ) {
384 object = xml_parse_box_props (object_node, label);
385 } else if ( xmlStrEqual (string, "Line") ) {
386 object = xml_parse_line_props (object_node, label);
387 } else if ( xmlStrEqual (string, "Ellipse") ) {
388 object = xml_parse_ellipse_props (object_node, label);
389 } else if ( xmlStrEqual (string, "Image") ) {
390 object = xml_parse_image_props (object_node, label);
391 } else if ( xmlStrEqual (string, "Barcode") ) {
392 object = xml_parse_barcode_props (object_node, label);
394 g_warning ("Unknown label object type \"%s\"", string);
401 x = gl_xml_get_prop_double (object_node, "x", 0.0);
402 y = gl_xml_get_prop_double (object_node, "y", 0.0);
404 gl_label_object_set_position (object, x, y);
407 affine[0] = gl_xml_get_prop_double (object_node, "a0", 0.0);
408 affine[1] = gl_xml_get_prop_double (object_node, "a1", 0.0);
409 affine[2] = gl_xml_get_prop_double (object_node, "a2", 0.0);
410 affine[3] = gl_xml_get_prop_double (object_node, "a3", 0.0);
411 affine[4] = gl_xml_get_prop_double (object_node, "a4", 0.0);
412 affine[5] = gl_xml_get_prop_double (object_node, "a5", 0.0);
414 gl_label_object_set_affine (object, affine);
417 gl_debug (DEBUG_XML, "END");
420 /*--------------------------------------------------------------------------*/
421 /* PRIVATE. Parse XML Label->Text Node Properties */
422 /*--------------------------------------------------------------------------*/
423 static glLabelObject *
424 xml_parse_text_props (xmlNodePtr object_node,
432 GnomeFontWeight font_weight;
433 gboolean font_italic_flag;
435 GtkJustification just;
436 xmlNodePtr line_node, text_node;
437 glTextNode *node_text;
441 gl_debug (DEBUG_XML, "START");
443 object = gl_label_text_new (label);
445 w = gl_xml_get_prop_double (object_node, "w", 0);
446 h = gl_xml_get_prop_double (object_node, "h", 0);
448 font_family = xmlGetProp (object_node, "font_family");
450 font_size = gl_xml_get_prop_double (object_node, "font_size", 0.0);
452 string = xmlGetProp (object_node, "font_weight");
453 font_weight = gl_util_string_to_weight (string);
456 font_italic_flag = gl_xml_get_prop_boolean (object_node, "font_italic", FALSE);
458 string = xmlGetProp (object_node, "justify");
459 just = gl_util_string_to_just (string);
462 color = gl_xml_get_prop_uint_hex (object_node, "color", 0);
465 for (line_node = object_node->xmlChildrenNode;
467 line_node = line_node->next) {
469 if (xmlStrEqual (line_node->name, "Line")) {
472 for (text_node = line_node->xmlChildrenNode;
473 text_node != NULL; text_node = text_node->next) {
475 if (xmlStrEqual (text_node->name, "Field")) {
476 node_text = g_new0 (glTextNode, 1);
477 node_text->field_flag = TRUE;
478 node_text->data = xmlGetProp (text_node, "name");
479 nodes = g_list_append (nodes, node_text);
480 } else if (xmlStrEqual (text_node->name, "Literal")) {
481 node_text = g_new0 (glTextNode, 1);
482 node_text->field_flag = FALSE;
484 xmlNodeGetContent (text_node);
486 g_list_append (nodes, node_text);
487 } else if (!xmlNodeIsText) {
488 g_warning ("Unexpected Text Line child: \"%s\"",
493 lines = g_list_append (lines, nodes);
495 } else if (!xmlNodeIsText (line_node)) {
496 g_warning ("Unexpected Text child: \"%s\"",
502 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
503 gl_label_text_set_lines (GL_LABEL_TEXT(object), lines);
504 gl_label_text_set_props (GL_LABEL_TEXT(object),
505 font_family, font_size, font_weight,
509 gl_text_node_lines_free (&lines);
510 g_free (font_family);
512 gl_debug (DEBUG_XML, "END");
514 return GL_LABEL_OBJECT(object);
517 /*--------------------------------------------------------------------------*/
518 /* PRIVATE. Parse XML Label->Box Node Properties */
519 /*--------------------------------------------------------------------------*/
520 static glLabelObject *
521 xml_parse_box_props (xmlNodePtr node,
526 guint line_color, fill_color;
529 gl_debug (DEBUG_XML, "START");
531 object = gl_label_box_new (label);
533 w = gl_xml_get_prop_double (node, "w", 0);
534 h = gl_xml_get_prop_double (node, "h", 0);
536 line_width = gl_xml_get_prop_double (node, "line_width", 1.0);
538 line_color = gl_xml_get_prop_uint_hex (node, "line_color", 0);
539 fill_color = gl_xml_get_prop_uint_hex (node, "fill_color", 0);
541 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
542 gl_label_box_set_line_width (GL_LABEL_BOX(object), line_width);
543 gl_label_box_set_line_color (GL_LABEL_BOX(object), line_color);
544 gl_label_box_set_fill_color (GL_LABEL_BOX(object), fill_color);
546 gl_debug (DEBUG_XML, "END");
548 return GL_LABEL_OBJECT(object);
551 /*--------------------------------------------------------------------------*/
552 /* PRIVATE. Parse XML Label->Line Node Properties */
553 /*--------------------------------------------------------------------------*/
554 static glLabelObject *
555 xml_parse_line_props (xmlNodePtr node,
563 gl_debug (DEBUG_XML, "START");
565 object = gl_label_line_new (label);
567 w = gl_xml_get_prop_double (node, "dx", 0);
568 h = gl_xml_get_prop_double (node, "dy", 0);
570 line_width = gl_xml_get_prop_double (node, "line_width", 1.0);
572 line_color = gl_xml_get_prop_uint_hex (node, "line_color", 0);
574 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
575 gl_label_line_set_line_width (GL_LABEL_LINE(object), line_width);
576 gl_label_line_set_line_color (GL_LABEL_LINE(object), line_color);
578 gl_debug (DEBUG_XML, "END");
580 return GL_LABEL_OBJECT(object);
583 /*--------------------------------------------------------------------------*/
584 /* PRIVATE. Parse XML Label->Ellipse Node Properties */
585 /*--------------------------------------------------------------------------*/
586 static glLabelObject *
587 xml_parse_ellipse_props (xmlNodePtr node,
592 guint line_color, fill_color;
595 gl_debug (DEBUG_XML, "START");
597 object = gl_label_ellipse_new (label);
599 w = gl_xml_get_prop_double (node, "w", 0);
600 h = gl_xml_get_prop_double (node, "h", 0);
602 line_width = gl_xml_get_prop_double (node, "line_width", 1.0);
604 line_color = gl_xml_get_prop_uint_hex (node, "line_color", 0);
605 fill_color = gl_xml_get_prop_uint_hex (node, "fill_color", 0);
607 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
608 gl_label_ellipse_set_line_width (GL_LABEL_ELLIPSE(object), line_width);
609 gl_label_ellipse_set_line_color (GL_LABEL_ELLIPSE(object), line_color);
610 gl_label_ellipse_set_fill_color (GL_LABEL_ELLIPSE(object), fill_color);
612 gl_debug (DEBUG_XML, "END");
614 return GL_LABEL_OBJECT(object);
617 /*--------------------------------------------------------------------------*/
618 /* PRIVATE. Parse XML Label->Image Node Properties */
619 /*--------------------------------------------------------------------------*/
620 static glLabelObject *
621 xml_parse_image_props (xmlNodePtr node,
627 glTextNode *filename;
629 gl_debug (DEBUG_XML, "START");
631 object = gl_label_image_new (label);
633 w = gl_xml_get_prop_double (node, "w", 0);
634 h = gl_xml_get_prop_double (node, "h", 0);
636 filename = g_new0 (glTextNode, 1);
637 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
638 if (xmlStrEqual (child->name, "Field")) {
639 filename->field_flag = TRUE;
640 filename->data = xmlGetProp (child, "name");
641 } else if (xmlStrEqual (child->name, "File")) {
642 filename->field_flag = FALSE;
643 filename->data = xmlGetProp (child, "src");
644 } else if (!xmlNodeIsText (child)) {
645 g_warning ("Unexpected Image child: \"%s\"", child->name);
649 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
650 gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename);
652 gl_text_node_free (&filename);
654 gl_debug (DEBUG_XML, "END");
656 return GL_LABEL_OBJECT(object);
659 /*--------------------------------------------------------------------------*/
660 /* PRIVATE. Parse XML Label->Barcode Node Properties */
661 /*--------------------------------------------------------------------------*/
662 static glLabelObject *
663 xml_parse_barcode_props (xmlNodePtr node,
670 glTextNode *text_node;
671 glBarcodeStyle style;
673 gboolean checksum_flag;
676 gl_debug (DEBUG_XML, "START");
678 object = gl_label_barcode_new (label);
680 w = gl_xml_get_prop_double (node, "w", 0);
681 h = gl_xml_get_prop_double (node, "h", 0);
683 color = gl_xml_get_prop_uint_hex (node, "color", 0);
685 string = xmlGetProp (node, "style");
686 style = gl_barcode_text_to_style (string);
689 text_flag = gl_xml_get_prop_boolean (node, "text", FALSE);
690 checksum_flag = gl_xml_get_prop_boolean (node, "checksum", TRUE);
692 text_node = g_new0 (glTextNode, 1);
693 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
694 if (xmlStrEqual (child->name, "Field")) {
695 text_node->field_flag = TRUE;
696 text_node->data = xmlGetProp (child, "name");
697 } else if (xmlStrEqual (child->name, "Literal")) {
698 text_node->field_flag = FALSE;
699 text_node->data = xmlNodeGetContent (child);
700 } else if (!xmlNodeIsText (child)) {
701 g_warning ("Unexpected Barcode child: \"%s\"", child->name);
705 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
707 gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node);
708 gl_label_barcode_set_props (GL_LABEL_BARCODE(object),
709 style, text_flag, checksum_flag, color);
711 gl_text_node_free (&text_node);
713 gl_debug (DEBUG_XML, "END");
715 return GL_LABEL_OBJECT(object);
718 /*--------------------------------------------------------------------------*/
719 /* PRIVATE. Parse XML merge fields tag. */
720 /*--------------------------------------------------------------------------*/
722 xml_parse_merge_fields (xmlNodePtr node,
729 gl_debug (DEBUG_XML, "START");
731 string = xmlGetProp (node, "type");
732 merge = gl_merge_new (string);
735 string = xmlGetProp (node, "src");
736 gl_merge_set_src (merge, string);
739 gl_label_set_merge (label, merge);
741 g_object_unref (G_OBJECT(merge));
743 gl_debug (DEBUG_XML, "END");
746 /*--------------------------------------------------------------------------*/
747 /* PRIVATE. Parse XML data tag. */
748 /*--------------------------------------------------------------------------*/
750 xml_parse_data (xmlNodePtr node,
755 gl_debug (DEBUG_XML, "START");
757 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
759 if (xmlStrEqual (child->name, "Pixdata")) {
760 xml_parse_pixdata (child, label);
762 if (!xmlNodeIsText (child)) {
763 g_warning (_("bad node in Data node = \"%s\""),
769 gl_debug (DEBUG_XML, "END");
772 /*--------------------------------------------------------------------------*/
773 /* PRIVATE. Parse XML pixbuf data tag. */
774 /*--------------------------------------------------------------------------*/
776 xml_parse_pixdata (xmlNodePtr node,
779 gchar *name, *base64;
785 GHashTable *pixbuf_cache;
787 gl_debug (DEBUG_XML, "START");
789 name = xmlGetProp (node, "name");
790 base64 = xmlNodeGetContent (node);
792 stream = gl_base64_decode (base64, &stream_length);
793 pixdata = g_new0 (GdkPixdata, 1);
794 ret = gdk_pixdata_deserialize (pixdata, stream_length, stream, NULL);
797 pixbuf = gdk_pixbuf_from_pixdata (pixdata, TRUE, NULL);
799 pixbuf_cache = gl_label_get_pixbuf_cache (label);
800 gl_pixbuf_cache_add_pixbuf (pixbuf_cache, name, pixbuf);
808 gl_debug (DEBUG_XML, "END");
811 /****************************************************************************/
812 /* Save label to xml label file. */
813 /****************************************************************************/
815 gl_xml_label_save (glLabel *label,
816 const gchar *filename,
817 glXMLLabelStatus *status)
822 gl_debug (DEBUG_XML, "START");
824 doc = xml_label_to_doc (label, status);
826 xmlSetDocCompressMode (doc, 9);
827 xml_ret = xmlSaveFormatFile (filename, doc, TRUE);
831 g_warning (_("Problem saving xml file."));
832 *status = XML_LABEL_ERROR_SAVE_FILE;
836 gl_label_set_filename (label, filename);
837 gl_label_clear_modified (label);
841 gl_debug (DEBUG_XML, "END");
844 /****************************************************************************/
845 /* Save label to xml buffer. */
846 /****************************************************************************/
848 gl_xml_label_save_buffer (glLabel *label,
849 glXMLLabelStatus *status)
855 gl_debug (DEBUG_XML, "START");
857 doc = xml_label_to_doc (label, status);
859 xmlDocDumpMemory (doc, (xmlChar **)&buffer, &size);
862 gl_label_clear_modified (label);
864 gl_debug (DEBUG_XML, "END");
869 /*--------------------------------------------------------------------------*/
870 /* PRIVATE. Convert label to xml doc structure. */
871 /*--------------------------------------------------------------------------*/
873 xml_label_to_doc (glLabel *label,
874 glXMLLabelStatus *status)
878 glTemplate *template;
881 gl_debug (DEBUG_XML, "START");
885 doc = xmlNewDoc ("1.0");
886 doc->xmlRootNode = xmlNewDocNode (doc, NULL, "Document", NULL);
888 ns = xmlNewNs (doc->xmlRootNode, NAME_SPACE, "glabels");
889 xmlSetNs (doc->xmlRootNode, ns);
891 template = gl_label_get_template (label);
892 gl_xml_template_add_sheet (template, doc->xmlRootNode, ns);
894 xml_create_objects (doc->xmlRootNode, ns, label);
896 merge = gl_label_get_merge (label);
897 gl_debug (DEBUG_XML, "merge=%p", merge);
899 xml_create_merge_fields (doc->xmlRootNode, ns, label);
900 g_object_unref (G_OBJECT(merge));
903 xml_create_data (doc->xmlRootNode, ns, label);
905 gl_debug (DEBUG_XML, "END");
907 *status = XML_LABEL_OK;
911 /*--------------------------------------------------------------------------*/
912 /* PRIVATE. Add XML Label->Objects Node */
913 /*--------------------------------------------------------------------------*/
915 xml_create_objects (xmlNodePtr root,
920 gboolean rotate_flag;
923 gl_debug (DEBUG_XML, "START");
925 rotate_flag = gl_label_get_rotate_flag (label);
927 node = xmlNewChild (root, ns, "Objects", NULL);
928 xmlSetProp (node, "id", "0");
929 gl_xml_set_prop_boolean (node, "rotate", rotate_flag);
931 for (p = label->objects; p != NULL; p = p->next) {
932 xml_create_object (node, ns, GL_LABEL_OBJECT(p->data));
935 gl_debug (DEBUG_XML, "END");
938 /*--------------------------------------------------------------------------*/
939 /* PRIVATE. Add XML label object Node */
940 /*--------------------------------------------------------------------------*/
942 xml_create_object (xmlNodePtr root,
944 glLabelObject *object)
946 xmlNodePtr object_node;
950 gl_debug (DEBUG_XML, "START");
952 object_node = xmlNewChild (root, ns, "Object", NULL);
954 gl_label_object_get_position (object, &x, &y);
955 gl_xml_set_prop_double (object_node, "x", x);
956 gl_xml_set_prop_double (object_node, "y", y);
958 gl_label_object_get_affine (object, affine);
959 gl_xml_set_prop_double (object_node, "a0", affine[0]);
960 gl_xml_set_prop_double (object_node, "a1", affine[1]);
961 gl_xml_set_prop_double (object_node, "a2", affine[2]);
962 gl_xml_set_prop_double (object_node, "a3", affine[3]);
963 gl_xml_set_prop_double (object_node, "a4", affine[4]);
964 gl_xml_set_prop_double (object_node, "a5", affine[5]);
966 if ( GL_IS_LABEL_TEXT(object) ) {
967 xml_create_text_props (object_node, ns, object);
968 } else if ( GL_IS_LABEL_BOX(object) ) {
969 xml_create_box_props (object_node, ns, object);
970 } else if ( GL_IS_LABEL_LINE(object) ) {
971 xml_create_line_props (object_node, ns, object);
972 } else if ( GL_IS_LABEL_ELLIPSE(object) ) {
973 xml_create_ellipse_props (object_node, ns, object);
974 } else if ( GL_IS_LABEL_IMAGE(object) ) {
975 xml_create_image_props (object_node, ns, object);
976 } else if ( GL_IS_LABEL_BARCODE(object) ) {
977 xml_create_barcode_props (object_node, ns, object);
979 g_warning ("Unknown label object");
982 gl_debug (DEBUG_XML, "END");
985 /*--------------------------------------------------------------------------*/
986 /* PRIVATE. Add XML Label->Text Node Properties */
987 /*--------------------------------------------------------------------------*/
989 xml_create_text_props (xmlNodePtr object_node,
991 glLabelObject *object)
993 xmlNodePtr line_node, field_node, literal_node;
998 GnomeFontWeight font_weight;
999 gboolean font_italic_flag;
1001 GtkJustification just;
1002 GList *p_line, *p_node;
1003 glTextNode *node_text;
1005 gl_debug (DEBUG_XML, "START");
1007 xmlSetProp (object_node, "type", "Text");
1009 gl_label_text_get_box ( GL_LABEL_TEXT(object), &w, &h);
1010 lines = gl_label_text_get_lines (GL_LABEL_TEXT(object));
1011 gl_label_text_get_props (GL_LABEL_TEXT(object),
1012 &font_family, &font_size, &font_weight,
1016 gl_xml_set_prop_double (object_node, "w", w);
1017 gl_xml_set_prop_double (object_node, "h", h);
1019 xmlSetProp (object_node, "font_family", font_family);
1020 gl_xml_set_prop_double (object_node, "font_size", font_size);
1021 xmlSetProp (object_node, "font_weight",
1022 gl_util_weight_to_string (font_weight));
1023 gl_xml_set_prop_boolean (object_node, "font_italic", font_italic_flag);
1025 xmlSetProp (object_node, "justify", gl_util_just_to_string (just));
1027 gl_xml_set_prop_uint_hex (object_node, "color", color);
1029 for (p_line = lines; p_line != NULL; p_line = p_line->next) {
1030 line_node = xmlNewChild (object_node, ns, "Line", NULL);
1032 for (p_node = (GList *) p_line->data; p_node != NULL;
1033 p_node = p_node->next) {
1034 node_text = (glTextNode *) p_node->data;
1036 if (node_text->field_flag) {
1038 xmlNewChild (line_node, ns, "Field", NULL);
1039 xmlSetProp (field_node, "name",
1043 xmlNewChild (line_node, ns,
1044 "Literal", node_text->data);
1051 gl_text_node_lines_free (&lines);
1052 g_free (font_family);
1054 gl_debug (DEBUG_XML, "END");
1057 /*--------------------------------------------------------------------------*/
1058 /* PRIVATE. Add XML Label->Box Node Properties */
1059 /*--------------------------------------------------------------------------*/
1061 xml_create_box_props (xmlNodePtr object_node,
1063 glLabelObject *object)
1066 guint line_color, fill_color;
1069 gl_debug (DEBUG_XML, "START");
1071 xmlSetProp (object_node, "type", "Box");
1073 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1074 line_width = gl_label_box_get_line_width (GL_LABEL_BOX(object));
1075 line_color = gl_label_box_get_line_color (GL_LABEL_BOX(object));
1076 fill_color = gl_label_box_get_fill_color (GL_LABEL_BOX(object));
1078 gl_xml_set_prop_double (object_node, "w", w);
1079 gl_xml_set_prop_double (object_node, "h", h);
1081 gl_xml_set_prop_double (object_node, "line_width", line_width);
1083 gl_xml_set_prop_uint_hex (object_node, "line_color", line_color);
1084 gl_xml_set_prop_uint_hex (object_node, "fill_color", fill_color);
1086 gl_debug (DEBUG_XML, "END");
1089 /*--------------------------------------------------------------------------*/
1090 /* PRIVATE. Add XML Label->Line Node Properties */
1091 /*--------------------------------------------------------------------------*/
1093 xml_create_line_props (xmlNodePtr object_node,
1095 glLabelObject *object)
1101 gl_debug (DEBUG_XML, "START");
1103 xmlSetProp (object_node, "type", "Line");
1105 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1106 line_width = gl_label_line_get_line_width (GL_LABEL_LINE(object));
1107 line_color = gl_label_line_get_line_color (GL_LABEL_LINE(object));
1109 gl_xml_set_prop_double (object_node, "dx", w);
1110 gl_xml_set_prop_double (object_node, "dy", h);
1112 gl_xml_set_prop_double (object_node, "line_width", line_width);
1114 gl_xml_set_prop_uint_hex (object_node, "line_color", line_color);
1116 gl_debug (DEBUG_XML, "END");
1119 /*--------------------------------------------------------------------------*/
1120 /* PRIVATE. Add XML Label->Ellipse Node Properties */
1121 /*--------------------------------------------------------------------------*/
1123 xml_create_ellipse_props (xmlNodePtr object_node,
1125 glLabelObject *object)
1128 guint line_color, fill_color;
1131 gl_debug (DEBUG_XML, "START");
1133 xmlSetProp (object_node, "type", "Ellipse");
1135 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1136 line_width = gl_label_ellipse_get_line_width (GL_LABEL_ELLIPSE(object));
1137 line_color = gl_label_ellipse_get_line_color (GL_LABEL_ELLIPSE(object));
1138 fill_color = gl_label_ellipse_get_fill_color (GL_LABEL_ELLIPSE(object));
1140 gl_xml_set_prop_double (object_node, "w", w);
1141 gl_xml_set_prop_double (object_node, "h", h);
1143 gl_xml_set_prop_double (object_node, "line_width", line_width);
1145 gl_xml_set_prop_uint_hex (object_node, "line_color", line_color);
1146 gl_xml_set_prop_uint_hex (object_node, "fill_color", fill_color);
1148 gl_debug (DEBUG_XML, "END");
1151 /*--------------------------------------------------------------------------*/
1152 /* PRIVATE. Add XML Label->Image Node Properties */
1153 /*--------------------------------------------------------------------------*/
1155 xml_create_image_props (xmlNodePtr object_node,
1157 glLabelObject *object)
1160 glTextNode *filename;
1163 gl_debug (DEBUG_XML, "START");
1165 xmlSetProp (object_node, "type", "Image");
1167 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1168 filename = gl_label_image_get_filename (GL_LABEL_IMAGE(object));
1170 gl_xml_set_prop_double (object_node, "w", w);
1171 gl_xml_set_prop_double (object_node, "h", h);
1173 if (filename->field_flag) {
1174 child = xmlNewChild (object_node, ns, "Field", NULL);
1175 xmlSetProp (child, "name", filename->data);
1177 child = xmlNewChild (object_node, ns, "File", NULL);
1178 xmlSetProp (child, "src", filename->data);
1181 gl_text_node_free (&filename);
1183 gl_debug (DEBUG_XML, "END");
1186 /*--------------------------------------------------------------------------*/
1187 /* PRIVATE. Add XML Label->Barcode Node Properties */
1188 /*--------------------------------------------------------------------------*/
1190 xml_create_barcode_props (xmlNodePtr object_node,
1192 glLabelObject *object)
1195 glTextNode *text_node;
1196 glBarcodeStyle style;
1198 gboolean checksum_flag;
1202 gl_debug (DEBUG_XML, "START");
1204 xmlSetProp (object_node, "type", "Barcode");
1206 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1208 gl_xml_set_prop_double (object_node, "w", w);
1209 gl_xml_set_prop_double (object_node, "h", h);
1212 text_node = gl_label_barcode_get_data (GL_LABEL_BARCODE(object));
1213 gl_label_barcode_get_props (GL_LABEL_BARCODE(object),
1214 &style, &text_flag, &checksum_flag, &color);
1216 gl_xml_set_prop_uint_hex (object_node, "color", color);
1218 xmlSetProp (object_node, "style", gl_barcode_style_to_text (style));
1219 gl_xml_set_prop_boolean (object_node, "text", text_flag);
1220 gl_xml_set_prop_boolean (object_node, "checksum", checksum_flag);
1222 if (text_node->field_flag) {
1223 child = xmlNewChild (object_node, ns, "Field", NULL);
1224 xmlSetProp (child, "name", text_node->data);
1226 child = xmlNewChild (object_node, ns, "Literal", text_node->data);
1229 gl_text_node_free (&text_node);
1231 gl_debug (DEBUG_XML, "END");
1234 /*--------------------------------------------------------------------------*/
1235 /* PRIVATE. Add XML Label Merge Fields Node */
1236 /*--------------------------------------------------------------------------*/
1238 xml_create_merge_fields (xmlNodePtr root,
1242 xmlNodePtr node, child;
1247 gl_debug (DEBUG_XML, "START");
1249 merge = gl_label_get_merge (label);
1251 node = xmlNewChild (root, ns, "Merge_Fields", NULL);
1253 string = gl_merge_get_name (merge);
1254 xmlSetProp (node, "type", string);
1257 string = gl_merge_get_src (merge);
1258 xmlSetProp (node, "src", string);
1261 g_object_unref (G_OBJECT(merge));
1263 gl_debug (DEBUG_XML, "END");
1266 /*--------------------------------------------------------------------------*/
1267 /* PRIVATE. Add XML Label Data Node */
1268 /*--------------------------------------------------------------------------*/
1270 xml_create_data (xmlNodePtr root,
1275 GList *name_list, *p;
1276 GHashTable *pixbuf_cache;
1278 gl_debug (DEBUG_XML, "START");
1280 node = xmlNewChild (root, ns, "Data", NULL);
1282 pixbuf_cache = gl_label_get_pixbuf_cache (label);
1283 name_list = gl_pixbuf_cache_get_name_list (pixbuf_cache);
1285 for (p = name_list; p != NULL; p=p->next) {
1286 xml_create_pixdata (node, ns, label, p->data);
1289 gl_pixbuf_cache_free_name_list (name_list);
1292 gl_debug (DEBUG_XML, "END");
1295 /*--------------------------------------------------------------------------*/
1296 /* PRIVATE. Add XML Label Data Pixbuf Node */
1297 /*--------------------------------------------------------------------------*/
1299 xml_create_pixdata (xmlNodePtr root,
1305 GHashTable *pixbuf_cache;
1307 GdkPixdata *pixdata;
1309 guint stream_length;
1312 gl_debug (DEBUG_XML, "START");
1314 pixbuf_cache = gl_label_get_pixbuf_cache (label);
1316 pixbuf = gl_pixbuf_cache_get_pixbuf (pixbuf_cache, name);
1317 if ( pixbuf != NULL ) {
1319 pixdata = g_new0 (GdkPixdata, 1);
1320 gdk_pixdata_from_pixbuf (pixdata, pixbuf, TRUE);
1321 stream = gdk_pixdata_serialize (pixdata, &stream_length);
1322 base64 = gl_base64_encode (stream, stream_length);
1324 node = xmlNewChild (root, ns, "Pixdata", base64);
1325 xmlSetProp (node, "name", name);
1326 xmlSetProp (node, "encoding", "base64");
1328 gl_pixbuf_cache_remove_pixbuf (pixbuf_cache, name);
1330 g_free (pixdata->pixel_data);
1337 gl_debug (DEBUG_XML, "END");