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"
47 /*========================================================*/
48 /* Private macros and constants. */
49 /*========================================================*/
50 #define NAME_SPACE "http://snaught.com/glabels/1.92/"
51 #define COMPAT01_NAME_SPACE "http://snaught.com/glabels/0.1/"
52 #define COMPAT04_NAME_SPACE "http://snaught.com/glabels/0.4/"
54 /*========================================================*/
56 /*========================================================*/
58 /*========================================================*/
59 /* Private globals. */
60 /*========================================================*/
62 /*========================================================*/
63 /* Private function prototypes. */
64 /*========================================================*/
66 static glLabel *xml_doc_to_label (xmlDocPtr doc,
67 glXMLLabelStatus *status);
69 static glLabel *xml_parse_label (xmlNodePtr root,
70 glXMLLabelStatus *status);
72 static void xml_parse_objects (xmlNodePtr node,
75 static void xml_parse_object (xmlNodePtr node,
78 static glLabelObject *xml_parse_text_props (xmlNodePtr node,
81 static glLabelObject *xml_parse_box_props (xmlNodePtr node,
84 static glLabelObject *xml_parse_line_props (xmlNodePtr node,
87 static glLabelObject *xml_parse_ellipse_props (xmlNodePtr node,
90 static glLabelObject *xml_parse_image_props (xmlNodePtr node,
93 static glLabelObject *xml_parse_barcode_props (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,
106 static xmlDocPtr xml_label_to_doc (glLabel *label,
107 glXMLLabelStatus *status);
109 static void xml_create_objects (xmlNodePtr root,
113 static void xml_create_object (xmlNodePtr root,
115 glLabelObject *object);
117 static void xml_create_text_props (xmlNodePtr root,
119 glLabelObject *object);
121 static void xml_create_box_props (xmlNodePtr root,
123 glLabelObject *object);
125 static void xml_create_line_props (xmlNodePtr root,
127 glLabelObject *object);
129 static void xml_create_ellipse_props (xmlNodePtr root,
131 glLabelObject *object);
133 static void xml_create_image_props (xmlNodePtr root,
135 glLabelObject *object);
137 static void xml_create_barcode_props (xmlNodePtr root,
139 glLabelObject *object);
141 static void xml_create_merge_fields (xmlNodePtr root,
145 static void xml_create_data (xmlNodePtr root,
149 static void xml_create_pixdata (xmlNodePtr root,
155 /****************************************************************************/
156 /* Open and read label from xml file. */
157 /****************************************************************************/
159 gl_xml_label_open (const gchar *filename,
160 glXMLLabelStatus *status)
165 gl_debug (DEBUG_XML, "START");
167 doc = xmlParseFile (filename);
169 g_warning (_("xmlParseFile error"));
170 *status = XML_LABEL_ERROR_OPEN_PARSE;
174 label = xml_doc_to_label (doc, status);
178 gl_label_set_filename (label, filename);
179 gl_label_clear_modified (label);
181 gl_debug (DEBUG_XML, "END");
186 /****************************************************************************/
187 /* Read label from xml buffer. */
188 /****************************************************************************/
190 gl_xml_label_open_buffer (const gchar *buffer,
191 glXMLLabelStatus *status)
196 gl_debug (DEBUG_XML, "START");
198 doc = xmlParseDoc ((xmlChar *) buffer);
200 g_warning (_("xmlParseFile error"));
201 *status = XML_LABEL_ERROR_OPEN_PARSE;
205 label = xml_doc_to_label (doc, status);
207 gl_label_clear_modified (label);
211 gl_debug (DEBUG_XML, "END");
216 /*--------------------------------------------------------------------------*/
217 /* PRIVATE. Parse xml doc structure and create label. */
218 /*--------------------------------------------------------------------------*/
220 xml_doc_to_label (xmlDocPtr doc,
221 glXMLLabelStatus *status)
223 xmlNodePtr root, node;
227 gl_debug (DEBUG_XML, "START");
231 *status = XML_LABEL_OK;
233 root = xmlDocGetRootElement (doc);
234 if (!root || !root->name) {
235 g_warning (_("No document root"));
236 *status = XML_LABEL_ERROR_OPEN_PARSE;
240 ns = xmlSearchNsByHref (doc, root, NAME_SPACE);
242 label = xml_parse_label (root, status);
244 /* Try compatability mode 0.1 */
245 ns = xmlSearchNsByHref (doc, root, COMPAT01_NAME_SPACE);
247 g_warning (_("Importing from glabels 0.1 format"));
249 label = NULL; /* TODO */
251 /* Try compatability mode 0.4 */
252 ns = xmlSearchNsByHref (doc, root,
253 COMPAT04_NAME_SPACE);
255 g_warning (_("Importing from glabels 0.4 format"));
256 label = gl_xml_label_04_parse (root, status);
258 g_warning (_("bad document, unknown glabels Namespace"));
259 *status = XML_LABEL_ERROR_OPEN_PARSE;
265 gl_debug (DEBUG_XML, "END");
270 /*--------------------------------------------------------------------------*/
271 /* PRIVATE. Parse xml root node and create label. */
272 /*--------------------------------------------------------------------------*/
274 xml_parse_label (xmlNodePtr root,
275 glXMLLabelStatus *status)
279 glTemplate *template;
281 gl_debug (DEBUG_XML, "START");
283 *status = XML_LABEL_OK;
285 if (g_strcasecmp (root->name, "Document") != 0) {
286 g_warning (_("Bad root node = \"%s\""), root->name);
287 *status = XML_LABEL_ERROR_OPEN_PARSE;
291 label = GL_LABEL(gl_label_new ());
293 /* Pass 1, extract data nodes to pre-load cache. */
294 for (node = root->xmlChildrenNode; node != NULL; node = node->next) {
295 if (g_strcasecmp (node->name, "Data") == 0) {
296 xml_parse_data (node, label);
300 /* Pass 2, now extract everything else. */
301 for (node = root->xmlChildrenNode; node != NULL; node = node->next) {
303 if (g_strcasecmp (node->name, "Sheet") == 0) {
304 template = gl_template_xml_parse_sheet (node);
306 *status = XML_LABEL_UNKNOWN_MEDIA;
309 gl_label_set_template (label, template);
310 gl_template_free (&template);
311 } else if (g_strcasecmp (node->name, "Objects") == 0) {
312 xml_parse_objects (node, label);
313 } else if (g_strcasecmp (node->name, "Merge_Fields") == 0) {
314 xml_parse_merge_fields (node, label);
315 } else if (g_strcasecmp (node->name, "Data") == 0) {
316 /* Handled in pass 1. */
318 if (!xmlNodeIsText (node)) {
319 g_warning (_("bad node in Document node = \"%s\""),
325 gl_debug (DEBUG_XML, "END");
330 /*--------------------------------------------------------------------------*/
331 /* PRIVATE. Parse Objects node. */
332 /*--------------------------------------------------------------------------*/
334 xml_parse_objects (xmlNodePtr objects_node,
337 gboolean rotate_flag;
340 gl_debug (DEBUG_XML, "START");
343 !(g_strcasecmp (xmlGetProp (objects_node, "rotate"), "false") == 0);
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 type_string = xmlGetProp (object_node, "type");
376 if ( g_strcasecmp (type_string, "text") == 0 ) {
377 object = xml_parse_text_props (object_node, label);
378 } else if ( g_strcasecmp (type_string, "box") == 0 ) {
379 object = xml_parse_box_props (object_node, label);
380 } else if ( g_strcasecmp (type_string, "line") == 0 ) {
381 object = xml_parse_line_props (object_node, label);
382 } else if ( g_strcasecmp (type_string, "ellipse") == 0 ) {
383 object = xml_parse_ellipse_props (object_node, label);
384 } else if ( g_strcasecmp (type_string, "image") == 0 ) {
385 object = xml_parse_image_props (object_node, label);
386 } else if ( g_strcasecmp (type_string, "barcode") == 0 ) {
387 object = xml_parse_barcode_props (object_node, label);
389 g_warning ("Unknown label object type \"%s\"", type_string);
393 x = g_strtod (xmlGetProp (object_node, "x"), NULL);
394 y = g_strtod (xmlGetProp (object_node, "y"), NULL);
396 gl_label_object_set_position (object, x, y);
398 affine[0] = g_strtod (xmlGetProp (object_node, "a0"), NULL);
399 affine[1] = g_strtod (xmlGetProp (object_node, "a1"), NULL);
400 affine[2] = g_strtod (xmlGetProp (object_node, "a2"), NULL);
401 affine[3] = g_strtod (xmlGetProp (object_node, "a3"), NULL);
402 affine[4] = g_strtod (xmlGetProp (object_node, "a4"), NULL);
403 affine[5] = g_strtod (xmlGetProp (object_node, "a5"), NULL);
405 gl_label_object_set_affine (object, affine);
407 gl_debug (DEBUG_XML, "END");
410 /*--------------------------------------------------------------------------*/
411 /* PRIVATE. Parse XML Label->Text Node Properties */
412 /*--------------------------------------------------------------------------*/
413 static glLabelObject *
414 xml_parse_text_props (xmlNodePtr object_node,
421 GnomeFontWeight font_weight;
422 gboolean font_italic_flag;
424 GtkJustification just;
425 xmlNodePtr line_node, text_node;
426 glTextNode *node_text;
429 gl_debug (DEBUG_XML, "START");
431 object = gl_label_text_new (label);
433 font_family = xmlGetProp (object_node, "font_family");
434 font_size = g_strtod (xmlGetProp (object_node, "font_size"), NULL);
435 font_weight = gl_util_string_to_weight (xmlGetProp (object_node,
438 !(g_strcasecmp (xmlGetProp (object_node, "font_italic"), "false") ==
441 just = gl_util_string_to_just (xmlGetProp (object_node, "justify"));
443 sscanf (xmlGetProp (object_node, "color"), "%x", &color);
446 for (line_node = object_node->xmlChildrenNode;
448 line_node = line_node->next) {
450 if (g_strcasecmp (line_node->name, "Line") == 0) {
453 for (text_node = line_node->xmlChildrenNode;
454 text_node != NULL; text_node = text_node->next) {
456 if (g_strcasecmp (text_node->name, "Field") == 0) {
457 node_text = g_new0 (glTextNode, 1);
458 node_text->field_flag = TRUE;
460 xmlGetProp (text_node, "name");
462 g_list_append (nodes, node_text);
463 } else if (g_strcasecmp (text_node->name, "Literal") == 0) {
464 node_text = g_new0 (glTextNode, 1);
465 node_text->field_flag = FALSE;
467 xmlNodeGetContent (text_node);
469 g_list_append (nodes, node_text);
470 } else if (!xmlNodeIsText) {
471 g_warning ("Unexpected Text Line child: \"%s\"",
476 lines = g_list_append (lines, nodes);
478 } else if (!xmlNodeIsText (line_node)) {
479 g_warning ("Unexpected Text child: \"%s\"",
485 gl_label_text_set_lines (GL_LABEL_TEXT(object), lines);
486 gl_label_text_set_props (GL_LABEL_TEXT(object),
487 font_family, font_size, font_weight,
491 gl_text_node_lines_free (&lines);
492 g_free (font_family);
494 gl_debug (DEBUG_XML, "END");
496 return GL_LABEL_OBJECT(object);
499 /*--------------------------------------------------------------------------*/
500 /* PRIVATE. Parse XML Label->Box Node Properties */
501 /*--------------------------------------------------------------------------*/
502 static glLabelObject *
503 xml_parse_box_props (xmlNodePtr node,
508 guint line_color, fill_color;
511 gl_debug (DEBUG_XML, "START");
513 object = gl_label_box_new (label);
515 w = g_strtod (xmlGetProp (node, "w"), NULL);
516 h = g_strtod (xmlGetProp (node, "h"), NULL);
518 line_width = g_strtod (xmlGetProp (node, "line_width"), NULL);
520 sscanf (xmlGetProp (node, "line_color"), "%x", &line_color);
521 sscanf (xmlGetProp (node, "fill_color"), "%x", &fill_color);
523 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
524 gl_label_box_set_line_width (GL_LABEL_BOX(object), line_width);
525 gl_label_box_set_line_color (GL_LABEL_BOX(object), line_color);
526 gl_label_box_set_fill_color (GL_LABEL_BOX(object), fill_color);
528 gl_debug (DEBUG_XML, "END");
530 return GL_LABEL_OBJECT(object);
533 /*--------------------------------------------------------------------------*/
534 /* PRIVATE. Parse XML Label->Line Node Properties */
535 /*--------------------------------------------------------------------------*/
536 static glLabelObject *
537 xml_parse_line_props (xmlNodePtr node,
545 gl_debug (DEBUG_XML, "START");
547 object = gl_label_line_new (label);
549 w = g_strtod (xmlGetProp (node, "dx"), NULL);
550 h = g_strtod (xmlGetProp (node, "dy"), NULL);
552 line_width = g_strtod (xmlGetProp (node, "line_width"), NULL);
554 sscanf (xmlGetProp (node, "line_color"), "%x", &line_color);
556 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
557 gl_label_line_set_line_width (GL_LABEL_LINE(object), line_width);
558 gl_label_line_set_line_color (GL_LABEL_LINE(object), line_color);
560 gl_debug (DEBUG_XML, "END");
562 return GL_LABEL_OBJECT(object);
565 /*--------------------------------------------------------------------------*/
566 /* PRIVATE. Parse XML Label->Ellipse Node Properties */
567 /*--------------------------------------------------------------------------*/
568 static glLabelObject *
569 xml_parse_ellipse_props (xmlNodePtr node,
574 guint line_color, fill_color;
577 gl_debug (DEBUG_XML, "START");
579 object = gl_label_ellipse_new (label);
581 w = g_strtod (xmlGetProp (node, "w"), NULL);
582 h = g_strtod (xmlGetProp (node, "h"), NULL);
584 line_width = g_strtod (xmlGetProp (node, "line_width"), NULL);
586 sscanf (xmlGetProp (node, "line_color"), "%x", &line_color);
587 sscanf (xmlGetProp (node, "fill_color"), "%x", &fill_color);
589 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
590 gl_label_ellipse_set_line_width (GL_LABEL_ELLIPSE(object), line_width);
591 gl_label_ellipse_set_line_color (GL_LABEL_ELLIPSE(object), line_color);
592 gl_label_ellipse_set_fill_color (GL_LABEL_ELLIPSE(object), fill_color);
594 gl_debug (DEBUG_XML, "END");
596 return GL_LABEL_OBJECT(object);
599 /*--------------------------------------------------------------------------*/
600 /* PRIVATE. Parse XML Label->Image Node Properties */
601 /*--------------------------------------------------------------------------*/
602 static glLabelObject *
603 xml_parse_image_props (xmlNodePtr node,
609 glTextNode *filename;
611 gl_debug (DEBUG_XML, "START");
613 object = gl_label_image_new (label);
615 w = g_strtod (xmlGetProp (node, "w"), NULL);
616 h = g_strtod (xmlGetProp (node, "h"), NULL);
618 filename = g_new0 (glTextNode, 1);
619 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
620 if (g_strcasecmp (child->name, "Field") == 0) {
621 filename->field_flag = TRUE;
622 filename->data = xmlGetProp (child, "name");
623 } else if (g_strcasecmp (child->name, "File") == 0) {
624 filename->field_flag = FALSE;
625 filename->data = xmlGetProp (child, "src");
626 } else if (!xmlNodeIsText (child)) {
627 g_warning ("Unexpected Image child: \"%s\"", child->name);
631 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
632 gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename);
634 gl_text_node_free (&filename);
636 gl_debug (DEBUG_XML, "END");
638 return GL_LABEL_OBJECT(object);
641 /*--------------------------------------------------------------------------*/
642 /* PRIVATE. Parse XML Label->Barcode Node Properties */
643 /*--------------------------------------------------------------------------*/
644 static glLabelObject *
645 xml_parse_barcode_props (xmlNodePtr node,
650 glTextNode *text_node;
651 glBarcodeStyle style;
656 gl_debug (DEBUG_XML, "START");
658 object = gl_label_barcode_new (label);
660 sscanf (xmlGetProp (node, "color"), "%x", &color);
662 style = gl_barcode_text_to_style (xmlGetProp (node, "style"));
663 text_flag = !(g_strcasecmp (xmlGetProp (node, "text"), "false") == 0);
664 scale = g_strtod (xmlGetProp (node, "scale"), NULL);
666 text_node = g_new0 (glTextNode, 1);
667 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
668 if (g_strcasecmp (child->name, "Field") == 0) {
669 text_node->field_flag = TRUE;
670 text_node->data = xmlGetProp (child, "name");
671 } else if (g_strcasecmp (child->name, "Literal") == 0) {
672 text_node->field_flag = FALSE;
673 text_node->data = xmlNodeGetContent (child);
674 } else if (!xmlNodeIsText (child)) {
675 g_warning ("Unexpected Barcode child: \"%s\"", child->name);
679 gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node);
680 gl_label_barcode_set_props (GL_LABEL_BARCODE(object),
681 style, text_flag, color, scale);
683 gl_text_node_free (&text_node);
685 gl_debug (DEBUG_XML, "END");
687 return GL_LABEL_OBJECT(object);
690 /*--------------------------------------------------------------------------*/
691 /* PRIVATE. Parse XML merge fields tag. */
692 /*--------------------------------------------------------------------------*/
694 xml_parse_merge_fields (xmlNodePtr node,
701 gl_debug (DEBUG_XML, "START");
703 merge = gl_merge_new (xmlGetProp (node, "type"));
704 src = xmlGetProp (node, "src");
705 gl_merge_set_src (merge, src);
707 gl_label_set_merge (label, merge);
709 g_object_unref (G_OBJECT(merge));
711 gl_debug (DEBUG_XML, "END");
714 /*--------------------------------------------------------------------------*/
715 /* PRIVATE. Parse XML data tag. */
716 /*--------------------------------------------------------------------------*/
718 xml_parse_data (xmlNodePtr node,
723 gl_debug (DEBUG_XML, "START");
725 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
727 if (g_strcasecmp (child->name, "Pixdata") == 0) {
728 xml_parse_pixdata (child, label);
730 if (!xmlNodeIsText (child)) {
731 g_warning (_("bad node in Data node = \"%s\""),
737 gl_debug (DEBUG_XML, "END");
740 /*--------------------------------------------------------------------------*/
741 /* PRIVATE. Parse XML pixbuf data tag. */
742 /*--------------------------------------------------------------------------*/
744 xml_parse_pixdata (xmlNodePtr node,
747 gchar *name, *base64;
753 GHashTable *pixbuf_cache;
755 gl_debug (DEBUG_XML, "START");
757 name = xmlGetProp (node, "name");
758 base64 = xmlNodeGetContent (node);
760 stream = gl_base64_decode (base64, &stream_length);
761 pixdata = g_new0 (GdkPixdata, 1);
762 ret = gdk_pixdata_deserialize (pixdata, stream_length, stream, NULL);
765 pixbuf = gdk_pixbuf_from_pixdata (pixdata, TRUE, NULL);
767 pixbuf_cache = gl_label_get_pixbuf_cache (label);
768 gl_pixbuf_cache_add_pixbuf (pixbuf_cache, name, pixbuf);
776 gl_debug (DEBUG_XML, "END");
779 /****************************************************************************/
780 /* Save label to xml label file. */
781 /****************************************************************************/
783 gl_xml_label_save (glLabel *label,
784 const gchar *filename,
785 glXMLLabelStatus *status)
790 gl_debug (DEBUG_XML, "START");
792 doc = xml_label_to_doc (label, status);
794 xmlSetDocCompressMode (doc, 9);
795 xml_ret = xmlSaveFormatFile (filename, doc, TRUE);
799 g_warning (_("Problem saving xml file."));
800 *status = XML_LABEL_ERROR_SAVE_FILE;
804 gl_label_set_filename (label, filename);
805 gl_label_clear_modified (label);
809 gl_debug (DEBUG_XML, "END");
812 /****************************************************************************/
813 /* Save label to xml buffer. */
814 /****************************************************************************/
816 gl_xml_label_save_buffer (glLabel *label,
817 glXMLLabelStatus *status)
823 gl_debug (DEBUG_XML, "START");
825 doc = xml_label_to_doc (label, status);
827 xmlDocDumpMemory (doc, (xmlChar **)&buffer, &size);
830 gl_label_clear_modified (label);
832 gl_debug (DEBUG_XML, "END");
837 /*--------------------------------------------------------------------------*/
838 /* PRIVATE. Convert label to xml doc structure. */
839 /*--------------------------------------------------------------------------*/
841 xml_label_to_doc (glLabel *label,
842 glXMLLabelStatus *status)
846 glTemplate *template;
849 gl_debug (DEBUG_XML, "START");
853 doc = xmlNewDoc ("1.0");
854 doc->xmlRootNode = xmlNewDocNode (doc, NULL, "Document", NULL);
856 ns = xmlNewNs (doc->xmlRootNode, NAME_SPACE, "glabels");
857 xmlSetNs (doc->xmlRootNode, ns);
859 template = gl_label_get_template (label);
860 gl_template_xml_add_sheet (template, doc->xmlRootNode, ns);
862 xml_create_objects (doc->xmlRootNode, ns, label);
864 merge = gl_label_get_merge (label);
865 gl_debug (DEBUG_XML, "merge=%p", merge);
867 xml_create_merge_fields (doc->xmlRootNode, ns, label);
868 g_object_unref (G_OBJECT(merge));
871 xml_create_data (doc->xmlRootNode, ns, label);
873 gl_debug (DEBUG_XML, "END");
875 *status = XML_LABEL_OK;
879 /*--------------------------------------------------------------------------*/
880 /* PRIVATE. Add XML Label->Objects Node */
881 /*--------------------------------------------------------------------------*/
883 xml_create_objects (xmlNodePtr root,
888 gboolean rotate_flag;
891 gl_debug (DEBUG_XML, "START");
893 rotate_flag = gl_label_get_rotate_flag (label);
895 node = xmlNewChild (root, ns, "Objects", NULL);
896 xmlSetProp (node, "id", "0");
897 xmlSetProp (node, "rotate", rotate_flag ? "True" : "False");
899 for (p = label->objects; p != NULL; p = p->next) {
900 xml_create_object (node, ns, GL_LABEL_OBJECT(p->data));
903 gl_debug (DEBUG_XML, "END");
906 /*--------------------------------------------------------------------------*/
907 /* PRIVATE. Add XML label object Node */
908 /*--------------------------------------------------------------------------*/
910 xml_create_object (xmlNodePtr root,
912 glLabelObject *object)
914 xmlNodePtr object_node;
919 gl_debug (DEBUG_XML, "START");
921 object_node = xmlNewChild (root, ns, "Object", NULL);
923 gl_label_object_get_position (object, &x, &y);
924 string = g_strdup_printf ("%g", x);
925 xmlSetProp (object_node, "x", string);
927 string = g_strdup_printf ("%g", y);
928 xmlSetProp (object_node, "y", string);
931 gl_label_object_get_affine (object, affine);
932 string = g_strdup_printf ("%g", affine[0]);
933 xmlSetProp (object_node, "a0", string);
935 string = g_strdup_printf ("%g", affine[1]);
936 xmlSetProp (object_node, "a1", string);
938 string = g_strdup_printf ("%g", affine[2]);
939 xmlSetProp (object_node, "a2", string);
941 string = g_strdup_printf ("%g", affine[3]);
942 xmlSetProp (object_node, "a3", string);
944 string = g_strdup_printf ("%g", affine[4]);
945 xmlSetProp (object_node, "a4", string);
947 string = g_strdup_printf ("%g", affine[5]);
948 xmlSetProp (object_node, "a5", string);
951 if ( GL_IS_LABEL_TEXT(object) ) {
952 xml_create_text_props (object_node, ns, object);
953 } else if ( GL_IS_LABEL_BOX(object) ) {
954 xml_create_box_props (object_node, ns, object);
955 } else if ( GL_IS_LABEL_LINE(object) ) {
956 xml_create_line_props (object_node, ns, object);
957 } else if ( GL_IS_LABEL_ELLIPSE(object) ) {
958 xml_create_ellipse_props (object_node, ns, object);
959 } else if ( GL_IS_LABEL_IMAGE(object) ) {
960 xml_create_image_props (object_node, ns, object);
961 } else if ( GL_IS_LABEL_BARCODE(object) ) {
962 xml_create_barcode_props (object_node, ns, object);
964 g_warning ("Unknown label object");
967 gl_debug (DEBUG_XML, "END");
970 /*--------------------------------------------------------------------------*/
971 /* PRIVATE. Add XML Label->Text Node Properties */
972 /*--------------------------------------------------------------------------*/
974 xml_create_text_props (xmlNodePtr object_node,
976 glLabelObject *object)
978 xmlNodePtr line_node, field_node, literal_node;
982 GnomeFontWeight font_weight;
983 gboolean font_italic_flag;
985 GtkJustification just;
987 GList *p_line, *p_node;
988 glTextNode *node_text;
990 gl_debug (DEBUG_XML, "START");
992 xmlSetProp (object_node, "type", "Text");
994 lines = gl_label_text_get_lines (GL_LABEL_TEXT(object));
995 gl_label_text_get_props (GL_LABEL_TEXT(object),
996 &font_family, &font_size, &font_weight,
1000 xmlSetProp (object_node, "font_family", font_family);
1001 string = g_strdup_printf ("%g", font_size);
1002 xmlSetProp (object_node, "font_size", string);
1004 xmlSetProp (object_node, "font_weight",
1005 gl_util_weight_to_string (font_weight));
1006 xmlSetProp (object_node, "font_italic",
1007 font_italic_flag?"True":"False");
1009 xmlSetProp (object_node, "justify", gl_util_just_to_string (just));
1011 string = g_strdup_printf ("0x%08x", color);
1012 xmlSetProp (object_node, "color", string);
1015 for (p_line = lines; p_line != NULL; p_line = p_line->next) {
1016 line_node = xmlNewChild (object_node, ns, "Line", NULL);
1018 for (p_node = (GList *) p_line->data; p_node != NULL;
1019 p_node = p_node->next) {
1020 node_text = (glTextNode *) p_node->data;
1022 if (node_text->field_flag) {
1024 xmlNewChild (line_node, ns, "Field", NULL);
1025 xmlSetProp (field_node, "name",
1029 xmlNewChild (line_node, ns,
1030 "Literal", node_text->data);
1037 gl_text_node_lines_free (&lines);
1038 g_free (font_family);
1040 gl_debug (DEBUG_XML, "END");
1043 /*--------------------------------------------------------------------------*/
1044 /* PRIVATE. Add XML Label->Box Node Properties */
1045 /*--------------------------------------------------------------------------*/
1047 xml_create_box_props (xmlNodePtr object_node,
1049 glLabelObject *object)
1053 guint line_color, fill_color;
1056 gl_debug (DEBUG_XML, "START");
1058 xmlSetProp (object_node, "type", "Box");
1060 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1061 line_width = gl_label_box_get_line_width (GL_LABEL_BOX(object));
1062 line_color = gl_label_box_get_line_color (GL_LABEL_BOX(object));
1063 fill_color = gl_label_box_get_fill_color (GL_LABEL_BOX(object));
1065 string = g_strdup_printf ("%g", w);
1066 xmlSetProp (object_node, "w", string);
1068 string = g_strdup_printf ("%g", h);
1069 xmlSetProp (object_node, "h", string);
1072 string = g_strdup_printf ("%g", line_width);
1073 xmlSetProp (object_node, "line_width", string);
1076 string = g_strdup_printf ("0x%08x", line_color);
1077 xmlSetProp (object_node, "line_color", string);
1080 string = g_strdup_printf ("0x%08x", fill_color);
1081 xmlSetProp (object_node, "fill_color", string);
1084 gl_debug (DEBUG_XML, "END");
1087 /*--------------------------------------------------------------------------*/
1088 /* PRIVATE. Add XML Label->Line Node Properties */
1089 /*--------------------------------------------------------------------------*/
1091 xml_create_line_props (xmlNodePtr object_node,
1093 glLabelObject *object)
1100 gl_debug (DEBUG_XML, "START");
1102 xmlSetProp (object_node, "type", "Line");
1104 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1105 line_width = gl_label_line_get_line_width (GL_LABEL_LINE(object));
1106 line_color = gl_label_line_get_line_color (GL_LABEL_LINE(object));
1108 string = g_strdup_printf ("%g", w);
1109 xmlSetProp (object_node, "dx", string);
1111 string = g_strdup_printf ("%g", h);
1112 xmlSetProp (object_node, "dy", string);
1115 string = g_strdup_printf ("%g", line_width);
1116 xmlSetProp (object_node, "line_width", string);
1119 string = g_strdup_printf ("0x%08x", line_color);
1120 xmlSetProp (object_node, "line_color", string);
1123 gl_debug (DEBUG_XML, "END");
1126 /*--------------------------------------------------------------------------*/
1127 /* PRIVATE. Add XML Label->Ellipse Node Properties */
1128 /*--------------------------------------------------------------------------*/
1130 xml_create_ellipse_props (xmlNodePtr object_node,
1132 glLabelObject *object)
1136 guint line_color, fill_color;
1139 gl_debug (DEBUG_XML, "START");
1141 xmlSetProp (object_node, "type", "Ellipse");
1143 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1144 line_width = gl_label_ellipse_get_line_width (GL_LABEL_ELLIPSE(object));
1145 line_color = gl_label_ellipse_get_line_color (GL_LABEL_ELLIPSE(object));
1146 fill_color = gl_label_ellipse_get_fill_color (GL_LABEL_ELLIPSE(object));
1148 string = g_strdup_printf ("%g", w);
1149 xmlSetProp (object_node, "w", string);
1151 string = g_strdup_printf ("%g", h);
1152 xmlSetProp (object_node, "h", string);
1155 string = g_strdup_printf ("%g", line_width);
1156 xmlSetProp (object_node, "line_width", string);
1159 string = g_strdup_printf ("0x%08x", line_color);
1160 xmlSetProp (object_node, "line_color", string);
1163 string = g_strdup_printf ("0x%08x", fill_color);
1164 xmlSetProp (object_node, "fill_color", string);
1167 gl_debug (DEBUG_XML, "END");
1170 /*--------------------------------------------------------------------------*/
1171 /* PRIVATE. Add XML Label->Image Node Properties */
1172 /*--------------------------------------------------------------------------*/
1174 xml_create_image_props (xmlNodePtr object_node,
1176 glLabelObject *object)
1180 glTextNode *filename;
1183 gl_debug (DEBUG_XML, "START");
1185 xmlSetProp (object_node, "type", "Image");
1187 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1188 filename = gl_label_image_get_filename (GL_LABEL_IMAGE(object));
1190 string = g_strdup_printf ("%g", w);
1191 xmlSetProp (object_node, "w", string);
1193 string = g_strdup_printf ("%g", h);
1194 xmlSetProp (object_node, "h", string);
1197 if (filename->field_flag) {
1198 child = xmlNewChild (object_node, ns, "Field", NULL);
1199 xmlSetProp (child, "name", filename->data);
1201 child = xmlNewChild (object_node, ns, "File", NULL);
1202 xmlSetProp (child, "src", filename->data);
1205 gl_text_node_free (&filename);
1207 gl_debug (DEBUG_XML, "END");
1210 /*--------------------------------------------------------------------------*/
1211 /* PRIVATE. Add XML Label->Barcode Node Properties */
1212 /*--------------------------------------------------------------------------*/
1214 xml_create_barcode_props (xmlNodePtr object_node,
1216 glLabelObject *object)
1218 glTextNode *text_node;
1219 glBarcodeStyle style;
1226 gl_debug (DEBUG_XML, "START");
1228 xmlSetProp (object_node, "type", "Barcode");
1230 text_node = gl_label_barcode_get_data (GL_LABEL_BARCODE(object));
1231 gl_label_barcode_get_props (GL_LABEL_BARCODE(object),
1232 &style, &text_flag, &color, &scale);
1234 string = g_strdup_printf ("0x%08x", color);
1235 xmlSetProp (object_node, "color", string);
1238 xmlSetProp (object_node, "style", gl_barcode_style_to_text (style));
1239 xmlSetProp (object_node, "text", text_flag?"True":"False");
1240 string = g_strdup_printf ("%g", scale);
1241 xmlSetProp (object_node, "scale", string);
1244 if (text_node->field_flag) {
1245 child = xmlNewChild (object_node, ns, "Field", NULL);
1246 xmlSetProp (child, "name", text_node->data);
1248 child = xmlNewChild (object_node, ns, "Literal", text_node->data);
1251 gl_text_node_free (&text_node);
1253 gl_debug (DEBUG_XML, "END");
1256 /*--------------------------------------------------------------------------*/
1257 /* PRIVATE. Add XML Label Merge Fields Node */
1258 /*--------------------------------------------------------------------------*/
1260 xml_create_merge_fields (xmlNodePtr root,
1264 xmlNodePtr node, child;
1269 gl_debug (DEBUG_XML, "START");
1271 merge = gl_label_get_merge (label);
1273 node = xmlNewChild (root, ns, "Merge_Fields", NULL);
1275 string = gl_merge_get_name (merge);
1276 xmlSetProp (node, "type", string);
1279 string = gl_merge_get_src (merge);
1280 xmlSetProp (node, "src", string);
1283 g_object_unref (G_OBJECT(merge));
1285 gl_debug (DEBUG_XML, "END");
1288 /*--------------------------------------------------------------------------*/
1289 /* PRIVATE. Add XML Label Data Node */
1290 /*--------------------------------------------------------------------------*/
1292 xml_create_data (xmlNodePtr root,
1297 GList *name_list, *p;
1298 GHashTable *pixbuf_cache;
1300 gl_debug (DEBUG_XML, "START");
1302 node = xmlNewChild (root, ns, "Data", NULL);
1304 pixbuf_cache = gl_label_get_pixbuf_cache (label);
1305 name_list = gl_pixbuf_cache_get_name_list (pixbuf_cache);
1307 for (p = name_list; p != NULL; p=p->next) {
1308 xml_create_pixdata (node, ns, label, p->data);
1311 gl_pixbuf_cache_free_name_list (name_list);
1314 gl_debug (DEBUG_XML, "END");
1317 /*--------------------------------------------------------------------------*/
1318 /* PRIVATE. Add XML Label Data Pixbuf Node */
1319 /*--------------------------------------------------------------------------*/
1321 xml_create_pixdata (xmlNodePtr root,
1327 GHashTable *pixbuf_cache;
1329 GdkPixdata *pixdata;
1331 guint stream_length;
1334 gl_debug (DEBUG_XML, "START");
1336 pixbuf_cache = gl_label_get_pixbuf_cache (label);
1338 pixbuf = gl_pixbuf_cache_get_pixbuf (pixbuf_cache, name);
1339 if ( pixbuf != NULL ) {
1341 pixdata = g_new0 (GdkPixdata, 1);
1342 gdk_pixdata_from_pixbuf (pixdata, pixbuf, TRUE);
1343 stream = gdk_pixdata_serialize (pixdata, &stream_length);
1344 base64 = gl_base64_encode (stream, stream_length);
1346 node = xmlNewChild (root, ns, "Pixdata", base64);
1347 xmlSetProp (node, "name", name);
1348 xmlSetProp (node, "encoding", "base64");
1350 gl_pixbuf_cache_remove_pixbuf (pixbuf_cache, name);
1352 g_free (pixdata->pixel_data);
1359 gl_debug (DEBUG_XML, "END");