diff options
author | Christian Persch <chpe@gnome.org> | 2010-06-15 21:11:39 +0200 |
---|---|---|
committer | Christian Persch <chpe@gnome.org> | 2010-06-22 15:50:14 +0200 |
commit | 3d28e419d726d972b178325c25b4f8d17aca17c1 (patch) | |
tree | 31519ce3960bda13eb805cfdced03224f8bd1f35 | |
parent | 28c2a570027b7d0b46b9e05a31757c09093e558f (diff) | |
download | librsvg-3d28e419d726d972b178325c25b4f8d17aca17c1.tar.gz |
Add GIO convenience to librsvg
Adds rsvg_handle_read_stream_sync() to read the handle's data from a
GInputStream, and rsvg_handle_new_from_{gfile,stream}_sync convenience
functions analogous to rsvg_handle_new_from_{file,data}.
Bug #621699.
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | doc/rsvg-sections.txt | 10 | ||||
-rw-r--r-- | doc/tmpl/rsvg-unused.sgml | 42 | ||||
-rw-r--r-- | doc/tmpl/rsvg.sgml | 53 | ||||
-rw-r--r-- | librsvg.def | 5 | ||||
-rw-r--r-- | librsvg.pc.in | 4 | ||||
-rw-r--r-- | rsvg-base.c | 212 | ||||
-rw-r--r-- | rsvg-gobject.c | 5 | ||||
-rw-r--r-- | rsvg-private.h | 1 | ||||
-rw-r--r-- | rsvg.h | 28 |
10 files changed, 358 insertions, 6 deletions
diff --git a/Makefile.am b/Makefile.am index ce74c724..578ffaea 100644 --- a/Makefile.am +++ b/Makefile.am @@ -62,7 +62,9 @@ librsvg_@RSVG_API_MAJOR_VERSION@_la_SOURCES = \ rsvg-cairo-clip.c \ rsvg.c \ rsvg-gobject.c \ - rsvg-file-util.c + rsvg-file-util.c \ + rsvg-xml.c \ + rsvg-xml.h librsvg_@RSVG_API_MAJOR_VERSION@_la_LDFLAGS = -version-info @RSVG_LT_VERSION_INFO@ -export-dynamic -no-undefined -export-symbols $(srcdir)/librsvg.def librsvg_@RSVG_API_MAJOR_VERSION@_la_LIBADD = $(LIBGSF_LIBS) $(LIBCROCO_LIBS) $(LIBRSVG_LIBS) -lm diff --git a/doc/rsvg-sections.txt b/doc/rsvg-sections.txt index 6cdd07d8..1b29b01c 100644 --- a/doc/rsvg-sections.txt +++ b/doc/rsvg-sections.txt @@ -27,6 +27,13 @@ rsvg_handle_get_dimensions rsvg_handle_get_dimensions_sub rsvg_handle_get_position_sub rsvg_handle_has_sub + +<SUBSECTION> +RsvgHandleFlags +rsvg_handle_set_base_gfile +rsvg_handle_read_stream_sync +rsvg_handle_new_from_gfile_sync +rsvg_handle_new_from_stream_sync </SECTION> <SECTION> @@ -35,7 +42,6 @@ rsvg_handle_has_sub rsvg_handle_render_cairo rsvg_handle_render_cairo_sub </SECTION> - <SECTION> <FILE>rsvg-file-util</FILE> <TITLE>GdkPixbuf</TITLE> @@ -47,5 +53,3 @@ rsvg_pixbuf_from_file_at_size rsvg_pixbuf_from_file_at_max_size rsvg_pixbuf_from_file_at_zoom_with_max </SECTION> - - diff --git a/doc/tmpl/rsvg-unused.sgml b/doc/tmpl/rsvg-unused.sgml index d744ec04..68e92b33 100644 --- a/doc/tmpl/rsvg-unused.sgml +++ b/doc/tmpl/rsvg-unused.sgml @@ -39,6 +39,29 @@ Creating a SVGZ reader @handle: @id: +<!-- ##### FUNCTION rsvg_handle_new_from_gfile ##### --> +<para> + +</para> + +@file: +@flags: +@cancellable: +@error: +@Returns: + +<!-- ##### FUNCTION rsvg_handle_new_from_stream ##### --> +<para> + +</para> + +@input_stream: +@base_file: +@flags: +@cancellable: +@error: +@Returns: + <!-- ##### FUNCTION rsvg_handle_new_gz ##### --> <para> @@ -46,6 +69,25 @@ Creating a SVGZ reader @Returns: +<!-- ##### FUNCTION rsvg_handle_read_stream ##### --> +<para> + +</para> + +@handle: +@stream: +@cancellable: +@error: +@Returns: + +<!-- ##### FUNCTION rsvg_handle_set_base_uri_from_gfile ##### --> +<para> + +</para> + +@handle: +@file: + <!-- ##### FUNCTION rsvg_pixbuf_from_file_at_max_size_ex ##### --> <para> diff --git a/doc/tmpl/rsvg.sgml b/doc/tmpl/rsvg.sgml index cdec9d58..d1c54e0c 100644 --- a/doc/tmpl/rsvg.sgml +++ b/doc/tmpl/rsvg.sgml @@ -268,3 +268,56 @@ librsvg is a component used within software applications to enable support for S @Returns: +<!-- ##### ENUM RsvgHandleFlags ##### --> +<para> + +</para> + +@RSVG_HANDLE_FLAGS_NONE: + +<!-- ##### FUNCTION rsvg_handle_set_base_gfile ##### --> +<para> + +</para> + +@handle: +@base_file: + + +<!-- ##### FUNCTION rsvg_handle_read_stream_sync ##### --> +<para> + +</para> + +@handle: +@stream: +@cancellable: +@error: +@Returns: + + +<!-- ##### FUNCTION rsvg_handle_new_from_gfile_sync ##### --> +<para> + +</para> + +@file: +@flags: +@cancellable: +@error: +@Returns: + + +<!-- ##### FUNCTION rsvg_handle_new_from_stream_sync ##### --> +<para> + +</para> + +@input_stream: +@base_file: +@flags: +@cancellable: +@error: +@Returns: + + diff --git a/librsvg.def b/librsvg.def index 3810812c..22c8654c 100644 --- a/librsvg.def +++ b/librsvg.def @@ -14,6 +14,7 @@ rsvg_handle_get_pixbuf_sub rsvg_handle_free rsvg_handle_get_base_uri rsvg_handle_set_base_uri +rsvg_handle_set_base_gfile rsvg_handle_get_dimensions rsvg_handle_get_dimensions_sub rsvg_handle_get_position_sub @@ -38,3 +39,7 @@ _rsvg_register_types rsvg_defs_lookup rsvg_pixbuf_from_data_with_size_data rsvg_css_parse_color +rsvg_cairo_to_pixbuf +rsvg_handle_read_stream_sync +rsvg_handle_new_from_gfile_sync +rsvg_handle_new_from_stream_sync diff --git a/librsvg.pc.in b/librsvg.pc.in index 6e345804..aa1ad49d 100644 --- a/librsvg.pc.in +++ b/librsvg.pc.in @@ -9,7 +9,7 @@ css_supported=@CSS_SUPPORTED@ Name: librsvg Description: library that renders svg files Version: @VERSION@ -Requires: glib-2.0 gdk-pixbuf-@GTK_API_VERSION@ cairo -Requires.private: gio-2.0 +Requires: glib-2.0 gio-2.0 gdk-pixbuf-@GTK_API_VERSION@ cairo +Requires.private: Libs: -L${libdir} -lrsvg-@RSVG_API_MAJOR_VERSION@ -lm Cflags: -I${includedir}/librsvg-@RSVG_API_VERSION@ diff --git a/rsvg-base.c b/rsvg-base.c index e80c4fbb..85ce8e5c 100644 --- a/rsvg-base.c +++ b/rsvg-base.c @@ -47,6 +47,8 @@ #include "rsvg-cairo-render.h" #include <libxml/uri.h> +#include <libxml/parser.h> +#include <libxml/parserInternals.h> #include <math.h> #include <string.h> @@ -55,6 +57,7 @@ #include "rsvg-bpath-util.h" #include "rsvg-path.h" #include "rsvg-paint-server.h" +#include "rsvg-xml.h" /* * This is configurable at runtime @@ -1058,6 +1061,39 @@ rsvg_handle_set_base_uri (RsvgHandle * handle, const char *base_uri) } /** + * rsvg_handle_set_base_gfile: + * @handle: a #RsvgHandle + * @file: a #GFile + * + * Set the base URI for @handle from @file. + * Note: This function may only be called before rsvg_handle_write() + * or rsvg_handle_read_stream() has been called. + * + * Since: 2.32 + */ +void +rsvg_handle_set_base_gfile (RsvgHandle *handle, + GFile *base_file) +{ + RsvgHandlePrivate *priv; + + g_return_if_fail (RSVG_IS_HANDLE (handle)); + g_return_if_fail (G_IS_FILE (base_file)); + + priv = handle->priv; + + g_object_ref (base_file); + if (priv->base_gfile) + g_object_unref (priv->base_gfile); + priv->base_gfile = base_file; + + g_free (priv->base_uri); + priv->base_uri = g_file_get_uri (base_file); + + rsvg_defs_set_base_uri (priv->defs, priv->base_uri); +} + +/** * rsvg_handle_get_base_uri: * @handle: A #RsvgHandle * @@ -1756,6 +1792,182 @@ rsvg_handle_close (RsvgHandle * handle, GError ** error) } /** + * rsvg_handle_read_stream_sync: + * @handle: a #RsvgHandle + * @stream: a #GInputStream + * @cancellable: (allow-none): a #GCancellable, or %NULL + * @error: (allow-none): a location to store a #GError, or %NULL + * + * Reads @stream and writes the data from it to @handle. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the + * operation was cancelled, the error G_IO_ERROR_CANCELLED will be + * returned. + * + * Returns: %TRUE if reading @stream succeeded, or %FALSE otherwise + * with @error filled in + * + * Since: 2.32 + */ +gboolean +rsvg_handle_read_stream_sync (RsvgHandle *handle, + GInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + RsvgHandlePrivate *priv; + xmlParserInputBufferPtr buffer; + xmlParserInputPtr input; + int result; + xmlDocPtr doc; + GError *err = NULL; + + g_return_val_if_fail (RSVG_IS_HANDLE (handle), FALSE); + g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + priv = handle->priv; + + priv->error = &err; + if (priv->ctxt == NULL) { + priv->ctxt = xmlCreatePushParserCtxt (&rsvgSAXHandlerStruct, handle, NULL, 0, + rsvg_handle_get_base_uri (handle)); + + /* if false, external entities work, but internal ones don't. if true, internal entities + work, but external ones don't. favor internal entities, in order to not cause a + regression */ + /* FIXMEchpe: FIX THIS! */ + priv->ctxt->replaceEntities = TRUE; + } + + buffer = _rsvg_xml_input_buffer_new_from_stream (stream, cancellable, XML_CHAR_ENCODING_NONE, &err); + input = xmlNewIOInputStream (priv->ctxt, buffer, XML_CHAR_ENCODING_NONE); + if (xmlPushInput (priv->ctxt, input) < 0) { + rsvg_set_error (error, priv->ctxt); + xmlFreeInputStream (input); + return FALSE; + } + + result = xmlParseDocument (priv->ctxt); + if (result != 0) { + if (err) + g_propagate_error (error, err); + else + rsvg_set_error (error, handle->priv->ctxt); + + return FALSE; + } + + priv->error = NULL; + + if (err != NULL) { + g_propagate_error (error, err); + return FALSE; + } + + doc = priv->ctxt->myDoc; + xmlFreeParserCtxt (priv->ctxt); + priv->ctxt = NULL; + + xmlFreeDoc (doc); + + rsvg_defs_resolve_all (priv->defs); + priv->finished = TRUE; + + return TRUE; +} + +/** + * rsvg_handle_new_from_gfile_sync: + * @file: a #GFile + * @flags: flags from #RsvgHandleFlags + * @cancellable: (allow-none): a #GCancellable, or %NULL + * @error: (allow-none): a location to store a #GError, or %NULL + * + * Creates a new #RsvgHandle for @file. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the + * operation was cancelled, the error G_IO_ERROR_CANCELLED will be + * returned. + * + * Returns: a new #RsvgHandle on success, or %NULL with @error filled in + * + * Since: 2.32 + */ +RsvgHandle * +rsvg_handle_new_from_gfile_sync (GFile *file, + RsvgHandleFlags flags, + GCancellable *cancellable, + GError **error) +{ + RsvgHandle *handle; + GFileInputStream *stream; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + stream = g_file_read (file, cancellable, error); + if (stream == NULL) + return NULL; + + handle = rsvg_handle_new_from_stream_sync (G_INPUT_STREAM (stream), file, + flags, cancellable, error); + g_object_unref (stream); + + return handle; +} + +/** + * rsvg_handle_new_from_stream_sync: + * @stream: a #GInputStream + * @base_file: (allow-none): a #GFile, or %NULL + * @flags: flags from #RsvgHandleFlags + * @cancellable: (allow-none): a #GCancellable, or %NULL + * @error: (allow-none): a location to store a #GError, or %NULL + * + * Creates a new #RsvgHandle for @stream. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the + * operation was cancelled, the error G_IO_ERROR_CANCELLED will be + * returned. + * + * Returns: a new #RsvgHandle on success, or %NULL with @error filled in + * + * Since: 2.32 + */ +RsvgHandle * +rsvg_handle_new_from_stream_sync (GInputStream *stream, + GFile *base_file, + RsvgHandleFlags flags, + GCancellable *cancellable, + GError **error) +{ + RsvgHandle *handle; + + g_return_val_if_fail (G_IS_INPUT_STREAM (stream), NULL); + g_return_val_if_fail (base_file == NULL || G_IS_FILE (base_file), NULL); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + handle = rsvg_handle_new (); + + if (base_file) + rsvg_handle_set_base_gfile (handle, base_file); + + if (!rsvg_handle_read_stream_sync (handle, stream, cancellable, error)) { + g_object_unref (handle); + return NULL; + } + + return handle; +} + +/** * rsvg_init: * * Initializes librsvg diff --git a/rsvg-gobject.c b/rsvg-gobject.c index 62c66708..358f6905 100644 --- a/rsvg-gobject.c +++ b/rsvg-gobject.c @@ -120,6 +120,11 @@ instance_dispose (GObject * instance) g_free (self->priv); + if (self->priv->base_gfile) { + g_object_unref (self->priv->base_gfile); + self->priv->base_gfile = NULL; + } + rsvg_parent_class->dispose (instance); } diff --git a/rsvg-private.h b/rsvg-private.h index c4fed2df..d18b922a 100644 --- a/rsvg-private.h +++ b/rsvg-private.h @@ -162,6 +162,7 @@ struct RsvgHandlePrivate { GString *metadata; gchar *base_uri; + GFile *base_gfile; gboolean finished; @@ -26,6 +26,9 @@ #ifndef RSVG_H #define RSVG_H +#include <glib-object.h> +#include <gio/gio.h> + #include <gdk-pixbuf/gdk-pixbuf.h> G_BEGIN_DECLS @@ -133,6 +136,31 @@ gboolean rsvg_handle_get_position_sub (RsvgHandle * handle, RsvgPositionData * p gboolean rsvg_handle_has_sub (RsvgHandle * handle, const char *id); +/* GIO APIs */ + +typedef enum { + RSVG_HANDLE_FLAGS_NONE = 0, +} RsvgHandleFlags; + +void rsvg_handle_set_base_gfile (RsvgHandle *handle, + GFile *base_file); + +gboolean rsvg_handle_read_stream_sync (RsvgHandle *handle, + GInputStream *stream, + GCancellable *cancellable, + GError **error); + +RsvgHandle *rsvg_handle_new_from_gfile_sync (GFile *file, + RsvgHandleFlags flags, + GCancellable *cancellable, + GError **error); + +RsvgHandle *rsvg_handle_new_from_stream_sync (GInputStream *input_stream, + GFile *base_file, + RsvgHandleFlags flags, + GCancellable *cancellable, + GError **error); + /* Accessibility API */ G_CONST_RETURN char *rsvg_handle_get_title (RsvgHandle * handle); |