summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDom Lachowicz <doml@src.gnome.org>2003-01-29 02:58:20 +0000
committerDom Lachowicz <doml@src.gnome.org>2003-01-29 02:58:20 +0000
commit878f8603cbb9e29a702012b86a659fc32aeec487 (patch)
tree7c1a77c75e194b9165749dca510fa076fea56316
parent7c72654bf03ae8d8c8a057c2117c94509d104a02 (diff)
downloadlibrsvg-878f8603cbb9e29a702012b86a659fc32aeec487.tar.gz
beginning of support for SVGZ files. currently not built. depends on libgsf. will be conditionally compiled
-rw-r--r--ChangeLog6
-rw-r--r--rsvg-gz.c110
-rw-r--r--rsvg-gz.h34
-rw-r--r--rsvg-private.h85
-rw-r--r--rsvg.c161
5 files changed, 303 insertions, 93 deletions
diff --git a/ChangeLog b/ChangeLog
index d9df3f2e..a392c693 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/rsvg.c b/rsvg.c
index 7df83f11..9f3a671c 100644
--- a/rsvg.c
+++ b/rsvg.c
@@ -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);
}