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 "bc-backends.h"
42 #include "xml-label-04.h"
49 /*========================================================*/
50 /* Private macros and constants. */
51 /*========================================================*/
52 #define COMPAT01_NAME_SPACE "http://snaught.com/glabels/0.1/"
53 #define COMPAT04_NAME_SPACE "http://snaught.com/glabels/0.4/"
54 #define COMPAT20_NAME_SPACE "http://snaught.com/glabels/2.0/"
55 #define COMPAT22_NAME_SPACE "http://snaught.com/glabels/2.2/"
58 /*========================================================*/
60 /*========================================================*/
63 /*========================================================*/
64 /* Private globals. */
65 /*========================================================*/
68 /*========================================================*/
69 /* Private function prototypes. */
70 /*========================================================*/
72 static glLabel *xml_doc_to_label (xmlDocPtr doc,
73 glXMLLabelStatus *status);
75 static glLabel *xml_parse_label (xmlNodePtr root,
76 glXMLLabelStatus *status);
78 static void xml_parse_objects (xmlNodePtr node,
81 static void xml_parse_object_text (xmlNodePtr node,
84 static void xml_parse_object_box (xmlNodePtr node,
87 static void xml_parse_object_ellipse (xmlNodePtr node,
90 static void xml_parse_object_line (xmlNodePtr node,
93 static void xml_parse_object_image (xmlNodePtr node,
96 static void xml_parse_object_barcode (xmlNodePtr node,
99 static void xml_parse_merge_fields (xmlNodePtr node,
102 static void xml_parse_data (xmlNodePtr node,
105 static void xml_parse_pixdata (xmlNodePtr node,
108 static void xml_parse_file_node (xmlNodePtr node,
111 static void xml_parse_toplevel_span (xmlNodePtr node,
112 glLabelObject *object);
114 static void xml_parse_affine_attrs (xmlNodePtr node,
115 glLabelObject *object);
117 static void xml_parse_shadow_attrs (xmlNodePtr node,
118 glLabelObject *object);
120 static xmlDocPtr xml_label_to_doc (glLabel *label,
121 glXMLLabelStatus *status);
123 static void xml_create_objects (xmlNodePtr parent,
127 static void xml_create_object_text (xmlNodePtr parent,
129 glLabelObject *object);
131 static void xml_create_object_box (xmlNodePtr parent,
133 glLabelObject *object);
135 static void xml_create_object_line (xmlNodePtr parent,
137 glLabelObject *object);
139 static void xml_create_object_ellipse(xmlNodePtr parent,
141 glLabelObject *object);
143 static void xml_create_object_image (xmlNodePtr parent,
145 glLabelObject *object);
147 static void xml_create_object_barcode(xmlNodePtr parent,
149 glLabelObject *object);
151 static void xml_create_merge_fields (xmlNodePtr parent,
155 static void xml_create_data (xmlDocPtr doc,
160 static void xml_create_pixdata (xmlNodePtr parent,
165 static void xml_create_file_svg (xmlDocPtr doc,
171 static void xml_create_toplevel_span (xmlNodePtr node,
173 glLabelText *object_text);
175 static void xml_create_affine_attrs (xmlNodePtr node,
176 glLabelObject *object);
178 static void xml_create_shadow_attrs (xmlNodePtr node,
179 glLabelObject *object);
182 /****************************************************************************/
183 /* Open and read label from xml file. */
184 /****************************************************************************/
186 gl_xml_label_open (const gchar *utf8_filename,
187 glXMLLabelStatus *status)
193 gl_debug (DEBUG_XML, "START");
195 filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
196 g_return_val_if_fail (filename, NULL);
198 doc = xmlReadFile (filename, NULL, XML_PARSE_HUGE);
200 g_message (_("xmlParseFile error"));
201 *status = XML_LABEL_ERROR_OPEN_PARSE;
205 xmlXIncludeProcess (doc);
206 xmlReconciliateNs (doc, xmlDocGetRootElement (doc));
208 label = xml_doc_to_label (doc, status);
213 gl_label_set_filename (label, utf8_filename);
214 gl_label_clear_modified (label);
218 gl_debug (DEBUG_XML, "END");
224 /****************************************************************************/
225 /* Read label from xml buffer. */
226 /****************************************************************************/
228 gl_xml_label_open_buffer (const gchar *buffer,
229 glXMLLabelStatus *status)
234 gl_debug (DEBUG_XML, "START");
236 doc = xmlReadDoc ((xmlChar *) buffer, NULL, NULL, XML_PARSE_HUGE);
238 g_message (_("xmlParseFile error"));
239 *status = XML_LABEL_ERROR_OPEN_PARSE;
243 label = xml_doc_to_label (doc, status);
248 gl_label_clear_modified (label);
251 gl_debug (DEBUG_XML, "END");
257 /*--------------------------------------------------------------------------*/
258 /* PRIVATE. Parse xml doc structure and create label. */
259 /*--------------------------------------------------------------------------*/
261 xml_doc_to_label (xmlDocPtr doc,
262 glXMLLabelStatus *status)
267 gl_debug (DEBUG_XML, "START");
271 *status = XML_LABEL_OK;
273 root = xmlDocGetRootElement (doc);
274 if (!root || !root->name) {
275 g_message (_("No document root"));
276 *status = XML_LABEL_ERROR_OPEN_PARSE;
280 /* Try compatability mode 0.1 */
281 if (xmlSearchNsByHref (doc, root, (xmlChar *)COMPAT01_NAME_SPACE))
283 g_message (_("Importing from glabels 0.1 format"));
285 label = NULL; /* TODO */
289 /* Try compatability mode 0.4 */
290 if (xmlSearchNsByHref (doc, root, (xmlChar *)COMPAT04_NAME_SPACE))
292 g_message (_("Importing from glabels 0.4 format"));
293 label = gl_xml_label_04_parse (root, status);
297 /* Test for current namespaces. */
298 if ( !xmlSearchNsByHref (doc, root, (xmlChar *)COMPAT20_NAME_SPACE) &&
299 !xmlSearchNsByHref (doc, root, (xmlChar *)COMPAT22_NAME_SPACE) &&
300 !xmlSearchNsByHref (doc, root, (xmlChar *)LGL_XML_NAME_SPACE) )
302 g_message (_("Unknown glabels Namespace -- Using %s"),
306 label = xml_parse_label (root, status);
309 gl_label_set_compression (label, xmlGetDocCompressMode (doc));
312 gl_debug (DEBUG_XML, "END");
318 /*--------------------------------------------------------------------------*/
319 /* PRIVATE. Parse xml root node and create label. */
320 /*--------------------------------------------------------------------------*/
322 xml_parse_label (xmlNodePtr root,
323 glXMLLabelStatus *status)
325 xmlNodePtr child_node;
327 lglTemplate *template;
329 gl_debug (DEBUG_XML, "START");
331 *status = XML_LABEL_OK;
333 if (!lgl_xml_is_node (root, "Glabels-document")) {
334 g_message (_("Bad root node = \"%s\""), root->name);
335 *status = XML_LABEL_ERROR_OPEN_PARSE;
339 label = GL_LABEL(gl_label_new ());
341 /* Pass 1, extract data nodes to pre-load cache. */
342 for (child_node = root->xmlChildrenNode; child_node != NULL; child_node = child_node->next) {
343 if (lgl_xml_is_node (child_node, "Data")) {
344 xml_parse_data (child_node, label);
348 /* Pass 2, now extract everything else. */
349 for (child_node = root->xmlChildrenNode;
351 child_node = child_node->next) {
353 if (lgl_xml_is_node (child_node, "Template")) {
354 template = lgl_xml_template_parse_template_node (child_node);
356 g_object_unref (label);
357 *status = XML_LABEL_UNKNOWN_MEDIA;
360 lgl_db_register_template (template);
361 gl_label_set_template (label, template, FALSE);
362 lgl_template_free (template);
363 } else if (lgl_xml_is_node (child_node, "Objects")) {
364 xml_parse_objects (child_node, label);
365 } else if (lgl_xml_is_node (child_node, "Merge")) {
366 xml_parse_merge_fields (child_node, label);
367 } else if (lgl_xml_is_node (child_node, "Data")) {
368 /* Handled in pass 1. */
370 if (!xmlNodeIsText (child_node)) {
371 g_message (_("bad node in Document node = \"%s\""),
373 g_object_unref (label);
374 *status = XML_LABEL_ERROR_OPEN_PARSE;
380 gl_debug (DEBUG_XML, "END");
386 /*--------------------------------------------------------------------------*/
387 /* PRIVATE. Parse Objects node. */
388 /*--------------------------------------------------------------------------*/
390 xml_parse_objects (xmlNodePtr node,
393 gboolean rotate_flag;
396 gl_debug (DEBUG_XML, "START");
398 rotate_flag = lgl_xml_get_prop_boolean (node, "rotate", FALSE);
399 gl_label_set_rotate_flag (label, rotate_flag, FALSE);
401 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
403 if (lgl_xml_is_node (child, "Object-text")) {
404 xml_parse_object_text (child, label);
405 } else if (lgl_xml_is_node (child, "Object-box")) {
406 xml_parse_object_box (child, label);
407 } else if (lgl_xml_is_node (child, "Object-ellipse")) {
408 xml_parse_object_ellipse (child, label);
409 } else if (lgl_xml_is_node (child, "Object-line")) {
410 xml_parse_object_line (child, label);
411 } else if (lgl_xml_is_node (child, "Object-image")) {
412 xml_parse_object_image (child, label);
413 } else if (lgl_xml_is_node (child, "Object-barcode")) {
414 xml_parse_object_barcode (child, label);
416 if (!xmlNodeIsText (child)) {
417 g_message (_("bad node = \"%s\""), child->name);
423 gl_debug (DEBUG_XML, "END");
427 /*--------------------------------------------------------------------------*/
428 /* PRIVATE. Parse XML Objects->Object-text Node */
429 /*--------------------------------------------------------------------------*/
431 xml_parse_object_text (xmlNodePtr node,
438 PangoAlignment align;
439 gboolean auto_shrink;
442 gl_debug (DEBUG_XML, "START");
444 object = gl_label_text_new (label, FALSE);
447 x = lgl_xml_get_prop_length (node, "x", 0.0);
448 y = lgl_xml_get_prop_length (node, "y", 0.0);
449 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y, FALSE);
451 /* implied size attrs */
452 w = lgl_xml_get_prop_length (node, "w", 0);
453 h = lgl_xml_get_prop_length (node, "h", 0);
454 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h, FALSE);
457 string = lgl_xml_get_prop_string (node, "justify", NULL);
458 align = gl_str_util_string_to_align (string);
460 gl_label_object_set_text_alignment (GL_LABEL_OBJECT(object), align, FALSE);
462 /* auto_shrink attr */
463 auto_shrink = lgl_xml_get_prop_boolean (node, "auto_shrink", FALSE);
464 gl_label_text_set_auto_shrink (GL_LABEL_TEXT(object), auto_shrink, FALSE);
467 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
470 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
472 /* Process children */
473 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
474 if (lgl_xml_is_node (child, "Span")) {
475 xml_parse_toplevel_span (child, GL_LABEL_OBJECT(object));
478 if (!xmlNodeIsText (child)) {
479 g_message ("Unexpected Object-text child: \"%s\"",
485 gl_debug (DEBUG_XML, "END");
489 /*--------------------------------------------------------------------------*/
490 /* PRIVATE. Parse XML Objects->Object-box Node */
491 /*--------------------------------------------------------------------------*/
493 xml_parse_object_box (xmlNodePtr node,
500 glColorNode *line_color_node;
502 glColorNode *fill_color_node;
504 gl_debug (DEBUG_XML, "START");
506 object = gl_label_box_new (label, FALSE);
509 x = lgl_xml_get_prop_length (node, "x", 0.0);
510 y = lgl_xml_get_prop_length (node, "y", 0.0);
511 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y, FALSE);
514 w = lgl_xml_get_prop_length (node, "w", 0);
515 h = lgl_xml_get_prop_length (node, "h", 0);
516 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h, FALSE);
519 line_width = lgl_xml_get_prop_length (node, "line_width", 1.0);
520 gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width, FALSE);
522 line_color_node = gl_color_node_new_default ();
523 string = lgl_xml_get_prop_string (node, "line_color_field", NULL);
525 line_color_node->field_flag = TRUE;
526 line_color_node->key = string;
528 line_color_node->color = lgl_xml_get_prop_uint (node, "line_color", 0);
530 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color_node, FALSE);
531 gl_color_node_free (&line_color_node);
535 fill_color_node = gl_color_node_new_default ();
536 string = lgl_xml_get_prop_string (node, "fill_color_field", NULL);
538 fill_color_node->field_flag = TRUE;
539 fill_color_node->key = string;
541 fill_color_node->color = lgl_xml_get_prop_uint (node, "fill_color", 0);
543 gl_label_object_set_fill_color (GL_LABEL_OBJECT(object), fill_color_node, FALSE);
544 gl_color_node_free (&fill_color_node);
547 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
550 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
552 gl_debug (DEBUG_XML, "END");
556 /*--------------------------------------------------------------------------*/
557 /* PRIVATE. Parse XML Objects->Object-ellipse Node */
558 /*--------------------------------------------------------------------------*/
560 xml_parse_object_ellipse (xmlNodePtr node,
567 glColorNode *line_color_node;
569 glColorNode *fill_color_node;
571 gl_debug (DEBUG_XML, "START");
573 object = gl_label_ellipse_new (label, FALSE);
576 x = lgl_xml_get_prop_length (node, "x", 0.0);
577 y = lgl_xml_get_prop_length (node, "y", 0.0);
578 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y, FALSE);
581 w = lgl_xml_get_prop_length (node, "w", 0);
582 h = lgl_xml_get_prop_length (node, "h", 0);
583 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h, FALSE);
586 line_width = lgl_xml_get_prop_length (node, "line_width", 1.0);
587 gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width, FALSE);
589 line_color_node = gl_color_node_new_default ();
590 string = lgl_xml_get_prop_string (node, "line_color_field", NULL);
592 line_color_node->field_flag = TRUE;
593 line_color_node->key = string;
595 line_color_node->color = lgl_xml_get_prop_uint (node, "line_color", 0);
597 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color_node, FALSE);
598 gl_color_node_free (&line_color_node);
602 fill_color_node = gl_color_node_new_default ();
603 string = lgl_xml_get_prop_string (node, "fill_color_field", NULL);
605 fill_color_node->field_flag = TRUE;
606 fill_color_node->key = string;
608 fill_color_node->color = lgl_xml_get_prop_uint (node, "fill_color", 0);
610 gl_label_object_set_fill_color (GL_LABEL_OBJECT(object), fill_color_node, FALSE);
611 gl_color_node_free (&fill_color_node);
614 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
617 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
619 gl_debug (DEBUG_XML, "END");
623 /*--------------------------------------------------------------------------*/
624 /* PRIVATE. Parse XML Objects->Object-line Node */
625 /*--------------------------------------------------------------------------*/
627 xml_parse_object_line (xmlNodePtr node,
634 glColorNode *line_color_node;
637 gl_debug (DEBUG_XML, "START");
639 object = gl_label_line_new (label, FALSE);
642 x = lgl_xml_get_prop_length (node, "x", 0.0);
643 y = lgl_xml_get_prop_length (node, "y", 0.0);
644 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y, FALSE);
647 dx = lgl_xml_get_prop_length (node, "dx", 0);
648 dy = lgl_xml_get_prop_length (node, "dy", 0);
649 gl_label_object_set_size (GL_LABEL_OBJECT(object), dx, dy, FALSE);
652 line_width = lgl_xml_get_prop_length (node, "line_width", 1.0);
653 gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width, FALSE);
655 line_color_node = gl_color_node_new_default ();
656 string = lgl_xml_get_prop_string (node, "line_color_field", NULL);
658 line_color_node->field_flag = TRUE;
659 line_color_node->key = string;
661 line_color_node->color = lgl_xml_get_prop_uint (node, "line_color", 0);
663 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color_node, FALSE);
664 gl_color_node_free (&line_color_node);
667 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
670 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
672 gl_debug (DEBUG_XML, "END");
676 /*--------------------------------------------------------------------------*/
677 /* PRIVATE. Parse XML Objects->Object-image Node */
678 /*--------------------------------------------------------------------------*/
680 xml_parse_object_image (xmlNodePtr node,
687 glTextNode *filename;
689 gl_debug (DEBUG_XML, "START");
691 object = gl_label_image_new (label, FALSE);
694 x = lgl_xml_get_prop_length (node, "x", 0.0);
695 y = lgl_xml_get_prop_length (node, "y", 0.0);
696 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y, FALSE);
698 /* src or field attr */
699 string = lgl_xml_get_prop_string (node, "src", NULL);
701 filename = g_new0 (glTextNode, 1);
702 filename->field_flag = FALSE;
703 filename->data = g_strdup ((gchar *)string);
704 gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename, FALSE);
705 gl_text_node_free (&filename);
708 string = lgl_xml_get_prop_string (node, "field", NULL);
710 filename = g_new0 (glTextNode, 1);
711 filename->field_flag = TRUE;
712 filename->data = g_strdup ((gchar *)string);
713 gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename, FALSE);
714 gl_text_node_free (&filename);
717 g_message ("Missing Object-image src or field attr");
722 w = lgl_xml_get_prop_length (node, "w", 0);
723 h = lgl_xml_get_prop_length (node, "h", 0);
724 gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h, FALSE);
727 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
730 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
732 gl_debug (DEBUG_XML, "END");
736 /*--------------------------------------------------------------------------*/
737 /* PRIVATE. Parse XML Objects->Object-barcode Node */
738 /*--------------------------------------------------------------------------*/
740 xml_parse_object_barcode (xmlNodePtr node,
747 glTextNode *text_node;
750 glLabelBarcodeStyle *style;
751 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 style = gl_label_barcode_style_new ();
769 backend_id = lgl_xml_get_prop_string (node, "backend", NULL);
770 id = lgl_xml_get_prop_string (node, "style", NULL);
773 backend_id = g_strdup (gl_barcode_backends_guess_backend_id (id));
775 gl_label_barcode_style_set_backend_id (style, backend_id);
776 gl_label_barcode_style_set_style_id (style, id);
777 style->text_flag = lgl_xml_get_prop_boolean (node, "text", FALSE);
778 style->checksum_flag = lgl_xml_get_prop_boolean (node, "checksum", TRUE);
779 style->format_digits = lgl_xml_get_prop_uint (node, "format", 10);
780 gl_label_barcode_set_style (GL_LABEL_BARCODE(object), style, FALSE);
783 gl_label_barcode_style_free (style);
785 color_node = gl_color_node_new_default ();
786 string = lgl_xml_get_prop_string (node, "color_field", NULL);
788 color_node->field_flag = TRUE;
789 color_node->key = string;
791 color_node->color = lgl_xml_get_prop_uint (node, "color", 0);
793 gl_label_object_set_line_color (GL_LABEL_OBJECT(object), color_node, FALSE);
794 gl_color_node_free (&color_node);
796 /* data or field attr */
797 string = lgl_xml_get_prop_string (node, "data", NULL);
799 text_node = g_new0 (glTextNode, 1);
800 text_node->field_flag = FALSE;
801 text_node->data = string;
802 gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node, FALSE);
803 gl_text_node_free (&text_node);
805 string = lgl_xml_get_prop_string (node, "field", NULL);
807 text_node = g_new0 (glTextNode, 1);
808 text_node->field_flag = TRUE;
809 text_node->data = string;
810 gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node, FALSE);
811 gl_text_node_free (&text_node);
813 g_message ("Missing Object-barcode data or field attr");
818 xml_parse_affine_attrs (node, GL_LABEL_OBJECT(object));
821 xml_parse_shadow_attrs (node, GL_LABEL_OBJECT(object));
823 gl_debug (DEBUG_XML, "END");
827 /*--------------------------------------------------------------------------*/
828 /* PRIVATE. Parse XML merge fields tag. */
829 /*--------------------------------------------------------------------------*/
831 xml_parse_merge_fields (xmlNodePtr node,
837 gl_debug (DEBUG_XML, "START");
839 string = lgl_xml_get_prop_string (node, "type", NULL);
840 merge = gl_merge_new (string);
845 string = lgl_xml_get_prop_string (node, "src", NULL);
846 gl_merge_set_src (merge, string);
849 gl_label_set_merge (label, merge, FALSE);
851 g_object_unref (G_OBJECT(merge));
854 gl_debug (DEBUG_XML, "END");
858 /*--------------------------------------------------------------------------*/
859 /* PRIVATE. Parse XML data tag. */
860 /*--------------------------------------------------------------------------*/
862 xml_parse_data (xmlNodePtr node,
867 gl_debug (DEBUG_XML, "START");
869 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
871 if (lgl_xml_is_node (child, "Pixdata")) {
872 xml_parse_pixdata (child, label);
873 } else if (lgl_xml_is_node (child, "File")) {
874 xml_parse_file_node (child, label);
876 if (!xmlNodeIsText (child)) {
877 g_message (_("bad node in Data node = \"%s\""),
883 gl_debug (DEBUG_XML, "END");
887 /*--------------------------------------------------------------------------*/
888 /* PRIVATE. Parse XML embedded Pixdata node. */
889 /*--------------------------------------------------------------------------*/
891 xml_parse_pixdata (xmlNodePtr node,
894 gchar *name, *base64;
900 GHashTable *pixbuf_cache;
902 gl_debug (DEBUG_XML, "START");
904 name = lgl_xml_get_prop_string (node, "name", NULL);
905 base64 = lgl_xml_get_node_content (node);
907 stream = g_base64_decode ((gchar *)base64, &stream_length);
908 pixdata = g_new0 (GdkPixdata, 1);
909 ret = gdk_pixdata_deserialize (pixdata, stream_length, stream, NULL);
912 pixbuf = gdk_pixbuf_from_pixdata (pixdata, TRUE, NULL);
914 pixbuf_cache = gl_label_get_pixbuf_cache (label);
915 gl_pixbuf_cache_add_pixbuf (pixbuf_cache, (gchar *)name, pixbuf);
924 gl_debug (DEBUG_XML, "END");
928 /*--------------------------------------------------------------------------*/
929 /* PRIVATE. Parse XML embedded File node. */
930 /*--------------------------------------------------------------------------*/
932 xml_parse_file_node (xmlNodePtr node,
935 gchar *name, *format;
937 GHashTable *svg_cache;
939 name = lgl_xml_get_prop_string (node, "name", NULL);
940 format = lgl_xml_get_prop_string (node, "format", NULL);
942 if ( format && (lgl_str_utf8_casecmp (format, "SVG") == 0) )
944 content = lgl_xml_get_node_content (node);
946 svg_cache = gl_label_get_svg_cache (label);
947 gl_svg_cache_add_svg (svg_cache, name, content);
953 g_message (_("Unknown embedded file format: \"%s\""), format);
962 /*--------------------------------------------------------------------------*/
963 /* PRIVATE. Parse top-level Span tag. */
964 /*--------------------------------------------------------------------------*/
966 xml_parse_toplevel_span (xmlNodePtr node,
967 glLabelObject *object)
971 PangoWeight font_weight;
972 gboolean font_italic_flag;
973 glColorNode *color_node;
974 gdouble text_line_spacing;
976 GList *lines, *text_nodes;
978 glTextNode *text_node;
981 gl_debug (DEBUG_XML, "START");
983 /* Font family attr */
984 font_family = lgl_xml_get_prop_string (node, "font_family", "Sans");
985 gl_label_object_set_font_family (object, font_family, FALSE);
986 g_free (font_family);
989 font_size = lgl_xml_get_prop_double (node, "font_size", 0.0);
990 gl_label_object_set_font_size (object, font_size, FALSE);
992 /* Font weight attr */
993 string = lgl_xml_get_prop_string (node, "font_weight", NULL);
994 font_weight = gl_str_util_string_to_weight (string);
996 gl_label_object_set_font_weight (object, font_weight, FALSE);
998 /* Font italic flag attr */
999 font_italic_flag = lgl_xml_get_prop_boolean (node, "font_italic", FALSE);
1000 gl_label_object_set_font_italic_flag (object, font_italic_flag, FALSE);
1002 /* Text color attr */
1003 color_node = gl_color_node_new_default ();
1004 string = lgl_xml_get_prop_string (node, "color_field", NULL);
1006 color_node->field_flag = TRUE;
1007 color_node->key = string;
1009 color_node->color = lgl_xml_get_prop_uint (node, "color", 0);
1011 gl_label_object_set_text_color (object, color_node, FALSE);
1012 gl_color_node_free (&color_node);
1014 /* Text line spacing attr */
1015 text_line_spacing = lgl_xml_get_prop_double (node, "line_spacing", 1.0);
1016 gl_label_object_set_text_line_spacing (object, text_line_spacing, FALSE);
1018 /* Now descend children, and build lines of text nodes */
1021 strip_regex = g_regex_new("\\A\\n\\s*|\\n\\s*\\Z", 0, 0, NULL);
1022 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
1024 if (lgl_xml_is_node (child, "Span")) {
1026 g_message ("Unexpected rich text (not supported, yet!)");
1028 } else if (lgl_xml_is_node (child, "Field")) {
1031 string = lgl_xml_get_prop_string (child, "name", NULL);
1032 text_node = g_new0 (glTextNode, 1);
1033 text_node->field_flag = TRUE;
1034 text_node->data = string;
1035 text_nodes = g_list_append (text_nodes, text_node);
1037 } else if (lgl_xml_is_node (child, "NL")) {
1040 lines = g_list_append (lines, text_nodes);
1043 } else if (xmlNodeIsText (child)) {
1044 gchar *orig_data = lgl_xml_get_node_content (child);
1049 /* Stip out white space before and after */
1050 data = g_regex_replace(strip_regex, orig_data, -1, 0, "", 0, NULL);
1053 text_node = g_new0 (glTextNode, 1);
1054 text_node->field_flag = FALSE;
1055 text_node->data = g_strdup ((gchar *)data);
1056 text_nodes = g_list_append (text_nodes, text_node);
1061 g_message ("Unexpected Span child: \"%s\"", child->name);
1065 g_free (strip_regex);
1067 /* Store last line. */
1068 lines = g_list_append (lines, text_nodes);
1071 gl_label_text_set_lines (GL_LABEL_TEXT(object), lines, FALSE);
1072 gl_text_node_lines_free (&lines);
1074 gl_debug (DEBUG_XML, "END");
1078 /*--------------------------------------------------------------------------*/
1079 /* PRIVATE. Parse affine attributes. */
1080 /*--------------------------------------------------------------------------*/
1082 xml_parse_affine_attrs (xmlNodePtr node,
1083 glLabelObject *object)
1086 cairo_matrix_t matrix;
1088 a[0] = lgl_xml_get_prop_double (node, "a0", 0.0);
1089 a[1] = lgl_xml_get_prop_double (node, "a1", 0.0);
1090 a[2] = lgl_xml_get_prop_double (node, "a2", 0.0);
1091 a[3] = lgl_xml_get_prop_double (node, "a3", 0.0);
1092 a[4] = lgl_xml_get_prop_double (node, "a4", 0.0);
1093 a[5] = lgl_xml_get_prop_double (node, "a5", 0.0);
1095 cairo_matrix_init (&matrix, a[0], a[1], a[2], a[3], a[4], a[5]);
1097 gl_label_object_set_matrix (object, &matrix);
1101 /*--------------------------------------------------------------------------*/
1102 /* PRIVATE. Parse shadow attributes. */
1103 /*--------------------------------------------------------------------------*/
1105 xml_parse_shadow_attrs (xmlNodePtr node,
1106 glLabelObject *object)
1108 gboolean shadow_state;
1111 glColorNode *shadow_color_node;
1112 gdouble shadow_opacity;
1115 shadow_state = lgl_xml_get_prop_boolean (node, "shadow", FALSE);
1116 gl_label_object_set_shadow_state (object, shadow_state, FALSE);
1120 shadow_x = lgl_xml_get_prop_length (node, "shadow_x", 0.0);
1121 shadow_y = lgl_xml_get_prop_length (node, "shadow_y", 0.0);
1122 gl_label_object_set_shadow_offset (object, shadow_x, shadow_y, FALSE);
1124 shadow_color_node = gl_color_node_new_default ();
1125 string = lgl_xml_get_prop_string (node, "shadow_color_field", NULL);
1127 shadow_color_node->field_flag = TRUE;
1128 shadow_color_node->key = string;
1130 shadow_color_node->color = lgl_xml_get_prop_uint (node, "shadow_color", 0);
1132 gl_label_object_set_shadow_color (object, shadow_color_node, FALSE);
1133 gl_color_node_free (&shadow_color_node);
1135 shadow_opacity = lgl_xml_get_prop_double (node, "shadow_opacity", 1.0);
1136 gl_label_object_set_shadow_opacity (object, shadow_opacity, FALSE);
1141 /****************************************************************************/
1142 /* Save label to xml label file. */
1143 /****************************************************************************/
1145 gl_xml_label_save (glLabel *label,
1146 const gchar *utf8_filename,
1147 glXMLLabelStatus *status)
1153 gl_debug (DEBUG_XML, "START");
1155 doc = xml_label_to_doc (label, status);
1157 filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
1159 g_message (_("Utf8 conversion error."));
1161 xmlSetDocCompressMode (doc, gl_label_get_compression (label));
1162 xml_ret = xmlSaveFormatFile (filename, doc, TRUE);
1164 if (xml_ret == -1) {
1166 g_message (_("Problem saving xml file."));
1167 *status = XML_LABEL_ERROR_SAVE_FILE;
1171 gl_label_set_filename (label, utf8_filename);
1172 gl_label_clear_modified (label);
1178 gl_debug (DEBUG_XML, "END");
1182 /****************************************************************************/
1183 /* Save label to xml buffer. */
1184 /****************************************************************************/
1186 gl_xml_label_save_buffer (glLabel *label,
1187 glXMLLabelStatus *status)
1193 gl_debug (DEBUG_XML, "START");
1195 doc = xml_label_to_doc (label, status);
1197 xmlDocDumpMemory (doc, &buffer, &size);
1200 gl_label_clear_modified (label);
1202 gl_debug (DEBUG_XML, "END");
1204 return (gchar *)buffer;
1208 /*--------------------------------------------------------------------------*/
1209 /* PRIVATE. Convert label to xml doc structure. */
1210 /*--------------------------------------------------------------------------*/
1212 xml_label_to_doc (glLabel *label,
1213 glXMLLabelStatus *status)
1218 const lglTemplate *template;
1221 gl_debug (DEBUG_XML, "START");
1223 LIBXML_TEST_VERSION;
1225 units = gl_prefs_model_get_units (gl_prefs);
1226 lgl_xml_set_default_units (units);
1228 doc = xmlNewDoc ((xmlChar *)"1.0");
1229 doc->xmlRootNode = xmlNewDocNode (doc, NULL, (xmlChar *)"Glabels-document", NULL);
1231 ns = xmlNewNs (doc->xmlRootNode, (xmlChar *)LGL_XML_NAME_SPACE, NULL);
1232 xmlSetNs (doc->xmlRootNode, ns);
1234 template = gl_label_get_template (label);
1235 lgl_xml_template_create_template_node (template, doc->xmlRootNode, ns);
1237 xml_create_objects (doc->xmlRootNode, ns, label);
1239 merge = gl_label_get_merge (label);
1240 gl_debug (DEBUG_XML, "merge=%p", merge);
1241 if (merge != NULL) {
1242 xml_create_merge_fields (doc->xmlRootNode, ns, label);
1243 g_object_unref (G_OBJECT(merge));
1246 xml_create_data (doc, doc->xmlRootNode, ns, label);
1248 gl_debug (DEBUG_XML, "END");
1250 *status = XML_LABEL_OK;
1255 /*--------------------------------------------------------------------------*/
1256 /* PRIVATE. Add XML Objects Node */
1257 /*--------------------------------------------------------------------------*/
1259 xml_create_objects (xmlNodePtr parent,
1264 gboolean rotate_flag;
1265 const GList *object_list;
1267 glLabelObject *object;
1269 gl_debug (DEBUG_XML, "START");
1271 rotate_flag = gl_label_get_rotate_flag (label);
1272 object_list = gl_label_get_object_list (label);
1274 node = xmlNewChild (parent, ns, (xmlChar *)"Objects", NULL);
1275 lgl_xml_set_prop_string (node, "id", "0");
1276 lgl_xml_set_prop_boolean (node, "rotate", rotate_flag);
1278 for (p = (GList *)object_list; p != NULL; p = p->next) {
1280 object = GL_LABEL_OBJECT(p->data);
1282 if ( GL_IS_LABEL_TEXT(object) ) {
1283 xml_create_object_text (node, ns, object);
1284 } else if ( GL_IS_LABEL_BOX(object) ) {
1285 xml_create_object_box (node, ns, object);
1286 } else if ( GL_IS_LABEL_ELLIPSE(object) ) {
1287 xml_create_object_ellipse (node, ns, object);
1288 } else if ( GL_IS_LABEL_LINE(object) ) {
1289 xml_create_object_line (node, ns, object);
1290 } else if ( GL_IS_LABEL_IMAGE(object) ) {
1291 xml_create_object_image (node, ns, object);
1292 } else if ( GL_IS_LABEL_BARCODE(object) ) {
1293 xml_create_object_barcode (node, ns, object);
1295 g_message ("Unknown label object");
1300 gl_debug (DEBUG_XML, "END");
1304 /*--------------------------------------------------------------------------*/
1305 /* PRIVATE. Add XML Objects->Object-text Node */
1306 /*--------------------------------------------------------------------------*/
1308 xml_create_object_text (xmlNodePtr parent,
1310 glLabelObject *object)
1315 PangoAlignment align;
1316 gboolean auto_shrink;
1318 gl_debug (DEBUG_XML, "START");
1320 node = xmlNewChild (parent, ns, (xmlChar *)"Object-text", NULL);
1322 /* position attrs */
1323 gl_label_object_get_position (object, &x, &y);
1324 lgl_xml_set_prop_length (node, "x", x);
1325 lgl_xml_set_prop_length (node, "y", y);
1328 gl_label_object_get_raw_size ( object, &w, &h);
1329 lgl_xml_set_prop_length (node, "w", w);
1330 lgl_xml_set_prop_length (node, "h", h);
1333 align = gl_label_object_get_text_alignment (object);
1334 lgl_xml_set_prop_string (node, "justify", gl_str_util_align_to_string (align));
1336 /* auto_shrink attr */
1337 auto_shrink = gl_label_text_get_auto_shrink (GL_LABEL_TEXT (object));
1338 lgl_xml_set_prop_boolean (node, "auto_shrink", auto_shrink);
1341 xml_create_affine_attrs (node, object);
1344 xml_create_shadow_attrs (node, object);
1347 xml_create_toplevel_span (node, ns, GL_LABEL_TEXT(object));
1349 gl_debug (DEBUG_XML, "END");
1353 /*--------------------------------------------------------------------------*/
1354 /* PRIVATE. Add XML Objects->Object-box Node */
1355 /*--------------------------------------------------------------------------*/
1357 xml_create_object_box (xmlNodePtr parent,
1359 glLabelObject *object)
1365 glColorNode *line_color_node;
1366 glColorNode *fill_color_node;
1368 gl_debug (DEBUG_XML, "START");
1370 node = xmlNewChild (parent, ns, (xmlChar *)"Object-box", NULL);
1372 /* position attrs */
1373 gl_label_object_get_position (object, &x, &y);
1374 lgl_xml_set_prop_length (node, "x", x);
1375 lgl_xml_set_prop_length (node, "y", y);
1378 gl_label_object_get_size (object, &w, &h);
1379 lgl_xml_set_prop_length (node, "w", w);
1380 lgl_xml_set_prop_length (node, "h", h);
1383 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1384 lgl_xml_set_prop_length (node, "line_width", line_width);
1386 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1387 if (line_color_node->field_flag)
1389 lgl_xml_set_prop_string (node, "line_color_field", line_color_node->key);
1393 lgl_xml_set_prop_uint_hex (node, "line_color", line_color_node->color);
1395 gl_color_node_free (&line_color_node);
1397 /* fill attrs (color or field) */
1398 fill_color_node = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
1399 if (fill_color_node->field_flag)
1401 lgl_xml_set_prop_string (node, "fill_color_field", fill_color_node->key);
1405 lgl_xml_set_prop_uint_hex (node, "fill_color", fill_color_node->color);
1407 gl_color_node_free (&fill_color_node);
1410 xml_create_affine_attrs (node, object);
1413 xml_create_shadow_attrs (node, object);
1415 gl_debug (DEBUG_XML, "END");
1419 /*--------------------------------------------------------------------------*/
1420 /* PRIVATE. Add XML Objects->Object-ellipse Node */
1421 /*--------------------------------------------------------------------------*/
1423 xml_create_object_ellipse (xmlNodePtr parent,
1425 glLabelObject *object)
1431 glColorNode *line_color_node;
1432 glColorNode *fill_color_node;
1434 gl_debug (DEBUG_XML, "START");
1436 node = xmlNewChild (parent, ns, (xmlChar *)"Object-ellipse", NULL);
1438 /* position attrs */
1439 gl_label_object_get_position (object, &x, &y);
1440 lgl_xml_set_prop_length (node, "x", x);
1441 lgl_xml_set_prop_length (node, "y", y);
1444 gl_label_object_get_size (object, &w, &h);
1445 lgl_xml_set_prop_length (node, "w", w);
1446 lgl_xml_set_prop_length (node, "h", h);
1449 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1450 lgl_xml_set_prop_length (node, "line_width", line_width);
1452 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1453 if (line_color_node->field_flag)
1455 lgl_xml_set_prop_string (node, "line_color_field", line_color_node->key);
1459 lgl_xml_set_prop_uint_hex (node, "line_color", line_color_node->color);
1461 gl_color_node_free (&line_color_node);
1464 /* fill attrs (color or field) */
1465 fill_color_node = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
1466 if (fill_color_node->field_flag)
1468 lgl_xml_set_prop_string (node, "fill_color_field", fill_color_node->key);
1472 lgl_xml_set_prop_uint_hex (node, "fill_color", fill_color_node->color);
1474 gl_color_node_free (&fill_color_node);
1477 xml_create_affine_attrs (node, object);
1480 xml_create_shadow_attrs (node, object);
1482 gl_debug (DEBUG_XML, "END");
1486 /*--------------------------------------------------------------------------*/
1487 /* PRIVATE. Add XML Objects->Object-line Node */
1488 /*--------------------------------------------------------------------------*/
1490 xml_create_object_line (xmlNodePtr parent,
1492 glLabelObject *object)
1498 glColorNode *line_color_node;
1500 gl_debug (DEBUG_XML, "START");
1502 node = xmlNewChild (parent, ns, (xmlChar *)"Object-line", NULL);
1504 /* position attrs */
1505 gl_label_object_get_position (object, &x, &y);
1506 lgl_xml_set_prop_length (node, "x", x);
1507 lgl_xml_set_prop_length (node, "y", y);
1510 gl_label_object_get_size (object, &dx, &dy);
1511 lgl_xml_set_prop_length (node, "dx", dx);
1512 lgl_xml_set_prop_length (node, "dy", dy);
1515 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
1516 lgl_xml_set_prop_length (node, "line_width", line_width);
1518 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1519 if (line_color_node->field_flag)
1521 lgl_xml_set_prop_string (node, "line_color_field", line_color_node->key);
1525 lgl_xml_set_prop_uint_hex (node, "line_color", line_color_node->color);
1527 gl_color_node_free (&line_color_node);
1531 xml_create_affine_attrs (node, object);
1534 xml_create_shadow_attrs (node, object);
1536 gl_debug (DEBUG_XML, "END");
1540 /*--------------------------------------------------------------------------*/
1541 /* PRIVATE. Add XML Objects->Object-image Node */
1542 /*--------------------------------------------------------------------------*/
1544 xml_create_object_image (xmlNodePtr parent,
1546 glLabelObject *object)
1551 glTextNode *filename;
1553 gl_debug (DEBUG_XML, "START");
1555 node = xmlNewChild (parent, ns, (xmlChar *)"Object-image", NULL);
1557 /* position attrs */
1558 gl_label_object_get_position (object, &x, &y);
1559 lgl_xml_set_prop_length (node, "x", x);
1560 lgl_xml_set_prop_length (node, "y", y);
1563 gl_label_object_get_size (object, &w, &h);
1564 lgl_xml_set_prop_length (node, "w", w);
1565 lgl_xml_set_prop_length (node, "h", h);
1567 /* src OR field attr */
1568 filename = gl_label_image_get_filename (GL_LABEL_IMAGE(object));
1569 if (filename->field_flag) {
1570 lgl_xml_set_prop_string (node, "field", filename->data);
1572 lgl_xml_set_prop_string (node, "src", filename->data);
1574 gl_text_node_free (&filename);
1577 xml_create_affine_attrs (node, object);
1580 xml_create_shadow_attrs (node, object);
1582 gl_debug (DEBUG_XML, "END");
1586 /*--------------------------------------------------------------------------*/
1587 /* PRIVATE. Add XML Objects->Object-barcode Node */
1588 /*--------------------------------------------------------------------------*/
1590 xml_create_object_barcode (xmlNodePtr parent,
1592 glLabelObject *object)
1597 glTextNode *text_node;
1598 glLabelBarcodeStyle *style;
1599 glColorNode *color_node;
1601 gl_debug (DEBUG_XML, "START");
1603 node = xmlNewChild (parent, ns, (xmlChar *)"Object-barcode", NULL);
1605 /* position attrs */
1606 gl_label_object_get_position (object, &x, &y);
1607 lgl_xml_set_prop_length (node, "x", x);
1608 lgl_xml_set_prop_length (node, "y", y);
1611 gl_label_object_get_raw_size (object, &w, &h);
1612 lgl_xml_set_prop_length (node, "w", w);
1613 lgl_xml_set_prop_length (node, "h", h);
1615 /* Barcode properties attrs */
1616 style = gl_label_barcode_get_style (GL_LABEL_BARCODE(object));
1617 lgl_xml_set_prop_string (node, "backend", style->backend_id);
1618 lgl_xml_set_prop_string (node, "style", style->id);
1619 lgl_xml_set_prop_boolean (node, "text", style->text_flag);
1620 lgl_xml_set_prop_boolean (node, "checksum", style->checksum_flag);
1622 color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
1623 if (color_node->field_flag)
1625 lgl_xml_set_prop_string (node, "color_field", color_node->key);
1629 lgl_xml_set_prop_uint_hex (node, "color", color_node->color);
1631 gl_color_node_free (&color_node);
1634 /* data OR field attr */
1635 text_node = gl_label_barcode_get_data (GL_LABEL_BARCODE(object));
1636 if (text_node->field_flag) {
1637 lgl_xml_set_prop_string (node, "field", text_node->data);
1638 lgl_xml_set_prop_int (node, "format", style->format_digits);
1640 lgl_xml_set_prop_string (node, "data", text_node->data);
1642 gl_text_node_free (&text_node);
1645 xml_create_affine_attrs (node, object);
1648 xml_create_shadow_attrs (node, object);
1650 gl_label_barcode_style_free (style);
1652 gl_debug (DEBUG_XML, "END");
1656 /*--------------------------------------------------------------------------*/
1657 /* PRIVATE. Add XML Label Merge Fields Node */
1658 /*--------------------------------------------------------------------------*/
1660 xml_create_merge_fields (xmlNodePtr parent,
1668 gl_debug (DEBUG_XML, "START");
1670 merge = gl_label_get_merge (label);
1672 node = xmlNewChild (parent, ns, (xmlChar *)"Merge", NULL);
1674 string = gl_merge_get_name (merge);
1675 lgl_xml_set_prop_string (node, "type", string);
1678 string = gl_merge_get_src (merge);
1679 lgl_xml_set_prop_string (node, "src", string);
1682 g_object_unref (G_OBJECT(merge));
1684 gl_debug (DEBUG_XML, "END");
1688 /*--------------------------------------------------------------------------*/
1689 /* PRIVATE. Add XML Label Data Node */
1690 /*--------------------------------------------------------------------------*/
1692 xml_create_data (xmlDocPtr doc,
1699 GList *name_list, *p;
1701 gl_debug (DEBUG_XML, "START");
1703 node = xmlNewChild (parent, ns, (xmlChar *)"Data", NULL);
1705 cache = gl_label_get_pixbuf_cache (label);
1706 name_list = gl_pixbuf_cache_get_name_list (cache);
1708 for (p = name_list; p != NULL; p=p->next) {
1709 xml_create_pixdata (node, ns, label, p->data);
1712 gl_pixbuf_cache_free_name_list (name_list);
1715 cache = gl_label_get_svg_cache (label);
1716 name_list = gl_svg_cache_get_name_list (cache);
1718 for (p = name_list; p != NULL; p=p->next) {
1719 xml_create_file_svg (doc, node, ns, label, p->data);
1722 gl_pixbuf_cache_free_name_list (name_list);
1725 gl_debug (DEBUG_XML, "END");
1729 /*--------------------------------------------------------------------------*/
1730 /* PRIVATE. Add XML Label Data embedded Pixdata Node */
1731 /*--------------------------------------------------------------------------*/
1733 xml_create_pixdata (xmlNodePtr parent,
1739 GHashTable *pixbuf_cache;
1741 GdkPixdata *pixdata;
1743 guint stream_length;
1746 gl_debug (DEBUG_XML, "START");
1748 pixbuf_cache = gl_label_get_pixbuf_cache (label);
1750 pixbuf = gl_pixbuf_cache_get_pixbuf (pixbuf_cache, name);
1751 if ( pixbuf != NULL ) {
1753 pixdata = g_new0 (GdkPixdata, 1);
1754 gdk_pixdata_from_pixbuf (pixdata, pixbuf, FALSE);
1755 stream = gdk_pixdata_serialize (pixdata, &stream_length);
1756 base64 = g_base64_encode (stream, stream_length);
1758 node = xmlNewChild (parent, ns, (xmlChar *)"Pixdata", (xmlChar *)base64);
1759 lgl_xml_set_prop_string (node, "name", name);
1760 lgl_xml_set_prop_string (node, "encoding", "Base64");
1762 gl_pixbuf_cache_remove_pixbuf (pixbuf_cache, name);
1770 gl_debug (DEBUG_XML, "END");
1774 /*--------------------------------------------------------------------------*/
1775 /* PRIVATE. Add XML Label Data embedded SVG file Node */
1776 /*--------------------------------------------------------------------------*/
1778 xml_create_file_svg (xmlDocPtr doc,
1785 xmlNodePtr cdata_section_node;
1786 GHashTable *svg_cache;
1789 gl_debug (DEBUG_XML, "START");
1791 svg_cache = gl_label_get_svg_cache (label);
1793 svg_data = gl_svg_cache_get_contents (svg_cache, name);
1794 if ( svg_data != NULL ) {
1796 node = xmlNewChild (parent, ns, (xmlChar *)"File", NULL);
1797 lgl_xml_set_prop_string (node, "name", name);
1798 lgl_xml_set_prop_string (node, "format", "SVG");
1800 cdata_section_node = xmlNewCDataBlock (doc, (xmlChar *)svg_data, strlen (svg_data));
1801 xmlAddChild (node, cdata_section_node);
1807 gl_debug (DEBUG_XML, "END");
1811 /*--------------------------------------------------------------------------*/
1812 /* PRIVATE. Create top-level Span node. */
1813 /*--------------------------------------------------------------------------*/
1815 xml_create_toplevel_span (xmlNodePtr parent,
1817 glLabelText *object_text)
1822 PangoWeight font_weight;
1823 gboolean font_italic_flag;
1824 glColorNode *color_node;
1825 PangoAlignment align;
1826 gdouble text_line_spacing;
1827 GList *lines, *p_line, *p_node;
1828 glTextNode *text_node;
1831 node = xmlNewChild (parent, ns, (xmlChar *)"Span", NULL);
1833 /* All span attrs at top level. */
1834 font_family = gl_label_object_get_font_family (GL_LABEL_OBJECT(object_text));
1835 font_size = gl_label_object_get_font_size (GL_LABEL_OBJECT(object_text));
1836 text_line_spacing = gl_label_object_get_text_line_spacing (GL_LABEL_OBJECT(object_text));
1837 font_weight = gl_label_object_get_font_weight (GL_LABEL_OBJECT(object_text));
1838 font_italic_flag = gl_label_object_get_font_italic_flag (GL_LABEL_OBJECT(object_text));
1840 color_node = gl_label_object_get_text_color (GL_LABEL_OBJECT(object_text));
1841 if (color_node->field_flag)
1843 lgl_xml_set_prop_string (node, "color_field", color_node->key);
1847 lgl_xml_set_prop_uint_hex (node, "color", color_node->color);
1849 gl_color_node_free (&color_node);
1851 align = gl_label_object_get_text_alignment (GL_LABEL_OBJECT(object_text));
1852 lgl_xml_set_prop_string (node, "font_family", font_family);
1853 lgl_xml_set_prop_double (node, "font_size", font_size);
1854 lgl_xml_set_prop_string (node, "font_weight", gl_str_util_weight_to_string (font_weight));
1855 lgl_xml_set_prop_boolean (node, "font_italic", font_italic_flag);
1857 lgl_xml_set_prop_double (node, "line_spacing", text_line_spacing);
1859 /* Build children. */
1860 lines = gl_label_text_get_lines (GL_LABEL_TEXT(object_text));
1861 for (p_line = lines; p_line != NULL; p_line = p_line->next) {
1863 for (p_node = (GList *) p_line->data; p_node != NULL;
1864 p_node = p_node->next) {
1865 text_node = (glTextNode *) p_node->data;
1867 if (text_node->field_flag) {
1868 child = xmlNewChild (node, ns, (xmlChar *)"Field", NULL);
1869 lgl_xml_set_prop_string (child, "name", text_node->data);
1871 xmlNodeAddContent (node, (xmlChar *)text_node->data);
1876 if ( p_line->next ) {
1877 child = xmlNewChild (node, ns, (xmlChar *)"NL", NULL);
1882 gl_text_node_lines_free (&lines);
1883 g_free (font_family);
1888 /*--------------------------------------------------------------------------*/
1889 /* PRIVATE. Create affine attributes. */
1890 /*--------------------------------------------------------------------------*/
1892 xml_create_affine_attrs (xmlNodePtr node,
1893 glLabelObject *object)
1895 cairo_matrix_t matrix;
1897 gl_label_object_get_matrix (object, &matrix);
1899 lgl_xml_set_prop_double (node, "a0", matrix.xx);
1900 lgl_xml_set_prop_double (node, "a1", matrix.yx);
1901 lgl_xml_set_prop_double (node, "a2", matrix.xy);
1902 lgl_xml_set_prop_double (node, "a3", matrix.yy);
1903 lgl_xml_set_prop_double (node, "a4", matrix.x0);
1904 lgl_xml_set_prop_double (node, "a5", matrix.y0);
1908 /*--------------------------------------------------------------------------*/
1909 /* PRIVATE. Create shadow attributes. */
1910 /*--------------------------------------------------------------------------*/
1912 xml_create_shadow_attrs (xmlNodePtr node,
1913 glLabelObject *object)
1915 gboolean shadow_state;
1918 glColorNode *shadow_color_node;
1919 gdouble shadow_opacity;
1921 shadow_state = gl_label_object_get_shadow_state (object);
1925 lgl_xml_set_prop_boolean (node, "shadow", shadow_state);
1927 gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
1928 lgl_xml_set_prop_length (node, "shadow_x", shadow_x);
1929 lgl_xml_set_prop_length (node, "shadow_y", shadow_y);
1931 shadow_color_node = gl_label_object_get_shadow_color (object);
1932 if (shadow_color_node->field_flag)
1934 lgl_xml_set_prop_string (node, "shadow_color_field", shadow_color_node->key);
1938 lgl_xml_set_prop_uint_hex (node, "shadow_color", shadow_color_node->color);
1940 gl_color_node_free (&shadow_color_node);
1942 shadow_opacity = gl_label_object_get_shadow_opacity (object);
1943 lgl_xml_set_prop_double (node, "shadow_opacity", shadow_opacity);
1950 * Local Variables: -- emacs
1952 * c-basic-offset: 8 -- emacs
1953 * tab-width: 8 -- emacs
1954 * indent-tabs-mode: nil -- emacs