3 * Copyright (C) 2001-2009 Jim Evins <evins@snaught.com>.
5 * This file is part of gLabels.
7 * gLabels is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * gLabels is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with gLabels. If not, see <http://www.gnu.org/licenses/>.
23 #include "xml-label.h"
25 #include <glib/gi18n.h>
27 #include <libxml/tree.h>
28 #include <libxml/parser.h>
29 #include <libxml/xinclude.h>
30 #include <gdk-pixbuf/gdk-pixdata.h>
32 #include <libglabels.h>
34 #include "label-object.h"
35 #include "label-text.h"
36 #include "label-box.h"
37 #include "label-line.h"
38 #include "label-ellipse.h"
39 #include "label-image.h"
40 #include "label-barcode.h"
41 #include "xml-label-04.h"
48 /*========================================================*/
49 /* Private macros and constants. */
50 /*========================================================*/
51 #define COMPAT01_NAME_SPACE "http://snaught.com/glabels/0.1/"
52 #define COMPAT04_NAME_SPACE "http://snaught.com/glabels/0.4/"
53 #define COMPAT20_NAME_SPACE "http://snaught.com/glabels/2.0/"
54 #define COMPAT22_NAME_SPACE "http://snaught.com/glabels/2.2/"
57 /*========================================================*/
59 /*========================================================*/
62 /*========================================================*/
63 /* Private globals. */
64 /*========================================================*/
67 /*========================================================*/
68 /* Private function prototypes. */
69 /*========================================================*/
71 static glLabel *xml_doc_to_label (xmlDocPtr doc,
72 glXMLLabelStatus *status);
74 static glLabel *xml_parse_label (xmlNodePtr root,
75 glXMLLabelStatus *status);
77 static void xml_parse_objects (xmlNodePtr node,
80 static void xml_parse_object_text (xmlNodePtr node,
83 static void xml_parse_object_box (xmlNodePtr node,
86 static void xml_parse_object_ellipse (xmlNodePtr node,
89 static void xml_parse_object_line (xmlNodePtr node,
92 static void xml_parse_object_image (xmlNodePtr node,
95 static void xml_parse_object_barcode (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,
107 static void xml_parse_toplevel_span (xmlNodePtr node,
108 glLabelObject *object);
110 static void xml_parse_affine_attrs (xmlNodePtr node,
111 glLabelObject *object);
113 static void xml_parse_shadow_attrs (xmlNodePtr node,
114 glLabelObject *object);
116 static xmlDocPtr xml_label_to_doc (glLabel *label,
117 glXMLLabelStatus *status);
119 static void xml_create_objects (xmlNodePtr root,
123 static void xml_create_object_text (xmlNodePtr root,
125 glLabelObject *object);
127 static void xml_create_object_box (xmlNodePtr root,
129 glLabelObject *object);
131 static void xml_create_object_line (xmlNodePtr root,
133 glLabelObject *object);
135 static void xml_create_object_ellipse(xmlNodePtr root,
137 glLabelObject *object);
139 static void xml_create_object_image (xmlNodePtr root,
141 glLabelObject *object);
143 static void xml_create_object_barcode(xmlNodePtr root,
145 glLabelObject *object);
147 static void xml_create_merge_fields (xmlNodePtr root,
151 static void xml_create_data (xmlNodePtr root,
155 static void xml_create_pixdata (xmlNodePtr root,
160 static void xml_create_toplevel_span (xmlNodePtr node,
162 glLabelText *object_text);
164 static void xml_create_affine_attrs (xmlNodePtr node,
165 glLabelObject *object);
167 static void xml_create_shadow_attrs (xmlNodePtr node,
168 glLabelObject *object);
171 /****************************************************************************/
172 /* Open and read label from xml file. */
173 /****************************************************************************/
175 gl_xml_label_open (const gchar *utf8_filename,
176 glXMLLabelStatus *status)
182 gl_debug (DEBUG_XML, "START");
184 filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
185 g_return_val_if_fail (filename, NULL);
187 doc = xmlReadFile (filename, NULL, XML_PARSE_HUGE);
189 g_message (_("xmlParseFile error"));
190 *status = XML_LABEL_ERROR_OPEN_PARSE;
194 xmlXIncludeProcess (doc);
195 xmlReconciliateNs (doc, xmlDocGetRootElement (doc));
197 label = xml_doc_to_label (doc, status);
202 gl_label_set_filename (label, utf8_filename);
203 gl_label_clear_modified (label);
207 gl_debug (DEBUG_XML, "END");
213 /****************************************************************************/
214 /* Read label from xml buffer. */
215 /****************************************************************************/
217 gl_xml_label_open_buffer (const gchar *buffer,
218 glXMLLabelStatus *status)
223 gl_debug (DEBUG_XML, "START");
225 doc = xmlReadDoc ((xmlChar *) buffer, NULL, NULL, XML_PARSE_HUGE);
227 g_message (_("xmlParseFile error"));
228 *status = XML_LABEL_ERROR_OPEN_PARSE;
232 label = xml_doc_to_label (doc, status);
237 gl_label_clear_modified (label);
240 gl_debug (DEBUG_XML, "END");
246 /*--------------------------------------------------------------------------*/
247 /* PRIVATE. Parse xml doc structure and create label. */
248 /*--------------------------------------------------------------------------*/
250 xml_doc_to_label (xmlDocPtr doc,
251 glXMLLabelStatus *status)
256 gl_debug (DEBUG_XML, "START");
260 *status = XML_LABEL_OK;
262 root = xmlDocGetRootElement (doc);
263 if (!root || !root->name) {
264 g_message (_("No document root"));
265 *status = XML_LABEL_ERROR_OPEN_PARSE;
269 /* Try compatability mode 0.1 */
270 if (xmlSearchNsByHref (doc, root, (xmlChar *)COMPAT01_NAME_SPACE))
272 g_message (_("Importing from glabels 0.1 format"));
274 label = NULL; /* TODO */
278 /* Try compatability mode 0.4 */
279 if (xmlSearchNsByHref (doc, root, (xmlChar *)COMPAT04_NAME_SPACE))
281 g_message (_("Importing from glabels 0.4 format"));
282 label = gl_xml_label_04_parse (root, status);
286 /* Test for current namespaces. */
287 if ( !xmlSearchNsByHref (doc, root, (xmlChar *)COMPAT20_NAME_SPACE) &&
288 !xmlSearchNsByHref (doc, root, (xmlChar *)COMPAT22_NAME_SPACE) &&
289 !xmlSearchNsByHref (doc, root, (xmlChar *)LGL_XML_NAME_SPACE) )
291 g_message (_("Unknown glabels Namespace -- Using %s"),
295 label = xml_parse_label (root, status);
298 gl_label_set_compression (label, xmlGetDocCompressMode (doc));
301 gl_debug (DEBUG_XML, "END");
307 /*--------------------------------------------------------------------------*/
308 /* PRIVATE. Parse xml root node and create label. */
309 /*--------------------------------------------------------------------------*/
311 xml_parse_label (xmlNodePtr root,
312 glXMLLabelStatus *status)
314 xmlNodePtr child_node;
316 lglTemplate *template;
318 gl_debug (DEBUG_XML, "START");
320 *status = XML_LABEL_OK;
322 if (!lgl_xml_is_node (root, "Glabels-document")) {
323 g_message (_("Bad root node = \"%s\""), root->name);
324 *status = XML_LABEL_ERROR_OPEN_PARSE;
328 label = GL_LABEL(gl_label_new ());
330 /* Pass 1, extract data nodes to pre-load cache. */
331 for (child_node = root->xmlChildrenNode; child_node != NULL; child_node = child_node->next) {
332 if (lgl_xml_is_node (child_node, "Data")) {
333 xml_parse_data (child_node, label);
337 /* Pass 2, now extract everything else. */
338 for (child_node = root->xmlChildrenNode;
340 child_node = child_node->next) {
342 if (lgl_xml_is_node (child_node, "Template")) {
343 template = lgl_xml_template_parse_template_node (child_node);
345 g_object_unref (label);
346 *status = XML_LABEL_UNKNOWN_MEDIA;
349 lgl_db_register_template (template);
350 gl_label_set_template (label, template, FALSE);
351 lgl_template_free (template);
352 } else if (lgl_xml_is_node (child_node, "Objects")) {
353 xml_parse_objects (child_node, label);
354 } else if (lgl_xml_is_node (child_node, "Merge")) {
355 xml_parse_merge_fields (child_node, label);
356 } else if (lgl_xml_is_node (child_node, "Data")) {
357 /* Handled in pass 1. */
359 if (!xmlNodeIsText (child_node)) {
360 g_message (_("bad node in Document node = \"%s\""),
362 g_object_unref (label);
363 *status = XML_LABEL_ERROR_OPEN_PARSE;
369 gl_debug (DEBUG_XML, "END");
375 /*--------------------------------------------------------------------------*/
376 /* PRIVATE. Parse Objects node. */
377 /*--------------------------------------------------------------------------*/
379 xml_parse_objects (xmlNodePtr node,
382 gboolean rotate_flag;
385 gl_debug (DEBUG_XML, "START");
387 rotate_flag = lgl_xml_get_prop_boolean (node, "rotate", FALSE);
388 gl_label_set_rotate_flag (label, rotate_flag, FALSE);
390 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
392 if (lgl_xml_is_node (child, "Object-text")) {
393 xml_parse_object_text (child, label);
394 } else if (lgl_xml_is_node (child, "Object-box")) {
395 xml_parse_object_box (child, label);
396 } else if (lgl_xml_is_node (child, "Object-ellipse")) {
397 xml_parse_object_ellipse (child, label);
398 } else if (lgl_xml_is_node (child, "Object-line")) {
399 xml_parse_object_line (child, label);
400 } else if (lgl_xml_is_node (child, "Object-image")) {
401 xml_parse_object_image (child, label);
402 } else if (lgl_xml_is_node (child, "Object-barcode")) {
403 xml_parse_object_barcode (child, label);
405 if (!xmlNodeIsText (child)) {
406 g_message (_("bad node = \"%s\""), child->name);
412 gl_debug (DEBUG_XML, "END");
416 /*--------------------------------------------------------------------------*/
417 /* PRIVATE. Parse XML Objects->Object-text Node */
418 /*--------------------------------------------------------------------------*/
420 xml_parse_object_text (xmlNodePtr node,
427 PangoAlignment align;
428 gboolean auto_shrink;
431 gl_debug (DEBUG_XML, "START");
433 object = gl_label_text_new (label, FALSE);
436 x = lgl_xml_get_prop_length (node, "x", 0.0);
437 y = lgl_xml_get_prop_length (node, "y", 0.0);
438 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y, FALSE);
440 /* implied size attrs */
441 w = lgl_xml_get_prop_length (node, "w", 0);
442 h = lgl_xml_get_prop_length (node, "h", 0);
443 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h, FALSE);
446 string = lgl_xml_get_prop_string (node, "justify", NULL);
447 align = gl_str_util_string_to_align (string);
449 gl_label_object_set_text_alignment (GL_LABEL_OBJECT(object), align, FALSE);
451 /* auto_shrink attr */
452 auto_shrink = lgl_xml_get_prop_boolean (node, "auto_shrink", FALSE);
453 gl_label_text_set_auto_shrink (GL_LABEL_TEXT(object), auto_shrink, FALSE);
456 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
459 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
461 /* Process children */
462 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
463 if (lgl_xml_is_node (child, "Span")) {
464 xml_parse_toplevel_span (child, GL_LABEL_OBJECT(object));
467 if (!xmlNodeIsText (child)) {
468 g_message ("Unexpected Object-text child: \"%s\"",
474 gl_debug (DEBUG_XML, "END");
478 /*--------------------------------------------------------------------------*/
479 /* PRIVATE. Parse XML Objects->Object-box Node */
480 /*--------------------------------------------------------------------------*/
482 xml_parse_object_box (xmlNodePtr node,
489 glColorNode *line_color_node;
491 glColorNode *fill_color_node;
493 gl_debug (DEBUG_XML, "START");
495 object = gl_label_box_new (label, FALSE);
498 x = lgl_xml_get_prop_length (node, "x", 0.0);
499 y = lgl_xml_get_prop_length (node, "y", 0.0);
500 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y, FALSE);
503 w = lgl_xml_get_prop_length (node, "w", 0);
504 h = lgl_xml_get_prop_length (node, "h", 0);
505 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h, FALSE);
508 line_width = lgl_xml_get_prop_length (node, "line_width", 1.0);
509 gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width, FALSE);
511 line_color_node = gl_color_node_new_default ();
512 string = lgl_xml_get_prop_string (node, "line_color_field", NULL);
514 line_color_node->field_flag = TRUE;
515 line_color_node->key = string;
517 line_color_node->color = lgl_xml_get_prop_uint (node, "line_color", 0);
519 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color_node, FALSE);
520 gl_color_node_free (&line_color_node);
524 fill_color_node = gl_color_node_new_default ();
525 string = lgl_xml_get_prop_string (node, "fill_color_field", NULL);
527 fill_color_node->field_flag = TRUE;
528 fill_color_node->key = string;
530 fill_color_node->color = lgl_xml_get_prop_uint (node, "fill_color", 0);
532 gl_label_object_set_fill_color (GL_LABEL_OBJECT(object), fill_color_node, FALSE);
533 gl_color_node_free (&fill_color_node);
536 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
539 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
541 gl_debug (DEBUG_XML, "END");
545 /*--------------------------------------------------------------------------*/
546 /* PRIVATE. Parse XML Objects->Object-ellipse Node */
547 /*--------------------------------------------------------------------------*/
549 xml_parse_object_ellipse (xmlNodePtr node,
556 glColorNode *line_color_node;
558 glColorNode *fill_color_node;
560 gl_debug (DEBUG_XML, "START");
562 object = gl_label_ellipse_new (label, FALSE);
565 x = lgl_xml_get_prop_length (node, "x", 0.0);
566 y = lgl_xml_get_prop_length (node, "y", 0.0);
567 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y, FALSE);
570 w = lgl_xml_get_prop_length (node, "w", 0);
571 h = lgl_xml_get_prop_length (node, "h", 0);
572 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h, FALSE);
575 line_width = lgl_xml_get_prop_length (node, "line_width", 1.0);
576 gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width, FALSE);
578 line_color_node = gl_color_node_new_default ();
579 string = lgl_xml_get_prop_string (node, "line_color_field", NULL);
581 line_color_node->field_flag = TRUE;
582 line_color_node->key = string;
584 line_color_node->color = lgl_xml_get_prop_uint (node, "line_color", 0);
586 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color_node, FALSE);
587 gl_color_node_free (&line_color_node);
591 fill_color_node = gl_color_node_new_default ();
592 string = lgl_xml_get_prop_string (node, "fill_color_field", NULL);
594 fill_color_node->field_flag = TRUE;
595 fill_color_node->key = string;
597 fill_color_node->color = lgl_xml_get_prop_uint (node, "fill_color", 0);
599 gl_label_object_set_fill_color (GL_LABEL_OBJECT(object), fill_color_node, FALSE);
600 gl_color_node_free (&fill_color_node);
603 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
606 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
608 gl_debug (DEBUG_XML, "END");
612 /*--------------------------------------------------------------------------*/
613 /* PRIVATE. Parse XML Objects->Object-line Node */
614 /*--------------------------------------------------------------------------*/
616 xml_parse_object_line (xmlNodePtr node,
623 glColorNode *line_color_node;
626 gl_debug (DEBUG_XML, "START");
628 object = gl_label_line_new (label, FALSE);
631 x = lgl_xml_get_prop_length (node, "x", 0.0);
632 y = lgl_xml_get_prop_length (node, "y", 0.0);
633 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y, FALSE);
636 dx = lgl_xml_get_prop_length (node, "dx", 0);
637 dy = lgl_xml_get_prop_length (node, "dy", 0);
638 gl_label_object_set_size (GL_LABEL_OBJECT(object), dx, dy, FALSE);
641 line_width = lgl_xml_get_prop_length (node, "line_width", 1.0);
642 gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width, FALSE);
644 line_color_node = gl_color_node_new_default ();
645 string = lgl_xml_get_prop_string (node, "line_color_field", NULL);
647 line_color_node->field_flag = TRUE;
648 line_color_node->key = string;
650 line_color_node->color = lgl_xml_get_prop_uint (node, "line_color", 0);
652 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color_node, FALSE);
653 gl_color_node_free (&line_color_node);
656 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
659 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
661 gl_debug (DEBUG_XML, "END");
665 /*--------------------------------------------------------------------------*/
666 /* PRIVATE. Parse XML Objects->Object-image Node */
667 /*--------------------------------------------------------------------------*/
669 xml_parse_object_image (xmlNodePtr node,
676 glTextNode *filename;
678 gl_debug (DEBUG_XML, "START");
680 object = gl_label_image_new (label, FALSE);
683 x = lgl_xml_get_prop_length (node, "x", 0.0);
684 y = lgl_xml_get_prop_length (node, "y", 0.0);
685 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y, FALSE);
687 /* src or field attr */
688 string = lgl_xml_get_prop_string (node, "src", NULL);
690 filename = g_new0 (glTextNode, 1);
691 filename->field_flag = FALSE;
692 filename->data = g_strdup ((gchar *)string);
693 gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename, FALSE);
694 gl_text_node_free (&filename);
697 string = lgl_xml_get_prop_string (node, "field", NULL);
699 filename = g_new0 (glTextNode, 1);
700 filename->field_flag = TRUE;
701 filename->data = g_strdup ((gchar *)string);
702 gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename, FALSE);
703 gl_text_node_free (&filename);
706 g_message ("Missing Object-image src or field attr");
711 w = lgl_xml_get_prop_length (node, "w", 0);
712 h = lgl_xml_get_prop_length (node, "h", 0);
713 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h, FALSE);
716 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
719 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
721 gl_debug (DEBUG_XML, "END");
725 /*--------------------------------------------------------------------------*/
726 /* PRIVATE. Parse XML Objects->Object-barcode Node */
727 /*--------------------------------------------------------------------------*/
729 xml_parse_object_barcode (xmlNodePtr node,
736 glTextNode *text_node;
739 gboolean checksum_flag;
740 glColorNode *color_node;
743 gl_debug (DEBUG_XML, "START");
745 object = gl_label_barcode_new (label, FALSE);
748 x = lgl_xml_get_prop_length (node, "x", 0.0);
749 y = lgl_xml_get_prop_length (node, "y", 0.0);
750 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y, FALSE);
753 w = lgl_xml_get_prop_length (node, "w", 0);
754 h = lgl_xml_get_prop_length (node, "h", 0);
755 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h, FALSE);
758 id = lgl_xml_get_prop_string (node, "style", NULL);
759 text_flag = lgl_xml_get_prop_boolean (node, "text", FALSE);
760 checksum_flag = lgl_xml_get_prop_boolean (node, "checksum", TRUE);
761 format_digits = lgl_xml_get_prop_uint (node, "format", 10);
762 gl_label_barcode_set_props (GL_LABEL_BARCODE(object),
763 (gchar *)id, text_flag, checksum_flag, format_digits, FALSE);
766 color_node = gl_color_node_new_default ();
767 string = lgl_xml_get_prop_string (node, "color_field", NULL);
769 color_node->field_flag = TRUE;
770 color_node->key = string;
772 color_node->color = lgl_xml_get_prop_uint (node, "color", 0);
774 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), color_node, FALSE);
775 gl_color_node_free (&color_node);
777 /* data or field attr */
778 string = lgl_xml_get_prop_string (node, "data", NULL);
780 text_node = g_new0 (glTextNode, 1);
781 text_node->field_flag = FALSE;
782 text_node->data = string;
783 gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node, FALSE);
784 gl_text_node_free (&text_node);
786 string = lgl_xml_get_prop_string (node, "field", NULL);
788 text_node = g_new0 (glTextNode, 1);
789 text_node->field_flag = TRUE;
790 text_node->data = string;
791 gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node, FALSE);
792 gl_text_node_free (&text_node);
794 g_message ("Missing Object-barcode data or field attr");
799 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
802 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
804 gl_debug (DEBUG_XML, "END");
808 /*--------------------------------------------------------------------------*/
809 /* PRIVATE. Parse XML merge fields tag. */
810 /*--------------------------------------------------------------------------*/
812 xml_parse_merge_fields (xmlNodePtr node,
818 gl_debug (DEBUG_XML, "START");
820 string = lgl_xml_get_prop_string (node, "type", NULL);
821 merge = gl_merge_new (string);
826 string = lgl_xml_get_prop_string (node, "src", NULL);
827 gl_merge_set_src (merge, string);
830 gl_label_set_merge (label, merge, FALSE);
832 g_object_unref (G_OBJECT(merge));
835 gl_debug (DEBUG_XML, "END");
839 /*--------------------------------------------------------------------------*/
840 /* PRIVATE. Parse XML data tag. */
841 /*--------------------------------------------------------------------------*/
843 xml_parse_data (xmlNodePtr node,
848 gl_debug (DEBUG_XML, "START");
850 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
852 if (lgl_xml_is_node (child, "Pixdata")) {
853 xml_parse_pixdata (child, label);
855 if (!xmlNodeIsText (child)) {
856 g_message (_("bad node in Data node = \"%s\""),
862 gl_debug (DEBUG_XML, "END");
866 /*--------------------------------------------------------------------------*/
867 /* PRIVATE. Parse XML pixbuf data tag. */
868 /*--------------------------------------------------------------------------*/
870 xml_parse_pixdata (xmlNodePtr node,
873 gchar *name, *base64;
879 GHashTable *pixbuf_cache;
881 gl_debug (DEBUG_XML, "START");
883 name = lgl_xml_get_prop_string (node, "name", NULL);
884 base64 = lgl_xml_get_node_content (node);
886 stream = g_base64_decode ((gchar *)base64, &stream_length);
887 pixdata = g_new0 (GdkPixdata, 1);
888 ret = gdk_pixdata_deserialize (pixdata, stream_length, stream, NULL);
891 pixbuf = gdk_pixbuf_from_pixdata (pixdata, TRUE, NULL);
893 pixbuf_cache = gl_label_get_pixbuf_cache (label);
894 gl_pixbuf_cache_add_pixbuf (pixbuf_cache, (gchar *)name, pixbuf);
903 gl_debug (DEBUG_XML, "END");
907 /*--------------------------------------------------------------------------*/
908 /* PRIVATE. Parse top-level Span tag. */
909 /*--------------------------------------------------------------------------*/
911 xml_parse_toplevel_span (xmlNodePtr node,
912 glLabelObject *object)
916 PangoWeight font_weight;
917 gboolean font_italic_flag;
918 glColorNode *color_node;
919 gdouble text_line_spacing;
921 GList *lines, *text_nodes;
923 glTextNode *text_node;
925 gl_debug (DEBUG_XML, "START");
927 /* Font family attr */
928 font_family = lgl_xml_get_prop_string (node, "font_family", "Sans");
929 gl_label_object_set_font_family (object, font_family, FALSE);
930 g_free (font_family);
933 font_size = lgl_xml_get_prop_double (node, "font_size", 0.0);
934 gl_label_object_set_font_size (object, font_size, FALSE);
936 /* Font weight attr */
937 string = lgl_xml_get_prop_string (node, "font_weight", NULL);
938 font_weight = gl_str_util_string_to_weight (string);
940 gl_label_object_set_font_weight (object, font_weight, FALSE);
942 /* Font italic flag attr */
943 font_italic_flag = lgl_xml_get_prop_boolean (node, "font_italic", FALSE);
944 gl_label_object_set_font_italic_flag (object, font_italic_flag, FALSE);
946 /* Text color attr */
947 color_node = gl_color_node_new_default ();
948 string = lgl_xml_get_prop_string (node, "color_field", NULL);
950 color_node->field_flag = TRUE;
951 color_node->key = string;
953 color_node->color = lgl_xml_get_prop_uint (node, "color", 0);
955 gl_label_object_set_text_color (object, color_node, FALSE);
956 gl_color_node_free (&color_node);
958 /* Text line spacing attr */
959 text_line_spacing = lgl_xml_get_prop_double (node, "line_spacing", 1.0);
960 gl_label_object_set_text_line_spacing (object, text_line_spacing, FALSE);
962 /* Now descend children, and build lines of text nodes */
965 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
967 if (xmlNodeIsText (child)) {
968 gchar *data = lgl_xml_get_node_content (child);
970 /* Hack: if the first char is LF, it's an xml formatting string */
971 if (data[0] != '\n') {
973 text_node = g_new0 (glTextNode, 1);
974 text_node->field_flag = FALSE;
975 text_node->data = g_strdup ((gchar *)data);
976 text_nodes = g_list_append (text_nodes, text_node);
980 } else if (lgl_xml_is_node (child, "Span")) {
982 g_message ("Unexpected rich text (not supported, yet!)");
984 } else if (lgl_xml_is_node (child, "Field")) {
987 string = lgl_xml_get_prop_string (child, "name", NULL);
988 text_node = g_new0 (glTextNode, 1);
989 text_node->field_flag = TRUE;
990 text_node->data = string;
991 text_nodes = g_list_append (text_nodes, text_node);
993 } else if (lgl_xml_is_node (child, "NL")) {
996 lines = g_list_append (lines, text_nodes);
1000 g_message ("Unexpected Span child: \"%s\"", child->name);
1005 /* Store last line. */
1006 lines = g_list_append (lines, text_nodes);
1009 gl_label_text_set_lines (GL_LABEL_TEXT(object), lines, FALSE);
1010 gl_text_node_lines_free (&lines);
1012 gl_debug (DEBUG_XML, "END");
1016 /*--------------------------------------------------------------------------*/
1017 /* PRIVATE. Parse affine attributes. */
1018 /*--------------------------------------------------------------------------*/
1020 xml_parse_affine_attrs (xmlNodePtr node,
1021 glLabelObject *object)
1024 cairo_matrix_t matrix;
1026 a[0] = lgl_xml_get_prop_double (node, "a0", 0.0);
1027 a[1] = lgl_xml_get_prop_double (node, "a1", 0.0);
1028 a[2] = lgl_xml_get_prop_double (node, "a2", 0.0);
1029 a[3] = lgl_xml_get_prop_double (node, "a3", 0.0);
1030 a[4] = lgl_xml_get_prop_double (node, "a4", 0.0);
1031 a[5] = lgl_xml_get_prop_double (node, "a5", 0.0);
1033 cairo_matrix_init (&matrix, a[0], a[1], a[2], a[3], a[4], a[5]);
1035 gl_label_object_set_matrix (object, &matrix);
1039 /*--------------------------------------------------------------------------*/
1040 /* PRIVATE. Parse shadow attributes. */
1041 /*--------------------------------------------------------------------------*/
1043 xml_parse_shadow_attrs (xmlNodePtr node,
1044 glLabelObject *object)
1046 gboolean shadow_state;
1049 glColorNode *shadow_color_node;
1050 gdouble shadow_opacity;
1053 shadow_state = lgl_xml_get_prop_boolean (node, "shadow", FALSE);
1054 gl_label_object_set_shadow_state (object, shadow_state, FALSE);
1058 shadow_x = lgl_xml_get_prop_length (node, "shadow_x", 0.0);
1059 shadow_y = lgl_xml_get_prop_length (node, "shadow_y", 0.0);
1060 gl_label_object_set_shadow_offset (object, shadow_x, shadow_y, FALSE);
1062 shadow_color_node = gl_color_node_new_default ();
1063 string = lgl_xml_get_prop_string (node, "shadow_color_field", NULL);
1065 shadow_color_node->field_flag = TRUE;
1066 shadow_color_node->key = string;
1068 shadow_color_node->color = lgl_xml_get_prop_uint (node, "shadow_color", 0);
1070 gl_label_object_set_shadow_color (object, shadow_color_node, FALSE);
1071 gl_color_node_free (&shadow_color_node);
1073 shadow_opacity = lgl_xml_get_prop_double (node, "shadow_opacity", 1.0);
1074 gl_label_object_set_shadow_opacity (object, shadow_opacity, FALSE);
1079 /****************************************************************************/
1080 /* Save label to xml label file. */
1081 /****************************************************************************/
1083 gl_xml_label_save (glLabel *label,
1084 const gchar *utf8_filename,
1085 glXMLLabelStatus *status)
1091 gl_debug (DEBUG_XML, "START");
1093 doc = xml_label_to_doc (label, status);
1095 filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
1097 g_message (_("Utf8 conversion error."));
1099 xmlSetDocCompressMode (doc, gl_label_get_compression (label));
1100 xml_ret = xmlSaveFormatFile (filename, doc, TRUE);
1102 if (xml_ret == -1) {
1104 g_message (_("Problem saving xml file."));
1105 *status = XML_LABEL_ERROR_SAVE_FILE;
1109 gl_label_set_filename (label, utf8_filename);
1110 gl_label_clear_modified (label);
1116 gl_debug (DEBUG_XML, "END");
1120 /****************************************************************************/
1121 /* Save label to xml buffer. */
1122 /****************************************************************************/
1124 gl_xml_label_save_buffer (glLabel *label,
1125 glXMLLabelStatus *status)
1131 gl_debug (DEBUG_XML, "START");
1133 doc = xml_label_to_doc (label, status);
1135 xmlDocDumpMemory (doc, &buffer, &size);
1138 gl_label_clear_modified (label);
1140 gl_debug (DEBUG_XML, "END");
1142 return (gchar *)buffer;
1146 /*--------------------------------------------------------------------------*/
1147 /* PRIVATE. Convert label to xml doc structure. */
1148 /*--------------------------------------------------------------------------*/
1150 xml_label_to_doc (glLabel *label,
1151 glXMLLabelStatus *status)
1156 const lglTemplate *template;
1159 gl_debug (DEBUG_XML, "START");
1161 LIBXML_TEST_VERSION;
1163 units = gl_prefs_model_get_units (gl_prefs);
1164 lgl_xml_set_default_units (units);
1166 doc = xmlNewDoc ((xmlChar *)"1.0");
1167 doc->xmlRootNode = xmlNewDocNode (doc, NULL, (xmlChar *)"Glabels-document", NULL);
1169 ns = xmlNewNs (doc->xmlRootNode, (xmlChar *)LGL_XML_NAME_SPACE, NULL);
1170 xmlSetNs (doc->xmlRootNode, ns);
1172 template = gl_label_get_template (label);
1173 lgl_xml_template_create_template_node (template, doc->xmlRootNode, ns);
1175 xml_create_objects (doc->xmlRootNode, ns, label);
1177 merge = gl_label_get_merge (label);
1178 gl_debug (DEBUG_XML, "merge=%p", merge);
1179 if (merge != NULL) {
1180 xml_create_merge_fields (doc->xmlRootNode, ns, label);
1181 g_object_unref (G_OBJECT(merge));
1184 xml_create_data (doc->xmlRootNode, ns, label);
1186 gl_debug (DEBUG_XML, "END");
1188 *status = XML_LABEL_OK;
1193 /*--------------------------------------------------------------------------*/
1194 /* PRIVATE. Add XML Objects Node */
1195 /*--------------------------------------------------------------------------*/
1197 xml_create_objects (xmlNodePtr root,
1202 gboolean rotate_flag;
1203 const GList *object_list;
1205 glLabelObject *object;
1207 gl_debug (DEBUG_XML, "START");
1209 rotate_flag = gl_label_get_rotate_flag (label);
1210 object_list = gl_label_get_object_list (label);
1212 node = xmlNewChild (root, ns, (xmlChar *)"Objects", NULL);
1213 lgl_xml_set_prop_string (node, "id", "0");
1214 lgl_xml_set_prop_boolean (node, "rotate", rotate_flag);
1216 for (p = (GList *)object_list; p != NULL; p = p->next) {
1218 object = GL_LABEL_OBJECT(p->data);
1220 if ( GL_IS_LABEL_TEXT(object) ) {
1221 xml_create_object_text (node, ns, object);
1222 } else if ( GL_IS_LABEL_BOX(object) ) {
1223 xml_create_object_box (node, ns, object);
1224 } else if ( GL_IS_LABEL_ELLIPSE(object) ) {
1225 xml_create_object_ellipse (node, ns, object);
1226 } else if ( GL_IS_LABEL_LINE(object) ) {
1227 xml_create_object_line (node, ns, object);
1228 } else if ( GL_IS_LABEL_IMAGE(object) ) {
1229 xml_create_object_image (node, ns, object);
1230 } else if ( GL_IS_LABEL_BARCODE(object) ) {
1231 xml_create_object_barcode (node, ns, object);
1233 g_message ("Unknown label object");
1238 gl_debug (DEBUG_XML, "END");
1242 /*--------------------------------------------------------------------------*/
1243 /* PRIVATE. Add XML Objects->Object-text Node */
1244 /*--------------------------------------------------------------------------*/
1246 xml_create_object_text (xmlNodePtr root,
1248 glLabelObject *object)
1253 PangoAlignment align;
1254 gboolean auto_shrink;
1256 gl_debug (DEBUG_XML, "START");
1258 node = xmlNewChild (root, ns, (xmlChar *)"Object-text", NULL);
1260 /* position attrs */
1261 gl_label_object_get_position (object, &x, &y);
1262 lgl_xml_set_prop_length (node, "x", x);
1263 lgl_xml_set_prop_length (node, "y", y);
1266 gl_label_object_get_raw_size ( object, &w, &h);
1267 lgl_xml_set_prop_length (node, "w", w);
1268 lgl_xml_set_prop_length (node, "h", h);
1271 align = gl_label_object_get_text_alignment (object);
1272 lgl_xml_set_prop_string (node, "justify", gl_str_util_align_to_string (align));
1274 /* auto_shrink attr */
1275 auto_shrink = gl_label_text_get_auto_shrink (GL_LABEL_TEXT (object));
1276 lgl_xml_set_prop_boolean (node, "auto_shrink", auto_shrink);
1279 xml_create_affine_attrs (node, object);
1282 xml_create_shadow_attrs (node, object);
1285 xml_create_toplevel_span (node, ns, GL_LABEL_TEXT(object));
1287 gl_debug (DEBUG_XML, "END");
1291 /*--------------------------------------------------------------------------*/
1292 /* PRIVATE. Add XML Objects->Object-box Node */
1293 /*--------------------------------------------------------------------------*/
1295 xml_create_object_box (xmlNodePtr root,
1297 glLabelObject *object)
1303 glColorNode *line_color_node;
1304 glColorNode *fill_color_node;
1306 gl_debug (DEBUG_XML, "START");
1308 node = xmlNewChild (root, ns, (xmlChar *)"Object-box", NULL);
1310 /* position attrs */
1311 gl_label_object_get_position (object, &x, &y);
1312 lgl_xml_set_prop_length (node, "x", x);
1313 lgl_xml_set_prop_length (node, "y", y);
1316 gl_label_object_get_size (object, &w, &h);
1317 lgl_xml_set_prop_length (node, "w", w);
1318 lgl_xml_set_prop_length (node, "h", h);
1321 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1322 lgl_xml_set_prop_length (node, "line_width", line_width);
1324 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1325 if (line_color_node->field_flag)
1327 lgl_xml_set_prop_string (node, "line_color_field", line_color_node->key);
1331 lgl_xml_set_prop_uint_hex (node, "line_color", line_color_node->color);
1333 gl_color_node_free (&line_color_node);
1335 /* fill attrs (color or field) */
1336 fill_color_node = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
1337 if (fill_color_node->field_flag)
1339 lgl_xml_set_prop_string (node, "fill_color_field", fill_color_node->key);
1343 lgl_xml_set_prop_uint_hex (node, "fill_color", fill_color_node->color);
1345 gl_color_node_free (&fill_color_node);
1348 xml_create_affine_attrs (node, object);
1351 xml_create_shadow_attrs (node, object);
1353 gl_debug (DEBUG_XML, "END");
1357 /*--------------------------------------------------------------------------*/
1358 /* PRIVATE. Add XML Objects->Object-ellipse Node */
1359 /*--------------------------------------------------------------------------*/
1361 xml_create_object_ellipse (xmlNodePtr root,
1363 glLabelObject *object)
1369 glColorNode *line_color_node;
1370 glColorNode *fill_color_node;
1372 gl_debug (DEBUG_XML, "START");
1374 node = xmlNewChild (root, ns, (xmlChar *)"Object-ellipse", NULL);
1376 /* position attrs */
1377 gl_label_object_get_position (object, &x, &y);
1378 lgl_xml_set_prop_length (node, "x", x);
1379 lgl_xml_set_prop_length (node, "y", y);
1382 gl_label_object_get_size (object, &w, &h);
1383 lgl_xml_set_prop_length (node, "w", w);
1384 lgl_xml_set_prop_length (node, "h", h);
1387 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1388 lgl_xml_set_prop_length (node, "line_width", line_width);
1390 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1391 if (line_color_node->field_flag)
1393 lgl_xml_set_prop_string (node, "line_color_field", line_color_node->key);
1397 lgl_xml_set_prop_uint_hex (node, "line_color", line_color_node->color);
1399 gl_color_node_free (&line_color_node);
1402 /* fill attrs (color or field) */
1403 fill_color_node = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
1404 if (fill_color_node->field_flag)
1406 lgl_xml_set_prop_string (node, "fill_color_field", fill_color_node->key);
1410 lgl_xml_set_prop_uint_hex (node, "fill_color", fill_color_node->color);
1412 gl_color_node_free (&fill_color_node);
1415 xml_create_affine_attrs (node, object);
1418 xml_create_shadow_attrs (node, object);
1420 gl_debug (DEBUG_XML, "END");
1424 /*--------------------------------------------------------------------------*/
1425 /* PRIVATE. Add XML Objects->Object-line Node */
1426 /*--------------------------------------------------------------------------*/
1428 xml_create_object_line (xmlNodePtr root,
1430 glLabelObject *object)
1436 glColorNode *line_color_node;
1438 gl_debug (DEBUG_XML, "START");
1440 node = xmlNewChild (root, ns, (xmlChar *)"Object-line", NULL);
1442 /* position attrs */
1443 gl_label_object_get_position (object, &x, &y);
1444 lgl_xml_set_prop_length (node, "x", x);
1445 lgl_xml_set_prop_length (node, "y", y);
1448 gl_label_object_get_size (object, &dx, &dy);
1449 lgl_xml_set_prop_length (node, "dx", dx);
1450 lgl_xml_set_prop_length (node, "dy", dy);
1453 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1454 lgl_xml_set_prop_length (node, "line_width", line_width);
1456 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1457 if (line_color_node->field_flag)
1459 lgl_xml_set_prop_string (node, "line_color_field", line_color_node->key);
1463 lgl_xml_set_prop_uint_hex (node, "line_color", line_color_node->color);
1465 gl_color_node_free (&line_color_node);
1469 xml_create_affine_attrs (node, object);
1472 xml_create_shadow_attrs (node, object);
1474 gl_debug (DEBUG_XML, "END");
1478 /*--------------------------------------------------------------------------*/
1479 /* PRIVATE. Add XML Objects->Object-image Node */
1480 /*--------------------------------------------------------------------------*/
1482 xml_create_object_image (xmlNodePtr root,
1484 glLabelObject *object)
1489 glTextNode *filename;
1491 gl_debug (DEBUG_XML, "START");
1493 node = xmlNewChild (root, ns, (xmlChar *)"Object-image", NULL);
1495 /* position attrs */
1496 gl_label_object_get_position (object, &x, &y);
1497 lgl_xml_set_prop_length (node, "x", x);
1498 lgl_xml_set_prop_length (node, "y", y);
1501 gl_label_object_get_size (object, &w, &h);
1502 lgl_xml_set_prop_length (node, "w", w);
1503 lgl_xml_set_prop_length (node, "h", h);
1505 /* src OR field attr */
1506 filename = gl_label_image_get_filename (GL_LABEL_IMAGE(object));
1507 if (filename->field_flag) {
1508 lgl_xml_set_prop_string (node, "field", filename->data);
1510 lgl_xml_set_prop_string (node, "src", filename->data);
1512 gl_text_node_free (&filename);
1515 xml_create_affine_attrs (node, object);
1518 xml_create_shadow_attrs (node, object);
1520 gl_debug (DEBUG_XML, "END");
1524 /*--------------------------------------------------------------------------*/
1525 /* PRIVATE. Add XML Objects->Object-barcode Node */
1526 /*--------------------------------------------------------------------------*/
1528 xml_create_object_barcode (xmlNodePtr root,
1530 glLabelObject *object)
1535 glTextNode *text_node;
1538 gboolean checksum_flag;
1539 glColorNode *color_node;
1540 guint format_digits;
1542 gl_debug (DEBUG_XML, "START");
1544 node = xmlNewChild (root, ns, (xmlChar *)"Object-barcode", NULL);
1546 /* position attrs */
1547 gl_label_object_get_position (object, &x, &y);
1548 lgl_xml_set_prop_length (node, "x", x);
1549 lgl_xml_set_prop_length (node, "y", y);
1552 gl_label_object_get_raw_size (object, &w, &h);
1553 lgl_xml_set_prop_length (node, "w", w);
1554 lgl_xml_set_prop_length (node, "h", h);
1556 /* Barcode properties attrs */
1557 gl_label_barcode_get_props (GL_LABEL_BARCODE(object),
1558 &id, &text_flag, &checksum_flag, &format_digits);
1559 lgl_xml_set_prop_string (node, "style", id);
1560 lgl_xml_set_prop_boolean (node, "text", text_flag);
1561 lgl_xml_set_prop_boolean (node, "checksum", checksum_flag);
1565 color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1566 if (color_node->field_flag)
1568 lgl_xml_set_prop_string (node, "color_field", color_node->key);
1572 lgl_xml_set_prop_uint_hex (node, "color", color_node->color);
1574 gl_color_node_free (&color_node);
1577 /* data OR field attr */
1578 text_node = gl_label_barcode_get_data (GL_LABEL_BARCODE(object));
1579 if (text_node->field_flag) {
1580 lgl_xml_set_prop_string (node, "field", text_node->data);
1581 lgl_xml_set_prop_int (node, "format", format_digits);
1583 lgl_xml_set_prop_string (node, "data", text_node->data);
1585 gl_text_node_free (&text_node);
1588 xml_create_affine_attrs (node, object);
1591 xml_create_shadow_attrs (node, object);
1593 gl_debug (DEBUG_XML, "END");
1597 /*--------------------------------------------------------------------------*/
1598 /* PRIVATE. Add XML Label Merge Fields Node */
1599 /*--------------------------------------------------------------------------*/
1601 xml_create_merge_fields (xmlNodePtr root,
1609 gl_debug (DEBUG_XML, "START");
1611 merge = gl_label_get_merge (label);
1613 node = xmlNewChild (root, ns, (xmlChar *)"Merge", NULL);
1615 string = gl_merge_get_name (merge);
1616 lgl_xml_set_prop_string (node, "type", string);
1619 string = gl_merge_get_src (merge);
1620 lgl_xml_set_prop_string (node, "src", string);
1623 g_object_unref (G_OBJECT(merge));
1625 gl_debug (DEBUG_XML, "END");
1629 /*--------------------------------------------------------------------------*/
1630 /* PRIVATE. Add XML Label Data Node */
1631 /*--------------------------------------------------------------------------*/
1633 xml_create_data (xmlNodePtr root,
1638 GList *name_list, *p;
1639 GHashTable *pixbuf_cache;
1641 gl_debug (DEBUG_XML, "START");
1643 node = xmlNewChild (root, ns, (xmlChar *)"Data", NULL);
1645 pixbuf_cache = gl_label_get_pixbuf_cache (label);
1646 name_list = gl_pixbuf_cache_get_name_list (pixbuf_cache);
1648 for (p = name_list; p != NULL; p=p->next) {
1649 xml_create_pixdata (node, ns, label, p->data);
1652 gl_pixbuf_cache_free_name_list (name_list);
1655 gl_debug (DEBUG_XML, "END");
1659 /*--------------------------------------------------------------------------*/
1660 /* PRIVATE. Add XML Label Data Pixbuf Node */
1661 /*--------------------------------------------------------------------------*/
1663 xml_create_pixdata (xmlNodePtr root,
1669 GHashTable *pixbuf_cache;
1671 GdkPixdata *pixdata;
1673 guint stream_length;
1676 gl_debug (DEBUG_XML, "START");
1678 pixbuf_cache = gl_label_get_pixbuf_cache (label);
1680 pixbuf = gl_pixbuf_cache_get_pixbuf (pixbuf_cache, name);
1681 if ( pixbuf != NULL ) {
1683 pixdata = g_new0 (GdkPixdata, 1);
1684 gdk_pixdata_from_pixbuf (pixdata, pixbuf, FALSE);
1685 stream = gdk_pixdata_serialize (pixdata, &stream_length);
1686 base64 = g_base64_encode (stream, stream_length);
1688 node = xmlNewChild (root, ns, (xmlChar *)"Pixdata", (xmlChar *)base64);
1689 lgl_xml_set_prop_string (node, "name", name);
1690 lgl_xml_set_prop_string (node, "encoding", "Base64");
1692 gl_pixbuf_cache_remove_pixbuf (pixbuf_cache, name);
1700 gl_debug (DEBUG_XML, "END");
1704 /*--------------------------------------------------------------------------*/
1705 /* PRIVATE. Create top-level Span node. */
1706 /*--------------------------------------------------------------------------*/
1708 xml_create_toplevel_span (xmlNodePtr root,
1710 glLabelText *object_text)
1715 PangoWeight font_weight;
1716 gboolean font_italic_flag;
1717 glColorNode *color_node;
1718 PangoAlignment align;
1719 gdouble text_line_spacing;
1720 GList *lines, *p_line, *p_node;
1721 glTextNode *text_node;
1724 node = xmlNewChild (root, ns, (xmlChar *)"Span", NULL);
1726 /* All span attrs at top level. */
1727 font_family = gl_label_object_get_font_family (GL_LABEL_OBJECT(object_text));
1728 font_size = gl_label_object_get_font_size (GL_LABEL_OBJECT(object_text));
1729 text_line_spacing = gl_label_object_get_text_line_spacing (GL_LABEL_OBJECT(object_text));
1730 font_weight = gl_label_object_get_font_weight (GL_LABEL_OBJECT(object_text));
1731 font_italic_flag = gl_label_object_get_font_italic_flag (GL_LABEL_OBJECT(object_text));
1733 color_node = gl_label_object_get_text_color (GL_LABEL_OBJECT(object_text));
1734 if (color_node->field_flag)
1736 lgl_xml_set_prop_string (node, "color_field", color_node->key);
1740 lgl_xml_set_prop_uint_hex (node, "color", color_node->color);
1742 gl_color_node_free (&color_node);
1744 align = gl_label_object_get_text_alignment (GL_LABEL_OBJECT(object_text));
1745 lgl_xml_set_prop_string (node, "font_family", font_family);
1746 lgl_xml_set_prop_double (node, "font_size", font_size);
1747 lgl_xml_set_prop_string (node, "font_weight", gl_str_util_weight_to_string (font_weight));
1748 lgl_xml_set_prop_boolean (node, "font_italic", font_italic_flag);
1750 lgl_xml_set_prop_double (node, "line_spacing", text_line_spacing);
1752 /* Build children. */
1753 lines = gl_label_text_get_lines (GL_LABEL_TEXT(object_text));
1754 for (p_line = lines; p_line != NULL; p_line = p_line->next) {
1756 for (p_node = (GList *) p_line->data; p_node != NULL;
1757 p_node = p_node->next) {
1758 text_node = (glTextNode *) p_node->data;
1760 if (text_node->field_flag) {
1761 child = xmlNewChild (node, ns, (xmlChar *)"Field", NULL);
1762 lgl_xml_set_prop_string (child, "name", text_node->data);
1764 xmlNodeAddContent (node, (xmlChar *)text_node->data);
1769 if ( p_line->next ) {
1770 child = xmlNewChild (node, ns, (xmlChar *)"NL", NULL);
1775 gl_text_node_lines_free (&lines);
1776 g_free (font_family);
1781 /*--------------------------------------------------------------------------*/
1782 /* PRIVATE. Create affine attributes. */
1783 /*--------------------------------------------------------------------------*/
1785 xml_create_affine_attrs (xmlNodePtr node,
1786 glLabelObject *object)
1788 cairo_matrix_t matrix;
1790 gl_label_object_get_matrix (object, &matrix);
1792 lgl_xml_set_prop_double (node, "a0", matrix.xx);
1793 lgl_xml_set_prop_double (node, "a1", matrix.yx);
1794 lgl_xml_set_prop_double (node, "a2", matrix.xy);
1795 lgl_xml_set_prop_double (node, "a3", matrix.yy);
1796 lgl_xml_set_prop_double (node, "a4", matrix.x0);
1797 lgl_xml_set_prop_double (node, "a5", matrix.y0);
1801 /*--------------------------------------------------------------------------*/
1802 /* PRIVATE. Create shadow attributes. */
1803 /*--------------------------------------------------------------------------*/
1805 xml_create_shadow_attrs (xmlNodePtr node,
1806 glLabelObject *object)
1808 gboolean shadow_state;
1811 glColorNode *shadow_color_node;
1812 gdouble shadow_opacity;
1814 shadow_state = gl_label_object_get_shadow_state (object);
1818 lgl_xml_set_prop_boolean (node, "shadow", shadow_state);
1820 gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
1821 lgl_xml_set_prop_length (node, "shadow_x", shadow_x);
1822 lgl_xml_set_prop_length (node, "shadow_y", shadow_y);
1824 shadow_color_node = gl_label_object_get_shadow_color (object);
1825 if (shadow_color_node->field_flag)
1827 lgl_xml_set_prop_string (node, "shadow_color_field", shadow_color_node->key);
1831 lgl_xml_set_prop_uint_hex (node, "shadow_color", shadow_color_node->color);
1833 gl_color_node_free (&shadow_color_node);
1835 shadow_opacity = gl_label_object_get_shadow_opacity (object);
1836 lgl_xml_set_prop_double (node, "shadow_opacity", shadow_opacity);
1843 * Local Variables: -- emacs
1845 * c-basic-offset: 8 -- emacs
1846 * tab-width: 8 -- emacs
1847 * indent-tabs-mode: nil -- emacs