diff options
author | Dom Lachowicz <doml@src.gnome.org> | 2003-01-29 02:58:20 +0000 |
---|---|---|
committer | Dom Lachowicz <doml@src.gnome.org> | 2003-01-29 02:58:20 +0000 |
commit | 878f8603cbb9e29a702012b86a659fc32aeec487 (patch) | |
tree | 7c1a77c75e194b9165749dca510fa076fea56316 | |
parent | 7c72654bf03ae8d8c8a057c2117c94509d104a02 (diff) | |
download | librsvg-878f8603cbb9e29a702012b86a659fc32aeec487.tar.gz |
beginning of support for SVGZ files. currently not built. depends on libgsf. will be conditionally compiled
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | rsvg-gz.c | 110 | ||||
-rw-r--r-- | rsvg-gz.h | 34 | ||||
-rw-r--r-- | rsvg-private.h | 85 | ||||
-rw-r--r-- | rsvg.c | 161 |
5 files changed, 303 insertions, 93 deletions
@@ -1,3 +1,9 @@ +2003-01-28 Dom Lachowicz <cinamod@hotmail.com> + + * rsvg-gz.[ch]: New handle type, capable of reading SVGZ files. + Not built currently, but will soon be conditionally compiled in. + * *: Groundwork needed for the above (method virtualization) + 2003-01-27 Dom Lachowicz <cinamod@hotmail.com> * rsvg-styles.c (parse_cssbuffer): Allow multiple declarations to be diff --git a/rsvg-gz.c b/rsvg-gz.c new file mode 100644 index 00000000..ef7abf21 --- /dev/null +++ b/rsvg-gz.c @@ -0,0 +1,110 @@ +/* vim: set sw=4: -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + rsvg-gz.c: SAX-based renderer for SVGZ files into a GdkPixbuf. + + Copyright (C) 2003 Dom Lachowicz <cinamod@hotmail.com> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "config.h" +#include "rsvg-gz.h" +#include "rsvg-private.h" + +#include <gsf/gsf-input-gzip.h> +#include <gsf/gsf-input-memory.h> +#include <gsf/gsf-output-memory.h> + +/* TODO: this could probably be done about a billion times better */ + +struct RsvgHandleGz +{ + RsvgHandle super; + GsfOutput * mem; +}; + +typedef struct RsvgHandleGz RsvgHandleGz; + +static gboolean +rsvg_handle_gz_write_impl (RsvgHandle *handle, + const guchar *buf, + gsize num_bytes, + GError **error) +{ + RsvgHandleGz * me = (RsvgHandleGz*)handle; + return gsf_output_write (me->mem, num_bytes, buf); +} + +static gboolean +rsvg_handle_gz_close_impl (RsvgHandle *handle, + GError **error) +{ + RsvgHandleGz * me = (RsvgHandleGz*)handle; + GsfInput * gzip; + const guchar * bytes; + gsize size; + + bytes = gsf_output_memory_get_bytes (GSF_OUTPUT_MEMORY (me->mem)); + size = gsf_output_size (me->mem); + + gzip = GSF_INPUT (gsf_input_gzip_new (gsf_input_memory_new (bytes, size, FALSE), error)); + while (TRUE) { + size = MIN (gsf_input_remaining (gzip), 1024); + if (size == 0) break; + + /* write to parent */ + rsvg_handle_write_impl (&(me->super), + gsf_input_read (gzip, size, NULL), + size, error); + } + gsf_input_close (gzip); + g_object_unref (gzip); + + /* close parent */ + gsf_output_close (me->mem); + return rsvg_handle_close_impl (handle, error); +} + +static void +rsvg_handle_gz_free_impl (RsvgHandle *handle) +{ + RsvgHandleGz * me = (RsvgHandleGz*)handle; + g_object_unref (G_OBJECT (me->mem)); + + /* free parent */ + rsvg_handle_free_impl (handle); +} + +/** + * See rsvg_handle_new, except that this will handle GZipped SVGs (svgz) + * Use the returned handle identically to how you use a handle returned + * from rsvg_handle_new() + */ +RsvgHandle * +rsvg_handle_new_gz (void) +{ + RsvgHandleGz * me = g_new0 (RsvgHandleGz, 1); + + /* init parent */ + rsvg_handle_init (&me->super); + me->mem = gsf_output_memory_new (); + + me->super.write = rsvg_handle_gz_write_impl; + me->super.close = rsvg_handle_gz_close_impl; + me->super.free = rsvg_handle_gz_free_impl; + + return (RsvgHandle*)me; +} diff --git a/rsvg-gz.h b/rsvg-gz.h new file mode 100644 index 00000000..7dda03b1 --- /dev/null +++ b/rsvg-gz.h @@ -0,0 +1,34 @@ +/* vim: set sw=4: -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + rsvg-gz.h: SAX-based renderer for SVGZ files into a GdkPixbuf. + + Copyright (C) 2003 Dom Lachowicz + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef RSVG_GZ_H +#define RSVG_GZ_H + +#include "rsvg.h" + +G_BEGIN_DECLS + +RsvgHandle * rsvg_handle_new_gz (void); + +G_END_DECLS + +#endif /* RSVG_GZ_H */ diff --git a/rsvg-private.h b/rsvg-private.h index 7d82c6b1..ce304bc3 100644 --- a/rsvg-private.h +++ b/rsvg-private.h @@ -37,46 +37,67 @@ G_BEGIN_DECLS typedef struct RsvgSaxHandler RsvgSaxHandler; struct RsvgSaxHandler { - void (*free) (RsvgSaxHandler *self); - void (*start_element) (RsvgSaxHandler *self, const xmlChar *name, const xmlChar **atts); - void (*end_element) (RsvgSaxHandler *self, const xmlChar *name); - void (*characters) (RsvgSaxHandler *self, const xmlChar *ch, int len); + void (*free) (RsvgSaxHandler *self); + void (*start_element) (RsvgSaxHandler *self, const xmlChar *name, const xmlChar **atts); + void (*end_element) (RsvgSaxHandler *self, const xmlChar *name); + void (*characters) (RsvgSaxHandler *self, const xmlChar *ch, int len); }; struct RsvgHandle { - RsvgSizeFunc size_func; - gpointer user_data; - GDestroyNotify user_data_destroy; - GdkPixbuf *pixbuf; - - /* stack; there is a state for each element */ - RsvgState *state; - int n_state; - int n_state_max; - - RsvgDefs *defs; - GHashTable *css_props; - - /* not a handler stack. each nested handler keeps - * track of its parent - */ - RsvgSaxHandler *handler; - int handler_nest; - - GHashTable *entities; /* g_malloc'd string -> xmlEntityPtr */ - - PangoContext *pango_context; - xmlParserCtxtPtr ctxt; - GError **error; - - int width; - int height; - double dpi; + RsvgSizeFunc size_func; + gpointer user_data; + GDestroyNotify user_data_destroy; + GdkPixbuf *pixbuf; + + /* stack; there is a state for each element */ + RsvgState *state; + int n_state; + int n_state_max; + + RsvgDefs *defs; + GHashTable *css_props; + + /* not a handler stack. each nested handler keeps + * track of its parent + */ + RsvgSaxHandler *handler; + int handler_nest; + + GHashTable *entities; /* g_malloc'd string -> xmlEntityPtr */ + + PangoContext *pango_context; + xmlParserCtxtPtr ctxt; + GError **error; + + int width; + int height; + double dpi; + + /* virtual fns */ + gboolean (* write) (RsvgHandle *handle, + const guchar *buf, + gsize count, + GError **error); + + gboolean (* close) (RsvgHandle *handle, + GError **error); + + void (* free) (RsvgHandle * handle); }; void rsvg_linear_gradient_free (RsvgDefVal *self); void rsvg_radial_gradient_free (RsvgDefVal *self); +/* "super"/parent calls */ +void rsvg_handle_init (RsvgHandle * handle); +gboolean rsvg_handle_write_impl (RsvgHandle *handle, + const guchar *buf, + gsize count, + GError **error); +gboolean rsvg_handle_close_impl (RsvgHandle *handle, + GError **error); +void rsvg_handle_free_impl (RsvgHandle *handle); + G_END_DECLS #endif @@ -940,6 +940,84 @@ rsvg_error_quark (void) return q; } +gboolean +rsvg_handle_write_impl (RsvgHandle *handle, + const guchar *buf, + gsize count, + GError **error) +{ + GError *real_error; + g_return_val_if_fail (handle != NULL, FALSE); + + handle->error = &real_error; + if (handle->ctxt == NULL) + { + handle->ctxt = xmlCreatePushParserCtxt (&rsvgSAXHandlerStruct, handle, NULL, 0, NULL); + handle->ctxt->replaceEntities = TRUE; + } + + xmlParseChunk (handle->ctxt, buf, count, 0); + + handle->error = NULL; + /* FIXME: Error handling not implemented. */ + /* if (*real_error != NULL) + { + g_propagate_error (error, real_error); + return FALSE; + }*/ + return TRUE; +} + +gboolean +rsvg_handle_close_impl (RsvgHandle *handle, + GError **error) +{ + gchar chars[1] = { '\0' }; + GError *real_error; + + handle->error = &real_error; + + if (handle->ctxt != NULL) + { + xmlParseChunk (handle->ctxt, chars, 1, TRUE); + xmlFreeParserCtxt (handle->ctxt); + } + + /* FIXME: Error handling not implemented. */ + /* + if (real_error != NULL) + { + g_propagate_error (error, real_error); + return FALSE; + }*/ + return TRUE; +} + +void +rsvg_handle_free_impl (RsvgHandle *handle) +{ + int i; + + if (handle->pango_context != NULL) + g_object_unref (handle->pango_context); + rsvg_defs_free (handle->defs); + + for (i = 0; i < handle->n_state; i++) + rsvg_state_finalize (&handle->state[i]); + g_free (handle->state); + + g_hash_table_foreach (handle->entities, rsvg_ctx_free_helper, NULL); + g_hash_table_destroy (handle->entities); + + g_hash_table_destroy (handle->css_props); + + if (handle->user_data_destroy) + (* handle->user_data_destroy) (handle->user_data); + if (handle->pixbuf) + g_object_unref (handle->pixbuf); + g_free (handle); +} + /** * rsvg_handle_new: * @void: @@ -957,6 +1035,18 @@ rsvg_handle_new (void) RsvgHandle *handle; handle = g_new0 (RsvgHandle, 1); + rsvg_handle_init (handle); + + handle->write = rsvg_handle_write_impl; + handle->close = rsvg_handle_close_impl; + handle->free = rsvg_handle_free_impl; + + return handle; +} + +void +rsvg_handle_init (RsvgHandle * handle) +{ handle->n_state = 0; handle->n_state_max = 16; handle->state = g_new (RsvgState, handle->n_state_max); @@ -969,8 +1059,6 @@ rsvg_handle_new (void) g_free, g_free); handle->ctxt = NULL; - - return handle; } /** @@ -1060,26 +1148,10 @@ rsvg_handle_write (RsvgHandle *handle, gsize count, GError **error) { - GError *real_error; - g_return_val_if_fail (handle != NULL, FALSE); - - handle->error = &real_error; - if (handle->ctxt == NULL) - { - handle->ctxt = xmlCreatePushParserCtxt (&rsvgSAXHandlerStruct, handle, NULL, 0, NULL); - handle->ctxt->replaceEntities = TRUE; - } - - xmlParseChunk (handle->ctxt, buf, count, 0); - - handle->error = NULL; - /* FIXME: Error handling not implemented. */ - /* if (*real_error != NULL) - { - g_propagate_error (error, real_error); - return FALSE; - }*/ - return TRUE; + if (handle->write) + return (*handle->write) (handle, buf, count, error); + + return FALSE; } /** @@ -1097,25 +1169,10 @@ gboolean rsvg_handle_close (RsvgHandle *handle, GError **error) { - gchar chars[1] = { '\0' }; - GError *real_error; - - handle->error = &real_error; - - if (handle->ctxt != NULL) - { - xmlParseChunk (handle->ctxt, chars, 1, TRUE); - xmlFreeParserCtxt (handle->ctxt); - } - - /* FIXME: Error handling not implemented. */ - /* - if (real_error != NULL) - { - g_propagate_error (error, real_error); - return FALSE; - }*/ - return TRUE; + if (handle->close) + return (*handle->close) (handle, error); + + return FALSE; } /** @@ -1150,25 +1207,7 @@ rsvg_handle_get_pixbuf (RsvgHandle *handle) void rsvg_handle_free (RsvgHandle *handle) { - int i; - - if (handle->pango_context != NULL) - g_object_unref (handle->pango_context); - rsvg_defs_free (handle->defs); - - for (i = 0; i < handle->n_state; i++) - rsvg_state_finalize (&handle->state[i]); - g_free (handle->state); - - g_hash_table_foreach (handle->entities, rsvg_ctx_free_helper, NULL); - g_hash_table_destroy (handle->entities); - - g_hash_table_destroy (handle->css_props); - - if (handle->user_data_destroy) - (* handle->user_data_destroy) (handle->user_data); - if (handle->pixbuf) - g_object_unref (handle->pixbuf); - g_free (handle); + if (handle->free) + (*handle->free) (handle); } |