summaryrefslogtreecommitdiff
path: root/librsvg
diff options
context:
space:
mode:
authorFederico Mena Quintero <federico@gnome.org>2018-07-30 21:10:41 -0700
committerFederico Mena Quintero <federico@gnome.org>2018-07-30 21:10:41 -0700
commit340a2635f36f510ad833f6ca34f29f89d21451f3 (patch)
tree7a1359afbe880e6ad552b3d4744ea71ac91fe412 /librsvg
parent0133a6964a02eeaf55dba320c8b513890691d0fd (diff)
parent184c10cbe2c3562152954b7a81399dca2dc834e8 (diff)
downloadlibrsvg-340a2635f36f510ad833f6ca34f29f89d21451f3.tar.gz
Merge branch 'pborelli/librsvg-cleanup'
Diffstat (limited to 'librsvg')
-rw-r--r--librsvg/rsvg-base-file-util.c129
-rw-r--r--librsvg/rsvg-base.c346
-rw-r--r--librsvg/rsvg-handle.c449
-rw-r--r--librsvg/rsvg-pixbuf.c (renamed from librsvg/rsvg-file-util.c)39
-rw-r--r--librsvg/rsvg-private.h9
5 files changed, 448 insertions, 524 deletions
diff --git a/librsvg/rsvg-base-file-util.c b/librsvg/rsvg-base-file-util.c
deleted file mode 100644
index 6b2aca14..00000000
--- a/librsvg/rsvg-base-file-util.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim: set sw=4 sts=4 expandtab: */
-/*
- rsvg-file-util.c: SAX-based renderer for SVG files into a GdkPixbuf.
-
- Copyright (C) 2000 Eazel, Inc.
- Copyright (C) 2002 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.
-
- Author: Raph Levien <raph@artofcode.com>
-*/
-
-#include "config.h"
-#include "rsvg-private.h"
-#include "rsvg-io.h"
-
-static gboolean
-rsvg_handle_fill_with_data (RsvgHandle * handle,
- const char * data, gsize data_len, GError ** error)
-{
- gboolean rv;
-
- rsvg_return_val_if_fail (data != NULL, FALSE, error);
- rsvg_return_val_if_fail (data_len != 0, FALSE, error);
-
- rv = rsvg_handle_write (handle, (guchar *) data, data_len, error);
-
- return rsvg_handle_close (handle, rv ? error : NULL) && rv;
-}
-
-/**
- * rsvg_handle_new_from_data:
- * @data: (array length=data_len): The SVG data
- * @data_len: The length of @data, in bytes
- * @error: return location for errors
- *
- * Loads the SVG specified by @data.
- *
- * Returns: A #RsvgHandle or %NULL if an error occurs.
- * Since: 2.14
- */
-RsvgHandle *
-rsvg_handle_new_from_data (const guint8 * data, gsize data_len, GError ** error)
-{
- RsvgHandle *handle;
-
- handle = rsvg_handle_new ();
-
- if (handle) {
- if (!rsvg_handle_fill_with_data (handle, (char *) data, data_len, error)) {
- g_object_unref (handle);
- handle = NULL;
- }
- }
-
- return handle;
-}
-
-/**
- * rsvg_handle_new_from_file:
- * @file_name: The file name to load. If built with gnome-vfs, can be a URI.
- * @error: return location for errors
- *
- * Loads the SVG specified by @file_name.
- *
- * Returns: A #RsvgHandle or %NULL if an error occurs.
- * Since: 2.14
- */
-RsvgHandle *
-rsvg_handle_new_from_file (const gchar * file_name, GError ** error)
-{
- gchar *base_uri;
- char *data;
- gsize data_len;
- RsvgHandle *handle = NULL;
- GFile *file;
- char *scheme;
-
- rsvg_return_val_if_fail (file_name != NULL, NULL, error);
-
- scheme = g_uri_parse_scheme (file_name);
- if (scheme) {
- file = g_file_new_for_uri (file_name);
- g_free (scheme);
- } else {
- file = g_file_new_for_path (file_name);
- }
-
- base_uri = g_file_get_uri (file);
- if (!base_uri) {
- g_set_error (error,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- _("Cannot obtain URI from '%s'"), file_name);
- g_object_unref (file);
- return NULL;
- }
-
- data = _rsvg_io_acquire_data (base_uri, base_uri, NULL, &data_len, NULL, error);
-
- if (data) {
- handle = rsvg_handle_new ();
- rsvg_handle_set_base_uri (handle, base_uri);
- if (!rsvg_handle_fill_with_data (handle, data, data_len, error)) {
- g_object_unref (handle);
- handle = NULL;
- }
- g_free (data);
- }
-
- g_free (base_uri);
- g_object_unref (file);
-
- return handle;
-}
diff --git a/librsvg/rsvg-base.c b/librsvg/rsvg-base.c
index 920bc04b..df770c85 100644
--- a/librsvg/rsvg-base.c
+++ b/librsvg/rsvg-base.c
@@ -31,7 +31,6 @@
#include "rsvg-css.h"
#include "rsvg-styles.h"
#include "rsvg-io.h"
-#include "rsvg-load.h"
#include <gio/gio.h>
@@ -146,142 +145,6 @@ rsvg_set_default_dpi_x_y (double dpi_x, double dpi_y)
}
/**
- * rsvg_handle_write:
- * @handle: an #RsvgHandle
- * @buf: (array length=count) (element-type guchar): pointer to svg data
- * @count: length of the @buf buffer in bytes
- * @error: (allow-none): a location to store a #GError, or %NULL
- *
- * Loads the next @count bytes of the image. This will return %TRUE if the data
- * was loaded successful, and %FALSE if an error occurred. In the latter case,
- * the loader will be closed, and will not accept further writes. If %FALSE is
- * returned, @error will be set to an error from the #RsvgError domain. Errors
- * from #GIOErrorEnum are also possible.
- *
- * Returns: %TRUE on success, or %FALSE on error
- **/
-gboolean
-rsvg_handle_write (RsvgHandle *handle, const guchar *buf, gsize count, GError **error)
-{
- RsvgHandlePrivate *priv;
-
- rsvg_return_val_if_fail (handle, FALSE, error);
- priv = handle->priv;
-
- rsvg_return_val_if_fail (priv->hstate == RSVG_HANDLE_STATE_START
- || priv->hstate == RSVG_HANDLE_STATE_LOADING,
- FALSE,
- error);
-
- if (priv->hstate == RSVG_HANDLE_STATE_START) {
- priv->hstate = RSVG_HANDLE_STATE_LOADING;
- priv->load = rsvg_load_new (handle, (priv->flags & RSVG_HANDLE_FLAG_UNLIMITED) != 0);
- }
-
- g_assert (priv->hstate == RSVG_HANDLE_STATE_LOADING);
-
- return rsvg_load_write (priv->load, buf, count, error);
-}
-
-static gboolean
-finish_load (RsvgHandle *handle, gboolean was_successful)
-{
- RsvgNode *treebase = rsvg_load_destroy (handle->priv->load);
- handle->priv->load = NULL;
-
- if (was_successful) {
- handle->priv->hstate = RSVG_HANDLE_STATE_CLOSED_OK;
- handle->priv->treebase = treebase;
- } else {
- handle->priv->hstate = RSVG_HANDLE_STATE_CLOSED_ERROR;
- treebase = rsvg_node_unref (treebase);
- }
-
- return was_successful;
-}
-
-/**
- * rsvg_handle_close:
- * @handle: a #RsvgHandle
- * @error: (allow-none): a location to store a #GError, or %NULL
- *
- * Closes @handle, to indicate that loading the image is complete. This will
- * return %TRUE if the loader closed successfully. Note that @handle isn't
- * freed until @g_object_unref is called.
- *
- * Returns: %TRUE on success, or %FALSE on error
- **/
-gboolean
-rsvg_handle_close (RsvgHandle *handle, GError **error)
-{
- RsvgHandlePrivate *priv;
- gboolean result;
-
- rsvg_return_val_if_fail (handle, FALSE, error);
- priv = handle->priv;
-
- if (priv->hstate == RSVG_HANDLE_STATE_CLOSED_OK
- || priv->hstate == RSVG_HANDLE_STATE_CLOSED_ERROR) {
- /* closing is idempotent */
- return TRUE;
- }
-
- result = finish_load (handle, rsvg_load_close (priv->load, error));
-
- return result;
-}
-
-/**
- * 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;
- gboolean result;
- RsvgLoad *saved_load;
-
- 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;
-
- g_return_val_if_fail (priv->hstate == RSVG_HANDLE_STATE_START, FALSE);
-
- priv->hstate = RSVG_HANDLE_STATE_LOADING;
-
- saved_load = priv->load;
-
- priv->load = rsvg_load_new (handle, (priv->flags & RSVG_HANDLE_FLAG_UNLIMITED) != 0);
- result = finish_load (handle, rsvg_load_read_stream_sync (priv->load, stream, cancellable, error));
-
- priv->load = saved_load;
-
- return result;
-}
-
-/**
* rsvg_init:
*
* This function does nothing.
@@ -321,138 +184,12 @@ rsvg_cleanup (void)
xmlCleanupParser ();
}
-cairo_surface_t *
-rsvg_cairo_surface_new_from_href (RsvgHandle *handle,
- const char *href,
- GError **error)
-{
- char *data;
- gsize data_len;
- char *mime_type = NULL;
- GdkPixbufLoader *loader = NULL;
- GdkPixbuf *pixbuf = NULL;
- cairo_surface_t *surface = NULL;
-
- data = _rsvg_handle_acquire_data (handle, href, &mime_type, &data_len, error);
- if (data == NULL)
- return NULL;
-
- if (mime_type) {
- loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, error);
- } else {
- loader = gdk_pixbuf_loader_new ();
- }
-
- if (loader == NULL)
- goto out;
-
- if (!gdk_pixbuf_loader_write (loader, (guchar *) data, data_len, error)) {
- gdk_pixbuf_loader_close (loader, NULL);
- goto out;
- }
-
- if (!gdk_pixbuf_loader_close (loader, error))
- goto out;
-
- pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
-
- if (!pixbuf) {
- g_set_error (error,
- GDK_PIXBUF_ERROR,
- GDK_PIXBUF_ERROR_FAILED,
- _("Failed to load image '%s': reason not known, probably a corrupt image file"),
- href);
- goto out;
- }
-
- surface = rsvg_cairo_surface_from_pixbuf (pixbuf);
-
- if (mime_type == NULL) {
- /* Try to get the information from the loader */
- GdkPixbufFormat *format;
- char **mime_types;
-
- if ((format = gdk_pixbuf_loader_get_format (loader)) != NULL) {
- mime_types = gdk_pixbuf_format_get_mime_types (format);
-
- if (mime_types != NULL)
- mime_type = g_strdup (mime_types[0]);
- g_strfreev (mime_types);
- }
- }
-
- if ((handle->priv->flags & RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA) != 0 &&
- mime_type != NULL &&
- cairo_surface_set_mime_data (surface, mime_type, (guchar *) data,
- data_len, g_free, data) == CAIRO_STATUS_SUCCESS) {
- data = NULL; /* transferred to the surface */
- }
-
- out:
- if (loader)
- g_object_unref (loader);
- g_free (mime_type);
- g_free (data);
-
- return surface;
-}
-
void
rsvg_return_if_fail_warning (const char *pretty_function, const char *expression, GError ** error)
{
g_set_error (error, RSVG_ERROR, 0, _("%s: assertion `%s' failed"), pretty_function, expression);
}
-#ifdef HAVE_PANGOFT2
-
-static void
-create_font_config_for_testing (RsvgHandle *handle)
-{
- const char *font_paths[] = {
- "resources/Roboto-Regular.ttf",
- "resources/Roboto-Italic.ttf",
- "resources/Roboto-Bold.ttf",
- "resources/Roboto-BoldItalic.ttf",
- };
-
- int i;
-
- if (handle->priv->font_config_for_testing != NULL)
- return;
-
- handle->priv->font_config_for_testing = FcConfigCreate ();
-
- for (i = 0; i < G_N_ELEMENTS(font_paths); i++) {
- char *font_path = g_test_build_filename (G_TEST_DIST, font_paths[i], NULL);
-
- if (!FcConfigAppFontAddFile (handle->priv->font_config_for_testing, (const FcChar8 *) font_path)) {
- g_error ("Could not load font file \"%s\" for tests; aborting", font_path);
- }
-
- g_free (font_path);
- }
-}
-
-#endif
-
-void
-rsvg_handle_update_font_map_for_testing (RsvgHandle *handle)
-{
-#ifdef HAVE_PANGOFT2
- if (handle->priv->is_testing) {
- create_font_config_for_testing (handle);
-
- if (handle->priv->font_map_for_testing == NULL) {
- handle->priv->font_map_for_testing = pango_cairo_font_map_new_for_font_type (CAIRO_FONT_TYPE_FT);
- pango_fc_font_map_set_config (PANGO_FC_FONT_MAP (handle->priv->font_map_for_testing),
- handle->priv->font_config_for_testing);
-
- pango_cairo_font_map_set_default (PANGO_CAIRO_FONT_MAP (handle->priv->font_map_for_testing));
- }
- }
-#endif
-}
-
gboolean
rsvg_allow_load (GFile *base_gfile,
const char *uri,
@@ -534,86 +271,3 @@ rsvg_allow_load (GFile *base_gfile,
"File may not link to URI \"%s\"", uri);
return FALSE;
}
-
-char *
-rsvg_handle_resolve_uri (RsvgHandle *handle,
- const char *uri)
-{
- RsvgHandlePrivate *priv = handle->priv;
- char *scheme, *resolved_uri;
- GFile *base, *resolved;
-
- if (uri == NULL)
- return NULL;
-
- scheme = g_uri_parse_scheme (uri);
- if (scheme != NULL ||
- priv->base_gfile == NULL ||
- (base = g_file_get_parent (priv->base_gfile)) == NULL) {
- g_free (scheme);
- return g_strdup (uri);
- }
-
- resolved = g_file_resolve_relative_path (base, uri);
- resolved_uri = g_file_get_uri (resolved);
-
- g_free (scheme);
- g_object_unref (base);
- g_object_unref (resolved);
-
- return resolved_uri;
-}
-
-char *
-_rsvg_handle_acquire_data (RsvgHandle *handle,
- const char *url,
- char **content_type,
- gsize *len,
- GError **error)
-{
- RsvgHandlePrivate *priv = handle->priv;
- char *uri;
- char *data;
-
- uri = rsvg_handle_resolve_uri (handle, url);
-
- if (rsvg_allow_load (priv->base_gfile, uri, error)) {
- data = _rsvg_io_acquire_data (uri,
- rsvg_handle_get_base_uri (handle),
- content_type,
- len,
- handle->priv->cancellable,
- error);
- } else {
- data = NULL;
- }
-
- g_free (uri);
- return data;
-}
-
-GInputStream *
-_rsvg_handle_acquire_stream (RsvgHandle *handle,
- const char *url,
- char **content_type,
- GError **error)
-{
- RsvgHandlePrivate *priv = handle->priv;
- char *uri;
- GInputStream *stream;
-
- uri = rsvg_handle_resolve_uri (handle, url);
-
- if (rsvg_allow_load (priv->base_gfile, uri, error)) {
- stream = _rsvg_io_acquire_stream (uri,
- rsvg_handle_get_base_uri (handle),
- content_type,
- handle->priv->cancellable,
- error);
- } else {
- stream = NULL;
- }
-
- g_free (uri);
- return stream;
-}
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index f2802ac6..01af7762 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -120,6 +120,8 @@
#include "config.h"
#include <string.h>
+#include "rsvg-io.h"
+#include "rsvg-load.h"
#include "rsvg-private.h"
enum {
@@ -425,6 +427,107 @@ rsvg_handle_new (void)
return RSVG_HANDLE (g_object_new (RSVG_TYPE_HANDLE, NULL));
}
+static gboolean
+rsvg_handle_fill_with_data (RsvgHandle *handle,
+ const char *data,
+ gsize data_len,
+ GError ** error)
+{
+ gboolean rv;
+
+ rsvg_return_val_if_fail (data != NULL, FALSE, error);
+ rsvg_return_val_if_fail (data_len != 0, FALSE, error);
+
+ rv = rsvg_handle_write (handle, (guchar *) data, data_len, error);
+
+ return rsvg_handle_close (handle, rv ? error : NULL) && rv;
+}
+
+/**
+ * rsvg_handle_new_from_data:
+ * @data: (array length=data_len): The SVG data
+ * @data_len: The length of @data, in bytes
+ * @error: return location for errors
+ *
+ * Loads the SVG specified by @data.
+ *
+ * Returns: A #RsvgHandle or %NULL if an error occurs.
+ * Since: 2.14
+ */
+RsvgHandle *
+rsvg_handle_new_from_data (const guint8 *data, gsize data_len, GError **error)
+{
+ RsvgHandle *handle;
+
+ handle = rsvg_handle_new ();
+
+ if (handle) {
+ if (!rsvg_handle_fill_with_data (handle, (char *) data, data_len, error)) {
+ g_object_unref (handle);
+ handle = NULL;
+ }
+ }
+
+ return handle;
+}
+
+/**
+ * rsvg_handle_new_from_file:
+ * @file_name: The file name to load. If built with gnome-vfs, can be a URI.
+ * @error: return location for errors
+ *
+ * Loads the SVG specified by @file_name.
+ *
+ * Returns: A #RsvgHandle or %NULL if an error occurs.
+ * Since: 2.14
+ */
+RsvgHandle *
+rsvg_handle_new_from_file (const gchar *file_name, GError **error)
+{
+ gchar *base_uri;
+ char *data;
+ gsize data_len;
+ RsvgHandle *handle = NULL;
+ GFile *file;
+ char *scheme;
+
+ rsvg_return_val_if_fail (file_name != NULL, NULL, error);
+
+ scheme = g_uri_parse_scheme (file_name);
+ if (scheme) {
+ file = g_file_new_for_uri (file_name);
+ g_free (scheme);
+ } else {
+ file = g_file_new_for_path (file_name);
+ }
+
+ base_uri = g_file_get_uri (file);
+ if (!base_uri) {
+ g_set_error (error,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ _("Cannot obtain URI from '%s'"), file_name);
+ g_object_unref (file);
+ return NULL;
+ }
+
+ data = _rsvg_io_acquire_data (base_uri, base_uri, NULL, &data_len, NULL, error);
+
+ if (data) {
+ handle = rsvg_handle_new ();
+ rsvg_handle_set_base_uri (handle, base_uri);
+ if (!rsvg_handle_fill_with_data (handle, data, data_len, error)) {
+ g_object_unref (handle);
+ handle = NULL;
+ }
+ g_free (data);
+ }
+
+ g_free (base_uri);
+ g_object_unref (file);
+
+ return handle;
+}
/**
* rsvg_handle_new_with_flags:
@@ -532,6 +635,142 @@ rsvg_handle_new_from_stream_sync (GInputStream *input_stream,
return handle;
}
+/**
+ * rsvg_handle_write:
+ * @handle: an #RsvgHandle
+ * @buf: (array length=count) (element-type guchar): pointer to svg data
+ * @count: length of the @buf buffer in bytes
+ * @error: (allow-none): a location to store a #GError, or %NULL
+ *
+ * Loads the next @count bytes of the image. This will return %TRUE if the data
+ * was loaded successful, and %FALSE if an error occurred. In the latter case,
+ * the loader will be closed, and will not accept further writes. If %FALSE is
+ * returned, @error will be set to an error from the #RsvgError domain. Errors
+ * from #GIOErrorEnum are also possible.
+ *
+ * Returns: %TRUE on success, or %FALSE on error
+ **/
+gboolean
+rsvg_handle_write (RsvgHandle *handle, const guchar *buf, gsize count, GError **error)
+{
+ RsvgHandlePrivate *priv;
+
+ rsvg_return_val_if_fail (handle, FALSE, error);
+ priv = handle->priv;
+
+ rsvg_return_val_if_fail (priv->hstate == RSVG_HANDLE_STATE_START
+ || priv->hstate == RSVG_HANDLE_STATE_LOADING,
+ FALSE,
+ error);
+
+ if (priv->hstate == RSVG_HANDLE_STATE_START) {
+ priv->hstate = RSVG_HANDLE_STATE_LOADING;
+ priv->load = rsvg_load_new (handle, (priv->flags & RSVG_HANDLE_FLAG_UNLIMITED) != 0);
+ }
+
+ g_assert (priv->hstate == RSVG_HANDLE_STATE_LOADING);
+
+ return rsvg_load_write (priv->load, buf, count, error);
+}
+
+static gboolean
+finish_load (RsvgHandle *handle, gboolean was_successful)
+{
+ RsvgNode *treebase = rsvg_load_destroy (handle->priv->load);
+ handle->priv->load = NULL;
+
+ if (was_successful) {
+ handle->priv->hstate = RSVG_HANDLE_STATE_CLOSED_OK;
+ handle->priv->treebase = treebase;
+ } else {
+ handle->priv->hstate = RSVG_HANDLE_STATE_CLOSED_ERROR;
+ treebase = rsvg_node_unref (treebase);
+ }
+
+ return was_successful;
+}
+
+/**
+ * rsvg_handle_close:
+ * @handle: a #RsvgHandle
+ * @error: (allow-none): a location to store a #GError, or %NULL
+ *
+ * Closes @handle, to indicate that loading the image is complete. This will
+ * return %TRUE if the loader closed successfully. Note that @handle isn't
+ * freed until @g_object_unref is called.
+ *
+ * Returns: %TRUE on success, or %FALSE on error
+ **/
+gboolean
+rsvg_handle_close (RsvgHandle *handle, GError **error)
+{
+ RsvgHandlePrivate *priv;
+ gboolean result;
+
+ rsvg_return_val_if_fail (handle, FALSE, error);
+ priv = handle->priv;
+
+ if (priv->hstate == RSVG_HANDLE_STATE_CLOSED_OK
+ || priv->hstate == RSVG_HANDLE_STATE_CLOSED_ERROR) {
+ /* closing is idempotent */
+ return TRUE;
+ }
+
+ result = finish_load (handle, rsvg_load_close (priv->load, error));
+
+ return result;
+}
+
+/**
+ * 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;
+ gboolean result;
+ RsvgLoad *saved_load;
+
+ 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;
+
+ g_return_val_if_fail (priv->hstate == RSVG_HANDLE_STATE_START, FALSE);
+
+ priv->hstate = RSVG_HANDLE_STATE_LOADING;
+
+ saved_load = priv->load;
+
+ priv->load = rsvg_load_new (handle, (priv->flags & RSVG_HANDLE_FLAG_UNLIMITED) != 0);
+ result = finish_load (handle, rsvg_load_read_stream_sync (priv->load, stream, cancellable, error));
+
+ priv->load = saved_load;
+
+ return result;
+}
+
/* http://www.ietf.org/rfc/rfc2396.txt */
static gboolean
@@ -771,7 +1010,6 @@ rsvg_handle_create_drawing_ctx(RsvgHandle *handle,
handle->priv->dpi_x, handle->priv->dpi_y,
handle->priv->defs,
handle->priv->is_testing);
-
}
/**
@@ -1256,6 +1494,215 @@ rsvg_handle_set_size_callback (RsvgHandle * handle,
handle->priv->user_data_destroy = user_data_destroy;
}
+char *
+rsvg_handle_resolve_uri (RsvgHandle *handle,
+ const char *uri)
+{
+ RsvgHandlePrivate *priv = handle->priv;
+ char *scheme, *resolved_uri;
+ GFile *base, *resolved;
+
+ if (uri == NULL)
+ return NULL;
+
+ scheme = g_uri_parse_scheme (uri);
+ if (scheme != NULL ||
+ priv->base_gfile == NULL ||
+ (base = g_file_get_parent (priv->base_gfile)) == NULL) {
+ g_free (scheme);
+ return g_strdup (uri);
+ }
+
+ resolved = g_file_resolve_relative_path (base, uri);
+ resolved_uri = g_file_get_uri (resolved);
+
+ g_free (scheme);
+ g_object_unref (base);
+ g_object_unref (resolved);
+
+ return resolved_uri;
+}
+
+char *
+_rsvg_handle_acquire_data (RsvgHandle *handle,
+ const char *url,
+ char **content_type,
+ gsize *len,
+ GError **error)
+{
+ RsvgHandlePrivate *priv = handle->priv;
+ char *uri;
+ char *data;
+
+ uri = rsvg_handle_resolve_uri (handle, url);
+
+ if (rsvg_allow_load (priv->base_gfile, uri, error)) {
+ data = _rsvg_io_acquire_data (uri,
+ rsvg_handle_get_base_uri (handle),
+ content_type,
+ len,
+ handle->priv->cancellable,
+ error);
+ } else {
+ data = NULL;
+ }
+
+ g_free (uri);
+ return data;
+}
+
+GInputStream *
+_rsvg_handle_acquire_stream (RsvgHandle *handle,
+ const char *url,
+ char **content_type,
+ GError **error)
+{
+ RsvgHandlePrivate *priv = handle->priv;
+ char *uri;
+ GInputStream *stream;
+
+ uri = rsvg_handle_resolve_uri (handle, url);
+
+ if (rsvg_allow_load (priv->base_gfile, uri, error)) {
+ stream = _rsvg_io_acquire_stream (uri,
+ rsvg_handle_get_base_uri (handle),
+ content_type,
+ handle->priv->cancellable,
+ error);
+ } else {
+ stream = NULL;
+ }
+
+ g_free (uri);
+ return stream;
+}
+
+cairo_surface_t *
+rsvg_cairo_surface_new_from_href (RsvgHandle *handle,
+ const char *href,
+ GError **error)
+{
+ char *data;
+ gsize data_len;
+ char *mime_type = NULL;
+ GdkPixbufLoader *loader = NULL;
+ GdkPixbuf *pixbuf = NULL;
+ cairo_surface_t *surface = NULL;
+
+ data = _rsvg_handle_acquire_data (handle, href, &mime_type, &data_len, error);
+ if (data == NULL)
+ return NULL;
+
+ if (mime_type) {
+ loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, error);
+ } else {
+ loader = gdk_pixbuf_loader_new ();
+ }
+
+ if (loader == NULL)
+ goto out;
+
+ if (!gdk_pixbuf_loader_write (loader, (guchar *) data, data_len, error)) {
+ gdk_pixbuf_loader_close (loader, NULL);
+ goto out;
+ }
+
+ if (!gdk_pixbuf_loader_close (loader, error))
+ goto out;
+
+ pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+
+ if (!pixbuf) {
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_FAILED,
+ _("Failed to load image '%s': reason not known, probably a corrupt image file"),
+ href);
+ goto out;
+ }
+
+ surface = rsvg_cairo_surface_from_pixbuf (pixbuf);
+
+ if (mime_type == NULL) {
+ /* Try to get the information from the loader */
+ GdkPixbufFormat *format;
+ char **mime_types;
+
+ if ((format = gdk_pixbuf_loader_get_format (loader)) != NULL) {
+ mime_types = gdk_pixbuf_format_get_mime_types (format);
+
+ if (mime_types != NULL)
+ mime_type = g_strdup (mime_types[0]);
+ g_strfreev (mime_types);
+ }
+ }
+
+ if ((handle->priv->flags & RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA) != 0 &&
+ mime_type != NULL &&
+ cairo_surface_set_mime_data (surface, mime_type, (guchar *) data,
+ data_len, g_free, data) == CAIRO_STATUS_SUCCESS) {
+ data = NULL; /* transferred to the surface */
+ }
+
+ out:
+ if (loader)
+ g_object_unref (loader);
+ g_free (mime_type);
+ g_free (data);
+
+ return surface;
+}
+
+#ifdef HAVE_PANGOFT2
+
+static void
+create_font_config_for_testing (RsvgHandle *handle)
+{
+ const char *font_paths[] = {
+ "resources/Roboto-Regular.ttf",
+ "resources/Roboto-Italic.ttf",
+ "resources/Roboto-Bold.ttf",
+ "resources/Roboto-BoldItalic.ttf",
+ };
+
+ int i;
+
+ if (handle->priv->font_config_for_testing != NULL)
+ return;
+
+ handle->priv->font_config_for_testing = FcConfigCreate ();
+
+ for (i = 0; i < G_N_ELEMENTS(font_paths); i++) {
+ char *font_path = g_test_build_filename (G_TEST_DIST, font_paths[i], NULL);
+
+ if (!FcConfigAppFontAddFile (handle->priv->font_config_for_testing, (const FcChar8 *) font_path)) {
+ g_error ("Could not load font file \"%s\" for tests; aborting", font_path);
+ }
+
+ g_free (font_path);
+ }
+}
+
+#endif
+
+static void
+rsvg_handle_update_font_map_for_testing (RsvgHandle *handle)
+{
+#ifdef HAVE_PANGOFT2
+ if (handle->priv->is_testing) {
+ create_font_config_for_testing (handle);
+
+ if (handle->priv->font_map_for_testing == NULL) {
+ handle->priv->font_map_for_testing = pango_cairo_font_map_new_for_font_type (CAIRO_FONT_TYPE_FT);
+ pango_fc_font_map_set_config (PANGO_FC_FONT_MAP (handle->priv->font_map_for_testing),
+ handle->priv->font_config_for_testing);
+
+ pango_cairo_font_map_set_default (PANGO_CAIRO_FONT_MAP (handle->priv->font_map_for_testing));
+ }
+ }
+#endif
+}
+
/**
* _rsvg_handle_internal_set_testing:
* @handle: a #RsvgHandle
diff --git a/librsvg/rsvg-file-util.c b/librsvg/rsvg-pixbuf.c
index 47eeec58..198a5642 100644
--- a/librsvg/rsvg-file-util.c
+++ b/librsvg/rsvg-pixbuf.c
@@ -42,45 +42,6 @@
#include <stdio.h>
#include <stdlib.h>
-#define SVG_BUFFER_SIZE (1024 * 8)
-
-/* private */
-GdkPixbuf *
-rsvg_pixbuf_from_data_with_size_data (const guchar * buff,
- size_t len,
- /* RsvgSizeCallbackData */ gpointer data,
- const char *base_uri, GError ** error)
-{
- RsvgHandle *handle;
- GdkPixbuf *retval;
-
- handle = rsvg_handle_new ();
-
- if (!handle) {
- g_set_error (error, rsvg_error_quark (), 0, _("Error creating SVG reader"));
- return NULL;
- }
-
- rsvg_handle_set_size_callback (handle, _rsvg_size_callback, data, NULL);
- rsvg_handle_set_base_uri (handle, base_uri);
-
- if (!rsvg_handle_write (handle, buff, len, error)) {
- (void) rsvg_handle_close (handle, NULL);
- g_object_unref (handle);
- return NULL;
- }
-
- if (!rsvg_handle_close (handle, error)) {
- g_object_unref (handle);
- return NULL;
- }
-
- retval = rsvg_handle_get_pixbuf (handle);
- g_object_unref (handle);
-
- return retval;
-}
-
static GdkPixbuf *
rsvg_pixbuf_from_stdio_file_with_size_data (const char *data,
gsize data_len,
diff --git a/librsvg/rsvg-private.h b/librsvg/rsvg-private.h
index 1d4269e9..c33f69f1 100644
--- a/librsvg/rsvg-private.h
+++ b/librsvg/rsvg-private.h
@@ -325,12 +325,6 @@ gboolean rsvg_property_bag_iter_next (RsvgPropertyBagIter *iter,
G_GNUC_INTERNAL
void rsvg_property_bag_iter_end (RsvgPropertyBagIter *iter);
-/* for some reason this one's public... */
-GdkPixbuf *rsvg_pixbuf_from_data_with_size_data (const guchar * buff,
- size_t len,
- gpointer data,
- const char *base_uri, GError ** error);
-
/* Implemented in rust/src/cond.rs */
G_GNUC_INTERNAL
gboolean rsvg_cond_check_required_features (const char *value);
@@ -418,9 +412,6 @@ RsvgHandle *rsvg_handle_load_extern (RsvgHandle *handle,
const char *uri);
G_GNUC_INTERNAL
-void rsvg_handle_update_font_map_for_testing (RsvgHandle *handle);
-
-G_GNUC_INTERNAL
gboolean rsvg_allow_load (GFile *base_gfile,
const char *uri,
GError **error);