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/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"
47 /*========================================================*/
48 /* Private macros and constants. */
49 /*========================================================*/
50 #define COMPAT01_NAME_SPACE "http://snaught.com/glabels/0.1/"
51 #define COMPAT04_NAME_SPACE "http://snaught.com/glabels/0.4/"
52 #define COMPAT20_NAME_SPACE "http://snaught.com/glabels/2.0/"
55 /*========================================================*/
57 /*========================================================*/
60 /*========================================================*/
61 /* Private globals. */
62 /*========================================================*/
65 /*========================================================*/
66 /* Private function prototypes. */
67 /*========================================================*/
69 static glLabel *xml_doc_to_label (xmlDocPtr doc,
70 glXMLLabelStatus *status);
72 static glLabel *xml_parse_label (xmlNodePtr root,
73 glXMLLabelStatus *status);
75 static void xml_parse_objects (xmlNodePtr node,
78 static void xml_parse_object_text (xmlNodePtr node,
81 static void xml_parse_object_box (xmlNodePtr node,
84 static void xml_parse_object_ellipse (xmlNodePtr node,
87 static void xml_parse_object_line (xmlNodePtr node,
90 static void xml_parse_object_image (xmlNodePtr node,
93 static void xml_parse_object_barcode (xmlNodePtr node,
96 static void xml_parse_merge_fields (xmlNodePtr node,
99 static void xml_parse_data (xmlNodePtr node,
102 static void xml_parse_pixdata (xmlNodePtr node,
105 static void xml_parse_toplevel_span (xmlNodePtr node,
106 glLabelObject *object);
108 static void xml_parse_affine_attrs (xmlNodePtr node,
109 glLabelObject *object);
111 static void xml_parse_shadow_attrs (xmlNodePtr node,
112 glLabelObject *object);
114 static xmlDocPtr xml_label_to_doc (glLabel *label,
115 glXMLLabelStatus *status);
117 static void xml_create_objects (xmlNodePtr root,
121 static void xml_create_object_text (xmlNodePtr root,
123 glLabelObject *object);
125 static void xml_create_object_box (xmlNodePtr root,
127 glLabelObject *object);
129 static void xml_create_object_line (xmlNodePtr root,
131 glLabelObject *object);
133 static void xml_create_object_ellipse(xmlNodePtr root,
135 glLabelObject *object);
137 static void xml_create_object_image (xmlNodePtr root,
139 glLabelObject *object);
141 static void xml_create_object_barcode(xmlNodePtr root,
143 glLabelObject *object);
145 static void xml_create_merge_fields (xmlNodePtr root,
149 static void xml_create_data (xmlNodePtr root,
153 static void xml_create_pixdata (xmlNodePtr root,
158 static void xml_create_toplevel_span (xmlNodePtr node,
160 glLabelText *object_text);
162 static void xml_create_affine_attrs (xmlNodePtr node,
163 glLabelObject *object);
165 static void xml_create_shadow_attrs (xmlNodePtr node,
166 glLabelObject *object);
169 /****************************************************************************/
170 /* Open and read label from xml file. */
171 /****************************************************************************/
173 gl_xml_label_open (const gchar *utf8_filename,
174 glXMLLabelStatus *status)
180 gl_debug (DEBUG_XML, "START");
182 filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
183 g_return_val_if_fail (filename, NULL);
185 doc = xmlReadFile (filename, NULL, XML_PARSE_HUGE);
187 g_message (_("xmlParseFile error"));
188 *status = XML_LABEL_ERROR_OPEN_PARSE;
192 xmlXIncludeProcess (doc);
193 xmlReconciliateNs (doc, xmlDocGetRootElement (doc));
195 label = xml_doc_to_label (doc, status);
200 gl_label_set_filename (label, utf8_filename);
201 gl_label_clear_modified (label);
205 gl_debug (DEBUG_XML, "END");
211 /****************************************************************************/
212 /* Read label from xml buffer. */
213 /****************************************************************************/
215 gl_xml_label_open_buffer (const gchar *buffer,
216 glXMLLabelStatus *status)
221 gl_debug (DEBUG_XML, "START");
223 doc = xmlReadDoc ((xmlChar *) buffer, NULL, NULL, XML_PARSE_HUGE);
225 g_message (_("xmlParseFile error"));
226 *status = XML_LABEL_ERROR_OPEN_PARSE;
230 label = xml_doc_to_label (doc, status);
235 gl_label_clear_modified (label);
238 gl_debug (DEBUG_XML, "END");
244 /*--------------------------------------------------------------------------*/
245 /* PRIVATE. Parse xml doc structure and create label. */
246 /*--------------------------------------------------------------------------*/
248 xml_doc_to_label (xmlDocPtr doc,
249 glXMLLabelStatus *status)
254 gl_debug (DEBUG_XML, "START");
258 *status = XML_LABEL_OK;
260 root = xmlDocGetRootElement (doc);
261 if (!root || !root->name) {
262 g_message (_("No document root"));
263 *status = XML_LABEL_ERROR_OPEN_PARSE;
267 /* Try compatability mode 0.1 */
268 if (xmlSearchNsByHref (doc, root, (xmlChar *)COMPAT01_NAME_SPACE))
270 g_message (_("Importing from glabels 0.1 format"));
272 label = NULL; /* TODO */
276 /* Try compatability mode 0.4 */
277 if (xmlSearchNsByHref (doc, root, (xmlChar *)COMPAT04_NAME_SPACE))
279 g_message (_("Importing from glabels 0.4 format"));
280 label = gl_xml_label_04_parse (root, status);
284 /* Test for current namespaces. */
285 if ( !xmlSearchNsByHref (doc, root, (xmlChar *)COMPAT20_NAME_SPACE) &&
286 !xmlSearchNsByHref (doc, root, (xmlChar *)LGL_XML_NAME_SPACE) )
288 g_message (_("Unknown glabels Namespace -- Using %s"),
292 label = xml_parse_label (root, status);
295 gl_label_set_compression (label, xmlGetDocCompressMode (doc));
298 gl_debug (DEBUG_XML, "END");
304 /*--------------------------------------------------------------------------*/
305 /* PRIVATE. Parse xml root node and create label. */
306 /*--------------------------------------------------------------------------*/
308 xml_parse_label (xmlNodePtr root,
309 glXMLLabelStatus *status)
311 xmlNodePtr child_node;
313 lglTemplate *template;
315 gl_debug (DEBUG_XML, "START");
317 *status = XML_LABEL_OK;
319 if (!lgl_xml_is_node (root, "Glabels-document")) {
320 g_message (_("Bad root node = \"%s\""), root->name);
321 *status = XML_LABEL_ERROR_OPEN_PARSE;
325 label = GL_LABEL(gl_label_new ());
327 /* Pass 1, extract data nodes to pre-load cache. */
328 for (child_node = root->xmlChildrenNode; child_node != NULL; child_node = child_node->next) {
329 if (lgl_xml_is_node (child_node, "Data")) {
330 xml_parse_data (child_node, label);
334 /* Pass 2, now extract everything else. */
335 for (child_node = root->xmlChildrenNode;
337 child_node = child_node->next) {
339 if (lgl_xml_is_node (child_node, "Template")) {
340 template = lgl_xml_template_parse_template_node (child_node);
342 g_object_unref (label);
343 *status = XML_LABEL_UNKNOWN_MEDIA;
346 lgl_db_register_template (template);
347 gl_label_set_template (label, template);
348 lgl_template_free (template);
349 } else if (lgl_xml_is_node (child_node, "Objects")) {
350 xml_parse_objects (child_node, label);
351 } else if (lgl_xml_is_node (child_node, "Merge")) {
352 xml_parse_merge_fields (child_node, label);
353 } else if (lgl_xml_is_node (child_node, "Data")) {
354 /* Handled in pass 1. */
356 if (!xmlNodeIsText (child_node)) {
357 g_message (_("bad node in Document node = \"%s\""),
359 g_object_unref (label);
360 *status = XML_LABEL_ERROR_OPEN_PARSE;
366 gl_debug (DEBUG_XML, "END");
372 /*--------------------------------------------------------------------------*/
373 /* PRIVATE. Parse Objects node. */
374 /*--------------------------------------------------------------------------*/
376 xml_parse_objects (xmlNodePtr node,
379 gboolean rotate_flag;
382 gl_debug (DEBUG_XML, "START");
384 rotate_flag = lgl_xml_get_prop_boolean (node, "rotate", FALSE);
385 gl_label_set_rotate_flag (label, rotate_flag);
387 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
389 if (lgl_xml_is_node (child, "Object-text")) {
390 xml_parse_object_text (child, label);
391 } else if (lgl_xml_is_node (child, "Object-box")) {
392 xml_parse_object_box (child, label);
393 } else if (lgl_xml_is_node (child, "Object-ellipse")) {
394 xml_parse_object_ellipse (child, label);
395 } else if (lgl_xml_is_node (child, "Object-line")) {
396 xml_parse_object_line (child, label);
397 } else if (lgl_xml_is_node (child, "Object-image")) {
398 xml_parse_object_image (child, label);
399 } else if (lgl_xml_is_node (child, "Object-barcode")) {
400 xml_parse_object_barcode (child, label);
402 if (!xmlNodeIsText (child)) {
403 g_message (_("bad node = \"%s\""), child->name);
409 gl_debug (DEBUG_XML, "END");
413 /*--------------------------------------------------------------------------*/
414 /* PRIVATE. Parse XML Objects->Object-text Node */
415 /*--------------------------------------------------------------------------*/
417 xml_parse_object_text (xmlNodePtr node,
424 PangoAlignment align;
425 gboolean auto_shrink;
428 gl_debug (DEBUG_XML, "START");
430 object = gl_label_text_new (label);
433 x = lgl_xml_get_prop_length (node, "x", 0.0);
434 y = lgl_xml_get_prop_length (node, "y", 0.0);
435 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
437 /* implied size attrs */
438 w = lgl_xml_get_prop_length (node, "w", 0);
439 h = lgl_xml_get_prop_length (node, "h", 0);
440 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
443 string = lgl_xml_get_prop_string (node, "justify", NULL);
444 align = gl_str_util_string_to_align (string);
446 gl_label_object_set_text_alignment (GL_LABEL_OBJECT(object), align);
448 /* auto_shrink attr */
449 auto_shrink = lgl_xml_get_prop_boolean (node, "auto_shrink", FALSE);
450 gl_label_text_set_auto_shrink (GL_LABEL_TEXT(object), auto_shrink);
453 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
456 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
458 /* Process children */
459 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
460 if (lgl_xml_is_node (child, "Span")) {
461 xml_parse_toplevel_span (child, GL_LABEL_OBJECT(object));
464 if (!xmlNodeIsText (child)) {
465 g_message ("Unexpected Object-text child: \"%s\"",
471 gl_debug (DEBUG_XML, "END");
475 /*--------------------------------------------------------------------------*/
476 /* PRIVATE. Parse XML Objects->Object-box Node */
477 /*--------------------------------------------------------------------------*/
479 xml_parse_object_box (xmlNodePtr node,
486 glColorNode *line_color_node;
488 glColorNode *fill_color_node;
490 gl_debug (DEBUG_XML, "START");
492 object = gl_label_box_new (label);
495 x = lgl_xml_get_prop_length (node, "x", 0.0);
496 y = lgl_xml_get_prop_length (node, "y", 0.0);
497 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
500 w = lgl_xml_get_prop_length (node, "w", 0);
501 h = lgl_xml_get_prop_length (node, "h", 0);
502 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
505 line_width = lgl_xml_get_prop_length (node, "line_width", 1.0);
506 gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width);
508 line_color_node = gl_color_node_new_default ();
509 string = lgl_xml_get_prop_string (node, "line_color_field", NULL);
511 line_color_node->field_flag = TRUE;
512 line_color_node->key = string;
514 line_color_node->color = lgl_xml_get_prop_uint (node, "line_color", 0);
516 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color_node);
517 gl_color_node_free (&line_color_node);
521 fill_color_node = gl_color_node_new_default ();
522 string = lgl_xml_get_prop_string (node, "fill_color_field", NULL);
524 fill_color_node->field_flag = TRUE;
525 fill_color_node->key = string;
527 fill_color_node->color = lgl_xml_get_prop_uint (node, "fill_color", 0);
529 gl_label_object_set_fill_color (GL_LABEL_OBJECT(object), fill_color_node);
530 gl_color_node_free (&fill_color_node);
533 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
536 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
538 gl_debug (DEBUG_XML, "END");
542 /*--------------------------------------------------------------------------*/
543 /* PRIVATE. Parse XML Objects->Object-ellipse Node */
544 /*--------------------------------------------------------------------------*/
546 xml_parse_object_ellipse (xmlNodePtr node,
553 glColorNode *line_color_node;
555 glColorNode *fill_color_node;
557 gl_debug (DEBUG_XML, "START");
559 object = gl_label_ellipse_new (label);
562 x = lgl_xml_get_prop_length (node, "x", 0.0);
563 y = lgl_xml_get_prop_length (node, "y", 0.0);
564 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
567 w = lgl_xml_get_prop_length (node, "w", 0);
568 h = lgl_xml_get_prop_length (node, "h", 0);
569 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
572 line_width = lgl_xml_get_prop_length (node, "line_width", 1.0);
573 gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width);
575 line_color_node = gl_color_node_new_default ();
576 string = lgl_xml_get_prop_string (node, "line_color_field", NULL);
578 line_color_node->field_flag = TRUE;
579 line_color_node->key = string;
581 line_color_node->color = lgl_xml_get_prop_uint (node, "line_color", 0);
583 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color_node);
584 gl_color_node_free (&line_color_node);
588 fill_color_node = gl_color_node_new_default ();
589 string = lgl_xml_get_prop_string (node, "fill_color_field", NULL);
591 fill_color_node->field_flag = TRUE;
592 fill_color_node->key = string;
594 fill_color_node->color = lgl_xml_get_prop_uint (node, "fill_color", 0);
596 gl_label_object_set_fill_color (GL_LABEL_OBJECT(object), fill_color_node);
597 gl_color_node_free (&fill_color_node);
600 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
603 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
605 gl_debug (DEBUG_XML, "END");
609 /*--------------------------------------------------------------------------*/
610 /* PRIVATE. Parse XML Objects->Object-line Node */
611 /*--------------------------------------------------------------------------*/
613 xml_parse_object_line (xmlNodePtr node,
620 glColorNode *line_color_node;
623 gl_debug (DEBUG_XML, "START");
625 object = gl_label_line_new (label);
628 x = lgl_xml_get_prop_length (node, "x", 0.0);
629 y = lgl_xml_get_prop_length (node, "y", 0.0);
630 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
633 dx = lgl_xml_get_prop_length (node, "dx", 0);
634 dy = lgl_xml_get_prop_length (node, "dy", 0);
635 gl_label_object_set_size (GL_LABEL_OBJECT(object), dx, dy);
638 line_width = lgl_xml_get_prop_length (node, "line_width", 1.0);
639 gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width);
641 line_color_node = gl_color_node_new_default ();
642 string = lgl_xml_get_prop_string (node, "line_color_field", NULL);
644 line_color_node->field_flag = TRUE;
645 line_color_node->key = string;
647 line_color_node->color = lgl_xml_get_prop_uint (node, "line_color", 0);
649 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color_node);
650 gl_color_node_free (&line_color_node);
653 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
656 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
658 gl_debug (DEBUG_XML, "END");
662 /*--------------------------------------------------------------------------*/
663 /* PRIVATE. Parse XML Objects->Object-image Node */
664 /*--------------------------------------------------------------------------*/
666 xml_parse_object_image (xmlNodePtr node,
673 glTextNode *filename;
675 gl_debug (DEBUG_XML, "START");
677 object = gl_label_image_new (label);
680 x = lgl_xml_get_prop_length (node, "x", 0.0);
681 y = lgl_xml_get_prop_length (node, "y", 0.0);
682 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
684 /* src or field attr */
685 string = lgl_xml_get_prop_string (node, "src", NULL);
687 filename = g_new0 (glTextNode, 1);
688 filename->field_flag = FALSE;
689 filename->data = g_strdup ((gchar *)string);
690 gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename);
691 gl_text_node_free (&filename);
694 string = lgl_xml_get_prop_string (node, "field", NULL);
696 filename = g_new0 (glTextNode, 1);
697 filename->field_flag = TRUE;
698 filename->data = g_strdup ((gchar *)string);
699 gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename);
700 gl_text_node_free (&filename);
703 g_message ("Missing Object-image src or field attr");
708 w = lgl_xml_get_prop_length (node, "w", 0);
709 h = lgl_xml_get_prop_length (node, "h", 0);
710 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
713 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
716 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
718 gl_debug (DEBUG_XML, "END");
722 /*--------------------------------------------------------------------------*/
723 /* PRIVATE. Parse XML Objects->Object-barcode Node */
724 /*--------------------------------------------------------------------------*/
726 xml_parse_object_barcode (xmlNodePtr node,
733 glTextNode *text_node;
736 gboolean checksum_flag;
737 glColorNode *color_node;
740 gl_debug (DEBUG_XML, "START");
742 object = gl_label_barcode_new (label);
745 x = lgl_xml_get_prop_length (node, "x", 0.0);
746 y = lgl_xml_get_prop_length (node, "y", 0.0);
747 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
750 w = lgl_xml_get_prop_length (node, "w", 0);
751 h = lgl_xml_get_prop_length (node, "h", 0);
752 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
755 id = lgl_xml_get_prop_string (node, "style", NULL);
756 text_flag = lgl_xml_get_prop_boolean (node, "text", FALSE);
757 checksum_flag = lgl_xml_get_prop_boolean (node, "checksum", TRUE);
758 format_digits = lgl_xml_get_prop_uint (node, "format", 10);
759 gl_label_barcode_set_props (GL_LABEL_BARCODE(object),
760 (gchar *)id, text_flag, checksum_flag, format_digits);
763 color_node = gl_color_node_new_default ();
764 string = lgl_xml_get_prop_string (node, "color_field", NULL);
766 color_node->field_flag = TRUE;
767 color_node->key = string;
769 color_node->color = lgl_xml_get_prop_uint (node, "color", 0);
771 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), color_node);
772 gl_color_node_free (&color_node);
774 /* data or field attr */
775 string = lgl_xml_get_prop_string (node, "data", NULL);
777 text_node = g_new0 (glTextNode, 1);
778 text_node->field_flag = FALSE;
779 text_node->data = string;
780 gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node);
781 gl_text_node_free (&text_node);
783 string = lgl_xml_get_prop_string (node, "field", NULL);
785 text_node = g_new0 (glTextNode, 1);
786 text_node->field_flag = TRUE;
787 text_node->data = string;
788 gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node);
789 gl_text_node_free (&text_node);
791 g_message ("Missing Object-barcode data or field attr");
796 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
799 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
801 gl_debug (DEBUG_XML, "END");
805 /*--------------------------------------------------------------------------*/
806 /* PRIVATE. Parse XML merge fields tag. */
807 /*--------------------------------------------------------------------------*/
809 xml_parse_merge_fields (xmlNodePtr node,
815 gl_debug (DEBUG_XML, "START");
817 string = lgl_xml_get_prop_string (node, "type", NULL);
818 merge = gl_merge_new (string);
821 string = lgl_xml_get_prop_string (node, "src", NULL);
822 gl_merge_set_src (merge, string);
825 gl_label_set_merge (label, merge);
827 g_object_unref (G_OBJECT(merge));
829 gl_debug (DEBUG_XML, "END");
833 /*--------------------------------------------------------------------------*/
834 /* PRIVATE. Parse XML data tag. */
835 /*--------------------------------------------------------------------------*/
837 xml_parse_data (xmlNodePtr node,
842 gl_debug (DEBUG_XML, "START");
844 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
846 if (lgl_xml_is_node (child, "Pixdata")) {
847 xml_parse_pixdata (child, label);
849 if (!xmlNodeIsText (child)) {
850 g_message (_("bad node in Data node = \"%s\""),
856 gl_debug (DEBUG_XML, "END");
860 /*--------------------------------------------------------------------------*/
861 /* PRIVATE. Parse XML pixbuf data tag. */
862 /*--------------------------------------------------------------------------*/
864 xml_parse_pixdata (xmlNodePtr node,
867 gchar *name, *base64;
873 GHashTable *pixbuf_cache;
875 gl_debug (DEBUG_XML, "START");
877 name = lgl_xml_get_prop_string (node, "name", NULL);
878 base64 = lgl_xml_get_node_content (node);
880 stream = g_base64_decode ((gchar *)base64, &stream_length);
881 pixdata = g_new0 (GdkPixdata, 1);
882 ret = gdk_pixdata_deserialize (pixdata, stream_length, stream, NULL);
885 pixbuf = gdk_pixbuf_from_pixdata (pixdata, TRUE, NULL);
887 pixbuf_cache = gl_label_get_pixbuf_cache (label);
888 gl_pixbuf_cache_add_pixbuf (pixbuf_cache, (gchar *)name, pixbuf);
897 gl_debug (DEBUG_XML, "END");
901 /*--------------------------------------------------------------------------*/
902 /* PRIVATE. Parse top-level Span tag. */
903 /*--------------------------------------------------------------------------*/
905 xml_parse_toplevel_span (xmlNodePtr node,
906 glLabelObject *object)
910 PangoWeight font_weight;
911 gboolean font_italic_flag;
912 glColorNode *color_node;
913 gdouble text_line_spacing;
915 GList *lines, *text_nodes;
917 glTextNode *text_node;
919 gl_debug (DEBUG_XML, "START");
921 /* Font family attr */
922 font_family = lgl_xml_get_prop_string (node, "font_family", "Sans");
923 gl_label_object_set_font_family (object, font_family);
924 g_free (font_family);
927 font_size = lgl_xml_get_prop_double (node, "font_size", 0.0);
928 gl_label_object_set_font_size (object, font_size);
930 /* Font weight attr */
931 string = lgl_xml_get_prop_string (node, "font_weight", NULL);
932 font_weight = gl_str_util_string_to_weight (string);
934 gl_label_object_set_font_weight (object, font_weight);
936 /* Font italic flag attr */
937 font_italic_flag = lgl_xml_get_prop_boolean (node, "font_italic", FALSE);
938 gl_label_object_set_font_italic_flag (object, font_italic_flag);
940 /* Text color attr */
941 color_node = gl_color_node_new_default ();
942 string = lgl_xml_get_prop_string (node, "color_field", NULL);
944 color_node->field_flag = TRUE;
945 color_node->key = string;
947 color_node->color = lgl_xml_get_prop_uint (node, "color", 0);
949 gl_label_object_set_text_color (object, color_node);
950 gl_color_node_free (&color_node);
953 /* Text line spacing attr */
954 text_line_spacing = lgl_xml_get_prop_double (node, "line_spacing", 1.0);
955 gl_label_object_set_text_line_spacing (object, text_line_spacing);
957 /* Now descend children, and build lines of text nodes */
960 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
962 if (xmlNodeIsText (child)) {
963 gchar *data = lgl_xml_get_node_content (child);
965 /* Hack: if the first char is LF, it's an xml formatting string */
966 if (data[0] != '\n') {
968 text_node = g_new0 (glTextNode, 1);
969 text_node->field_flag = FALSE;
970 text_node->data = g_strdup ((gchar *)data);
971 text_nodes = g_list_append (text_nodes, text_node);
975 } else if (lgl_xml_is_node (child, "Span")) {
977 g_message ("Unexpected rich text (not supported, yet!)");
979 } else if (lgl_xml_is_node (child, "Field")) {
982 string = lgl_xml_get_prop_string (child, "name", NULL);
983 text_node = g_new0 (glTextNode, 1);
984 text_node->field_flag = TRUE;
985 text_node->data = string;
986 text_nodes = g_list_append (text_nodes, text_node);
988 } else if (lgl_xml_is_node (child, "NL")) {
991 lines = g_list_append (lines, text_nodes);
995 g_message ("Unexpected Span child: \"%s\"", child->name);
1000 /* Store last line. */
1001 lines = g_list_append (lines, text_nodes);
1004 gl_label_text_set_lines (GL_LABEL_TEXT(object), lines);
1005 gl_text_node_lines_free (&lines);
1007 gl_debug (DEBUG_XML, "END");
1011 /*--------------------------------------------------------------------------*/
1012 /* PRIVATE. Parse affine attributes. */
1013 /*--------------------------------------------------------------------------*/
1015 xml_parse_affine_attrs (xmlNodePtr node,
1016 glLabelObject *object)
1019 cairo_matrix_t matrix;
1021 a[0] = lgl_xml_get_prop_double (node, "a0", 0.0);
1022 a[1] = lgl_xml_get_prop_double (node, "a1", 0.0);
1023 a[2] = lgl_xml_get_prop_double (node, "a2", 0.0);
1024 a[3] = lgl_xml_get_prop_double (node, "a3", 0.0);
1025 a[4] = lgl_xml_get_prop_double (node, "a4", 0.0);
1026 a[5] = lgl_xml_get_prop_double (node, "a5", 0.0);
1028 cairo_matrix_init (&matrix, a[0], a[1], a[2], a[3], a[4], a[5]);
1030 gl_label_object_set_matrix (object, &matrix);
1034 /*--------------------------------------------------------------------------*/
1035 /* PRIVATE. Parse shadow attributes. */
1036 /*--------------------------------------------------------------------------*/
1038 xml_parse_shadow_attrs (xmlNodePtr node,
1039 glLabelObject *object)
1041 gboolean shadow_state;
1044 glColorNode *shadow_color_node;
1045 gdouble shadow_opacity;
1048 shadow_state = lgl_xml_get_prop_boolean (node, "shadow", FALSE);
1049 gl_label_object_set_shadow_state (object, shadow_state);
1053 shadow_x = lgl_xml_get_prop_length (node, "shadow_x", 0.0);
1054 shadow_y = lgl_xml_get_prop_length (node, "shadow_y", 0.0);
1055 gl_label_object_set_shadow_offset (object, shadow_x, shadow_y);
1057 shadow_color_node = gl_color_node_new_default ();
1058 string = lgl_xml_get_prop_string (node, "shadow_color_field", NULL);
1060 shadow_color_node->field_flag = TRUE;
1061 shadow_color_node->key = string;
1063 shadow_color_node->color = lgl_xml_get_prop_uint (node, "shadow_color", 0);
1065 gl_label_object_set_shadow_color (object, shadow_color_node);
1066 gl_color_node_free (&shadow_color_node);
1068 shadow_opacity = lgl_xml_get_prop_double (node, "shadow_opacity", 1.0);
1069 gl_label_object_set_shadow_opacity (object, shadow_opacity);
1074 /****************************************************************************/
1075 /* Save label to xml label file. */
1076 /****************************************************************************/
1078 gl_xml_label_save (glLabel *label,
1079 const gchar *utf8_filename,
1080 glXMLLabelStatus *status)
1086 gl_debug (DEBUG_XML, "START");
1088 doc = xml_label_to_doc (label, status);
1090 filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
1092 g_message (_("Utf8 conversion error."));
1094 xmlSetDocCompressMode (doc, gl_label_get_compression (label));
1095 xml_ret = xmlSaveFormatFile (filename, doc, TRUE);
1097 if (xml_ret == -1) {
1099 g_message (_("Problem saving xml file."));
1100 *status = XML_LABEL_ERROR_SAVE_FILE;
1104 gl_label_set_filename (label, utf8_filename);
1105 gl_label_clear_modified (label);
1111 gl_debug (DEBUG_XML, "END");
1115 /****************************************************************************/
1116 /* Save label to xml buffer. */
1117 /****************************************************************************/
1119 gl_xml_label_save_buffer (glLabel *label,
1120 glXMLLabelStatus *status)
1126 gl_debug (DEBUG_XML, "START");
1128 doc = xml_label_to_doc (label, status);
1130 xmlDocDumpMemory (doc, &buffer, &size);
1133 gl_label_clear_modified (label);
1135 gl_debug (DEBUG_XML, "END");
1137 return (gchar *)buffer;
1141 /*--------------------------------------------------------------------------*/
1142 /* PRIVATE. Convert label to xml doc structure. */
1143 /*--------------------------------------------------------------------------*/
1145 xml_label_to_doc (glLabel *label,
1146 glXMLLabelStatus *status)
1152 gl_debug (DEBUG_XML, "START");
1154 LIBXML_TEST_VERSION;
1156 doc = xmlNewDoc ((xmlChar *)"1.0");
1157 doc->xmlRootNode = xmlNewDocNode (doc, NULL, (xmlChar *)"Glabels-document", NULL);
1159 ns = xmlNewNs (doc->xmlRootNode, (xmlChar *)LGL_XML_NAME_SPACE, NULL);
1160 xmlSetNs (doc->xmlRootNode, ns);
1162 lgl_xml_template_create_template_node (label->template, doc->xmlRootNode, ns);
1164 xml_create_objects (doc->xmlRootNode, ns, label);
1166 merge = gl_label_get_merge (label);
1167 gl_debug (DEBUG_XML, "merge=%p", merge);
1168 if (merge != NULL) {
1169 xml_create_merge_fields (doc->xmlRootNode, ns, label);
1170 g_object_unref (G_OBJECT(merge));
1173 xml_create_data (doc->xmlRootNode, ns, label);
1175 gl_debug (DEBUG_XML, "END");
1177 *status = XML_LABEL_OK;
1182 /*--------------------------------------------------------------------------*/
1183 /* PRIVATE. Add XML Objects Node */
1184 /*--------------------------------------------------------------------------*/
1186 xml_create_objects (xmlNodePtr root,
1192 glLabelObject *object;
1194 gl_debug (DEBUG_XML, "START");
1196 node = xmlNewChild (root, ns, (xmlChar *)"Objects", NULL);
1197 lgl_xml_set_prop_string (node, "id", "0");
1198 lgl_xml_set_prop_boolean (node, "rotate", label->rotate_flag);
1200 for (p = label->objects; p != NULL; p = p->next) {
1202 object = GL_LABEL_OBJECT(p->data);
1204 if ( GL_IS_LABEL_TEXT(object) ) {
1205 xml_create_object_text (node, ns, object);
1206 } else if ( GL_IS_LABEL_BOX(object) ) {
1207 xml_create_object_box (node, ns, object);
1208 } else if ( GL_IS_LABEL_ELLIPSE(object) ) {
1209 xml_create_object_ellipse (node, ns, object);
1210 } else if ( GL_IS_LABEL_LINE(object) ) {
1211 xml_create_object_line (node, ns, object);
1212 } else if ( GL_IS_LABEL_IMAGE(object) ) {
1213 xml_create_object_image (node, ns, object);
1214 } else if ( GL_IS_LABEL_BARCODE(object) ) {
1215 xml_create_object_barcode (node, ns, object);
1217 g_message ("Unknown label object");
1222 gl_debug (DEBUG_XML, "END");
1226 /*--------------------------------------------------------------------------*/
1227 /* PRIVATE. Add XML Objects->Object-text Node */
1228 /*--------------------------------------------------------------------------*/
1230 xml_create_object_text (xmlNodePtr root,
1232 glLabelObject *object)
1237 PangoAlignment align;
1238 gboolean auto_shrink;
1240 gl_debug (DEBUG_XML, "START");
1242 node = xmlNewChild (root, ns, (xmlChar *)"Object-text", NULL);
1244 /* position attrs */
1245 gl_label_object_get_position (object, &x, &y);
1246 lgl_xml_set_prop_length (node, "x", x);
1247 lgl_xml_set_prop_length (node, "y", y);
1250 gl_label_object_get_raw_size ( object, &w, &h);
1251 lgl_xml_set_prop_length (node, "w", w);
1252 lgl_xml_set_prop_length (node, "h", h);
1255 align = gl_label_object_get_text_alignment (object);
1256 lgl_xml_set_prop_string (node, "justify", gl_str_util_align_to_string (align));
1258 /* auto_shrink attr */
1259 auto_shrink = gl_label_text_get_auto_shrink (GL_LABEL_TEXT (object));
1260 lgl_xml_set_prop_boolean (node, "auto_shrink", auto_shrink);
1263 xml_create_affine_attrs (node, object);
1266 xml_create_shadow_attrs (node, object);
1269 xml_create_toplevel_span (node, ns, GL_LABEL_TEXT(object));
1271 gl_debug (DEBUG_XML, "END");
1275 /*--------------------------------------------------------------------------*/
1276 /* PRIVATE. Add XML Objects->Object-box Node */
1277 /*--------------------------------------------------------------------------*/
1279 xml_create_object_box (xmlNodePtr root,
1281 glLabelObject *object)
1287 glColorNode *line_color_node;
1288 glColorNode *fill_color_node;
1290 gl_debug (DEBUG_XML, "START");
1292 node = xmlNewChild (root, ns, (xmlChar *)"Object-box", NULL);
1294 /* position attrs */
1295 gl_label_object_get_position (object, &x, &y);
1296 lgl_xml_set_prop_length (node, "x", x);
1297 lgl_xml_set_prop_length (node, "y", y);
1300 gl_label_object_get_size (object, &w, &h);
1301 lgl_xml_set_prop_length (node, "w", w);
1302 lgl_xml_set_prop_length (node, "h", h);
1305 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1306 lgl_xml_set_prop_length (node, "line_width", line_width);
1308 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1309 if (line_color_node->field_flag)
1311 lgl_xml_set_prop_string (node, "line_color_field", line_color_node->key);
1315 lgl_xml_set_prop_uint_hex (node, "line_color", line_color_node->color);
1317 gl_color_node_free (&line_color_node);
1319 /* fill attrs (color or field) */
1320 fill_color_node = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
1321 if (fill_color_node->field_flag)
1323 lgl_xml_set_prop_string (node, "fill_color_field", fill_color_node->key);
1327 lgl_xml_set_prop_uint_hex (node, "fill_color", fill_color_node->color);
1329 gl_color_node_free (&fill_color_node);
1332 xml_create_affine_attrs (node, object);
1335 xml_create_shadow_attrs (node, object);
1337 gl_debug (DEBUG_XML, "END");
1341 /*--------------------------------------------------------------------------*/
1342 /* PRIVATE. Add XML Objects->Object-ellipse Node */
1343 /*--------------------------------------------------------------------------*/
1345 xml_create_object_ellipse (xmlNodePtr root,
1347 glLabelObject *object)
1353 glColorNode *line_color_node;
1354 glColorNode *fill_color_node;
1356 gl_debug (DEBUG_XML, "START");
1358 node = xmlNewChild (root, ns, (xmlChar *)"Object-ellipse", NULL);
1360 /* position attrs */
1361 gl_label_object_get_position (object, &x, &y);
1362 lgl_xml_set_prop_length (node, "x", x);
1363 lgl_xml_set_prop_length (node, "y", y);
1366 gl_label_object_get_size (object, &w, &h);
1367 lgl_xml_set_prop_length (node, "w", w);
1368 lgl_xml_set_prop_length (node, "h", h);
1371 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1372 lgl_xml_set_prop_length (node, "line_width", line_width);
1374 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1375 if (line_color_node->field_flag)
1377 lgl_xml_set_prop_string (node, "line_color_field", line_color_node->key);
1381 lgl_xml_set_prop_uint_hex (node, "line_color", line_color_node->color);
1383 gl_color_node_free (&line_color_node);
1386 /* fill attrs (color or field) */
1387 fill_color_node = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
1388 if (fill_color_node->field_flag)
1390 lgl_xml_set_prop_string (node, "fill_color_field", fill_color_node->key);
1394 lgl_xml_set_prop_uint_hex (node, "fill_color", fill_color_node->color);
1396 gl_color_node_free (&fill_color_node);
1399 xml_create_affine_attrs (node, object);
1402 xml_create_shadow_attrs (node, object);
1404 gl_debug (DEBUG_XML, "END");
1408 /*--------------------------------------------------------------------------*/
1409 /* PRIVATE. Add XML Objects->Object-line Node */
1410 /*--------------------------------------------------------------------------*/
1412 xml_create_object_line (xmlNodePtr root,
1414 glLabelObject *object)
1420 glColorNode *line_color_node;
1422 gl_debug (DEBUG_XML, "START");
1424 node = xmlNewChild (root, ns, (xmlChar *)"Object-line", NULL);
1426 /* position attrs */
1427 gl_label_object_get_position (object, &x, &y);
1428 lgl_xml_set_prop_length (node, "x", x);
1429 lgl_xml_set_prop_length (node, "y", y);
1432 gl_label_object_get_size (object, &dx, &dy);
1433 lgl_xml_set_prop_length (node, "dx", dx);
1434 lgl_xml_set_prop_length (node, "dy", dy);
1437 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1438 lgl_xml_set_prop_length (node, "line_width", line_width);
1440 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1441 if (line_color_node->field_flag)
1443 lgl_xml_set_prop_string (node, "line_color_field", line_color_node->key);
1447 lgl_xml_set_prop_uint_hex (node, "line_color", line_color_node->color);
1449 gl_color_node_free (&line_color_node);
1453 xml_create_affine_attrs (node, object);
1456 xml_create_shadow_attrs (node, object);
1458 gl_debug (DEBUG_XML, "END");
1462 /*--------------------------------------------------------------------------*/
1463 /* PRIVATE. Add XML Objects->Object-image Node */
1464 /*--------------------------------------------------------------------------*/
1466 xml_create_object_image (xmlNodePtr root,
1468 glLabelObject *object)
1473 glTextNode *filename;
1475 gl_debug (DEBUG_XML, "START");
1477 node = xmlNewChild (root, ns, (xmlChar *)"Object-image", NULL);
1479 /* position attrs */
1480 gl_label_object_get_position (object, &x, &y);
1481 lgl_xml_set_prop_length (node, "x", x);
1482 lgl_xml_set_prop_length (node, "y", y);
1485 gl_label_object_get_size (object, &w, &h);
1486 lgl_xml_set_prop_length (node, "w", w);
1487 lgl_xml_set_prop_length (node, "h", h);
1489 /* src OR field attr */
1490 filename = gl_label_image_get_filename (GL_LABEL_IMAGE(object));
1491 if (filename->field_flag) {
1492 lgl_xml_set_prop_string (node, "field", filename->data);
1494 lgl_xml_set_prop_string (node, "src", filename->data);
1496 gl_text_node_free (&filename);
1499 xml_create_affine_attrs (node, object);
1502 xml_create_shadow_attrs (node, object);
1504 gl_debug (DEBUG_XML, "END");
1508 /*--------------------------------------------------------------------------*/
1509 /* PRIVATE. Add XML Objects->Object-barcode Node */
1510 /*--------------------------------------------------------------------------*/
1512 xml_create_object_barcode (xmlNodePtr root,
1514 glLabelObject *object)
1519 glTextNode *text_node;
1522 gboolean checksum_flag;
1523 glColorNode *color_node;
1524 guint format_digits;
1526 gl_debug (DEBUG_XML, "START");
1528 node = xmlNewChild (root, ns, (xmlChar *)"Object-barcode", NULL);
1530 /* position attrs */
1531 gl_label_object_get_position (object, &x, &y);
1532 lgl_xml_set_prop_length (node, "x", x);
1533 lgl_xml_set_prop_length (node, "y", y);
1536 gl_label_object_get_raw_size (object, &w, &h);
1537 lgl_xml_set_prop_length (node, "w", w);
1538 lgl_xml_set_prop_length (node, "h", h);
1540 /* Barcode properties attrs */
1541 gl_label_barcode_get_props (GL_LABEL_BARCODE(object),
1542 &id, &text_flag, &checksum_flag, &format_digits);
1543 lgl_xml_set_prop_string (node, "style", id);
1544 lgl_xml_set_prop_boolean (node, "text", text_flag);
1545 lgl_xml_set_prop_boolean (node, "checksum", checksum_flag);
1549 color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1550 if (color_node->field_flag)
1552 lgl_xml_set_prop_string (node, "color_field", color_node->key);
1556 lgl_xml_set_prop_uint_hex (node, "color", color_node->color);
1558 gl_color_node_free (&color_node);
1561 /* data OR field attr */
1562 text_node = gl_label_barcode_get_data (GL_LABEL_BARCODE(object));
1563 if (text_node->field_flag) {
1564 lgl_xml_set_prop_string (node, "field", text_node->data);
1565 lgl_xml_set_prop_int (node, "format", format_digits);
1567 lgl_xml_set_prop_string (node, "data", text_node->data);
1569 gl_text_node_free (&text_node);
1572 xml_create_affine_attrs (node, object);
1575 xml_create_shadow_attrs (node, object);
1577 gl_debug (DEBUG_XML, "END");
1581 /*--------------------------------------------------------------------------*/
1582 /* PRIVATE. Add XML Label Merge Fields Node */
1583 /*--------------------------------------------------------------------------*/
1585 xml_create_merge_fields (xmlNodePtr root,
1593 gl_debug (DEBUG_XML, "START");
1595 merge = gl_label_get_merge (label);
1597 node = xmlNewChild (root, ns, (xmlChar *)"Merge", NULL);
1599 string = gl_merge_get_name (merge);
1600 lgl_xml_set_prop_string (node, "type", string);
1603 string = gl_merge_get_src (merge);
1604 lgl_xml_set_prop_string (node, "src", string);
1607 g_object_unref (G_OBJECT(merge));
1609 gl_debug (DEBUG_XML, "END");
1613 /*--------------------------------------------------------------------------*/
1614 /* PRIVATE. Add XML Label Data Node */
1615 /*--------------------------------------------------------------------------*/
1617 xml_create_data (xmlNodePtr root,
1622 GList *name_list, *p;
1623 GHashTable *pixbuf_cache;
1625 gl_debug (DEBUG_XML, "START");
1627 node = xmlNewChild (root, ns, (xmlChar *)"Data", NULL);
1629 pixbuf_cache = gl_label_get_pixbuf_cache (label);
1630 name_list = gl_pixbuf_cache_get_name_list (pixbuf_cache);
1632 for (p = name_list; p != NULL; p=p->next) {
1633 xml_create_pixdata (node, ns, label, p->data);
1636 gl_pixbuf_cache_free_name_list (name_list);
1639 gl_debug (DEBUG_XML, "END");
1643 /*--------------------------------------------------------------------------*/
1644 /* PRIVATE. Add XML Label Data Pixbuf Node */
1645 /*--------------------------------------------------------------------------*/
1647 xml_create_pixdata (xmlNodePtr root,
1653 GHashTable *pixbuf_cache;
1655 GdkPixdata *pixdata;
1657 guint stream_length;
1660 gl_debug (DEBUG_XML, "START");
1662 pixbuf_cache = gl_label_get_pixbuf_cache (label);
1664 pixbuf = gl_pixbuf_cache_get_pixbuf (pixbuf_cache, name);
1665 if ( pixbuf != NULL ) {
1667 pixdata = g_new0 (GdkPixdata, 1);
1668 gdk_pixdata_from_pixbuf (pixdata, pixbuf, FALSE);
1669 stream = gdk_pixdata_serialize (pixdata, &stream_length);
1670 base64 = g_base64_encode (stream, stream_length);
1672 node = xmlNewChild (root, ns, (xmlChar *)"Pixdata", (xmlChar *)base64);
1673 lgl_xml_set_prop_string (node, "name", name);
1674 lgl_xml_set_prop_string (node, "encoding", "Base64");
1676 gl_pixbuf_cache_remove_pixbuf (pixbuf_cache, name);
1684 gl_debug (DEBUG_XML, "END");
1688 /*--------------------------------------------------------------------------*/
1689 /* PRIVATE. Create top-level Span node. */
1690 /*--------------------------------------------------------------------------*/
1692 xml_create_toplevel_span (xmlNodePtr root,
1694 glLabelText *object_text)
1699 PangoWeight font_weight;
1700 gboolean font_italic_flag;
1701 glColorNode *color_node;
1702 PangoAlignment align;
1703 gdouble text_line_spacing;
1704 GList *lines, *p_line, *p_node;
1705 glTextNode *text_node;
1708 node = xmlNewChild (root, ns, (xmlChar *)"Span", NULL);
1710 /* All span attrs at top level. */
1711 font_family = gl_label_object_get_font_family (GL_LABEL_OBJECT(object_text));
1712 font_size = gl_label_object_get_font_size (GL_LABEL_OBJECT(object_text));
1713 text_line_spacing = gl_label_object_get_text_line_spacing (GL_LABEL_OBJECT(object_text));
1714 font_weight = gl_label_object_get_font_weight (GL_LABEL_OBJECT(object_text));
1715 font_italic_flag = gl_label_object_get_font_italic_flag (GL_LABEL_OBJECT(object_text));
1717 color_node = gl_label_object_get_text_color (GL_LABEL_OBJECT(object_text));
1718 if (color_node->field_flag)
1720 lgl_xml_set_prop_string (node, "color_field", color_node->key);
1724 lgl_xml_set_prop_uint_hex (node, "color", color_node->color);
1726 gl_color_node_free (&color_node);
1728 align = gl_label_object_get_text_alignment (GL_LABEL_OBJECT(object_text));
1729 lgl_xml_set_prop_string (node, "font_family", font_family);
1730 lgl_xml_set_prop_double (node, "font_size", font_size);
1731 lgl_xml_set_prop_string (node, "font_weight", gl_str_util_weight_to_string (font_weight));
1732 lgl_xml_set_prop_boolean (node, "font_italic", font_italic_flag);
1734 lgl_xml_set_prop_double (node, "line_spacing", text_line_spacing);
1736 /* Build children. */
1737 lines = gl_label_text_get_lines (GL_LABEL_TEXT(object_text));
1738 for (p_line = lines; p_line != NULL; p_line = p_line->next) {
1740 for (p_node = (GList *) p_line->data; p_node != NULL;
1741 p_node = p_node->next) {
1742 text_node = (glTextNode *) p_node->data;
1744 if (text_node->field_flag) {
1745 child = xmlNewChild (node, ns, (xmlChar *)"Field", NULL);
1746 lgl_xml_set_prop_string (child, "name", text_node->data);
1748 xmlNodeAddContent (node, (xmlChar *)text_node->data);
1753 if ( p_line->next ) {
1754 child = xmlNewChild (node, ns, (xmlChar *)"NL", NULL);
1759 gl_text_node_lines_free (&lines);
1760 g_free (font_family);
1765 /*--------------------------------------------------------------------------*/
1766 /* PRIVATE. Create affine attributes. */
1767 /*--------------------------------------------------------------------------*/
1769 xml_create_affine_attrs (xmlNodePtr node,
1770 glLabelObject *object)
1772 cairo_matrix_t matrix;
1774 gl_label_object_get_matrix (object, &matrix);
1776 lgl_xml_set_prop_double (node, "a0", matrix.xx);
1777 lgl_xml_set_prop_double (node, "a1", matrix.yx);
1778 lgl_xml_set_prop_double (node, "a2", matrix.xy);
1779 lgl_xml_set_prop_double (node, "a3", matrix.yy);
1780 lgl_xml_set_prop_double (node, "a4", matrix.x0);
1781 lgl_xml_set_prop_double (node, "a5", matrix.y0);
1785 /*--------------------------------------------------------------------------*/
1786 /* PRIVATE. Create shadow attributes. */
1787 /*--------------------------------------------------------------------------*/
1789 xml_create_shadow_attrs (xmlNodePtr node,
1790 glLabelObject *object)
1792 gboolean shadow_state;
1795 glColorNode *shadow_color_node;
1796 gdouble shadow_opacity;
1798 shadow_state = gl_label_object_get_shadow_state (object);
1802 lgl_xml_set_prop_boolean (node, "shadow", shadow_state);
1804 gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
1805 lgl_xml_set_prop_length (node, "shadow_x", shadow_x);
1806 lgl_xml_set_prop_length (node, "shadow_y", shadow_y);
1808 shadow_color_node = gl_label_object_get_shadow_color (object);
1809 if (shadow_color_node->field_flag)
1811 lgl_xml_set_prop_string (node, "shadow_color_field", shadow_color_node->key);
1815 lgl_xml_set_prop_uint_hex (node, "shadow_color", shadow_color_node->color);
1817 gl_color_node_free (&shadow_color_node);
1819 shadow_opacity = gl_label_object_get_shadow_opacity (object);
1820 lgl_xml_set_prop_double (node, "shadow_opacity", shadow_opacity);
1827 * Local Variables: -- emacs
1829 * c-basic-offset: 8 -- emacs
1830 * tab-width: 8 -- emacs
1831 * indent-tabs-mode: nil -- emacs