source: trunk/third/librsvg/gdk-pixbuf-loader/io-svg.c @ 18805

Revision 18805, 5.9 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18804, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2/* GdkPixbuf library - SVG image loader
3 *
4 * Copyright (C) 2002 Matthias Clasen
5 * Copyright (C) 2002 Dom Lachowicz
6 *
7 * Authors: Matthias Clasen <maclas@gmx.de>
8 *          Dom Lachowicz <cinamod@hotmail.com>
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 * Lesser General Public License for more  * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
22 */
23
24#include <rsvg.h>
25#include <stdlib.h>
26#include <gdk-pixbuf/gdk-pixbuf.h>
27#include <gdk-pixbuf/gdk-pixbuf-io.h>
28
29#if HAVE_SVGZ
30#include <rsvg-gz.h>
31#endif
32
33typedef struct {
34        RsvgHandle                 *handle;
35        GdkPixbuf                  *pixbuf;
36        GdkPixbufModuleUpdatedFunc  updated_func;
37        GdkPixbufModulePreparedFunc prepared_func;
38        gpointer                    user_data;
39
40#if HAVE_SVGZ
41        GdkPixbufModuleSizeFunc     size_func;
42        gboolean                    first_write;
43#endif
44
45} SvgContext;
46
47G_MODULE_EXPORT void fill_vtable (GdkPixbufModule *module);
48G_MODULE_EXPORT void fill_info (GdkPixbufFormat *info);
49
50static gpointer
51gdk_pixbuf__svg_image_begin_load (GdkPixbufModuleSizeFunc size_func,
52                                  GdkPixbufModulePreparedFunc prepared_func,
53                                  GdkPixbufModuleUpdatedFunc  updated_func,
54                                  gpointer user_data,
55                                  GError **error)
56{
57        SvgContext *context    = g_new0 (SvgContext, 1);
58
59        if (error)
60                *error = NULL;
61
62#if HAVE_SVGZ
63        /* lazy create the handle on the first write */
64        context->handle        = NULL;
65        context->first_write   = TRUE;
66        context->size_func     = size_func;
67#else
68        context->handle        = rsvg_handle_new ();
69        rsvg_handle_set_size_callback (context->handle, size_func, user_data, NULL);
70#endif
71
72        context->prepared_func = prepared_func;
73        context->updated_func  = updated_func;
74        context->user_data     = user_data;
75
76        return context;
77}
78
79static gboolean
80gdk_pixbuf__svg_image_load_increment (gpointer data,
81                                      const guchar *buf, guint size,
82                                      GError **error)
83{
84        SvgContext *context = (SvgContext *)data;
85        gboolean result;
86
87        if (error)
88                *error = NULL;
89
90#if HAVE_SVGZ
91        if (context->first_write == TRUE) {
92                context->first_write = FALSE;
93
94                /* lazy create a SVGZ or SVG loader */
95                if ((size >= 2) && (buf[0] == (guchar)0x1f) && (buf[1] == (guchar)0x8b))
96                        context->handle = rsvg_handle_new_gz ();
97                else
98                        context->handle = rsvg_handle_new ();
99
100                rsvg_handle_set_size_callback (context->handle, context->size_func, context->user_data, NULL);
101        }
102#endif
103
104        result = rsvg_handle_write (context->handle, buf, size, error); 
105
106        context->pixbuf = rsvg_handle_get_pixbuf (context->handle);
107 
108        if (context->pixbuf != NULL && context->prepared_func != NULL)
109                (* context->prepared_func) (context->pixbuf, NULL, context->user_data);       
110 
111        return result;
112}
113
114static gboolean
115gdk_pixbuf__svg_image_stop_load (gpointer data, GError **error)
116{
117        SvgContext *context = (SvgContext *)data; 
118
119        if (error)
120                *error = NULL;
121
122        rsvg_handle_close (context->handle, error);
123
124        if (context->pixbuf == NULL) {
125                context->pixbuf = rsvg_handle_get_pixbuf (context->handle);
126   
127                if (context->pixbuf != NULL && context->prepared_func != NULL)
128                        (* context->prepared_func) (context->pixbuf, NULL, context->user_data);
129        }
130
131        if (context->pixbuf != NULL && context->updated_func != NULL)
132                (* context->updated_func) (context->pixbuf,
133                                           0, 0,
134                                           gdk_pixbuf_get_width (context->pixbuf),
135                                           gdk_pixbuf_get_height (context->pixbuf),
136                                           context->user_data);
137
138        rsvg_handle_free (context->handle);
139        g_object_unref (context->pixbuf);
140        g_free (context);
141
142        return TRUE;
143}
144
145void
146fill_vtable (GdkPixbufModule *module)
147{
148        module->begin_load     = gdk_pixbuf__svg_image_begin_load;
149        module->stop_load      = gdk_pixbuf__svg_image_stop_load;
150        module->load_increment = gdk_pixbuf__svg_image_load_increment;
151}
152
153void
154fill_info (GdkPixbufFormat *info)
155{
156        static GdkPixbufModulePattern signature[] = {
157                { "<?xml", NULL, 50 },
158                { "<svg", NULL, 100 },
159                { "<!DOCTYPE svg", NULL, 100 },
160#if HAVE_SVGZ
161                { "\x1f\x8b", NULL, 50 }, /* todo: recognizes any gzipped file, not much we can do */
162#endif
163                { NULL, NULL, 0 }
164        };
165        static gchar *mime_types[] = {
166                "image/svg",
167                "image/svg+xml",
168                NULL
169        };
170        static gchar *extensions[] = {
171                "svg",
172#if HAVE_SVGZ
173                "svgz",
174#endif
175                NULL
176        };
177       
178        info->name        = "svg";
179        info->signature   = signature;
180        info->description = "Scalable Vector Graphics";
181        info->mime_types  = mime_types;
182        info->extensions  = extensions;
183        info->flags       = 0;
184}
Note: See TracBrowser for help on using the repository browser.