]> git.sur5r.net Git - glabels/blob - glabels2/src/xml-label.c
Added pixbuf cache and base64 modules.
[glabels] / glabels2 / src / xml-label.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  label.c:  GLabels xml label module
5  *
6  *  Copyright (C) 2001-2002  Jim Evins <evins@snaught.com>.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  */
22
23 #include <config.h>
24
25 #include <gnome.h>
26
27 #include <libxml/tree.h>
28 #include <libxml/parser.h>
29 #include <gdk-pixbuf/gdk-pixdata.h>
30
31 #include "label.h"
32 #include "label-object.h"
33 #include "label-text.h"
34 #include "label-box.h"
35 #include "label-line.h"
36 #include "label-ellipse.h"
37 #include "label-image.h"
38 #include "label-barcode.h"
39 #include "template.h"
40 #include "base64.h"
41 #include "xml-label.h"
42 #include "xml-label-04.h"
43 #include "util.h"
44
45 #include "debug.h"
46
47 /*========================================================*/
48 /* Private macros and constants.                          */
49 /*========================================================*/
50 #define NAME_SPACE "http://snaught.com/glabels/1.92/"
51 #define COMPAT01_NAME_SPACE "http://snaught.com/glabels/0.1/"
52 #define COMPAT04_NAME_SPACE "http://snaught.com/glabels/0.4/"
53
54 /*========================================================*/
55 /* Private types.                                         */
56 /*========================================================*/
57
58 /*========================================================*/
59 /* Private globals.                                       */
60 /*========================================================*/
61
62 /*========================================================*/
63 /* Private function prototypes.                           */
64 /*========================================================*/
65
66 static glLabel       *xml_doc_to_label         (xmlDocPtr         doc,
67                                                 glXMLLabelStatus *status);
68
69 static glLabel       *xml_parse_label          (xmlNodePtr        root,
70                                                 glXMLLabelStatus *status);
71
72 static void           xml_parse_objects        (xmlNodePtr        node,
73                                                 glLabel          *label);
74
75 static void           xml_parse_object         (xmlNodePtr        node,
76                                                 glLabel          *label);
77
78 static glLabelObject *xml_parse_text_props     (xmlNodePtr        node,
79                                                 glLabel          *label);
80
81 static glLabelObject *xml_parse_box_props      (xmlNodePtr        node,
82                                                 glLabel          *label);
83
84 static glLabelObject *xml_parse_line_props     (xmlNodePtr        node,
85                                                 glLabel          *label);
86
87 static glLabelObject *xml_parse_ellipse_props  (xmlNodePtr        node,
88                                                 glLabel          *label);
89
90 static glLabelObject *xml_parse_image_props    (xmlNodePtr        node,
91                                                 glLabel          *label);
92
93 static glLabelObject *xml_parse_barcode_props  (xmlNodePtr        node,
94                                                 glLabel          *label);
95
96 static void           xml_parse_merge_fields   (xmlNodePtr        node,
97                                                 glLabel          *label);
98
99 static void           xml_parse_data           (xmlNodePtr        node,
100                                                 glLabel          *label);
101
102 static void           xml_parse_pixdata        (xmlNodePtr        node,
103                                                 glLabel          *label);
104
105
106 static xmlDocPtr      xml_label_to_doc         (glLabel          *label,
107                                                 glXMLLabelStatus *status);
108
109 static void           xml_create_objects       (xmlNodePtr        root,
110                                                 xmlNsPtr          ns,
111                                                 glLabel          *label);
112
113 static void           xml_create_object        (xmlNodePtr        root,
114                                                 xmlNsPtr          ns,
115                                                 glLabelObject    *object);
116
117 static void           xml_create_text_props    (xmlNodePtr        root,
118                                                 xmlNsPtr          ns,
119                                                 glLabelObject    *object);
120
121 static void           xml_create_box_props     (xmlNodePtr        root,
122                                                 xmlNsPtr          ns,
123                                                 glLabelObject    *object);
124
125 static void           xml_create_line_props    (xmlNodePtr        root,
126                                                 xmlNsPtr          ns,
127                                                 glLabelObject    *object);
128
129 static void           xml_create_ellipse_props (xmlNodePtr        root,
130                                                 xmlNsPtr          ns,
131                                                 glLabelObject    *object);
132
133 static void           xml_create_image_props   (xmlNodePtr        root,
134                                                 xmlNsPtr          ns,
135                                                 glLabelObject    *object);
136
137 static void           xml_create_barcode_props (xmlNodePtr        root,
138                                                 xmlNsPtr          ns,
139                                                 glLabelObject    *object);
140
141 static void           xml_create_merge_fields  (xmlNodePtr        root,
142                                                 xmlNsPtr          ns,
143                                                 glLabel          *label);
144
145 static void           xml_create_data          (xmlNodePtr        root,
146                                                 xmlNsPtr          ns,
147                                                 glLabel          *label);
148
149 static void           xml_create_pixdata       (xmlNodePtr        root,
150                                                 xmlNsPtr          ns,
151                                                 glLabel          *label,
152                                                 gchar            *name);
153
154
155 /****************************************************************************/
156 /* Open and read label from xml file.                                       */
157 /****************************************************************************/
158 glLabel *
159 gl_xml_label_open (const gchar      *filename,
160                    glXMLLabelStatus *status)
161 {
162         xmlDocPtr  doc;
163         glLabel   *label;
164
165         gl_debug (DEBUG_XML, "START");
166
167         doc = xmlParseFile (filename);
168         if (!doc) {
169                 g_warning (_("xmlParseFile error"));
170                 *status = XML_LABEL_ERROR_OPEN_PARSE;
171                 return NULL;
172         }
173
174         label = xml_doc_to_label (doc, status);
175
176         xmlFreeDoc (doc);
177
178         gl_label_set_filename (label, filename);
179         gl_label_clear_modified (label);
180
181         gl_debug (DEBUG_XML, "END");
182
183         return label;
184 }
185
186 /****************************************************************************/
187 /* Read label from xml buffer.                                              */
188 /****************************************************************************/
189 glLabel *
190 gl_xml_label_open_buffer (const gchar      *buffer,
191                           glXMLLabelStatus *status)
192 {
193         xmlDocPtr  doc;
194         glLabel   *label;
195
196         gl_debug (DEBUG_XML, "START");
197
198         doc = xmlParseDoc ((xmlChar *) buffer);
199         if (!doc) {
200                 g_warning (_("xmlParseFile error"));
201                 *status = XML_LABEL_ERROR_OPEN_PARSE;
202                 return NULL;
203         }
204
205         label = xml_doc_to_label (doc, status);
206
207         gl_label_clear_modified (label);
208
209         xmlFreeDoc (doc);
210
211         gl_debug (DEBUG_XML, "END");
212
213         return label;
214 }
215
216 /*--------------------------------------------------------------------------*/
217 /* PRIVATE.  Parse xml doc structure and create label.                      */
218 /*--------------------------------------------------------------------------*/
219 static glLabel *
220 xml_doc_to_label (xmlDocPtr         doc,
221                   glXMLLabelStatus *status)
222 {
223         xmlNodePtr  root, node;
224         xmlNsPtr    ns;
225         glLabel    *label;
226
227         gl_debug (DEBUG_XML, "START");
228
229         LIBXML_TEST_VERSION;
230
231         *status = XML_LABEL_OK;
232
233         root = xmlDocGetRootElement (doc);
234         if (!root || !root->name) {
235                 g_warning (_("No document root"));
236                 *status = XML_LABEL_ERROR_OPEN_PARSE;
237                 return NULL;
238         }
239
240         ns = xmlSearchNsByHref (doc, root, NAME_SPACE);
241         if (ns != NULL) {
242                 label = xml_parse_label (root, status);
243         } else {
244                 /* Try compatability mode 0.1 */
245                 ns = xmlSearchNsByHref (doc, root, COMPAT01_NAME_SPACE);
246                 if (ns != NULL) {
247                         g_warning (_("Importing from glabels 0.1 format"));
248                         g_warning ("TODO");
249                         label = NULL; /* TODO */
250                 } else {
251                         /* Try compatability mode 0.4 */
252                         ns = xmlSearchNsByHref (doc, root,
253                                                 COMPAT04_NAME_SPACE);
254                         if (ns != NULL) {
255                                 g_warning (_("Importing from glabels 0.4 format"));
256                                 label = gl_xml_label_04_parse (root, status);
257                         } else {
258                                 g_warning (_("bad document, unknown glabels Namespace"));
259                                 *status = XML_LABEL_ERROR_OPEN_PARSE;
260                                 return NULL;
261                         }
262                 }
263         }
264
265         gl_debug (DEBUG_XML, "END");
266
267         return label;
268 }
269
270 /*--------------------------------------------------------------------------*/
271 /* PRIVATE.  Parse xml root node and create label.                          */
272 /*--------------------------------------------------------------------------*/
273 static glLabel *
274 xml_parse_label (xmlNodePtr        root,
275                  glXMLLabelStatus *status)
276 {
277         xmlNodePtr  node;
278         glLabel    *label;
279         glTemplate *template;
280
281         gl_debug (DEBUG_XML, "START");
282
283         *status = XML_LABEL_OK;
284
285         if (g_strcasecmp (root->name, "Document") != 0) {
286                 g_warning (_("Bad root node = \"%s\""), root->name);
287                 *status = XML_LABEL_ERROR_OPEN_PARSE;
288                 return NULL;
289         }
290
291         label = GL_LABEL(gl_label_new ());
292
293         /* Pass 1, extract data nodes to pre-load cache. */
294         for (node = root->xmlChildrenNode; node != NULL; node = node->next) {
295                 if (g_strcasecmp (node->name, "Data") == 0) {
296                         xml_parse_data (node, label);
297                 }
298         }
299
300         /* Pass 2, now extract everything else. */
301         for (node = root->xmlChildrenNode; node != NULL; node = node->next) {
302
303                 if (g_strcasecmp (node->name, "Sheet") == 0) {
304                         template = gl_template_xml_parse_sheet (node);
305                         if (!template) {
306                                 *status = XML_LABEL_UNKNOWN_MEDIA;
307                                 return NULL;
308                         }
309                         gl_label_set_template (label, template);
310                         gl_template_free (&template);
311                 } else if (g_strcasecmp (node->name, "Objects") == 0) {
312                         xml_parse_objects (node, label);
313                 } else if (g_strcasecmp (node->name, "Merge_Fields") == 0) {
314                         xml_parse_merge_fields (node, label);
315                 } else if (g_strcasecmp (node->name, "Data") == 0) {
316                         /* Handled in pass 1. */
317                 } else {
318                         if (!xmlNodeIsText (node)) {
319                                 g_warning (_("bad node in Document node =  \"%s\""),
320                                            node->name);
321                         }
322                 }
323         }
324
325         gl_debug (DEBUG_XML, "END");
326
327         return label;
328 }
329
330 /*--------------------------------------------------------------------------*/
331 /* PRIVATE.  Parse Objects node.                                            */
332 /*--------------------------------------------------------------------------*/
333 static void
334 xml_parse_objects (xmlNodePtr  objects_node,
335                    glLabel    *label)
336 {
337         gboolean   rotate_flag;
338         xmlNodePtr node;
339
340         gl_debug (DEBUG_XML, "START");
341
342         rotate_flag =
343                 !(g_strcasecmp (xmlGetProp (objects_node, "rotate"), "false") == 0);
344         gl_label_set_rotate_flag (label, rotate_flag);
345
346         for (node = objects_node->xmlChildrenNode; node != NULL; node = node->next) {
347
348                 if (g_strcasecmp (node->name, "Object") == 0) {
349                         xml_parse_object (node, label);
350                 } else {
351                         if (!xmlNodeIsText (node)) {
352                                 g_warning (_("bad node =  \"%s\""), node->name);
353                         }
354                 }
355         }
356
357         gl_debug (DEBUG_XML, "END");
358 }
359
360 /*--------------------------------------------------------------------------*/
361 /* PRIVATE.  Parse XML Object Node                                          */
362 /*--------------------------------------------------------------------------*/
363 static void
364 xml_parse_object (xmlNodePtr  object_node,
365                   glLabel    *label)
366 {
367         glLabelObject *object;
368         gdouble        x, y;
369         gchar         *type_string;
370         gdouble        affine[6];
371
372         gl_debug (DEBUG_XML, "START");
373
374         type_string = xmlGetProp (object_node, "type");
375
376         if ( g_strcasecmp (type_string, "text") == 0 ) {
377                 object = xml_parse_text_props (object_node, label);
378         } else if ( g_strcasecmp (type_string, "box") == 0 ) {
379                 object = xml_parse_box_props (object_node, label);
380         } else if ( g_strcasecmp (type_string, "line") == 0 ) {
381                 object = xml_parse_line_props (object_node, label);
382         } else if ( g_strcasecmp (type_string, "ellipse") == 0 ) {
383                 object = xml_parse_ellipse_props (object_node, label);
384         } else if ( g_strcasecmp (type_string, "image") == 0 ) {
385                 object = xml_parse_image_props (object_node, label);
386         } else if ( g_strcasecmp (type_string, "barcode") == 0 ) {
387                 object = xml_parse_barcode_props (object_node, label);
388         } else {
389                 g_warning ("Unknown label object type \"%s\"", type_string);
390                 return;
391         }
392
393         x = g_strtod (xmlGetProp (object_node, "x"), NULL);
394         y = g_strtod (xmlGetProp (object_node, "y"), NULL);
395
396         gl_label_object_set_position (object, x, y);
397
398         affine[0] = g_strtod (xmlGetProp (object_node, "a0"), NULL);
399         affine[1] = g_strtod (xmlGetProp (object_node, "a1"), NULL);
400         affine[2] = g_strtod (xmlGetProp (object_node, "a2"), NULL);
401         affine[3] = g_strtod (xmlGetProp (object_node, "a3"), NULL);
402         affine[4] = g_strtod (xmlGetProp (object_node, "a4"), NULL);
403         affine[5] = g_strtod (xmlGetProp (object_node, "a5"), NULL);
404
405         gl_label_object_set_affine (object, affine);
406
407         gl_debug (DEBUG_XML, "END");
408 }
409
410 /*--------------------------------------------------------------------------*/
411 /* PRIVATE.  Parse XML Label->Text Node Properties                          */
412 /*--------------------------------------------------------------------------*/
413 static glLabelObject *
414 xml_parse_text_props (xmlNodePtr  object_node,
415                       glLabel    *label)
416 {
417         GObject          *object;
418         GList            *lines;
419         gchar            *font_family;
420         gdouble           font_size;
421         GnomeFontWeight   font_weight;
422         gboolean          font_italic_flag;
423         guint             color;
424         GtkJustification  just;
425         xmlNodePtr        line_node, text_node;
426         glTextNode       *node_text;
427         GList            *nodes;
428
429         gl_debug (DEBUG_XML, "START");
430
431         object = gl_label_text_new (label);
432
433         font_family = xmlGetProp (object_node, "font_family");
434         font_size = g_strtod (xmlGetProp (object_node, "font_size"), NULL);
435         font_weight = gl_util_string_to_weight (xmlGetProp (object_node,
436                                                           "font_weight"));
437         font_italic_flag =
438                 !(g_strcasecmp (xmlGetProp (object_node, "font_italic"), "false") ==
439                   0);
440
441         just = gl_util_string_to_just (xmlGetProp (object_node, "justify"));
442
443         sscanf (xmlGetProp (object_node, "color"), "%x", &color);
444
445         lines = NULL;
446         for (line_node = object_node->xmlChildrenNode;
447              line_node != NULL;
448              line_node = line_node->next) {
449
450                 if (g_strcasecmp (line_node->name, "Line") == 0) {
451
452                         nodes = NULL;
453                         for (text_node = line_node->xmlChildrenNode;
454                              text_node != NULL; text_node = text_node->next) {
455
456                                 if (g_strcasecmp (text_node->name, "Field") == 0) {
457                                         node_text = g_new0 (glTextNode, 1);
458                                         node_text->field_flag = TRUE;
459                                         node_text->data =
460                                                 xmlGetProp (text_node, "name");
461                                         nodes =
462                                                 g_list_append (nodes, node_text);
463                                 } else if (g_strcasecmp (text_node->name, "Literal") == 0) {
464                                         node_text = g_new0 (glTextNode, 1);
465                                         node_text->field_flag = FALSE;
466                                         node_text->data =
467                                                 xmlNodeGetContent (text_node);
468                                         nodes =
469                                                 g_list_append (nodes, node_text);
470                                 } else if (!xmlNodeIsText) {
471                                         g_warning ("Unexpected Text Line child: \"%s\"",
472                                                    text_node->name);
473                                 }
474
475                         }
476                         lines = g_list_append (lines, nodes);
477
478                 } else if (!xmlNodeIsText (line_node)) {
479                         g_warning ("Unexpected Text child: \"%s\"",
480                                    line_node->name);
481                 }
482
483         }
484
485         gl_label_text_set_lines (GL_LABEL_TEXT(object), lines);
486         gl_label_text_set_props (GL_LABEL_TEXT(object),
487                                  font_family, font_size, font_weight,
488                                  font_italic_flag,
489                                  color, just);
490
491         gl_text_node_lines_free (&lines);
492         g_free (font_family);
493
494         gl_debug (DEBUG_XML, "END");
495
496         return GL_LABEL_OBJECT(object);
497 }
498
499 /*--------------------------------------------------------------------------*/
500 /* PRIVATE.  Parse XML Label->Box Node Properties                           */
501 /*--------------------------------------------------------------------------*/
502 static glLabelObject *
503 xml_parse_box_props (xmlNodePtr  node,
504                      glLabel    *label)
505 {
506         GObject *object;
507         gdouble  line_width;
508         guint    line_color, fill_color;
509         gdouble  w, h;
510
511         gl_debug (DEBUG_XML, "START");
512
513         object = gl_label_box_new (label);
514
515         w = g_strtod (xmlGetProp (node, "w"), NULL);
516         h = g_strtod (xmlGetProp (node, "h"), NULL);
517
518         line_width = g_strtod (xmlGetProp (node, "line_width"), NULL);
519
520         sscanf (xmlGetProp (node, "line_color"), "%x", &line_color);
521         sscanf (xmlGetProp (node, "fill_color"), "%x", &fill_color);
522
523         gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
524         gl_label_box_set_line_width (GL_LABEL_BOX(object), line_width);
525         gl_label_box_set_line_color (GL_LABEL_BOX(object), line_color);
526         gl_label_box_set_fill_color (GL_LABEL_BOX(object), fill_color);
527
528         gl_debug (DEBUG_XML, "END");
529
530         return GL_LABEL_OBJECT(object);
531 }
532
533 /*--------------------------------------------------------------------------*/
534 /* PRIVATE.  Parse XML Label->Line Node Properties                          */
535 /*--------------------------------------------------------------------------*/
536 static glLabelObject *
537 xml_parse_line_props (xmlNodePtr  node,
538                       glLabel    *label)
539 {
540         GObject *object;
541         gdouble  line_width;
542         guint    line_color;
543         gdouble  w, h;
544
545         gl_debug (DEBUG_XML, "START");
546
547         object = gl_label_line_new (label);
548
549         w = g_strtod (xmlGetProp (node, "dx"), NULL);
550         h = g_strtod (xmlGetProp (node, "dy"), NULL);
551
552         line_width = g_strtod (xmlGetProp (node, "line_width"), NULL);
553
554         sscanf (xmlGetProp (node, "line_color"), "%x", &line_color);
555
556         gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
557         gl_label_line_set_line_width (GL_LABEL_LINE(object), line_width);
558         gl_label_line_set_line_color (GL_LABEL_LINE(object), line_color);
559
560         gl_debug (DEBUG_XML, "END");
561
562         return GL_LABEL_OBJECT(object);
563 }
564
565 /*--------------------------------------------------------------------------*/
566 /* PRIVATE.  Parse XML Label->Ellipse Node Properties                       */
567 /*--------------------------------------------------------------------------*/
568 static glLabelObject *
569 xml_parse_ellipse_props (xmlNodePtr  node,
570                          glLabel    *label)
571 {
572         GObject *object;
573         gdouble  line_width;
574         guint    line_color, fill_color;
575         gdouble  w, h;
576
577         gl_debug (DEBUG_XML, "START");
578
579         object = gl_label_ellipse_new (label);
580
581         w = g_strtod (xmlGetProp (node, "w"), NULL);
582         h = g_strtod (xmlGetProp (node, "h"), NULL);
583
584         line_width = g_strtod (xmlGetProp (node, "line_width"), NULL);
585
586         sscanf (xmlGetProp (node, "line_color"), "%x", &line_color);
587         sscanf (xmlGetProp (node, "fill_color"), "%x", &fill_color);
588
589         gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
590         gl_label_ellipse_set_line_width (GL_LABEL_ELLIPSE(object), line_width);
591         gl_label_ellipse_set_line_color (GL_LABEL_ELLIPSE(object), line_color);
592         gl_label_ellipse_set_fill_color (GL_LABEL_ELLIPSE(object), fill_color);
593
594         gl_debug (DEBUG_XML, "END");
595
596         return GL_LABEL_OBJECT(object);
597 }
598
599 /*--------------------------------------------------------------------------*/
600 /* PRIVATE.  Parse XML Label->Image Node Properties                         */
601 /*--------------------------------------------------------------------------*/
602 static glLabelObject *
603 xml_parse_image_props (xmlNodePtr  node,
604                        glLabel    *label)
605 {
606         GObject      *object;
607         xmlNodePtr    child;
608         gdouble       w, h;
609         glTextNode   *filename;
610
611         gl_debug (DEBUG_XML, "START");
612
613         object = gl_label_image_new (label);
614
615         w = g_strtod (xmlGetProp (node, "w"), NULL);
616         h = g_strtod (xmlGetProp (node, "h"), NULL);
617
618         filename = g_new0 (glTextNode, 1);
619         for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
620                 if (g_strcasecmp (child->name, "Field") == 0) {
621                         filename->field_flag = TRUE;
622                         filename->data = xmlGetProp (child, "name");
623                 } else if (g_strcasecmp (child->name, "File") == 0) {
624                         filename->field_flag = FALSE;
625                         filename->data = xmlGetProp (child, "src");
626                 } else if (!xmlNodeIsText (child)) {
627                         g_warning ("Unexpected Image child: \"%s\"", child->name);
628                 }
629         }
630
631         gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
632         gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename);
633
634         gl_text_node_free (&filename);
635
636         gl_debug (DEBUG_XML, "END");
637
638         return GL_LABEL_OBJECT(object);
639 }
640
641 /*--------------------------------------------------------------------------*/
642 /* PRIVATE.  Parse XML Label->Barcode Node Properties                       */
643 /*--------------------------------------------------------------------------*/
644 static glLabelObject *
645 xml_parse_barcode_props (xmlNodePtr  node,
646                          glLabel    *label)
647 {
648         GObject            *object;
649         xmlNodePtr          child;
650         glTextNode         *text_node;
651         glBarcodeStyle      style;
652         gboolean            text_flag;
653         guint               color;
654         gdouble             scale;
655
656         gl_debug (DEBUG_XML, "START");
657
658         object = gl_label_barcode_new (label);
659
660         sscanf (xmlGetProp (node, "color"), "%x", &color);
661
662         style = gl_barcode_text_to_style (xmlGetProp (node, "style"));
663         text_flag = !(g_strcasecmp (xmlGetProp (node, "text"), "false") == 0);
664         scale = g_strtod (xmlGetProp (node, "scale"), NULL);
665
666         text_node = g_new0 (glTextNode, 1);
667         for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
668                 if (g_strcasecmp (child->name, "Field") == 0) {
669                         text_node->field_flag = TRUE;
670                         text_node->data = xmlGetProp (child, "name");
671                 } else if (g_strcasecmp (child->name, "Literal") == 0) {
672                         text_node->field_flag = FALSE;
673                         text_node->data = xmlNodeGetContent (child);
674                 } else if (!xmlNodeIsText (child)) {
675                         g_warning ("Unexpected Barcode child: \"%s\"", child->name);
676                 }
677         }
678
679         gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node);
680         gl_label_barcode_set_props (GL_LABEL_BARCODE(object),
681                                     style, text_flag, color, scale);
682
683         gl_text_node_free (&text_node);
684
685         gl_debug (DEBUG_XML, "END");
686
687         return GL_LABEL_OBJECT(object);
688 }
689
690 /*--------------------------------------------------------------------------*/
691 /* PRIVATE.  Parse XML merge fields tag.                                */
692 /*--------------------------------------------------------------------------*/
693 static void
694 xml_parse_merge_fields (xmlNodePtr  node,
695                         glLabel    *label)
696 {
697         xmlNodePtr  child;
698         glMerge    *merge;
699         gchar      *src;
700
701         gl_debug (DEBUG_XML, "START");
702
703         merge = gl_merge_new (xmlGetProp (node, "type"));
704         src = xmlGetProp (node, "src");
705         gl_merge_set_src (merge, src);
706
707         gl_label_set_merge (label, merge);
708
709         g_object_unref (G_OBJECT(merge));
710
711         gl_debug (DEBUG_XML, "END");
712 }
713
714 /*--------------------------------------------------------------------------*/
715 /* PRIVATE.  Parse XML data tag.                                            */
716 /*--------------------------------------------------------------------------*/
717 static void
718 xml_parse_data (xmlNodePtr  node,
719                 glLabel    *label)
720 {
721         xmlNodePtr  child;
722
723         gl_debug (DEBUG_XML, "START");
724
725         for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
726
727                 if (g_strcasecmp (child->name, "Pixdata") == 0) {
728                         xml_parse_pixdata (child, label);
729                 } else {
730                         if (!xmlNodeIsText (child)) {
731                                 g_warning (_("bad node in Data node =  \"%s\""),
732                                            child->name);
733                         }
734                 }
735         }
736
737         gl_debug (DEBUG_XML, "END");
738 }
739
740 /*--------------------------------------------------------------------------*/
741 /* PRIVATE.  Parse XML pixbuf data tag.                                     */
742 /*--------------------------------------------------------------------------*/
743 static void
744 xml_parse_pixdata (xmlNodePtr  node,
745                    glLabel    *label)
746 {
747         gchar      *name, *base64;
748         guchar     *stream;
749         guint       stream_length;
750         gboolean    ret;
751         GdkPixdata *pixdata;
752         GdkPixbuf  *pixbuf;
753         GHashTable *pixbuf_cache;
754
755         gl_debug (DEBUG_XML, "START");
756
757         name = xmlGetProp (node, "name");
758         base64 = xmlNodeGetContent (node);
759
760         stream = gl_base64_decode (base64, &stream_length);
761         pixdata = g_new0 (GdkPixdata, 1);
762         ret = gdk_pixdata_deserialize (pixdata, stream_length, stream, NULL);
763
764         if (ret) {
765                 pixbuf = gdk_pixbuf_from_pixdata (pixdata, TRUE, NULL);
766
767                 pixbuf_cache = gl_label_get_pixbuf_cache (label);
768                 gl_pixbuf_cache_add_pixbuf (pixbuf_cache, name, pixbuf);
769         }
770
771         g_free (name);
772         g_free (base64);
773         g_free (stream);
774         g_free (pixdata);
775
776         gl_debug (DEBUG_XML, "END");
777 }
778
779 /****************************************************************************/
780 /* Save label to xml label file.                                            */
781 /****************************************************************************/
782 void
783 gl_xml_label_save (glLabel          *label,
784                    const gchar      *filename,
785                    glXMLLabelStatus *status)
786 {
787         xmlDocPtr doc;
788         gint      xml_ret;
789
790         gl_debug (DEBUG_XML, "START");
791
792         doc = xml_label_to_doc (label, status);
793
794         xmlSetDocCompressMode (doc, 9);
795         xml_ret = xmlSaveFormatFile (filename, doc, TRUE);
796         xmlFreeDoc (doc);
797         if (xml_ret == -1) {
798
799                 g_warning (_("Problem saving xml file."));
800                 *status = XML_LABEL_ERROR_SAVE_FILE;
801
802         } else {
803
804                 gl_label_set_filename (label, filename);
805                 gl_label_clear_modified (label);
806
807         }
808
809         gl_debug (DEBUG_XML, "END");
810 }
811
812 /****************************************************************************/
813 /* Save label to xml buffer.                                                */
814 /****************************************************************************/
815 gchar *
816 gl_xml_label_save_buffer (glLabel          *label,
817                           glXMLLabelStatus *status)
818 {
819         xmlDocPtr  doc;
820         gint       size;
821         gchar     *buffer;
822
823         gl_debug (DEBUG_XML, "START");
824
825         doc = xml_label_to_doc (label, status);
826
827         xmlDocDumpMemory (doc, (xmlChar **)&buffer, &size);
828         xmlFreeDoc (doc);
829
830         gl_label_clear_modified (label);
831
832         gl_debug (DEBUG_XML, "END");
833
834         return buffer;
835 }
836
837 /*--------------------------------------------------------------------------*/
838 /* PRIVATE.  Convert label to xml doc structure.                            */
839 /*--------------------------------------------------------------------------*/
840 static xmlDocPtr
841 xml_label_to_doc (glLabel          *label,
842                   glXMLLabelStatus *status)
843 {
844         xmlDocPtr   doc;
845         xmlNsPtr    ns;
846         glTemplate *template;
847         glMerge    *merge;
848
849         gl_debug (DEBUG_XML, "START");
850
851         LIBXML_TEST_VERSION;
852
853         doc = xmlNewDoc ("1.0");
854         doc->xmlRootNode = xmlNewDocNode (doc, NULL, "Document", NULL);
855
856         ns = xmlNewNs (doc->xmlRootNode, NAME_SPACE, "glabels");
857         xmlSetNs (doc->xmlRootNode, ns);
858
859         template = gl_label_get_template (label);
860         gl_template_xml_add_sheet (template, doc->xmlRootNode, ns);
861
862         xml_create_objects (doc->xmlRootNode, ns, label);
863
864         merge = gl_label_get_merge (label);
865         gl_debug (DEBUG_XML, "merge=%p", merge);
866         if (merge != NULL) {
867                 xml_create_merge_fields (doc->xmlRootNode, ns, label);
868                 g_object_unref (G_OBJECT(merge));
869         }
870
871         xml_create_data (doc->xmlRootNode, ns, label);
872
873         gl_debug (DEBUG_XML, "END");
874
875         *status = XML_LABEL_OK;
876         return doc;
877 }
878
879 /*--------------------------------------------------------------------------*/
880 /* PRIVATE.  Add XML Label->Objects Node                                    */
881 /*--------------------------------------------------------------------------*/
882 static void
883 xml_create_objects (xmlNodePtr  root,
884                     xmlNsPtr    ns,
885                     glLabel    *label)
886 {
887         xmlNodePtr  node;
888         gboolean    rotate_flag;
889         GList      *p;
890
891         gl_debug (DEBUG_XML, "START");
892
893         rotate_flag = gl_label_get_rotate_flag (label);
894
895         node = xmlNewChild (root, ns, "Objects", NULL);
896         xmlSetProp (node, "id", "0");
897         xmlSetProp (node, "rotate", rotate_flag ? "True" : "False");
898
899         for (p = label->objects; p != NULL; p = p->next) {
900                 xml_create_object (node, ns, GL_LABEL_OBJECT(p->data));
901         }
902
903         gl_debug (DEBUG_XML, "END");
904 }
905
906 /*--------------------------------------------------------------------------*/
907 /* PRIVATE.  Add XML label object Node                                      */
908 /*--------------------------------------------------------------------------*/
909 static void
910 xml_create_object (xmlNodePtr     root,
911                    xmlNsPtr       ns,
912                    glLabelObject *object)
913 {
914         xmlNodePtr  object_node;
915         gdouble     x, y;
916         gchar      *string;
917         gdouble     affine[6];
918
919         gl_debug (DEBUG_XML, "START");
920
921         object_node = xmlNewChild (root, ns, "Object", NULL);
922
923         gl_label_object_get_position (object, &x, &y);
924         string = g_strdup_printf ("%g", x);
925         xmlSetProp (object_node, "x", string);
926         g_free (string);
927         string = g_strdup_printf ("%g", y);
928         xmlSetProp (object_node, "y", string);
929         g_free (string);
930
931         gl_label_object_get_affine (object, affine);
932         string = g_strdup_printf ("%g", affine[0]);
933         xmlSetProp (object_node, "a0", string);
934         g_free (string);
935         string = g_strdup_printf ("%g", affine[1]);
936         xmlSetProp (object_node, "a1", string);
937         g_free (string);
938         string = g_strdup_printf ("%g", affine[2]);
939         xmlSetProp (object_node, "a2", string);
940         g_free (string);
941         string = g_strdup_printf ("%g", affine[3]);
942         xmlSetProp (object_node, "a3", string);
943         g_free (string);
944         string = g_strdup_printf ("%g", affine[4]);
945         xmlSetProp (object_node, "a4", string);
946         g_free (string);
947         string = g_strdup_printf ("%g", affine[5]);
948         xmlSetProp (object_node, "a5", string);
949         g_free (string);
950
951         if ( GL_IS_LABEL_TEXT(object) ) {
952                 xml_create_text_props (object_node, ns, object);
953         } else if ( GL_IS_LABEL_BOX(object) ) {
954                 xml_create_box_props (object_node, ns, object);
955         } else if ( GL_IS_LABEL_LINE(object) ) {
956                 xml_create_line_props (object_node, ns, object);
957         } else if ( GL_IS_LABEL_ELLIPSE(object) ) {
958                 xml_create_ellipse_props (object_node, ns, object);
959         } else if ( GL_IS_LABEL_IMAGE(object) ) {
960                 xml_create_image_props (object_node, ns, object);
961         } else if ( GL_IS_LABEL_BARCODE(object) ) {
962                 xml_create_barcode_props (object_node, ns, object);
963         } else {
964                 g_warning ("Unknown label object");
965         }
966
967         gl_debug (DEBUG_XML, "END");
968 }
969
970 /*--------------------------------------------------------------------------*/
971 /* PRIVATE.  Add XML Label->Text Node Properties                            */
972 /*--------------------------------------------------------------------------*/
973 static void
974 xml_create_text_props (xmlNodePtr     object_node,
975                        xmlNsPtr       ns,
976                        glLabelObject *object)
977 {
978         xmlNodePtr        line_node, field_node, literal_node;
979         GList            *lines;
980         gchar            *font_family;
981         gdouble           font_size;
982         GnomeFontWeight   font_weight;
983         gboolean          font_italic_flag;
984         guint             color;
985         GtkJustification  just;
986         gchar            *string;
987         GList            *p_line, *p_node;
988         glTextNode       *node_text;
989
990         gl_debug (DEBUG_XML, "START");
991
992         xmlSetProp (object_node, "type", "Text");
993
994         lines = gl_label_text_get_lines (GL_LABEL_TEXT(object));
995         gl_label_text_get_props (GL_LABEL_TEXT(object),
996                                  &font_family, &font_size, &font_weight,
997                                  &font_italic_flag,
998                                  &color, &just);
999
1000         xmlSetProp (object_node, "font_family", font_family);
1001         string = g_strdup_printf ("%g", font_size);
1002         xmlSetProp (object_node, "font_size", string);
1003         g_free (string);
1004         xmlSetProp (object_node, "font_weight",
1005                     gl_util_weight_to_string (font_weight));
1006         xmlSetProp (object_node, "font_italic",
1007                     font_italic_flag?"True":"False");
1008
1009         xmlSetProp (object_node, "justify", gl_util_just_to_string (just));
1010
1011         string = g_strdup_printf ("0x%08x", color);
1012         xmlSetProp (object_node, "color", string);
1013         g_free (string);
1014
1015         for (p_line = lines; p_line != NULL; p_line = p_line->next) {
1016                 line_node = xmlNewChild (object_node, ns, "Line", NULL);
1017
1018                 for (p_node = (GList *) p_line->data; p_node != NULL;
1019                      p_node = p_node->next) {
1020                         node_text = (glTextNode *) p_node->data;
1021
1022                         if (node_text->field_flag) {
1023                                 field_node =
1024                                     xmlNewChild (line_node, ns, "Field", NULL);
1025                                 xmlSetProp (field_node, "name",
1026                                             node_text->data);
1027                         } else {
1028                                 literal_node =
1029                                     xmlNewChild (line_node, ns,
1030                                                  "Literal", node_text->data);
1031                         }
1032
1033                 }
1034
1035         }
1036
1037         gl_text_node_lines_free (&lines);
1038         g_free (font_family);
1039
1040         gl_debug (DEBUG_XML, "END");
1041 }
1042
1043 /*--------------------------------------------------------------------------*/
1044 /* PRIVATE.  Add XML Label->Box Node Properties                             */
1045 /*--------------------------------------------------------------------------*/
1046 static void
1047 xml_create_box_props (xmlNodePtr     object_node,
1048                       xmlNsPtr       ns,
1049                       glLabelObject *object)
1050 {
1051         gchar   *string;
1052         gdouble  line_width;
1053         guint    line_color, fill_color;
1054         gdouble  w, h;
1055
1056         gl_debug (DEBUG_XML, "START");
1057
1058         xmlSetProp (object_node, "type", "Box");
1059
1060         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1061         line_width = gl_label_box_get_line_width (GL_LABEL_BOX(object));
1062         line_color = gl_label_box_get_line_color (GL_LABEL_BOX(object));
1063         fill_color = gl_label_box_get_fill_color (GL_LABEL_BOX(object));
1064
1065         string = g_strdup_printf ("%g", w);
1066         xmlSetProp (object_node, "w", string);
1067         g_free (string);
1068         string = g_strdup_printf ("%g", h);
1069         xmlSetProp (object_node, "h", string);
1070         g_free (string);
1071
1072         string = g_strdup_printf ("%g", line_width);
1073         xmlSetProp (object_node, "line_width", string);
1074         g_free (string);
1075
1076         string = g_strdup_printf ("0x%08x", line_color);
1077         xmlSetProp (object_node, "line_color", string);
1078         g_free (string);
1079
1080         string = g_strdup_printf ("0x%08x", fill_color);
1081         xmlSetProp (object_node, "fill_color", string);
1082         g_free (string);
1083
1084         gl_debug (DEBUG_XML, "END");
1085 }
1086
1087 /*--------------------------------------------------------------------------*/
1088 /* PRIVATE.  Add XML Label->Line Node Properties                            */
1089 /*--------------------------------------------------------------------------*/
1090 static void
1091 xml_create_line_props (xmlNodePtr     object_node,
1092                        xmlNsPtr       ns,
1093                        glLabelObject *object)
1094 {
1095         gchar   *string;
1096         gdouble  line_width;
1097         guint    line_color;
1098         gdouble  w, h;
1099
1100         gl_debug (DEBUG_XML, "START");
1101
1102         xmlSetProp (object_node, "type", "Line");
1103
1104         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1105         line_width = gl_label_line_get_line_width (GL_LABEL_LINE(object));
1106         line_color = gl_label_line_get_line_color (GL_LABEL_LINE(object));
1107
1108         string = g_strdup_printf ("%g", w);
1109         xmlSetProp (object_node, "dx", string);
1110         g_free (string);
1111         string = g_strdup_printf ("%g", h);
1112         xmlSetProp (object_node, "dy", string);
1113         g_free (string);
1114
1115         string = g_strdup_printf ("%g", line_width);
1116         xmlSetProp (object_node, "line_width", string);
1117         g_free (string);
1118
1119         string = g_strdup_printf ("0x%08x", line_color);
1120         xmlSetProp (object_node, "line_color", string);
1121         g_free (string);
1122
1123         gl_debug (DEBUG_XML, "END");
1124 }
1125
1126 /*--------------------------------------------------------------------------*/
1127 /* PRIVATE.  Add XML Label->Ellipse Node Properties                         */
1128 /*--------------------------------------------------------------------------*/
1129 static void
1130 xml_create_ellipse_props (xmlNodePtr     object_node,
1131                           xmlNsPtr       ns,
1132                           glLabelObject *object)
1133 {
1134         gchar   *string;
1135         gdouble  line_width;
1136         guint    line_color, fill_color;
1137         gdouble  w, h;
1138
1139         gl_debug (DEBUG_XML, "START");
1140
1141         xmlSetProp (object_node, "type", "Ellipse");
1142
1143         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1144         line_width = gl_label_ellipse_get_line_width (GL_LABEL_ELLIPSE(object));
1145         line_color = gl_label_ellipse_get_line_color (GL_LABEL_ELLIPSE(object));
1146         fill_color = gl_label_ellipse_get_fill_color (GL_LABEL_ELLIPSE(object));
1147
1148         string = g_strdup_printf ("%g", w);
1149         xmlSetProp (object_node, "w", string);
1150         g_free (string);
1151         string = g_strdup_printf ("%g", h);
1152         xmlSetProp (object_node, "h", string);
1153         g_free (string);
1154
1155         string = g_strdup_printf ("%g", line_width);
1156         xmlSetProp (object_node, "line_width", string);
1157         g_free (string);
1158
1159         string = g_strdup_printf ("0x%08x", line_color);
1160         xmlSetProp (object_node, "line_color", string);
1161         g_free (string);
1162
1163         string = g_strdup_printf ("0x%08x", fill_color);
1164         xmlSetProp (object_node, "fill_color", string);
1165         g_free (string);
1166
1167         gl_debug (DEBUG_XML, "END");
1168 }
1169
1170 /*--------------------------------------------------------------------------*/
1171 /* PRIVATE.  Add XML Label->Image Node Properties                           */
1172 /*--------------------------------------------------------------------------*/
1173 static void
1174 xml_create_image_props (xmlNodePtr     object_node,
1175                         xmlNsPtr       ns,
1176                         glLabelObject *object)
1177 {
1178         gchar      *string;
1179         gdouble     w, h;
1180         glTextNode *filename;
1181         xmlNodePtr  child;
1182
1183         gl_debug (DEBUG_XML, "START");
1184
1185         xmlSetProp (object_node, "type", "Image");
1186
1187         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
1188         filename = gl_label_image_get_filename (GL_LABEL_IMAGE(object));
1189
1190         string = g_strdup_printf ("%g", w);
1191         xmlSetProp (object_node, "w", string);
1192         g_free (string);
1193         string = g_strdup_printf ("%g", h);
1194         xmlSetProp (object_node, "h", string);
1195         g_free (string);
1196
1197         if (filename->field_flag) {
1198                 child = xmlNewChild (object_node, ns, "Field", NULL);
1199                 xmlSetProp (child, "name", filename->data);
1200         } else {
1201                 child = xmlNewChild (object_node, ns, "File", NULL);
1202                 xmlSetProp (child, "src", filename->data);
1203         }
1204
1205         gl_text_node_free (&filename);
1206
1207         gl_debug (DEBUG_XML, "END");
1208 }
1209
1210 /*--------------------------------------------------------------------------*/
1211 /* PRIVATE.  Add XML Label->Barcode Node Properties                         */
1212 /*--------------------------------------------------------------------------*/
1213 static void
1214 xml_create_barcode_props (xmlNodePtr     object_node,
1215                           xmlNsPtr       ns,
1216                           glLabelObject *object)
1217 {
1218         glTextNode          *text_node;
1219         glBarcodeStyle      style;
1220         gboolean            text_flag;
1221         guint               color;
1222         gdouble             scale;
1223         xmlNodePtr          child;
1224         gchar              *string;
1225
1226         gl_debug (DEBUG_XML, "START");
1227
1228         xmlSetProp (object_node, "type", "Barcode");
1229
1230         text_node = gl_label_barcode_get_data (GL_LABEL_BARCODE(object));
1231         gl_label_barcode_get_props (GL_LABEL_BARCODE(object),
1232                                     &style, &text_flag, &color, &scale);
1233
1234         string = g_strdup_printf ("0x%08x", color);
1235         xmlSetProp (object_node, "color", string);
1236         g_free (string);
1237
1238         xmlSetProp (object_node, "style", gl_barcode_style_to_text (style));
1239         xmlSetProp (object_node, "text", text_flag?"True":"False");
1240         string = g_strdup_printf ("%g", scale);
1241         xmlSetProp (object_node, "scale", string);
1242         g_free (string);
1243
1244         if (text_node->field_flag) {
1245                 child = xmlNewChild (object_node, ns, "Field", NULL);
1246                 xmlSetProp (child, "name", text_node->data);
1247         } else {
1248                 child = xmlNewChild (object_node, ns, "Literal", text_node->data);
1249         }
1250
1251         gl_text_node_free (&text_node);
1252
1253         gl_debug (DEBUG_XML, "END");
1254 }
1255
1256 /*--------------------------------------------------------------------------*/
1257 /* PRIVATE.  Add XML Label Merge Fields Node                                */
1258 /*--------------------------------------------------------------------------*/
1259 static void
1260 xml_create_merge_fields (xmlNodePtr  root,
1261                          xmlNsPtr    ns,
1262                          glLabel    *label)
1263 {
1264         xmlNodePtr  node, child;
1265         gchar      *string;
1266         GList      *p;
1267         glMerge    *merge;
1268
1269         gl_debug (DEBUG_XML, "START");
1270
1271         merge = gl_label_get_merge (label);
1272
1273         node = xmlNewChild (root, ns, "Merge_Fields", NULL);
1274
1275         string = gl_merge_get_name (merge);
1276         xmlSetProp (node, "type", string);
1277         g_free (string);
1278
1279         string = gl_merge_get_src (merge);
1280         xmlSetProp (node, "src", string);
1281         g_free (string);
1282
1283         g_object_unref (G_OBJECT(merge));
1284
1285         gl_debug (DEBUG_XML, "END");
1286 }
1287
1288 /*--------------------------------------------------------------------------*/
1289 /* PRIVATE.  Add XML Label Data Node                                        */
1290 /*--------------------------------------------------------------------------*/
1291 static void
1292 xml_create_data (xmlNodePtr  root,
1293                  xmlNsPtr    ns,
1294                  glLabel    *label)
1295 {
1296         xmlNodePtr  node;
1297         GList      *name_list, *p;
1298         GHashTable *pixbuf_cache;
1299
1300         gl_debug (DEBUG_XML, "START");
1301
1302         node = xmlNewChild (root, ns, "Data", NULL);
1303
1304         pixbuf_cache = gl_label_get_pixbuf_cache (label);
1305         name_list = gl_pixbuf_cache_get_name_list (pixbuf_cache);
1306
1307         for (p = name_list; p != NULL; p=p->next) {
1308                 xml_create_pixdata (node, ns, label, p->data);
1309         }
1310
1311         gl_pixbuf_cache_free_name_list (name_list);
1312
1313
1314         gl_debug (DEBUG_XML, "END");
1315 }
1316
1317 /*--------------------------------------------------------------------------*/
1318 /* PRIVATE.  Add XML Label Data Pixbuf Node                                 */
1319 /*--------------------------------------------------------------------------*/
1320 static void
1321 xml_create_pixdata (xmlNodePtr  root,
1322                     xmlNsPtr    ns,
1323                     glLabel    *label,
1324                     gchar      *name)
1325 {
1326         xmlNodePtr  node;
1327         GHashTable *pixbuf_cache;
1328         GdkPixbuf  *pixbuf;
1329         GdkPixdata *pixdata;
1330         guchar     *stream;
1331         guint       stream_length;
1332         gchar      *base64;
1333
1334         gl_debug (DEBUG_XML, "START");
1335
1336         pixbuf_cache = gl_label_get_pixbuf_cache (label);
1337
1338         pixbuf = gl_pixbuf_cache_get_pixbuf (pixbuf_cache, name);
1339         if ( pixbuf != NULL ) {
1340
1341                 pixdata = g_new0 (GdkPixdata, 1);
1342                 gdk_pixdata_from_pixbuf (pixdata, pixbuf, TRUE);
1343                 stream = gdk_pixdata_serialize (pixdata, &stream_length);
1344                 base64 = gl_base64_encode (stream, stream_length);
1345
1346                 node = xmlNewChild (root, ns, "Pixdata", base64);
1347                 xmlSetProp (node, "name", name);
1348                 xmlSetProp (node, "encoding", "base64");
1349
1350                 gl_pixbuf_cache_remove_pixbuf (pixbuf_cache, name);
1351
1352                 g_free (pixdata->pixel_data);
1353                 g_free (pixdata);
1354                 g_free (stream);
1355                 g_free (base64);
1356         }
1357
1358
1359         gl_debug (DEBUG_XML, "END");
1360 }
1361