Commit 3d28e419 authored by Christian Persch's avatar Christian Persch

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.
parent 28c2a570
......@@ -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
......
......@@ -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>
......@@ -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>
......
......@@ -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:
......@@ -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
......@@ -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@
......@@ -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
......@@ -1057,6 +1060,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
......@@ -1755,6 +1791,182 @@ rsvg_handle_close (RsvgHandle * handle, GError ** error)
return rsvg_handle_close_impl (handle, 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:
*
......
......@@ -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);
}
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment