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_file_node (xmlNodePtr node,
110 static void xml_parse_toplevel_span (xmlNodePtr node,
111 glLabelObject *object);
113 static void xml_parse_affine_attrs (xmlNodePtr node,
114 glLabelObject *object);
116 static void xml_parse_shadow_attrs (xmlNodePtr node,
117 glLabelObject *object);
119 static xmlDocPtr xml_label_to_doc (glLabel *label,
120 glXMLLabelStatus *status);
122 static void xml_create_objects (xmlNodePtr parent,
126 static void xml_create_object_text (xmlNodePtr parent,
128 glLabelObject *object);
130 static void xml_create_object_box (xmlNodePtr parent,
132 glLabelObject *object);
134 static void xml_create_object_line (xmlNodePtr parent,
136 glLabelObject *object);
138 static void xml_create_object_ellipse(xmlNodePtr parent,
140 glLabelObject *object);
142 static void xml_create_object_image (xmlNodePtr parent,
144 glLabelObject *object);
146 static void xml_create_object_barcode(xmlNodePtr parent,
148 glLabelObject *object);
150 static void xml_create_merge_fields (xmlNodePtr parent,
154 static void xml_create_data (xmlDocPtr doc,
159 static void xml_create_pixdata (xmlNodePtr parent,
164 static void xml_create_file_svg (xmlDocPtr doc,
170 static void xml_create_toplevel_span (xmlNodePtr node,
172 glLabelText *object_text);
174 static void xml_create_affine_attrs (xmlNodePtr node,
175 glLabelObject *object);
177 static void xml_create_shadow_attrs (xmlNodePtr node,
178 glLabelObject *object);
181 /****************************************************************************/
182 /* Open and read label from xml file. */
183 /****************************************************************************/
185 gl_xml_label_open (const gchar *utf8_filename,
186 glXMLLabelStatus *status)
192 gl_debug (DEBUG_XML, "START");
194 filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
195 g_return_val_if_fail (filename, NULL);
197 doc = xmlReadFile (filename, NULL, XML_PARSE_HUGE);
199 g_message (_("xmlParseFile error"));
200 *status = XML_LABEL_ERROR_OPEN_PARSE;
204 xmlXIncludeProcess (doc);
205 xmlReconciliateNs (doc, xmlDocGetRootElement (doc));
207 label = xml_doc_to_label (doc, status);
212 gl_label_set_filename (label, utf8_filename);
213 gl_label_clear_modified (label);
217 gl_debug (DEBUG_XML, "END");
223 /****************************************************************************/
224 /* Read label from xml buffer. */
225 /****************************************************************************/
227 gl_xml_label_open_buffer (const gchar *buffer,
228 glXMLLabelStatus *status)
233 gl_debug (DEBUG_XML, "START");
235 doc = xmlReadDoc ((xmlChar *) buffer, NULL, NULL, XML_PARSE_HUGE);
237 g_message (_("xmlParseFile error"));
238 *status = XML_LABEL_ERROR_OPEN_PARSE;
242 label = xml_doc_to_label (doc, status);
247 gl_label_clear_modified (label);
250 gl_debug (DEBUG_XML, "END");
256 /*--------------------------------------------------------------------------*/
257 /* PRIVATE. Parse xml doc structure and create label. */
258 /*--------------------------------------------------------------------------*/
260 xml_doc_to_label (xmlDocPtr doc,
261 glXMLLabelStatus *status)
266 gl_debug (DEBUG_XML, "START");
270 *status = XML_LABEL_OK;
272 root = xmlDocGetRootElement (doc);
273 if (!root || !root->name) {
274 g_message (_("No document root"));
275 *status = XML_LABEL_ERROR_OPEN_PARSE;
279 /* Try compatability mode 0.1 */
280 if (xmlSearchNsByHref (doc, root, (xmlChar *)COMPAT01_NAME_SPACE))
282 g_message (_("Importing from glabels 0.1 format"));
284 label = NULL; /* TODO */
288 /* Try compatability mode 0.4 */
289 if (xmlSearchNsByHref (doc, root, (xmlChar *)COMPAT04_NAME_SPACE))
291 g_message (_("Importing from glabels 0.4 format"));
292 label = gl_xml_label_04_parse (root, status);
296 /* Test for current namespaces. */
297 if ( !xmlSearchNsByHref (doc, root, (xmlChar *)COMPAT20_NAME_SPACE) &&
298 !xmlSearchNsByHref (doc, root, (xmlChar *)COMPAT22_NAME_SPACE) &&
299 !xmlSearchNsByHref (doc, root, (xmlChar *)LGL_XML_NAME_SPACE) )
301 g_message (_("Unknown glabels Namespace -- Using %s"),
305 label = xml_parse_label (root, status);
308 gl_label_set_compression (label, xmlGetDocCompressMode (doc));
311 gl_debug (DEBUG_XML, "END");
317 /*--------------------------------------------------------------------------*/
318 /* PRIVATE. Parse xml root node and create label. */
319 /*--------------------------------------------------------------------------*/
321 xml_parse_label (xmlNodePtr root,
322 glXMLLabelStatus *status)
324 xmlNodePtr child_node;
326 lglTemplate *template;
328 gl_debug (DEBUG_XML, "START");
330 *status = XML_LABEL_OK;
332 if (!lgl_xml_is_node (root, "Glabels-document")) {
333 g_message (_("Bad root node = \"%s\""), root->name);
334 *status = XML_LABEL_ERROR_OPEN_PARSE;
338 label = GL_LABEL(gl_label_new ());
340 /* Pass 1, extract data nodes to pre-load cache. */
341 for (child_node = root->xmlChildrenNode; child_node != NULL; child_node = child_node->next) {
342 if (lgl_xml_is_node (child_node, "Data")) {
343 xml_parse_data (child_node, label);
347 /* Pass 2, now extract everything else. */
348 for (child_node = root->xmlChildrenNode;
350 child_node = child_node->next) {
352 if (lgl_xml_is_node (child_node, "Template")) {
353 template = lgl_xml_template_parse_template_node (child_node);
355 g_object_unref (label);
356 *status = XML_LABEL_UNKNOWN_MEDIA;
359 lgl_db_register_template (template);
360 gl_label_set_template (label, template, FALSE);
361 lgl_template_free (template);
362 } else if (lgl_xml_is_node (child_node, "Objects")) {
363 xml_parse_objects (child_node, label);
364 } else if (lgl_xml_is_node (child_node, "Merge")) {
365 xml_parse_merge_fields (child_node, label);
366 } else if (lgl_xml_is_node (child_node, "Data")) {
367 /* Handled in pass 1. */
369 if (!xmlNodeIsText (child_node)) {
370 g_message (_("bad node in Document node = \"%s\""),
372 g_object_unref (label);
373 *status = XML_LABEL_ERROR_OPEN_PARSE;
379 gl_debug (DEBUG_XML, "END");
385 /*--------------------------------------------------------------------------*/
386 /* PRIVATE. Parse Objects node. */
387 /*--------------------------------------------------------------------------*/
389 xml_parse_objects (xmlNodePtr node,
392 gboolean rotate_flag;
395 gl_debug (DEBUG_XML, "START");
397 rotate_flag = lgl_xml_get_prop_boolean (node, "rotate", FALSE);
398 gl_label_set_rotate_flag (label, rotate_flag, FALSE);
400 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
402 if (lgl_xml_is_node (child, "Object-text")) {
403 xml_parse_object_text (child, label);
404 } else if (lgl_xml_is_node (child, "Object-box")) {
405 xml_parse_object_box (child, label);
406 } else if (lgl_xml_is_node (child, "Object-ellipse")) {
407 xml_parse_object_ellipse (child, label);
408 } else if (lgl_xml_is_node (child, "Object-line")) {
409 xml_parse_object_line (child, label);
410 } else if (lgl_xml_is_node (child, "Object-image")) {
411 xml_parse_object_image (child, label);
412 } else if (lgl_xml_is_node (child, "Object-barcode")) {
413 xml_parse_object_barcode (child, label);
415 if (!xmlNodeIsText (child)) {
416 g_message (_("bad node = \"%s\""), child->name);
422 gl_debug (DEBUG_XML, "END");
426 /*--------------------------------------------------------------------------*/
427 /* PRIVATE. Parse XML Objects->Object-text Node */
428 /*--------------------------------------------------------------------------*/
430 xml_parse_object_text (xmlNodePtr node,
437 PangoAlignment align;
438 gboolean auto_shrink;
441 gl_debug (DEBUG_XML, "START");
443 object = gl_label_text_new (label, FALSE);
446 x = lgl_xml_get_prop_length (node, "x", 0.0);
447 y = lgl_xml_get_prop_length (node, "y", 0.0);
448 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y, FALSE);
450 /* implied size attrs */
451 w = lgl_xml_get_prop_length (node, "w", 0);
452 h = lgl_xml_get_prop_length (node, "h", 0);
453 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h, FALSE);
456 string = lgl_xml_get_prop_string (node, "justify", NULL);
457 align = gl_str_util_string_to_align (string);
459 gl_label_object_set_text_alignment (GL_LABEL_OBJECT(object), align, FALSE);
461 /* auto_shrink attr */
462 auto_shrink = lgl_xml_get_prop_boolean (node, "auto_shrink", FALSE);
463 gl_label_text_set_auto_shrink (GL_LABEL_TEXT(object), auto_shrink, FALSE);
466 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
469 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
471 /* Process children */
472 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
473 if (lgl_xml_is_node (child, "Span")) {
474 xml_parse_toplevel_span (child, GL_LABEL_OBJECT(object));
477 if (!xmlNodeIsText (child)) {
478 g_message ("Unexpected Object-text child: \"%s\"",
484 gl_debug (DEBUG_XML, "END");
488 /*--------------------------------------------------------------------------*/
489 /* PRIVATE. Parse XML Objects->Object-box Node */
490 /*--------------------------------------------------------------------------*/
492 xml_parse_object_box (xmlNodePtr node,
499 glColorNode *line_color_node;
501 glColorNode *fill_color_node;
503 gl_debug (DEBUG_XML, "START");
505 object = gl_label_box_new (label, FALSE);
508 x = lgl_xml_get_prop_length (node, "x", 0.0);
509 y = lgl_xml_get_prop_length (node, "y", 0.0);
510 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y, FALSE);
513 w = lgl_xml_get_prop_length (node, "w", 0);
514 h = lgl_xml_get_prop_length (node, "h", 0);
515 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h, FALSE);
518 line_width = lgl_xml_get_prop_length (node, "line_width", 1.0);
519 gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width, FALSE);
521 line_color_node = gl_color_node_new_default ();
522 string = lgl_xml_get_prop_string (node, "line_color_field", NULL);
524 line_color_node->field_flag = TRUE;
525 line_color_node->key = string;
527 line_color_node->color = lgl_xml_get_prop_uint (node, "line_color", 0);
529 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color_node, FALSE);
530 gl_color_node_free (&line_color_node);
534 fill_color_node = gl_color_node_new_default ();
535 string = lgl_xml_get_prop_string (node, "fill_color_field", NULL);
537 fill_color_node->field_flag = TRUE;
538 fill_color_node->key = string;
540 fill_color_node->color = lgl_xml_get_prop_uint (node, "fill_color", 0);
542 gl_label_object_set_fill_color (GL_LABEL_OBJECT(object), fill_color_node, FALSE);
543 gl_color_node_free (&fill_color_node);
546 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
549 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
551 gl_debug (DEBUG_XML, "END");
555 /*--------------------------------------------------------------------------*/
556 /* PRIVATE. Parse XML Objects->Object-ellipse Node */
557 /*--------------------------------------------------------------------------*/
559 xml_parse_object_ellipse (xmlNodePtr node,
566 glColorNode *line_color_node;
568 glColorNode *fill_color_node;
570 gl_debug (DEBUG_XML, "START");
572 object = gl_label_ellipse_new (label, FALSE);
575 x = lgl_xml_get_prop_length (node, "x", 0.0);
576 y = lgl_xml_get_prop_length (node, "y", 0.0);
577 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y, FALSE);
580 w = lgl_xml_get_prop_length (node, "w", 0);
581 h = lgl_xml_get_prop_length (node, "h", 0);
582 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h, FALSE);
585 line_width = lgl_xml_get_prop_length (node, "line_width", 1.0);
586 gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width, FALSE);
588 line_color_node = gl_color_node_new_default ();
589 string = lgl_xml_get_prop_string (node, "line_color_field", NULL);
591 line_color_node->field_flag = TRUE;
592 line_color_node->key = string;
594 line_color_node->color = lgl_xml_get_prop_uint (node, "line_color", 0);
596 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color_node, FALSE);
597 gl_color_node_free (&line_color_node);
601 fill_color_node = gl_color_node_new_default ();
602 string = lgl_xml_get_prop_string (node, "fill_color_field", NULL);
604 fill_color_node->field_flag = TRUE;
605 fill_color_node->key = string;
607 fill_color_node->color = lgl_xml_get_prop_uint (node, "fill_color", 0);
609 gl_label_object_set_fill_color (GL_LABEL_OBJECT(object), fill_color_node, FALSE);
610 gl_color_node_free (&fill_color_node);
613 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
616 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
618 gl_debug (DEBUG_XML, "END");
622 /*--------------------------------------------------------------------------*/
623 /* PRIVATE. Parse XML Objects->Object-line Node */
624 /*--------------------------------------------------------------------------*/
626 xml_parse_object_line (xmlNodePtr node,
633 glColorNode *line_color_node;
636 gl_debug (DEBUG_XML, "START");
638 object = gl_label_line_new (label, FALSE);
641 x = lgl_xml_get_prop_length (node, "x", 0.0);
642 y = lgl_xml_get_prop_length (node, "y", 0.0);
643 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y, FALSE);
646 dx = lgl_xml_get_prop_length (node, "dx", 0);
647 dy = lgl_xml_get_prop_length (node, "dy", 0);
648 gl_label_object_set_size (GL_LABEL_OBJECT(object), dx, dy, FALSE);
651 line_width = lgl_xml_get_prop_length (node, "line_width", 1.0);
652 gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width, FALSE);
654 line_color_node = gl_color_node_new_default ();
655 string = lgl_xml_get_prop_string (node, "line_color_field", NULL);
657 line_color_node->field_flag = TRUE;
658 line_color_node->key = string;
660 line_color_node->color = lgl_xml_get_prop_uint (node, "line_color", 0);
662 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color_node, FALSE);
663 gl_color_node_free (&line_color_node);
666 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
669 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
671 gl_debug (DEBUG_XML, "END");
675 /*--------------------------------------------------------------------------*/
676 /* PRIVATE. Parse XML Objects->Object-image Node */
677 /*--------------------------------------------------------------------------*/
679 xml_parse_object_image (xmlNodePtr node,
686 glTextNode *filename;
688 gl_debug (DEBUG_XML, "START");
690 object = gl_label_image_new (label, FALSE);
693 x = lgl_xml_get_prop_length (node, "x", 0.0);
694 y = lgl_xml_get_prop_length (node, "y", 0.0);
695 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y, FALSE);
697 /* src or field attr */
698 string = lgl_xml_get_prop_string (node, "src", NULL);
700 filename = g_new0 (glTextNode, 1);
701 filename->field_flag = FALSE;
702 filename->data = g_strdup ((gchar *)string);
703 gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename, FALSE);
704 gl_text_node_free (&filename);
707 string = lgl_xml_get_prop_string (node, "field", NULL);
709 filename = g_new0 (glTextNode, 1);
710 filename->field_flag = TRUE;
711 filename->data = g_strdup ((gchar *)string);
712 gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename, FALSE);
713 gl_text_node_free (&filename);
716 g_message ("Missing Object-image src or field attr");
721 w = lgl_xml_get_prop_length (node, "w", 0);
722 h = lgl_xml_get_prop_length (node, "h", 0);
723 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h, FALSE);
726 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
729 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
731 gl_debug (DEBUG_XML, "END");
735 /*--------------------------------------------------------------------------*/
736 /* PRIVATE. Parse XML Objects->Object-barcode Node */
737 /*--------------------------------------------------------------------------*/
739 xml_parse_object_barcode (xmlNodePtr node,
746 glTextNode *text_node;
749 gboolean checksum_flag;
750 glColorNode *color_node;
753 gl_debug (DEBUG_XML, "START");
755 object = gl_label_barcode_new (label, FALSE);
758 x = lgl_xml_get_prop_length (node, "x", 0.0);
759 y = lgl_xml_get_prop_length (node, "y", 0.0);
760 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y, FALSE);
763 w = lgl_xml_get_prop_length (node, "w", 0);
764 h = lgl_xml_get_prop_length (node, "h", 0);
765 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h, FALSE);
768 id = lgl_xml_get_prop_string (node, "style", NULL);
769 text_flag = lgl_xml_get_prop_boolean (node, "text", FALSE);
770 checksum_flag = lgl_xml_get_prop_boolean (node, "checksum", TRUE);
771 format_digits = lgl_xml_get_prop_uint (node, "format", 10);
772 gl_label_barcode_set_props (GL_LABEL_BARCODE(object),
773 (gchar *)id, text_flag, checksum_flag, format_digits, FALSE);
776 color_node = gl_color_node_new_default ();
777 string = lgl_xml_get_prop_string (node, "color_field", NULL);
779 color_node->field_flag = TRUE;
780 color_node->key = string;
782 color_node->color = lgl_xml_get_prop_uint (node, "color", 0);
784 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), color_node, FALSE);
785 gl_color_node_free (&color_node);
787 /* data or field attr */
788 string = lgl_xml_get_prop_string (node, "data", NULL);
790 text_node = g_new0 (glTextNode, 1);
791 text_node->field_flag = FALSE;
792 text_node->data = string;
793 gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node, FALSE);
794 gl_text_node_free (&text_node);
796 string = lgl_xml_get_prop_string (node, "field", NULL);
798 text_node = g_new0 (glTextNode, 1);
799 text_node->field_flag = TRUE;
800 text_node->data = string;
801 gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node, FALSE);
802 gl_text_node_free (&text_node);
804 g_message ("Missing Object-barcode data or field attr");
809 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
812 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
814 gl_debug (DEBUG_XML, "END");
818 /*--------------------------------------------------------------------------*/
819 /* PRIVATE. Parse XML merge fields tag. */
820 /*--------------------------------------------------------------------------*/
822 xml_parse_merge_fields (xmlNodePtr node,
828 gl_debug (DEBUG_XML, "START");
830 string = lgl_xml_get_prop_string (node, "type", NULL);
831 merge = gl_merge_new (string);
836 string = lgl_xml_get_prop_string (node, "src", NULL);
837 gl_merge_set_src (merge, string);
840 gl_label_set_merge (label, merge, FALSE);
842 g_object_unref (G_OBJECT(merge));
845 gl_debug (DEBUG_XML, "END");
849 /*--------------------------------------------------------------------------*/
850 /* PRIVATE. Parse XML data tag. */
851 /*--------------------------------------------------------------------------*/
853 xml_parse_data (xmlNodePtr node,
858 gl_debug (DEBUG_XML, "START");
860 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
862 if (lgl_xml_is_node (child, "Pixdata")) {
863 xml_parse_pixdata (child, label);
864 } else if (lgl_xml_is_node (child, "File")) {
865 xml_parse_file_node (child, label);
867 if (!xmlNodeIsText (child)) {
868 g_message (_("bad node in Data node = \"%s\""),
874 gl_debug (DEBUG_XML, "END");
878 /*--------------------------------------------------------------------------*/
879 /* PRIVATE. Parse XML embedded Pixdata node. */
880 /*--------------------------------------------------------------------------*/
882 xml_parse_pixdata (xmlNodePtr node,
885 gchar *name, *base64;
891 GHashTable *pixbuf_cache;
893 gl_debug (DEBUG_XML, "START");
895 name = lgl_xml_get_prop_string (node, "name", NULL);
896 base64 = lgl_xml_get_node_content (node);
898 stream = g_base64_decode ((gchar *)base64, &stream_length);
899 pixdata = g_new0 (GdkPixdata, 1);
900 ret = gdk_pixdata_deserialize (pixdata, stream_length, stream, NULL);
903 pixbuf = gdk_pixbuf_from_pixdata (pixdata, TRUE, NULL);
905 pixbuf_cache = gl_label_get_pixbuf_cache (label);
906 gl_pixbuf_cache_add_pixbuf (pixbuf_cache, (gchar *)name, pixbuf);
915 gl_debug (DEBUG_XML, "END");
919 /*--------------------------------------------------------------------------*/
920 /* PRIVATE. Parse XML embedded File node. */
921 /*--------------------------------------------------------------------------*/
923 xml_parse_file_node (xmlNodePtr node,
926 gchar *name, *format;
928 GHashTable *svg_cache;
930 name = lgl_xml_get_prop_string (node, "name", NULL);
931 format = lgl_xml_get_prop_string (node, "format", NULL);
933 if ( format && (lgl_str_utf8_casecmp (format, "SVG") == 0) )
935 content = lgl_xml_get_node_content (node);
937 svg_cache = gl_label_get_svg_cache (label);
938 gl_svg_cache_add_svg (svg_cache, name, content);
944 g_message (_("Unknown embedded file format: \"%s\""), format);
953 /*--------------------------------------------------------------------------*/
954 /* PRIVATE. Parse top-level Span tag. */
955 /*--------------------------------------------------------------------------*/
957 xml_parse_toplevel_span (xmlNodePtr node,
958 glLabelObject *object)
962 PangoWeight font_weight;
963 gboolean font_italic_flag;
964 glColorNode *color_node;
965 gdouble text_line_spacing;
967 GList *lines, *text_nodes;
969 glTextNode *text_node;
971 gl_debug (DEBUG_XML, "START");
973 /* Font family attr */
974 font_family = lgl_xml_get_prop_string (node, "font_family", "Sans");
975 gl_label_object_set_font_family (object, font_family, FALSE);
976 g_free (font_family);
979 font_size = lgl_xml_get_prop_double (node, "font_size", 0.0);
980 gl_label_object_set_font_size (object, font_size, FALSE);
982 /* Font weight attr */
983 string = lgl_xml_get_prop_string (node, "font_weight", NULL);
984 font_weight = gl_str_util_string_to_weight (string);
986 gl_label_object_set_font_weight (object, font_weight, FALSE);
988 /* Font italic flag attr */
989 font_italic_flag = lgl_xml_get_prop_boolean (node, "font_italic", FALSE);
990 gl_label_object_set_font_italic_flag (object, font_italic_flag, FALSE);
992 /* Text color attr */
993 color_node = gl_color_node_new_default ();
994 string = lgl_xml_get_prop_string (node, "color_field", NULL);
996 color_node->field_flag = TRUE;
997 color_node->key = string;
999 color_node->color = lgl_xml_get_prop_uint (node, "color", 0);
1001 gl_label_object_set_text_color (object, color_node, FALSE);
1002 gl_color_node_free (&color_node);
1004 /* Text line spacing attr */
1005 text_line_spacing = lgl_xml_get_prop_double (node, "line_spacing", 1.0);
1006 gl_label_object_set_text_line_spacing (object, text_line_spacing, FALSE);
1008 /* Now descend children, and build lines of text nodes */
1011 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
1013 if (xmlNodeIsText (child)) {
1014 gchar *data = lgl_xml_get_node_content (child);
1016 /* Hack: if the first char is LF, it's an xml formatting string */
1017 if (data[0] != '\n') {
1019 text_node = g_new0 (glTextNode, 1);
1020 text_node->field_flag = FALSE;
1021 text_node->data = g_strdup ((gchar *)data);
1022 text_nodes = g_list_append (text_nodes, text_node);
1026 } else if (lgl_xml_is_node (child, "Span")) {
1028 g_message ("Unexpected rich text (not supported, yet!)");
1030 } else if (lgl_xml_is_node (child, "Field")) {
1033 string = lgl_xml_get_prop_string (child, "name", NULL);
1034 text_node = g_new0 (glTextNode, 1);
1035 text_node->field_flag = TRUE;
1036 text_node->data = string;
1037 text_nodes = g_list_append (text_nodes, text_node);
1039 } else if (lgl_xml_is_node (child, "NL")) {
1042 lines = g_list_append (lines, text_nodes);
1046 g_message ("Unexpected Span child: \"%s\"", child->name);
1051 /* Store last line. */
1052 lines = g_list_append (lines, text_nodes);
1055 gl_label_text_set_lines (GL_LABEL_TEXT(object), lines, FALSE);
1056 gl_text_node_lines_free (&lines);
1058 gl_debug (DEBUG_XML, "END");
1062 /*--------------------------------------------------------------------------*/
1063 /* PRIVATE. Parse affine attributes. */
1064 /*--------------------------------------------------------------------------*/
1066 xml_parse_affine_attrs (xmlNodePtr node,
1067 glLabelObject *object)
1070 cairo_matrix_t matrix;
1072 a[0] = lgl_xml_get_prop_double (node, "a0", 0.0);
1073 a[1] = lgl_xml_get_prop_double (node, "a1", 0.0);
1074 a[2] = lgl_xml_get_prop_double (node, "a2", 0.0);
1075 a[3] = lgl_xml_get_prop_double (node, "a3", 0.0);
1076 a[4] = lgl_xml_get_prop_double (node, "a4", 0.0);
1077 a[5] = lgl_xml_get_prop_double (node, "a5", 0.0);
1079 cairo_matrix_init (&matrix, a[0], a[1], a[2], a[3], a[4], a[5]);
1081 gl_label_object_set_matrix (object, &matrix);
1085 /*--------------------------------------------------------------------------*/
1086 /* PRIVATE. Parse shadow attributes. */
1087 /*--------------------------------------------------------------------------*/
1089 xml_parse_shadow_attrs (xmlNodePtr node,
1090 glLabelObject *object)
1092 gboolean shadow_state;
1095 glColorNode *shadow_color_node;
1096 gdouble shadow_opacity;
1099 shadow_state = lgl_xml_get_prop_boolean (node, "shadow", FALSE);
1100 gl_label_object_set_shadow_state (object, shadow_state, FALSE);
1104 shadow_x = lgl_xml_get_prop_length (node, "shadow_x", 0.0);
1105 shadow_y = lgl_xml_get_prop_length (node, "shadow_y", 0.0);
1106 gl_label_object_set_shadow_offset (object, shadow_x, shadow_y, FALSE);
1108 shadow_color_node = gl_color_node_new_default ();
1109 string = lgl_xml_get_prop_string (node, "shadow_color_field", NULL);
1111 shadow_color_node->field_flag = TRUE;
1112 shadow_color_node->key = string;
1114 shadow_color_node->color = lgl_xml_get_prop_uint (node, "shadow_color", 0);
1116 gl_label_object_set_shadow_color (object, shadow_color_node, FALSE);
1117 gl_color_node_free (&shadow_color_node);
1119 shadow_opacity = lgl_xml_get_prop_double (node, "shadow_opacity", 1.0);
1120 gl_label_object_set_shadow_opacity (object, shadow_opacity, FALSE);
1125 /****************************************************************************/
1126 /* Save label to xml label file. */
1127 /****************************************************************************/
1129 gl_xml_label_save (glLabel *label,
1130 const gchar *utf8_filename,
1131 glXMLLabelStatus *status)
1137 gl_debug (DEBUG_XML, "START");
1139 doc = xml_label_to_doc (label, status);
1141 filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
1143 g_message (_("Utf8 conversion error."));
1145 xmlSetDocCompressMode (doc, gl_label_get_compression (label));
1146 xml_ret = xmlSaveFormatFile (filename, doc, TRUE);
1148 if (xml_ret == -1) {
1150 g_message (_("Problem saving xml file."));
1151 *status = XML_LABEL_ERROR_SAVE_FILE;
1155 gl_label_set_filename (label, utf8_filename);
1156 gl_label_clear_modified (label);
1162 gl_debug (DEBUG_XML, "END");
1166 /****************************************************************************/
1167 /* Save label to xml buffer. */
1168 /****************************************************************************/
1170 gl_xml_label_save_buffer (glLabel *label,
1171 glXMLLabelStatus *status)
1177 gl_debug (DEBUG_XML, "START");
1179 doc = xml_label_to_doc (label, status);
1181 xmlDocDumpMemory (doc, &buffer, &size);
1184 gl_label_clear_modified (label);
1186 gl_debug (DEBUG_XML, "END");
1188 return (gchar *)buffer;
1192 /*--------------------------------------------------------------------------*/
1193 /* PRIVATE. Convert label to xml doc structure. */
1194 /*--------------------------------------------------------------------------*/
1196 xml_label_to_doc (glLabel *label,
1197 glXMLLabelStatus *status)
1202 const lglTemplate *template;
1205 gl_debug (DEBUG_XML, "START");
1207 LIBXML_TEST_VERSION;
1209 units = gl_prefs_model_get_units (gl_prefs);
1210 lgl_xml_set_default_units (units);
1212 doc = xmlNewDoc ((xmlChar *)"1.0");
1213 doc->xmlRootNode = xmlNewDocNode (doc, NULL, (xmlChar *)"Glabels-document", NULL);
1215 ns = xmlNewNs (doc->xmlRootNode, (xmlChar *)LGL_XML_NAME_SPACE, NULL);
1216 xmlSetNs (doc->xmlRootNode, ns);
1218 template = gl_label_get_template (label);
1219 lgl_xml_template_create_template_node (template, doc->xmlRootNode, ns);
1221 xml_create_objects (doc->xmlRootNode, ns, label);
1223 merge = gl_label_get_merge (label);
1224 gl_debug (DEBUG_XML, "merge=%p", merge);
1225 if (merge != NULL) {
1226 xml_create_merge_fields (doc->xmlRootNode, ns, label);
1227 g_object_unref (G_OBJECT(merge));
1230 xml_create_data (doc, doc->xmlRootNode, ns, label);
1232 gl_debug (DEBUG_XML, "END");
1234 *status = XML_LABEL_OK;
1239 /*--------------------------------------------------------------------------*/
1240 /* PRIVATE. Add XML Objects Node */
1241 /*--------------------------------------------------------------------------*/
1243 xml_create_objects (xmlNodePtr parent,
1248 gboolean rotate_flag;
1249 const GList *object_list;
1251 glLabelObject *object;
1253 gl_debug (DEBUG_XML, "START");
1255 rotate_flag = gl_label_get_rotate_flag (label);
1256 object_list = gl_label_get_object_list (label);
1258 node = xmlNewChild (parent, ns, (xmlChar *)"Objects", NULL);
1259 lgl_xml_set_prop_string (node, "id", "0");
1260 lgl_xml_set_prop_boolean (node, "rotate", rotate_flag);
1262 for (p = (GList *)object_list; p != NULL; p = p->next) {
1264 object = GL_LABEL_OBJECT(p->data);
1266 if ( GL_IS_LABEL_TEXT(object) ) {
1267 xml_create_object_text (node, ns, object);
1268 } else if ( GL_IS_LABEL_BOX(object) ) {
1269 xml_create_object_box (node, ns, object);
1270 } else if ( GL_IS_LABEL_ELLIPSE(object) ) {
1271 xml_create_object_ellipse (node, ns, object);
1272 } else if ( GL_IS_LABEL_LINE(object) ) {
1273 xml_create_object_line (node, ns, object);
1274 } else if ( GL_IS_LABEL_IMAGE(object) ) {
1275 xml_create_object_image (node, ns, object);
1276 } else if ( GL_IS_LABEL_BARCODE(object) ) {
1277 xml_create_object_barcode (node, ns, object);
1279 g_message ("Unknown label object");
1284 gl_debug (DEBUG_XML, "END");
1288 /*--------------------------------------------------------------------------*/
1289 /* PRIVATE. Add XML Objects->Object-text Node */
1290 /*--------------------------------------------------------------------------*/
1292 xml_create_object_text (xmlNodePtr parent,
1294 glLabelObject *object)
1299 PangoAlignment align;
1300 gboolean auto_shrink;
1302 gl_debug (DEBUG_XML, "START");
1304 node = xmlNewChild (parent, ns, (xmlChar *)"Object-text", NULL);
1306 /* position attrs */
1307 gl_label_object_get_position (object, &x, &y);
1308 lgl_xml_set_prop_length (node, "x", x);
1309 lgl_xml_set_prop_length (node, "y", y);
1312 gl_label_object_get_raw_size ( object, &w, &h);
1313 lgl_xml_set_prop_length (node, "w", w);
1314 lgl_xml_set_prop_length (node, "h", h);
1317 align = gl_label_object_get_text_alignment (object);
1318 lgl_xml_set_prop_string (node, "justify", gl_str_util_align_to_string (align));
1320 /* auto_shrink attr */
1321 auto_shrink = gl_label_text_get_auto_shrink (GL_LABEL_TEXT (object));
1322 lgl_xml_set_prop_boolean (node, "auto_shrink", auto_shrink);
1325 xml_create_affine_attrs (node, object);
1328 xml_create_shadow_attrs (node, object);
1331 xml_create_toplevel_span (node, ns, GL_LABEL_TEXT(object));
1333 gl_debug (DEBUG_XML, "END");
1337 /*--------------------------------------------------------------------------*/
1338 /* PRIVATE. Add XML Objects->Object-box Node */
1339 /*--------------------------------------------------------------------------*/
1341 xml_create_object_box (xmlNodePtr parent,
1343 glLabelObject *object)
1349 glColorNode *line_color_node;
1350 glColorNode *fill_color_node;
1352 gl_debug (DEBUG_XML, "START");
1354 node = xmlNewChild (parent, ns, (xmlChar *)"Object-box", NULL);
1356 /* position attrs */
1357 gl_label_object_get_position (object, &x, &y);
1358 lgl_xml_set_prop_length (node, "x", x);
1359 lgl_xml_set_prop_length (node, "y", y);
1362 gl_label_object_get_size (object, &w, &h);
1363 lgl_xml_set_prop_length (node, "w", w);
1364 lgl_xml_set_prop_length (node, "h", h);
1367 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1368 lgl_xml_set_prop_length (node, "line_width", line_width);
1370 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1371 if (line_color_node->field_flag)
1373 lgl_xml_set_prop_string (node, "line_color_field", line_color_node->key);
1377 lgl_xml_set_prop_uint_hex (node, "line_color", line_color_node->color);
1379 gl_color_node_free (&line_color_node);
1381 /* fill attrs (color or field) */
1382 fill_color_node = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
1383 if (fill_color_node->field_flag)
1385 lgl_xml_set_prop_string (node, "fill_color_field", fill_color_node->key);
1389 lgl_xml_set_prop_uint_hex (node, "fill_color", fill_color_node->color);
1391 gl_color_node_free (&fill_color_node);
1394 xml_create_affine_attrs (node, object);
1397 xml_create_shadow_attrs (node, object);
1399 gl_debug (DEBUG_XML, "END");
1403 /*--------------------------------------------------------------------------*/
1404 /* PRIVATE. Add XML Objects->Object-ellipse Node */
1405 /*--------------------------------------------------------------------------*/
1407 xml_create_object_ellipse (xmlNodePtr parent,
1409 glLabelObject *object)
1415 glColorNode *line_color_node;
1416 glColorNode *fill_color_node;
1418 gl_debug (DEBUG_XML, "START");
1420 node = xmlNewChild (parent, ns, (xmlChar *)"Object-ellipse", NULL);
1422 /* position attrs */
1423 gl_label_object_get_position (object, &x, &y);
1424 lgl_xml_set_prop_length (node, "x", x);
1425 lgl_xml_set_prop_length (node, "y", y);
1428 gl_label_object_get_size (object, &w, &h);
1429 lgl_xml_set_prop_length (node, "w", w);
1430 lgl_xml_set_prop_length (node, "h", h);
1433 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1434 lgl_xml_set_prop_length (node, "line_width", line_width);
1436 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1437 if (line_color_node->field_flag)
1439 lgl_xml_set_prop_string (node, "line_color_field", line_color_node->key);
1443 lgl_xml_set_prop_uint_hex (node, "line_color", line_color_node->color);
1445 gl_color_node_free (&line_color_node);
1448 /* fill attrs (color or field) */
1449 fill_color_node = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
1450 if (fill_color_node->field_flag)
1452 lgl_xml_set_prop_string (node, "fill_color_field", fill_color_node->key);
1456 lgl_xml_set_prop_uint_hex (node, "fill_color", fill_color_node->color);
1458 gl_color_node_free (&fill_color_node);
1461 xml_create_affine_attrs (node, object);
1464 xml_create_shadow_attrs (node, object);
1466 gl_debug (DEBUG_XML, "END");
1470 /*--------------------------------------------------------------------------*/
1471 /* PRIVATE. Add XML Objects->Object-line Node */
1472 /*--------------------------------------------------------------------------*/
1474 xml_create_object_line (xmlNodePtr parent,
1476 glLabelObject *object)
1482 glColorNode *line_color_node;
1484 gl_debug (DEBUG_XML, "START");
1486 node = xmlNewChild (parent, ns, (xmlChar *)"Object-line", NULL);
1488 /* position attrs */
1489 gl_label_object_get_position (object, &x, &y);
1490 lgl_xml_set_prop_length (node, "x", x);
1491 lgl_xml_set_prop_length (node, "y", y);
1494 gl_label_object_get_size (object, &dx, &dy);
1495 lgl_xml_set_prop_length (node, "dx", dx);
1496 lgl_xml_set_prop_length (node, "dy", dy);
1499 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1500 lgl_xml_set_prop_length (node, "line_width", line_width);
1502 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1503 if (line_color_node->field_flag)
1505 lgl_xml_set_prop_string (node, "line_color_field", line_color_node->key);
1509 lgl_xml_set_prop_uint_hex (node, "line_color", line_color_node->color);
1511 gl_color_node_free (&line_color_node);
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-image Node */
1526 /*--------------------------------------------------------------------------*/
1528 xml_create_object_image (xmlNodePtr parent,
1530 glLabelObject *object)
1535 glTextNode *filename;
1537 gl_debug (DEBUG_XML, "START");
1539 node = xmlNewChild (parent, ns, (xmlChar *)"Object-image", NULL);
1541 /* position attrs */
1542 gl_label_object_get_position (object, &x, &y);
1543 lgl_xml_set_prop_length (node, "x", x);
1544 lgl_xml_set_prop_length (node, "y", y);
1547 gl_label_object_get_size (object, &w, &h);
1548 lgl_xml_set_prop_length (node, "w", w);
1549 lgl_xml_set_prop_length (node, "h", h);
1551 /* src OR field attr */
1552 filename = gl_label_image_get_filename (GL_LABEL_IMAGE(object));
1553 if (filename->field_flag) {
1554 lgl_xml_set_prop_string (node, "field", filename->data);
1556 lgl_xml_set_prop_string (node, "src", filename->data);
1558 gl_text_node_free (&filename);
1561 xml_create_affine_attrs (node, object);
1564 xml_create_shadow_attrs (node, object);
1566 gl_debug (DEBUG_XML, "END");
1570 /*--------------------------------------------------------------------------*/
1571 /* PRIVATE. Add XML Objects->Object-barcode Node */
1572 /*--------------------------------------------------------------------------*/
1574 xml_create_object_barcode (xmlNodePtr parent,
1576 glLabelObject *object)
1581 glTextNode *text_node;
1584 gboolean checksum_flag;
1585 glColorNode *color_node;
1586 guint format_digits;
1588 gl_debug (DEBUG_XML, "START");
1590 node = xmlNewChild (parent, ns, (xmlChar *)"Object-barcode", NULL);
1592 /* position attrs */
1593 gl_label_object_get_position (object, &x, &y);
1594 lgl_xml_set_prop_length (node, "x", x);
1595 lgl_xml_set_prop_length (node, "y", y);
1598 gl_label_object_get_raw_size (object, &w, &h);
1599 lgl_xml_set_prop_length (node, "w", w);
1600 lgl_xml_set_prop_length (node, "h", h);
1602 /* Barcode properties attrs */
1603 gl_label_barcode_get_props (GL_LABEL_BARCODE(object),
1604 &id, &text_flag, &checksum_flag, &format_digits);
1605 lgl_xml_set_prop_string (node, "style", id);
1606 lgl_xml_set_prop_boolean (node, "text", text_flag);
1607 lgl_xml_set_prop_boolean (node, "checksum", checksum_flag);
1611 color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1612 if (color_node->field_flag)
1614 lgl_xml_set_prop_string (node, "color_field", color_node->key);
1618 lgl_xml_set_prop_uint_hex (node, "color", color_node->color);
1620 gl_color_node_free (&color_node);
1623 /* data OR field attr */
1624 text_node = gl_label_barcode_get_data (GL_LABEL_BARCODE(object));
1625 if (text_node->field_flag) {
1626 lgl_xml_set_prop_string (node, "field", text_node->data);
1627 lgl_xml_set_prop_int (node, "format", format_digits);
1629 lgl_xml_set_prop_string (node, "data", text_node->data);
1631 gl_text_node_free (&text_node);
1634 xml_create_affine_attrs (node, object);
1637 xml_create_shadow_attrs (node, object);
1639 gl_debug (DEBUG_XML, "END");
1643 /*--------------------------------------------------------------------------*/
1644 /* PRIVATE. Add XML Label Merge Fields Node */
1645 /*--------------------------------------------------------------------------*/
1647 xml_create_merge_fields (xmlNodePtr parent,
1655 gl_debug (DEBUG_XML, "START");
1657 merge = gl_label_get_merge (label);
1659 node = xmlNewChild (parent, ns, (xmlChar *)"Merge", NULL);
1661 string = gl_merge_get_name (merge);
1662 lgl_xml_set_prop_string (node, "type", string);
1665 string = gl_merge_get_src (merge);
1666 lgl_xml_set_prop_string (node, "src", string);
1669 g_object_unref (G_OBJECT(merge));
1671 gl_debug (DEBUG_XML, "END");
1675 /*--------------------------------------------------------------------------*/
1676 /* PRIVATE. Add XML Label Data Node */
1677 /*--------------------------------------------------------------------------*/
1679 xml_create_data (xmlDocPtr doc,
1686 GList *name_list, *p;
1688 gl_debug (DEBUG_XML, "START");
1690 node = xmlNewChild (parent, ns, (xmlChar *)"Data", NULL);
1692 cache = gl_label_get_pixbuf_cache (label);
1693 name_list = gl_pixbuf_cache_get_name_list (cache);
1695 for (p = name_list; p != NULL; p=p->next) {
1696 xml_create_pixdata (node, ns, label, p->data);
1699 gl_pixbuf_cache_free_name_list (name_list);
1702 cache = gl_label_get_svg_cache (label);
1703 name_list = gl_svg_cache_get_name_list (cache);
1705 for (p = name_list; p != NULL; p=p->next) {
1706 xml_create_file_svg (doc, node, ns, label, p->data);
1709 gl_pixbuf_cache_free_name_list (name_list);
1712 gl_debug (DEBUG_XML, "END");
1716 /*--------------------------------------------------------------------------*/
1717 /* PRIVATE. Add XML Label Data embedded Pixdata Node */
1718 /*--------------------------------------------------------------------------*/
1720 xml_create_pixdata (xmlNodePtr parent,
1726 GHashTable *pixbuf_cache;
1728 GdkPixdata *pixdata;
1730 guint stream_length;
1733 gl_debug (DEBUG_XML, "START");
1735 pixbuf_cache = gl_label_get_pixbuf_cache (label);
1737 pixbuf = gl_pixbuf_cache_get_pixbuf (pixbuf_cache, name);
1738 if ( pixbuf != NULL ) {
1740 pixdata = g_new0 (GdkPixdata, 1);
1741 gdk_pixdata_from_pixbuf (pixdata, pixbuf, FALSE);
1742 stream = gdk_pixdata_serialize (pixdata, &stream_length);
1743 base64 = g_base64_encode (stream, stream_length);
1745 node = xmlNewChild (parent, ns, (xmlChar *)"Pixdata", (xmlChar *)base64);
1746 lgl_xml_set_prop_string (node, "name", name);
1747 lgl_xml_set_prop_string (node, "encoding", "Base64");
1749 gl_pixbuf_cache_remove_pixbuf (pixbuf_cache, name);
1757 gl_debug (DEBUG_XML, "END");
1761 /*--------------------------------------------------------------------------*/
1762 /* PRIVATE. Add XML Label Data embedded SVG file Node */
1763 /*--------------------------------------------------------------------------*/
1765 xml_create_file_svg (xmlDocPtr doc,
1772 xmlNodePtr cdata_section_node;
1773 GHashTable *svg_cache;
1776 gl_debug (DEBUG_XML, "START");
1778 svg_cache = gl_label_get_svg_cache (label);
1780 svg_data = gl_svg_cache_get_contents (svg_cache, name);
1781 if ( svg_data != NULL ) {
1783 node = xmlNewChild (parent, ns, (xmlChar *)"File", NULL);
1784 lgl_xml_set_prop_string (node, "name", name);
1785 lgl_xml_set_prop_string (node, "format", "SVG");
1787 cdata_section_node = xmlNewCDataBlock (doc, (xmlChar *)svg_data, strlen (svg_data));
1788 xmlAddChild (node, cdata_section_node);
1794 gl_debug (DEBUG_XML, "END");
1798 /*--------------------------------------------------------------------------*/
1799 /* PRIVATE. Create top-level Span node. */
1800 /*--------------------------------------------------------------------------*/
1802 xml_create_toplevel_span (xmlNodePtr parent,
1804 glLabelText *object_text)
1809 PangoWeight font_weight;
1810 gboolean font_italic_flag;
1811 glColorNode *color_node;
1812 PangoAlignment align;
1813 gdouble text_line_spacing;
1814 GList *lines, *p_line, *p_node;
1815 glTextNode *text_node;
1818 node = xmlNewChild (parent, ns, (xmlChar *)"Span", NULL);
1820 /* All span attrs at top level. */
1821 font_family = gl_label_object_get_font_family (GL_LABEL_OBJECT(object_text));
1822 font_size = gl_label_object_get_font_size (GL_LABEL_OBJECT(object_text));
1823 text_line_spacing = gl_label_object_get_text_line_spacing (GL_LABEL_OBJECT(object_text));
1824 font_weight = gl_label_object_get_font_weight (GL_LABEL_OBJECT(object_text));
1825 font_italic_flag = gl_label_object_get_font_italic_flag (GL_LABEL_OBJECT(object_text));
1827 color_node = gl_label_object_get_text_color (GL_LABEL_OBJECT(object_text));
1828 if (color_node->field_flag)
1830 lgl_xml_set_prop_string (node, "color_field", color_node->key);
1834 lgl_xml_set_prop_uint_hex (node, "color", color_node->color);
1836 gl_color_node_free (&color_node);
1838 align = gl_label_object_get_text_alignment (GL_LABEL_OBJECT(object_text));
1839 lgl_xml_set_prop_string (node, "font_family", font_family);
1840 lgl_xml_set_prop_double (node, "font_size", font_size);
1841 lgl_xml_set_prop_string (node, "font_weight", gl_str_util_weight_to_string (font_weight));
1842 lgl_xml_set_prop_boolean (node, "font_italic", font_italic_flag);
1844 lgl_xml_set_prop_double (node, "line_spacing", text_line_spacing);
1846 /* Build children. */
1847 lines = gl_label_text_get_lines (GL_LABEL_TEXT(object_text));
1848 for (p_line = lines; p_line != NULL; p_line = p_line->next) {
1850 for (p_node = (GList *) p_line->data; p_node != NULL;
1851 p_node = p_node->next) {
1852 text_node = (glTextNode *) p_node->data;
1854 if (text_node->field_flag) {
1855 child = xmlNewChild (node, ns, (xmlChar *)"Field", NULL);
1856 lgl_xml_set_prop_string (child, "name", text_node->data);
1858 xmlNodeAddContent (node, (xmlChar *)text_node->data);
1863 if ( p_line->next ) {
1864 child = xmlNewChild (node, ns, (xmlChar *)"NL", NULL);
1869 gl_text_node_lines_free (&lines);
1870 g_free (font_family);
1875 /*--------------------------------------------------------------------------*/
1876 /* PRIVATE. Create affine attributes. */
1877 /*--------------------------------------------------------------------------*/
1879 xml_create_affine_attrs (xmlNodePtr node,
1880 glLabelObject *object)
1882 cairo_matrix_t matrix;
1884 gl_label_object_get_matrix (object, &matrix);
1886 lgl_xml_set_prop_double (node, "a0", matrix.xx);
1887 lgl_xml_set_prop_double (node, "a1", matrix.yx);
1888 lgl_xml_set_prop_double (node, "a2", matrix.xy);
1889 lgl_xml_set_prop_double (node, "a3", matrix.yy);
1890 lgl_xml_set_prop_double (node, "a4", matrix.x0);
1891 lgl_xml_set_prop_double (node, "a5", matrix.y0);
1895 /*--------------------------------------------------------------------------*/
1896 /* PRIVATE. Create shadow attributes. */
1897 /*--------------------------------------------------------------------------*/
1899 xml_create_shadow_attrs (xmlNodePtr node,
1900 glLabelObject *object)
1902 gboolean shadow_state;
1905 glColorNode *shadow_color_node;
1906 gdouble shadow_opacity;
1908 shadow_state = gl_label_object_get_shadow_state (object);
1912 lgl_xml_set_prop_boolean (node, "shadow", shadow_state);
1914 gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
1915 lgl_xml_set_prop_length (node, "shadow_x", shadow_x);
1916 lgl_xml_set_prop_length (node, "shadow_y", shadow_y);
1918 shadow_color_node = gl_label_object_get_shadow_color (object);
1919 if (shadow_color_node->field_flag)
1921 lgl_xml_set_prop_string (node, "shadow_color_field", shadow_color_node->key);
1925 lgl_xml_set_prop_uint_hex (node, "shadow_color", shadow_color_node->color);
1927 gl_color_node_free (&shadow_color_node);
1929 shadow_opacity = gl_label_object_get_shadow_opacity (object);
1930 lgl_xml_set_prop_double (node, "shadow_opacity", shadow_opacity);
1937 * Local Variables: -- emacs
1939 * c-basic-offset: 8 -- emacs
1940 * tab-width: 8 -- emacs
1941 * indent-tabs-mode: nil -- emacs