[librsvg] Consolidate (tree, defs, css_styles) into an Svg type, invisible to C
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] Consolidate (tree, defs, css_styles) into an Svg type, invisible to C
- Date: Mon, 3 Dec 2018 18:53:21 +0000 (UTC)
commit 04e93aef8725c208031bc29cf5be92d06d5ebee9
Author: Federico Mena Quintero <federico gnome org>
Date: Fri Nov 30 18:53:56 2018 -0600
Consolidate (tree, defs, css_styles) into an Svg type, invisible to C
The tree/defs/css_styles always go together, so we encapsulate them
into an Svg type.
In addition, we put this in the Rust Handle, not in the C
RsvgHandlePrivate, so the C code does not ever see the Svg type.
This requires moving a bunch of C-visible functions like
rsvg_defs_foo() to rsvg_handle_rust_defs_foo(). These will go away in
the end, as more of the code is ported to Rust.
Makefile.am | 1 +
librsvg/rsvg-handle.c | 109 +++++-----------
librsvg/rsvg-load.c | 31 ++---
librsvg/rsvg-load.h | 7 +-
librsvg/rsvg-private.h | 73 +----------
rsvg_internals/src/clip_path.rs | 2 +-
rsvg_internals/src/css.rs | 14 --
rsvg_internals/src/defs.rs | 81 ++----------
rsvg_internals/src/drawing_ctx.rs | 37 +++---
rsvg_internals/src/filters/blend.rs | 2 +-
rsvg_internals/src/filters/bounds.rs | 6 +-
rsvg_internals/src/filters/color_matrix.rs | 2 +-
rsvg_internals/src/filters/component_transfer.rs | 2 +-
rsvg_internals/src/filters/composite.rs | 2 +-
rsvg_internals/src/filters/context.rs | 18 +--
rsvg_internals/src/filters/convolve_matrix.rs | 2 +-
rsvg_internals/src/filters/displacement_map.rs | 2 +-
rsvg_internals/src/filters/flood.rs | 2 +-
rsvg_internals/src/filters/gaussian_blur.rs | 2 +-
rsvg_internals/src/filters/image.rs | 6 +-
rsvg_internals/src/filters/light/lighting.rs | 2 +-
rsvg_internals/src/filters/merge.rs | 4 +-
rsvg_internals/src/filters/mod.rs | 6 +-
rsvg_internals/src/filters/morphology.rs | 2 +-
rsvg_internals/src/filters/offset.rs | 2 +-
rsvg_internals/src/filters/tile.rs | 2 +-
rsvg_internals/src/filters/turbulence.rs | 2 +-
rsvg_internals/src/gradient.rs | 6 +-
rsvg_internals/src/handle.rs | 159 ++++++++++++++++++++---
rsvg_internals/src/image.rs | 2 +-
rsvg_internals/src/lib.rs | 17 +--
rsvg_internals/src/link.rs | 2 +-
rsvg_internals/src/marker.rs | 6 +-
rsvg_internals/src/mask.rs | 2 +-
rsvg_internals/src/node.rs | 6 +-
rsvg_internals/src/paint_server.rs | 15 +--
rsvg_internals/src/pattern.rs | 4 +-
rsvg_internals/src/shapes.rs | 16 +--
rsvg_internals/src/structure.rs | 8 +-
rsvg_internals/src/svg.rs | 30 +++++
rsvg_internals/src/text.rs | 28 ++--
rsvg_internals/src/tree.rs | 59 +--------
rsvg_internals/src/viewport.rs | 4 +-
rsvg_internals/src/xml.rs | 72 +++++-----
44 files changed, 373 insertions(+), 484 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index ec8a4dd5..cb67d101 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -111,6 +111,7 @@ RUST_SRC = \
rsvg_internals/src/stop.rs \
rsvg_internals/src/structure.rs \
rsvg_internals/src/style.rs \
+ rsvg_internals/src/svg.rs \
rsvg_internals/src/text.rs \
rsvg_internals/src/transform.rs \
rsvg_internals/src/tree.rs \
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index 17ab2934..f9bf7e66 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -127,6 +127,16 @@
#include "rsvg-load.h"
#include "rsvg-private.h"
+/* Implemented in rsvg_internals/src/handle.rs */
+extern RsvgHandleRust *rsvg_handle_rust_new (void);
+extern void rsvg_handle_rust_free (RsvgHandleRust *raw_handle);
+extern void rsvg_handle_rust_cascade (RsvgHandleRust *raw_handle);
+extern void rsvg_handle_rust_set_base_url (RsvgHandleRust *raw_handle, const char *uri);
+extern RsvgNode *rsvg_handle_rust_get_root (RsvgHandleRust *raw_handle);
+extern GFile *rsvg_handle_rust_get_base_gfile (RsvgHandleRust *raw_handle);
+extern RsvgNode *rsvg_handle_defs_lookup (RsvgHandle *handle, const char *name);
+extern gboolean rsvg_handle_rust_node_is_root(RsvgHandleRust *raw_handle, RsvgNode *node);
+
enum {
PROP_0,
PROP_FLAGS,
@@ -158,10 +168,6 @@ rsvg_handle_init (RsvgHandle * self)
self->priv->dpi_x = rsvg_internal_dpi_x;
self->priv->dpi_y = rsvg_internal_dpi_y;
- self->priv->tree = NULL;
- self->priv->defs = NULL;
- self->priv->css_styles = NULL;
-
self->priv->cancellable = NULL;
self->priv->in_loop = FALSE;
@@ -187,9 +193,7 @@ rsvg_handle_dispose (GObject *instance)
}
g_clear_pointer (&self->priv->load, rsvg_load_free);
- g_clear_pointer (&self->priv->defs, rsvg_defs_free);
- g_clear_pointer (&self->priv->css_styles, rsvg_css_styles_free);
- g_clear_pointer (&self->priv->tree, rsvg_tree_free);
+
g_clear_pointer (&self->priv->base_uri, g_free);
#ifdef HAVE_PANGOFT2
@@ -659,55 +663,24 @@ rsvg_handle_write (RsvgHandle *handle, const guchar *buf, gsize count, GError **
return rsvg_load_write (priv->load, buf, count, error);
}
-static gboolean
-tree_is_valid (RsvgTree *tree, GError **error)
-{
- if (!tree) {
- g_set_error (error, RSVG_ERROR, RSVG_ERROR_FAILED, _("SVG has no elements"));
- return FALSE;
- }
-
- if (!rsvg_tree_root_is_svg (tree)) {
- g_set_error (error, RSVG_ERROR, RSVG_ERROR_FAILED, _("root element is not <svg>"));
- return FALSE;
- }
-
- return TRUE;
-}
-
static gboolean
finish_load (RsvgHandle *handle, gboolean was_successful, GError **error)
{
- RsvgTree *tree = NULL;
- RsvgDefs *defs = NULL;
- RsvgCssStyles *css_styles = NULL;
-
g_assert (handle->priv->load != NULL);
- g_assert (handle->priv->tree == NULL);
if (was_successful) {
g_assert (error == NULL || *error == NULL);
- rsvg_load_steal_result (handle->priv->load, &tree, &defs, &css_styles);
- was_successful = tree_is_valid (tree, error);
- if (!was_successful) {
- g_clear_pointer (&tree, rsvg_tree_free);
- g_clear_pointer (&defs, rsvg_defs_free);
- g_clear_pointer (&css_styles, rsvg_css_styles_free);
- }
+ was_successful = rsvg_load_finish_load(handle->priv->load, error);
}
if (was_successful) {
- g_assert (tree != NULL);
handle->priv->hstate = RSVG_HANDLE_STATE_CLOSED_OK;
} else {
handle->priv->hstate = RSVG_HANDLE_STATE_CLOSED_ERROR;
}
g_clear_pointer (&handle->priv->load, rsvg_load_free);
- handle->priv->tree = tree;
- handle->priv->defs = defs;
- handle->priv->css_styles = css_styles;
return was_successful;
}
@@ -885,7 +858,7 @@ rsvg_handle_set_base_uri (RsvgHandle * handle, const char *base_uri)
gchar *uri;
GFile *file;
- g_return_if_fail (handle != NULL);
+ g_return_if_fail (RSVG_IS_HANDLE (handle));
if (base_uri == NULL)
return;
@@ -1017,30 +990,12 @@ rsvg_handle_get_flags (RsvgHandle *handle)
return (guint) handle->priv->flags;
}
-RsvgDefs *
-rsvg_handle_get_defs (RsvgHandle *handle)
-{
- return handle->priv->defs;
-}
-
-RsvgTree *
-rsvg_handle_get_tree (RsvgHandle *handle)
-{
- return handle->priv->tree;
-}
-
RsvgHandleRust *
rsvg_handle_get_rust (RsvgHandle *handle)
{
return handle->priv->rust_handle;
}
-RsvgCssStyles *
-rsvg_handle_get_css_styles (RsvgHandle *handle)
-{
- return handle->priv->css_styles;
-}
-
gboolean
rsvg_handle_keep_image_data (RsvgHandle *handle)
{
@@ -1085,7 +1040,7 @@ rsvg_handle_render_cairo_sub (RsvgHandle * handle, cairo_t * cr, const char *id)
cairo_status_t status;
gboolean res;
- g_return_val_if_fail (handle != NULL, FALSE);
+ g_return_val_if_fail (RSVG_IS_HANDLE (handle), FALSE);
if (handle->priv->hstate != RSVG_HANDLE_STATE_CLOSED_OK)
return FALSE;
@@ -1100,7 +1055,7 @@ rsvg_handle_render_cairo_sub (RsvgHandle * handle, cairo_t * cr, const char *id)
}
if (id && *id)
- drawsub = rsvg_defs_lookup (handle->priv->defs, handle, id);
+ drawsub = rsvg_handle_defs_lookup (handle, id);
if (drawsub == NULL && id != NULL) {
g_warning ("element id=\"%s\" does not exist", id);
@@ -1120,8 +1075,8 @@ rsvg_handle_render_cairo_sub (RsvgHandle * handle, cairo_t * cr, const char *id)
rsvg_drawing_ctx_add_node_and_ancestors_to_stack (draw, drawsub);
}
- rsvg_tree_cascade (handle->priv->tree);
- res = rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->tree);
+ rsvg_handle_rust_cascade (handle->priv->rust_handle);
+ res = rsvg_drawing_ctx_draw_node_from_stack (draw);
rsvg_drawing_ctx_free (draw);
@@ -1199,9 +1154,9 @@ get_node_geometry(RsvgHandle *handle, RsvgNode *node, RsvgRectangle *ink_rect, R
draw = rsvg_handle_create_drawing_ctx (handle, cr, &dimensions);
rsvg_drawing_ctx_add_node_and_ancestors_to_stack (draw, node);
- rsvg_tree_cascade (handle->priv->tree);
+ rsvg_handle_rust_cascade (handle->priv->rust_handle);
/* FIXME: expose this as a RenderingError in the public API */
- res = rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->tree);
+ res = rsvg_drawing_ctx_draw_node_from_stack (draw);
if (res) {
rsvg_drawing_ctx_get_geometry (draw, ink_rect, logical_rect);
}
@@ -1272,7 +1227,7 @@ gboolean
rsvg_handle_get_geometry_sub (RsvgHandle * handle, RsvgRectangle * ink_rect, RsvgRectangle * logical_rect,
const char *id)
{
RsvgNode *root = NULL;
- RsvgNode *node;
+ RsvgNode *node = NULL;
gboolean has_size;
int root_width, root_height;
gboolean res = FALSE;
@@ -1283,18 +1238,15 @@ rsvg_handle_get_geometry_sub (RsvgHandle * handle, RsvgRectangle * ink_rect, Rsv
memset (&ink_r, 0, sizeof (RsvgRectangle));
memset (&logical_r, 0, sizeof (RsvgRectangle));
- if (handle->priv->tree == NULL)
- return FALSE;
+ g_return_val_if_fail (handle->priv->hstate == RSVG_HANDLE_STATE_CLOSED_OK, FALSE);
- root = rsvg_tree_get_root (handle->priv->tree);
+ root = rsvg_handle_rust_get_root (handle->priv->rust_handle);
if (id && *id) {
- node = rsvg_defs_lookup (handle->priv->defs, handle, id);
+ node = rsvg_handle_defs_lookup (handle, id);
- if (node && rsvg_tree_is_root (handle->priv->tree, node))
+ if (node && rsvg_handle_rust_node_is_root (handle->priv->rust_handle, node))
id = NULL;
- } else {
- node = root;
}
if (!node && id) {
@@ -1306,7 +1258,7 @@ rsvg_handle_get_geometry_sub (RsvgHandle * handle, RsvgRectangle * ink_rect, Rsv
&root_width, &root_height);
if (id || !has_size) {
- res = get_node_geometry (handle, node, &ink_r, &logical_r);
+ res = get_node_geometry (handle, node ? node : root, &ink_r, &logical_r);
if (!res) {
goto out;
}
@@ -1334,6 +1286,7 @@ out:
*logical_rect = logical_r;
}
+ g_clear_pointer (&node, rsvg_node_unref);
g_clear_pointer (&root, rsvg_node_unref);
return res;
@@ -1398,12 +1351,12 @@ gboolean
rsvg_handle_has_sub (RsvgHandle * handle,
const char *id)
{
- g_return_val_if_fail (handle, FALSE);
+ g_return_val_if_fail (RSVG_IS_HANDLE (handle), FALSE);
if (G_UNLIKELY (!id || !id[0]))
return FALSE;
- return rsvg_defs_lookup (handle->priv->defs, handle, id) != NULL;
+ return rsvg_handle_defs_lookup (handle, id) != NULL;
}
/**
@@ -1436,7 +1389,7 @@ rsvg_handle_get_pixbuf_sub (RsvgHandle * handle, const char *id)
cairo_surface_t *surface;
cairo_t *cr;
- g_return_val_if_fail (handle != NULL, NULL);
+ g_return_val_if_fail (RSVG_IS_HANDLE (handle), NULL);
if (handle->priv->hstate != RSVG_HANDLE_STATE_CLOSED_OK)
return NULL;
@@ -1518,7 +1471,7 @@ rsvg_handle_set_dpi (RsvgHandle * handle, double dpi)
void
rsvg_handle_set_dpi_x_y (RsvgHandle * handle, double dpi_x, double dpi_y)
{
- g_return_if_fail (handle != NULL);
+ g_return_if_fail (RSVG_IS_HANDLE (handle));
if (dpi_x <= 0.)
handle->priv->dpi_x = rsvg_internal_dpi_x;
@@ -1576,7 +1529,7 @@ rsvg_handle_set_size_callback (RsvgHandle * handle,
RsvgSizeFunc size_func,
gpointer user_data, GDestroyNotify user_data_destroy)
{
- g_return_if_fail (handle != NULL);
+ g_return_if_fail (RSVG_IS_HANDLE (handle));
if (handle->priv->user_data_destroy)
(*handle->priv->user_data_destroy) (handle->priv->user_data);
diff --git a/librsvg/rsvg-load.c b/librsvg/rsvg-load.c
index a4944a16..7caaecb9 100644
--- a/librsvg/rsvg-load.c
+++ b/librsvg/rsvg-load.c
@@ -38,24 +38,13 @@ typedef enum {
LOAD_STATE_CLOSED
} LoadState;
-/* Implemented in rsvg_internals/src/load.rs */
-G_GNUC_INTERNAL
-void rsvg_load_set_svg_node_atts (RsvgHandle *handle, RsvgNode *node);
-
-/* Implemented in rsvg_internals/src/node.rs */
-G_GNUC_INTERNAL
-void rsvg_node_register_in_defs(RsvgNode *node, RsvgDefs *defs);
-
/* Implemented in rsvg_internals/src/xml.rs */
typedef struct RsvgXmlState RsvgXmlState;
/* Implemented in rsvg_internals/src/xml.rs */
extern RsvgXmlState *rsvg_xml_state_new ();
extern void rsvg_xml_state_free (RsvgXmlState *xml);
-extern void rsvg_xml_state_steal_result(RsvgXmlState *xml,
- RsvgTree **out_tree,
- RsvgDefs **out_defs,
- RsvgCssStyles **out_css_styles);
+extern gboolean rsvg_xml_state_tree_is_valid(RsvgXmlState *xml, GError **error);
extern void rsvg_xml_state_start_element(RsvgXmlState *xml, RsvgHandle *handle, const char *name,
RsvgPropertyBag atts);
extern void rsvg_xml_state_end_element(RsvgXmlState *xml, RsvgHandle *handle, const char *name);
extern void rsvg_xml_state_characters(RsvgXmlState *xml, const char *unterminated_text, gsize len);
@@ -72,6 +61,9 @@ extern void rsvg_xml_state_load_css_from_href(RsvgXmlState *xml,
RsvgHandle *handle,
const char *href);
+/* Implemented in rsvg_internals/src/handle.rs */
+extern void rsvg_handle_rust_steal_result (RsvgHandleRust *raw_handle, RsvgXmlState *xml);
+
/* Holds the XML parsing state */
typedef struct {
@@ -149,13 +141,16 @@ rsvg_load_free (RsvgLoad *load)
g_free (load);
}
-void
-rsvg_load_steal_result (RsvgLoad *load,
- RsvgTree **out_tree,
- RsvgDefs **out_defs,
- RsvgCssStyles **out_css_styles)
+gboolean
+rsvg_load_finish_load (RsvgLoad *load, GError **error)
{
- rsvg_xml_state_steal_result (load->xml.rust_state, out_tree, out_defs, out_css_styles);
+ gboolean was_successful = rsvg_xml_state_tree_is_valid(load->xml.rust_state, error);
+
+ if (was_successful) {
+ rsvg_handle_rust_steal_result (load->handle->priv->rust_handle, load->xml.rust_state);
+ }
+
+ return was_successful;
}
static void
diff --git a/librsvg/rsvg-load.h b/librsvg/rsvg-load.h
index 4b803cfb..99e9fed7 100644
--- a/librsvg/rsvg-load.h
+++ b/librsvg/rsvg-load.h
@@ -32,13 +32,10 @@ G_GNUC_INTERNAL
void rsvg_load_free (RsvgLoad *load);
G_GNUC_INTERNAL
-gboolean rsvg_load_handle_xml_xinclude (RsvgHandle *handle, const char *url);
+gboolean rsvg_load_finish_load(RsvgLoad *load, GError **error);
G_GNUC_INTERNAL
-void rsvg_load_steal_result (RsvgLoad *load,
- RsvgTree **out_tree,
- RsvgDefs **out_defs,
- RsvgCssStyles **out_css_styles);
+gboolean rsvg_load_handle_xml_xinclude (RsvgHandle *handle, const char *url);
G_GNUC_INTERNAL
gboolean rsvg_load_write (RsvgLoad *load, const guchar *buf, gsize count, GError **error)
G_GNUC_WARN_UNUSED_RESULT;
diff --git a/librsvg/rsvg-private.h b/librsvg/rsvg-private.h
index f934b06b..49343060 100644
--- a/librsvg/rsvg-private.h
+++ b/librsvg/rsvg-private.h
@@ -58,7 +58,6 @@ typedef struct RsvgDrawingCtx RsvgDrawingCtx;
typedef struct RsvgState RsvgState;
typedef void *RsvgPropertyBag;
-typedef struct _RsvgDefs RsvgDefs;
typedef struct _RsvgNode RsvgNode;
typedef struct _RsvgFilter RsvgFilter;
@@ -81,10 +80,6 @@ typedef enum {
typedef struct RsvgLoad RsvgLoad;
-typedef struct RsvgTree RsvgTree;
-
-typedef struct RsvgCssStyles RsvgCssStyles;
-
/* Defined in rsvg_internals/src/handle.rs */
typedef struct RsvgHandleRust RsvgHandleRust;
@@ -99,10 +94,6 @@ struct RsvgHandlePrivate {
gpointer user_data;
GDestroyNotify user_data_destroy;
- RsvgTree *tree;
- RsvgDefs *defs; /* lookup table for nodes that have an id="foo" attribute */
- RsvgCssStyles *css_styles;
-
GCancellable *cancellable;
double dpi_x;
@@ -133,34 +124,6 @@ void rsvg_node_set_overridden_properties (RsvgNode *node);
typedef struct RsvgNodeChildrenIter *RsvgNodeChildrenIter;
-/* Implemented in rsvg_internals/src/tree.rs */
-G_GNUC_INTERNAL
-void rsvg_tree_free (RsvgTree *tree);
-
-/* Implemented in rsvg_internals/src/tree.rs */
-G_GNUC_INTERNAL
-RsvgNode *rsvg_tree_get_root (RsvgTree *tree);
-
-/* Implemented in rsvg_internals/src/tree.rs */
-G_GNUC_INTERNAL
-gboolean rsvg_tree_is_root (RsvgTree *tree, RsvgNode *node);
-
-/* Implemented in rsvg_internals/src/tree.rs */
-G_GNUC_INTERNAL
-gboolean rsvg_tree_root_is_svg (RsvgTree *tree);
-
-/* Implemented in rsvg_internals/src/tree.rs */
-G_GNUC_INTERNAL
-void rsvg_tree_cascade (RsvgTree *tree);
-
-/* Implemented in rsvg_internals/src/css.rs */
-G_GNUC_INTERNAL
-RsvgCssStyles *rsvg_css_styles_new (void);
-
-/* Implemented in rsvg_internals/src/css.rs */
-G_GNUC_INTERNAL
-void rsvg_css_styles_free (RsvgCssStyles *styles);
-
/* Implemented in rsvg_internals/src/structure.rs */
G_GNUC_INTERNAL
gboolean rsvg_node_svg_get_size (RsvgNode *node, double dpi_x, double dpi_y, int *out_width, int
*out_height);
@@ -218,7 +181,7 @@ void rsvg_drawing_ctx_add_node_and_ancestors_to_stack (RsvgDrawingCtx *draw_ctx,
/* Defined in rsvg_internals/src/drawing_ctx.rs */
G_GNUC_INTERNAL
-gboolean rsvg_drawing_ctx_draw_node_from_stack (RsvgDrawingCtx *ctx, RsvgTree *tree)
G_GNUC_WARN_UNUSED_RESULT;;
+gboolean rsvg_drawing_ctx_draw_node_from_stack (RsvgDrawingCtx *ctx) G_GNUC_WARN_UNUSED_RESULT;;
/* Defined in rsvg_internals/src/drawing_ctx.rs */
G_GNUC_INTERNAL
@@ -235,46 +198,12 @@ void rsvg_return_if_fail_warning (const char *pretty_function,
G_GNUC_INTERNAL
RsvgNode *rsvg_load_destroy (RsvgLoad *load) G_GNUC_WARN_UNUSED_RESULT;
-/* Defined in rsvg_internals/src/defs.rs */
-G_GNUC_INTERNAL
-void rsvg_defs_free (RsvgDefs *defs);
-
-/* Defined in rsvg_internals/src/defs.rs */
-G_GNUC_INTERNAL
-RsvgNode *rsvg_defs_lookup (const RsvgDefs * defs, RsvgHandle *handle, const char *name);
-
G_GNUC_INTERNAL
guint rsvg_handle_get_flags (RsvgHandle *handle);
-G_GNUC_INTERNAL
-RsvgDefs *rsvg_handle_get_defs (RsvgHandle *handle);
-
-G_GNUC_INTERNAL
-RsvgTree *rsvg_handle_get_tree (RsvgHandle *handle);
-
G_GNUC_INTERNAL
RsvgHandleRust *rsvg_handle_get_rust (RsvgHandle *handle);
-G_GNUC_INTERNAL
-RsvgCssStyles *rsvg_handle_get_css_styles (RsvgHandle *handle);
-
-/* Implemented in rsvg_internals/src/handle.rs */
-G_GNUC_INTERNAL
-RsvgHandleRust *rsvg_handle_rust_new (void);
-
-/* Implemented in rsvg_internals/src/handle.rs */
-G_GNUC_INTERNAL
-void rsvg_handle_rust_free (RsvgHandleRust *raw_handle);
-
-/* Implemented in rsvg_internals/src/handle.rs */
-G_GNUC_INTERNAL
-void rsvg_handle_rust_set_base_url (RsvgHandleRust *raw_handle,
- const char *uri);
-
-/* Implemented in rsvg_internals/src/handle.rs */
-G_GNUC_INTERNAL
-GFile *rsvg_handle_rust_get_base_gfile (RsvgHandleRust *raw_handle);
-
G_GNUC_INTERNAL
gboolean rsvg_handle_keep_image_data (RsvgHandle *handle);
diff --git a/rsvg_internals/src/clip_path.rs b/rsvg_internals/src/clip_path.rs
index 3a8f2347..d674e10f 100644
--- a/rsvg_internals/src/clip_path.rs
+++ b/rsvg_internals/src/clip_path.rs
@@ -32,7 +32,7 @@ impl NodeClipPath {
&self,
node: &RsvgNode,
affine_before_clip: &cairo::Matrix,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
) -> Result<(), RenderingError> {
let cascaded = node.get_cascaded_values();
diff --git a/rsvg_internals/src/css.rs b/rsvg_internals/src/css.rs
index efedb35e..9c6d0163 100644
--- a/rsvg_internals/src/css.rs
+++ b/rsvg_internals/src/css.rs
@@ -14,8 +14,6 @@ use handle::{self, RsvgHandle};
use state::State;
use util::utf8_cstr;
-pub enum RsvgCssStyles {}
-
struct Declaration {
prop_value: String,
important: bool,
@@ -224,15 +222,3 @@ unsafe extern "C" fn css_error(_a_this: *mut CRDocHandler) {
unsafe extern "C" fn css_unrecoverable_error(_a_this: *mut CRDocHandler) {
println!("CSS unrecoverable error");
}
-
-#[no_mangle]
-pub extern "C" fn rsvg_css_styles_new() -> *mut RsvgCssStyles {
- Box::into_raw(Box::new(CssStyles::new())) as *mut RsvgCssStyles
-}
-
-#[no_mangle]
-pub unsafe extern "C" fn rsvg_css_styles_free(raw_styles: *mut RsvgCssStyles) {
- assert!(!raw_styles.is_null());
-
- Box::from_raw(raw_styles as *mut CssStyles);
-}
diff --git a/rsvg_internals/src/defs.rs b/rsvg_internals/src/defs.rs
index 6f50cd63..373e8e22 100644
--- a/rsvg_internals/src/defs.rs
+++ b/rsvg_internals/src/defs.rs
@@ -1,19 +1,13 @@
-use libc;
use std::collections::hash_map::Entry;
use std::collections::HashMap;
use std::fmt;
-use std::ptr;
use std::rc::Rc;
use allowed_url::AllowedUrl;
use error::ValueErrorKind;
use handle::{self, RsvgHandle};
-use node::{Node, RsvgNode};
+use node::Node;
use parsers::ParseError;
-use util::rsvg_g_warning;
-use util::utf8_cstr;
-
-pub enum RsvgDefs {}
pub struct Defs {
nodes: HashMap<String, Rc<Node>>,
@@ -32,6 +26,10 @@ impl Defs {
self.nodes.entry(id.to_string()).or_insert(node.clone());
}
+ pub fn lookup_fragment_id(&self, id: &str) -> Option<Rc<Node>> {
+ self.nodes.get(id).map(|n| (*n).clone())
+ }
+
/// Returns a node referenced by a fragment ID
///
/// If the `Fragment`'s URL is `None`, then the fragment ID refers
@@ -39,16 +37,14 @@ impl Defs {
/// an externally-loaded SVG file that is referenced by the
/// current one. If the element's id is not found, returns
/// `None`.
- pub fn lookup(&mut self, handle: *const RsvgHandle, fragment: &Fragment) -> Option<&Rc<Node>> {
+ pub fn lookup(&mut self, handle: *const RsvgHandle, fragment: &Fragment) -> Option<Rc<Node>> {
if let Some(ref href) = fragment.uri() {
match self.get_extern_handle(handle, href) {
- Ok(extern_handle) => handle::get_defs(extern_handle)
- .nodes
- .get(fragment.fragment()),
+ Ok(extern_handle) => handle::lookup_fragment_id(extern_handle, fragment),
Err(()) => None,
}
} else {
- self.nodes.get(fragment.fragment())
+ self.lookup_fragment_id(fragment.fragment())
}
}
@@ -204,67 +200,6 @@ impl Href {
}
}
-#[no_mangle]
-pub extern "C" fn rsvg_defs_free(defs: *mut RsvgDefs) {
- assert!(!defs.is_null());
-
- unsafe {
- let defs = { &mut *(defs as *mut Defs) };
- Box::from_raw(defs);
- }
-}
-
-#[no_mangle]
-pub extern "C" fn rsvg_defs_lookup(
- defs: *mut RsvgDefs,
- handle: *const RsvgHandle,
- name: *const libc::c_char,
-) -> *const RsvgNode {
- assert!(!defs.is_null());
- assert!(!name.is_null());
-
- let defs = unsafe { &mut *(defs as *mut Defs) };
- let name = unsafe { utf8_cstr(name) };
-
- let r = Href::with_fragment(name);
- if r.is_err() {
- return ptr::null();
- }
-
- match r.unwrap() {
- Href::WithFragment(fragment) => {
- if let Some(uri) = fragment.uri() {
- // The public APIs to get geometries of individual elements, or to render
- // them, should only allow referencing elements within the main handle's
- // SVG file; that is, only plain "#foo" fragment IDs are allowed here.
- // Otherwise, a calling program could request "another-file#foo" and cause
- // another-file to be loaded, even if it is not part of the set of
- // resources that the main SVG actually references. In the future we may
- // relax this requirement to allow lookups within that set, but not to
- // other random files.
-
- let msg = format!(
- "the public API is not allowed to look up external references: {}#{}",
- uri,
- fragment.fragment()
- );
-
- rsvg_log!("{}", msg);
-
- rsvg_g_warning(&msg);
- return ptr::null();
- }
-
- match defs.lookup(handle, &fragment) {
- Some(n) => n as *const RsvgNode,
- None => ptr::null(),
- }
- }
-
- _ => unreachable!(),
- }
-}
-
#[cfg(test)]
mod tests {
use super::*;
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index f7594249..56af9951 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -13,7 +13,7 @@ use std::rc::{Rc, Weak};
use bbox::BoundingBox;
use clip_path::{ClipPathUnits, NodeClipPath};
use coord_units::CoordUnits;
-use defs::{Defs, Fragment};
+use defs::Fragment;
use error::RenderingError;
use filters;
use float_eq_cairo::ApproxEqCairo;
@@ -35,7 +35,6 @@ use state::{
StrokeLinejoin,
TextRendering,
};
-use tree::{RsvgTree, Tree};
use unitinterval::UnitInterval;
use viewbox::ViewBox;
@@ -98,7 +97,7 @@ impl Drop for ViewParams {
pub enum RsvgDrawingCtx {}
-pub struct DrawingCtx<'a> {
+pub struct DrawingCtx {
handle: *const RsvgHandle,
rect: cairo::Rectangle,
@@ -130,13 +129,12 @@ pub struct DrawingCtx<'a> {
drawsub_stack: Vec<RsvgNode>,
- defs: RefCell<&'a mut Defs>,
acquired_nodes: Rc<RefCell<Vec<RsvgNode>>>,
is_testing: bool,
}
-impl<'a> DrawingCtx<'a> {
+impl DrawingCtx {
pub fn new(
handle: *const RsvgHandle,
cr: cairo::Context,
@@ -147,7 +145,7 @@ impl<'a> DrawingCtx<'a> {
dpi_x: f64,
dpi_y: f64,
is_testing: bool,
- ) -> DrawingCtx<'a> {
+ ) -> DrawingCtx {
let mut affine = cr.get_matrix();
let rect = cairo::Rectangle {
x: 0.0,
@@ -186,7 +184,6 @@ impl<'a> DrawingCtx<'a> {
bbox: BoundingBox::new(&affine),
bbox_stack: Vec::new(),
drawsub_stack: Vec::new(),
- defs: RefCell::new(handle::get_defs(handle)),
acquired_nodes: Rc::new(RefCell::new(Vec::new())),
is_testing,
}
@@ -291,8 +288,8 @@ impl<'a> DrawingCtx<'a> {
// acquire it again. If you acquire a node "#foo" and don't release it before
// trying to acquire "foo" again, you will obtain a %NULL the second time.
pub fn get_acquired_node(&mut self, fragment: &Fragment) -> Option<AcquiredNode> {
- if let Some(node) = self.defs.borrow_mut().lookup(self.handle, fragment) {
- if !self.acquired_nodes_contains(node) {
+ if let Some(node) = handle::lookup_node(self.handle, fragment) {
+ if !self.acquired_nodes_contains(&node) {
self.acquired_nodes.borrow_mut().push(node.clone());
let acq = AcquiredNode(self.acquired_nodes.clone(), node.clone());
return Some(acq);
@@ -345,7 +342,7 @@ impl<'a> DrawingCtx<'a> {
node: &RsvgNode,
values: &ComputedValues,
clipping: bool,
- draw_fn: &mut FnMut(&mut DrawingCtx<'_>) -> Result<(), RenderingError>,
+ draw_fn: &mut FnMut(&mut DrawingCtx) -> Result<(), RenderingError>,
) -> Result<(), RenderingError> {
if clipping {
draw_fn(self)
@@ -1058,19 +1055,21 @@ impl From<TextRendering> for cairo::Antialias {
#[no_mangle]
pub extern "C" fn rsvg_drawing_ctx_draw_node_from_stack(
raw_draw_ctx: *mut RsvgDrawingCtx,
- raw_tree: *const RsvgTree,
) -> glib_sys::gboolean {
assert!(!raw_draw_ctx.is_null());
- let draw_ctx = unsafe { &mut *(raw_draw_ctx as *mut DrawingCtx<'_>) };
-
- assert!(!raw_tree.is_null());
- let tree = unsafe { &*(raw_tree as *const Tree) };
+ let draw_ctx = unsafe { &mut *(raw_draw_ctx as *mut DrawingCtx) };
// FIXME: The public API doesn't let us return a GError from the rendering
// functions, just a boolean. Add a proper API to return proper errors from
// the rendering path.
+
+ let svg_ref = handle::get_svg(draw_ctx.handle);
+ let svg = svg_ref.as_ref().unwrap();
+
+ let root = svg.tree.root();
+
if draw_ctx
- .draw_node_from_stack(&tree.root.get_cascaded_values(), &tree.root, false)
+ .draw_node_from_stack(&root.get_cascaded_values(), &root, false)
.is_ok()
{
true.to_glib()
@@ -1085,7 +1084,7 @@ pub extern "C" fn rsvg_drawing_ctx_add_node_and_ancestors_to_stack(
raw_node: *const RsvgNode,
) {
assert!(!raw_draw_ctx.is_null());
- let draw_ctx = unsafe { &mut *(raw_draw_ctx as *mut DrawingCtx<'_>) };
+ let draw_ctx = unsafe { &mut *(raw_draw_ctx as *mut DrawingCtx) };
assert!(!raw_node.is_null());
let node = unsafe { &*raw_node };
@@ -1109,7 +1108,7 @@ pub unsafe extern "C" fn rsvg_drawing_ctx_get_geometry(
logical_rect: *mut RsvgRectangle,
) {
assert!(!raw_draw_ctx.is_null());
- let draw_ctx = &mut *(raw_draw_ctx as *mut DrawingCtx<'_>);
+ let draw_ctx = &mut *(raw_draw_ctx as *mut DrawingCtx);
assert!(!ink_rect.is_null());
assert!(!logical_rect.is_null());
@@ -1213,7 +1212,7 @@ pub extern "C" fn rsvg_drawing_ctx_new(
#[no_mangle]
pub extern "C" fn rsvg_drawing_ctx_free(raw_draw_ctx: *mut RsvgDrawingCtx) {
assert!(!raw_draw_ctx.is_null());
- let draw_ctx = unsafe { &mut *(raw_draw_ctx as *mut DrawingCtx<'_>) };
+ let draw_ctx = unsafe { &mut *(raw_draw_ctx as *mut DrawingCtx) };
unsafe {
Box::from_raw(draw_ctx);
diff --git a/rsvg_internals/src/filters/blend.rs b/rsvg_internals/src/filters/blend.rs
index cd237df2..27accc41 100644
--- a/rsvg_internals/src/filters/blend.rs
+++ b/rsvg_internals/src/filters/blend.rs
@@ -72,7 +72,7 @@ impl Filter for Blend {
&self,
_node: &RsvgNode,
ctx: &FilterContext,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
let input = self.base.get_input(ctx, draw_ctx)?;
let input_2 = ctx.get_input(draw_ctx, self.in2.borrow().as_ref())?;
diff --git a/rsvg_internals/src/filters/bounds.rs b/rsvg_internals/src/filters/bounds.rs
index cb8e90a4..d858cab3 100644
--- a/rsvg_internals/src/filters/bounds.rs
+++ b/rsvg_internals/src/filters/bounds.rs
@@ -83,7 +83,7 @@ impl<'a> BoundsBuilder<'a> {
/// Returns the final pixel bounds.
#[inline]
- pub fn into_irect(self, draw_ctx: &mut DrawingCtx<'_>) -> IRect {
+ pub fn into_irect(self, draw_ctx: &mut DrawingCtx) -> IRect {
let mut bbox = self.apply_properties(draw_ctx);
let effects_region = self.ctx.effects_region();
@@ -96,12 +96,12 @@ impl<'a> BoundsBuilder<'a> {
///
/// Used by feImage.
#[inline]
- pub fn into_irect_without_clipping(self, draw_ctx: &mut DrawingCtx<'_>) -> IRect {
+ pub fn into_irect_without_clipping(self, draw_ctx: &mut DrawingCtx) -> IRect {
self.apply_properties(draw_ctx).rect.unwrap().into()
}
/// Applies the filter primitive properties.
- fn apply_properties(mut self, draw_ctx: &mut DrawingCtx<'_>) -> BoundingBox {
+ fn apply_properties(mut self, draw_ctx: &mut DrawingCtx) -> BoundingBox {
if self.bbox.rect.is_none() || self.standard_input_was_referenced {
// The default value is the filter effects region.
let effects_region = self.ctx.effects_region();
diff --git a/rsvg_internals/src/filters/color_matrix.rs b/rsvg_internals/src/filters/color_matrix.rs
index ec06e230..c0488f83 100644
--- a/rsvg_internals/src/filters/color_matrix.rs
+++ b/rsvg_internals/src/filters/color_matrix.rs
@@ -170,7 +170,7 @@ impl Filter for ColorMatrix {
&self,
_node: &RsvgNode,
ctx: &FilterContext,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
let input = self.base.get_input(ctx, draw_ctx)?;
let bounds = self
diff --git a/rsvg_internals/src/filters/component_transfer.rs
b/rsvg_internals/src/filters/component_transfer.rs
index 863a5f34..de3075f9 100644
--- a/rsvg_internals/src/filters/component_transfer.rs
+++ b/rsvg_internals/src/filters/component_transfer.rs
@@ -276,7 +276,7 @@ impl Filter for ComponentTransfer {
&self,
node: &RsvgNode,
ctx: &FilterContext,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
let input = self.base.get_input(ctx, draw_ctx)?;
let bounds = self
diff --git a/rsvg_internals/src/filters/composite.rs b/rsvg_internals/src/filters/composite.rs
index 378d4732..b86a62aa 100644
--- a/rsvg_internals/src/filters/composite.rs
+++ b/rsvg_internals/src/filters/composite.rs
@@ -149,7 +149,7 @@ impl Filter for Composite {
&self,
_node: &RsvgNode,
ctx: &FilterContext,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
let input = self.base.get_input(ctx, draw_ctx)?;
let input_2 = ctx.get_input(draw_ctx, self.in2.borrow().as_ref())?;
diff --git a/rsvg_internals/src/filters/context.rs b/rsvg_internals/src/filters/context.rs
index 62d07930..1c230643 100644
--- a/rsvg_internals/src/filters/context.rs
+++ b/rsvg_internals/src/filters/context.rs
@@ -104,7 +104,7 @@ pub struct FilterContext {
fn compute_effects_region(
filter_node: &RsvgNode,
computed_from_target_node: &ComputedValues,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
affine: cairo::Matrix,
width: f64,
height: f64,
@@ -195,7 +195,7 @@ impl FilterContext {
filter_node: &RsvgNode,
computed_from_node_being_filtered: &ComputedValues,
source_surface: SharedImageSurface,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
) -> Self {
let cr_affine = draw_ctx.get_cairo_context().get_matrix();
let bbox = draw_ctx.get_bbox().clone();
@@ -294,7 +294,7 @@ impl FilterContext {
/// Computes and returns the background image snapshot.
fn compute_background_image(
&self,
- draw_ctx: &DrawingCtx<'_>,
+ draw_ctx: &DrawingCtx,
) -> Result<cairo::ImageSurface, cairo::Status> {
let surface = cairo::ImageSurface::create(
cairo::Format::ARgb32,
@@ -325,7 +325,7 @@ impl FilterContext {
/// Returns the surface corresponding to the background image snapshot.
pub fn background_image(
&self,
- draw_ctx: &DrawingCtx<'_>,
+ draw_ctx: &DrawingCtx,
) -> Result<&SharedImageSurface, FilterError> {
{
// At this point either no, or only immutable references to background_surface exist, so
@@ -360,7 +360,7 @@ impl FilterContext {
#[inline]
pub fn background_alpha(
&self,
- draw_ctx: &DrawingCtx<'_>,
+ draw_ctx: &DrawingCtx,
bounds: IRect,
) -> Result<SharedImageSurface, FilterError> {
self.background_image(draw_ctx)?
@@ -422,7 +422,7 @@ impl FilterContext {
}
/// Calls the given function with correct behavior for the value of `primitiveUnits`.
- pub fn with_primitive_units<F, T>(&self, draw_ctx: &mut DrawingCtx<'_>, f: F) -> T
+ pub fn with_primitive_units<F, T>(&self, draw_ctx: &mut DrawingCtx, f: F) -> T
// TODO: Get rid of this Box? Can't just impl Trait because Rust cannot do higher-ranked types.
where
for<'b> F: FnOnce(Box<Fn(&Length) -> f64 + 'b>) -> T,
@@ -449,7 +449,7 @@ impl FilterContext {
/// Computes and returns a surface corresponding to the given paint server.
fn get_paint_server_surface(
&self,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
paint_server: &PaintServer,
opacity: UnitInterval,
) -> Result<cairo::ImageSurface, cairo::Status> {
@@ -489,7 +489,7 @@ impl FilterContext {
/// Does not take `processing_linear_rgb` into account.
fn get_input_raw(
&self,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
in_: Option<&Input>,
) -> Result<FilterInput, FilterError> {
if in_.is_none() {
@@ -546,7 +546,7 @@ impl FilterContext {
/// Retrieves the filter input surface according to the SVG rules.
pub fn get_input(
&self,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
in_: Option<&Input>,
) -> Result<FilterInput, FilterError> {
let raw = self.get_input_raw(draw_ctx, in_)?;
diff --git a/rsvg_internals/src/filters/convolve_matrix.rs b/rsvg_internals/src/filters/convolve_matrix.rs
index d04acac1..892b10c6 100644
--- a/rsvg_internals/src/filters/convolve_matrix.rs
+++ b/rsvg_internals/src/filters/convolve_matrix.rs
@@ -233,7 +233,7 @@ impl Filter for ConvolveMatrix {
&self,
_node: &RsvgNode,
ctx: &FilterContext,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
let input = self.base.get_input(ctx, draw_ctx)?;
let mut bounds = self
diff --git a/rsvg_internals/src/filters/displacement_map.rs b/rsvg_internals/src/filters/displacement_map.rs
index 41ac3944..006879db 100644
--- a/rsvg_internals/src/filters/displacement_map.rs
+++ b/rsvg_internals/src/filters/displacement_map.rs
@@ -82,7 +82,7 @@ impl Filter for DisplacementMap {
&self,
_node: &RsvgNode,
ctx: &FilterContext,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
let input = self.base.get_input(ctx, draw_ctx)?;
let displacement_input = ctx.get_input(draw_ctx, self.in2.borrow().as_ref())?;
diff --git a/rsvg_internals/src/filters/flood.rs b/rsvg_internals/src/filters/flood.rs
index ee87fcbb..bd65ae3b 100644
--- a/rsvg_internals/src/filters/flood.rs
+++ b/rsvg_internals/src/filters/flood.rs
@@ -42,7 +42,7 @@ impl Filter for Flood {
&self,
node: &RsvgNode,
ctx: &FilterContext,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
let bounds = self.base.get_bounds(ctx).into_irect(draw_ctx);
diff --git a/rsvg_internals/src/filters/gaussian_blur.rs b/rsvg_internals/src/filters/gaussian_blur.rs
index c66e7948..f508f921 100644
--- a/rsvg_internals/src/filters/gaussian_blur.rs
+++ b/rsvg_internals/src/filters/gaussian_blur.rs
@@ -206,7 +206,7 @@ impl Filter for GaussianBlur {
&self,
_node: &RsvgNode,
ctx: &FilterContext,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
let input = self.base.get_input(ctx, draw_ctx)?;
let bounds = self
diff --git a/rsvg_internals/src/filters/image.rs b/rsvg_internals/src/filters/image.rs
index f5290ea1..56dad677 100644
--- a/rsvg_internals/src/filters/image.rs
+++ b/rsvg_internals/src/filters/image.rs
@@ -56,7 +56,7 @@ impl Image {
fn render_node(
&self,
ctx: &FilterContext,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
bounds: IRect,
fragment: &Fragment,
) -> Result<ImageSurface, FilterError> {
@@ -120,7 +120,7 @@ impl Image {
fn render_external_image(
&self,
ctx: &FilterContext,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
bounds_builder: BoundsBuilder<'_>,
href: &Href,
) -> Result<ImageSurface, FilterError> {
@@ -218,7 +218,7 @@ impl Filter for Image {
&self,
_node: &RsvgNode,
ctx: &FilterContext,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
let bounds_builder = self.base.get_bounds(ctx);
let bounds = bounds_builder.into_irect(draw_ctx);
diff --git a/rsvg_internals/src/filters/light/lighting.rs b/rsvg_internals/src/filters/light/lighting.rs
index 1e77f882..55661037 100644
--- a/rsvg_internals/src/filters/light/lighting.rs
+++ b/rsvg_internals/src/filters/light/lighting.rs
@@ -202,7 +202,7 @@ impl Filter for Lighting {
&self,
node: &RsvgNode,
ctx: &FilterContext,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
let input = self.base.get_input(ctx, draw_ctx)?;
let mut bounds = self
diff --git a/rsvg_internals/src/filters/merge.rs b/rsvg_internals/src/filters/merge.rs
index 08668c7c..fa5bb8c4 100644
--- a/rsvg_internals/src/filters/merge.rs
+++ b/rsvg_internals/src/filters/merge.rs
@@ -80,7 +80,7 @@ impl MergeNode {
fn render(
&self,
ctx: &FilterContext,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
bounds: IRect,
output_surface: Option<SharedImageSurface>,
) -> Result<SharedImageSurface, FilterError> {
@@ -134,7 +134,7 @@ impl Filter for Merge {
&self,
node: &RsvgNode,
ctx: &FilterContext,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
// Compute the filter bounds, taking each child node's input into account.
let mut bounds = self.base.get_bounds(ctx);
diff --git a/rsvg_internals/src/filters/mod.rs b/rsvg_internals/src/filters/mod.rs
index cf88be9d..769091b3 100644
--- a/rsvg_internals/src/filters/mod.rs
+++ b/rsvg_internals/src/filters/mod.rs
@@ -58,7 +58,7 @@ trait Filter: NodeTrait {
&self,
node: &RsvgNode,
ctx: &FilterContext,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError>;
/// Returns `true` if this filter primitive is affected by the `color-interpolation-filters`
@@ -195,7 +195,7 @@ impl PrimitiveWithInput {
fn get_input(
&self,
ctx: &FilterContext,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
) -> Result<FilterInput, FilterError> {
ctx.get_input(draw_ctx, self.in_.borrow().as_ref())
}
@@ -235,7 +235,7 @@ pub fn render(
filter_node: &RsvgNode,
computed_from_node_being_filtered: &ComputedValues,
source: &cairo::ImageSurface,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
) -> Result<cairo::ImageSurface, RenderingError> {
let filter_node = &*filter_node;
assert_eq!(filter_node.get_type(), NodeType::Filter);
diff --git a/rsvg_internals/src/filters/morphology.rs b/rsvg_internals/src/filters/morphology.rs
index 60fbcef0..3e43a614 100644
--- a/rsvg_internals/src/filters/morphology.rs
+++ b/rsvg_internals/src/filters/morphology.rs
@@ -83,7 +83,7 @@ impl Filter for Morphology {
&self,
_node: &RsvgNode,
ctx: &FilterContext,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
let input = self.base.get_input(ctx, draw_ctx)?;
let bounds = self
diff --git a/rsvg_internals/src/filters/offset.rs b/rsvg_internals/src/filters/offset.rs
index f9f8a524..2b85c2d8 100644
--- a/rsvg_internals/src/filters/offset.rs
+++ b/rsvg_internals/src/filters/offset.rs
@@ -64,7 +64,7 @@ impl Filter for Offset {
&self,
_node: &RsvgNode,
ctx: &FilterContext,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
let input = self.base.get_input(ctx, draw_ctx)?;
let bounds = self
diff --git a/rsvg_internals/src/filters/tile.rs b/rsvg_internals/src/filters/tile.rs
index f18c73a8..1c407ff4 100644
--- a/rsvg_internals/src/filters/tile.rs
+++ b/rsvg_internals/src/filters/tile.rs
@@ -40,7 +40,7 @@ impl Filter for Tile {
&self,
_node: &RsvgNode,
ctx: &FilterContext,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
let input = self.base.get_input(ctx, draw_ctx)?;
diff --git a/rsvg_internals/src/filters/turbulence.rs b/rsvg_internals/src/filters/turbulence.rs
index 30643d59..a5eebdf9 100644
--- a/rsvg_internals/src/filters/turbulence.rs
+++ b/rsvg_internals/src/filters/turbulence.rs
@@ -345,7 +345,7 @@ impl Filter for Turbulence {
&self,
node: &RsvgNode,
ctx: &FilterContext,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
let bounds = self.base.get_bounds(ctx).into_irect(draw_ctx);
diff --git a/rsvg_internals/src/gradient.rs b/rsvg_internals/src/gradient.rs
index eb6846e3..2e8867b1 100644
--- a/rsvg_internals/src/gradient.rs
+++ b/rsvg_internals/src/gradient.rs
@@ -430,7 +430,7 @@ impl Gradient {
}
}
-fn acquire_gradient<'a>(draw_ctx: &'a mut DrawingCtx<'_>, name: &Fragment) -> Option<AcquiredNode> {
+fn acquire_gradient<'a>(draw_ctx: &'a mut DrawingCtx, name: &Fragment) -> Option<AcquiredNode> {
if let Some(acquired) = draw_ctx.get_acquired_node(name) {
let node_type = acquired.get().get_type();
@@ -519,7 +519,7 @@ impl PaintSource<Gradient> for NodeGradient {
fn resolve(
&self,
node: &RsvgNode,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
bbox: &BoundingBox,
) -> Option<Gradient> {
let gradient =
@@ -559,7 +559,7 @@ impl PaintSource<Gradient> for NodeGradient {
&self,
gradient: &Gradient,
values: &ComputedValues,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
opacity: &UnitInterval,
bbox: &BoundingBox,
) -> Result<bool, RenderingError> {
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index 9d8ce5f7..a7683db5 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -1,6 +1,7 @@
use std::cell::{Ref, RefCell};
use std::error::Error;
use std::ptr;
+use std::rc::Rc;
use cairo::{ImageSurface, Status};
use cairo_sys;
@@ -14,11 +15,14 @@ use url::Url;
use allowed_url::AllowedUrl;
use css::{self, CssStyles};
-use defs::{Defs, RsvgDefs};
+use defs::{Fragment, Href};
use error::{set_gerror, LoadingError};
use io;
+use node::{box_node, Node, RsvgNode};
use surface_utils::shared_surface::SharedImageSurface;
-use tree::{RsvgTree, Tree};
+use svg::Svg;
+use util::rsvg_g_warning;
+use xml::{RsvgXmlState, XmlState};
pub enum RsvgHandle {}
@@ -26,12 +30,14 @@ pub enum RsvgHandleRust {}
struct Handle {
base_url: RefCell<Option<Url>>,
+ svg: RefCell<Option<Svg>>,
}
impl Handle {
fn new() -> Handle {
Handle {
base_url: RefCell::new(None),
+ svg: RefCell::new(None),
}
}
}
@@ -39,8 +45,6 @@ impl Handle {
#[allow(improper_ctypes)]
extern "C" {
fn rsvg_handle_get_flags(handle: *const RsvgHandle) -> u32;
- fn rsvg_handle_get_defs(handle: *const RsvgHandle) -> *const RsvgDefs;
- fn rsvg_handle_get_tree(handle: *const RsvgHandle) -> *const RsvgTree;
fn rsvg_handle_new_from_gfile_sync(
file: *const gio_sys::GFile,
@@ -61,18 +65,27 @@ extern "C" {
fn rsvg_handle_get_cancellable(handle: *const RsvgHandle) -> *mut gio_sys::GCancellable;
}
-pub fn get_defs<'a>(handle: *const RsvgHandle) -> &'a mut Defs {
- unsafe {
- let d = rsvg_handle_get_defs(handle);
- &mut *(d as *mut Defs)
- }
+pub fn lookup_node(handle: *const RsvgHandle, fragment: &Fragment) -> Option<Rc<Node>> {
+ let rhandle = get_rust_handle(handle);
+
+ let svg_ref = rhandle.svg.borrow();
+ let svg = svg_ref.as_ref().unwrap();
+ let mut defs_ref = svg.defs.borrow_mut();
+
+ defs_ref.lookup(handle, fragment)
}
-pub fn get_tree<'a>(handle: *const RsvgHandle) -> &'a Tree {
- unsafe {
- let t = rsvg_handle_get_tree(handle);
- &*(t as *mut Tree)
- }
+// Looks up a node by its id.
+//
+// Note that this ignores the Fragment's url; it only uses the fragment identifier.
+pub fn lookup_fragment_id(handle: *const RsvgHandle, fragment: &Fragment) -> Option<Rc<Node>> {
+ let rhandle = get_rust_handle(handle);
+
+ let svg_ref = rhandle.svg.borrow();
+ let svg = svg_ref.as_ref().unwrap();
+ let defs_ref = svg.defs.borrow();
+
+ defs_ref.lookup_fragment_id(fragment.fragment())
}
pub fn load_extern(handle: *const RsvgHandle, aurl: &AllowedUrl) -> Result<*const RsvgHandle, ()> {
@@ -89,8 +102,12 @@ pub fn load_extern(handle: *const RsvgHandle, aurl: &AllowedUrl) -> Result<*cons
if res.is_null() {
Err(())
} else {
- let tree = get_tree(res);
- tree.cascade();
+ let rhandle = get_rust_handle(handle);
+
+ let svg_ref = rhandle.svg.borrow();
+ let svg = svg_ref.as_ref().unwrap();
+
+ svg.tree.cascade();
Ok(res)
}
@@ -237,6 +254,12 @@ pub fn load_css(css_styles: &mut CssStyles, handle: *mut RsvgHandle, href_str: &
}
}
+pub fn get_svg<'a>(handle: *const RsvgHandle) -> Ref<'a, Option<Svg>> {
+ let rhandle = get_rust_handle(handle);
+
+ rhandle.svg.borrow()
+}
+
#[no_mangle]
pub unsafe extern "C" fn rsvg_handle_rust_new() -> *mut RsvgHandleRust {
Box::into_raw(Box::new(Handle::new())) as *mut RsvgHandleRust
@@ -293,6 +316,61 @@ pub unsafe extern "C" fn rsvg_handle_rust_get_base_gfile(
}
}
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_handle_defs_lookup(
+ handle: *const RsvgHandle,
+ name: *const libc::c_char,
+) -> *const RsvgNode {
+ assert!(!name.is_null());
+
+ let rhandle = get_rust_handle(handle);
+
+ let svg_ref = rhandle.svg.borrow();
+ let svg = svg_ref.as_ref().unwrap();
+
+ let mut defs = svg.defs.borrow_mut();
+
+ let name: String = from_glib_none(name);
+
+ let r = Href::with_fragment(&name);
+ if r.is_err() {
+ return ptr::null();
+ }
+
+ match r.unwrap() {
+ Href::WithFragment(fragment) => {
+ if let Some(uri) = fragment.uri() {
+ // The public APIs to get geometries of individual elements, or to render
+ // them, should only allow referencing elements within the main handle's
+ // SVG file; that is, only plain "#foo" fragment IDs are allowed here.
+ // Otherwise, a calling program could request "another-file#foo" and cause
+ // another-file to be loaded, even if it is not part of the set of
+ // resources that the main SVG actually references. In the future we may
+ // relax this requirement to allow lookups within that set, but not to
+ // other random files.
+
+ let msg = format!(
+ "the public API is not allowed to look up external references: {}#{}",
+ uri,
+ fragment.fragment()
+ );
+
+ rsvg_log!("{}", msg);
+
+ rsvg_g_warning(&msg);
+ return ptr::null();
+ }
+
+ match defs.lookup(handle, &fragment) {
+ Some(n) => box_node(n),
+ None => ptr::null(),
+ }
+ }
+
+ _ => unreachable!(),
+ }
+}
+
#[no_mangle]
pub unsafe extern "C" fn rsvg_handle_acquire_data(
handle: *mut RsvgHandle,
@@ -368,3 +446,52 @@ pub unsafe extern "C" fn rsvg_handle_acquire_stream(
}
}
}
+
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_handle_rust_steal_result(
+ raw_handle: *const RsvgHandleRust,
+ raw_xml_state: *mut RsvgXmlState,
+) {
+ let handle = &*(raw_handle as *const Handle);
+ let xml = &mut *(raw_xml_state as *mut XmlState);
+
+ *handle.svg.borrow_mut() = Some(xml.steal_result());
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_handle_rust_cascade(raw_handle: *const RsvgHandleRust) {
+ let rhandle = &*(raw_handle as *const Handle);
+
+ let svg_ref = rhandle.svg.borrow();
+ let svg = svg_ref.as_ref().unwrap();
+
+ svg.tree.cascade();
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_handle_rust_get_root(
+ raw_handle: *const RsvgHandleRust,
+) -> *const RsvgNode {
+ let rhandle = &*(raw_handle as *const Handle);
+
+ let svg_ref = rhandle.svg.borrow();
+ let svg = svg_ref.as_ref().unwrap();
+
+ box_node(svg.tree.root())
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_handle_rust_node_is_root(
+ raw_handle: *const RsvgHandleRust,
+ node: *mut RsvgNode,
+) -> glib_sys::gboolean {
+ let rhandle = &*(raw_handle as *const Handle);
+
+ assert!(!node.is_null());
+ let node: &RsvgNode = &*node;
+
+ let svg_ref = rhandle.svg.borrow();
+ let svg = svg_ref.as_ref().unwrap();
+
+ Rc::ptr_eq(&svg.tree.root(), node).to_glib()
+}
diff --git a/rsvg_internals/src/image.rs b/rsvg_internals/src/image.rs
index cfe2079c..2b3cda1c 100644
--- a/rsvg_internals/src/image.rs
+++ b/rsvg_internals/src/image.rs
@@ -103,7 +103,7 @@ impl NodeTrait for NodeImage {
&self,
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
clipping: bool,
) -> Result<(), RenderingError> {
let values = cascaded.get();
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 8b88d6fa..23d3e763 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -34,10 +34,6 @@ extern crate lazy_static;
pub use color::{rsvg_css_parse_color, ColorKind, ColorSpec};
-pub use css::{rsvg_css_styles_free, rsvg_css_styles_new};
-
-pub use defs::{rsvg_defs_free, rsvg_defs_lookup};
-
pub use drawing_ctx::{
rsvg_drawing_ctx_add_node_and_ancestors_to_stack,
rsvg_drawing_ctx_draw_node_from_stack,
@@ -49,24 +45,19 @@ pub use drawing_ctx::{
pub use handle::{
rsvg_handle_acquire_data,
rsvg_handle_acquire_stream,
+ rsvg_handle_defs_lookup,
rsvg_handle_rust_free,
rsvg_handle_rust_get_base_gfile,
rsvg_handle_rust_new,
+ rsvg_handle_rust_node_is_root,
rsvg_handle_rust_set_base_url,
+ rsvg_handle_rust_steal_result,
};
pub use io::rsvg_get_input_stream_for_loading;
pub use node::rsvg_node_unref;
-pub use tree::{
- rsvg_tree_cascade,
- rsvg_tree_free,
- rsvg_tree_get_root,
- rsvg_tree_is_root,
- rsvg_tree_root_is_svg,
-};
-
pub use property_bag::{
rsvg_property_bag_free,
rsvg_property_bag_iter_begin,
@@ -87,7 +78,6 @@ pub use xml::{
rsvg_xml_state_load_css_from_href,
rsvg_xml_state_new,
rsvg_xml_state_start_element,
- rsvg_xml_state_steal_result,
};
#[macro_use]
@@ -142,6 +132,7 @@ mod stop;
mod structure;
mod style;
pub mod surface_utils;
+mod svg;
mod text;
mod transform;
mod tree;
diff --git a/rsvg_internals/src/link.rs b/rsvg_internals/src/link.rs
index 216232a8..32b92818 100644
--- a/rsvg_internals/src/link.rs
+++ b/rsvg_internals/src/link.rs
@@ -43,7 +43,7 @@ impl NodeTrait for NodeLink {
&self,
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
clipping: bool,
) -> Result<(), RenderingError> {
let link = self.link.borrow();
diff --git a/rsvg_internals/src/marker.rs b/rsvg_internals/src/marker.rs
index b58c1b1a..a6f1b341 100644
--- a/rsvg_internals/src/marker.rs
+++ b/rsvg_internals/src/marker.rs
@@ -122,7 +122,7 @@ impl NodeMarker {
fn render(
&self,
node: &RsvgNode,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
xpos: f64,
ypos: f64,
computed_angle: f64,
@@ -634,7 +634,7 @@ enum MarkerType {
}
fn emit_marker_by_name(
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
name: &Fragment,
xpos: f64,
ypos: f64,
@@ -692,7 +692,7 @@ where
pub fn render_markers_for_path_builder(
builder: &PathBuilder,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
values: &ComputedValues,
clipping: bool,
) -> Result<(), RenderingError> {
diff --git a/rsvg_internals/src/mask.rs b/rsvg_internals/src/mask.rs
index 906157b5..11ff7c7a 100644
--- a/rsvg_internals/src/mask.rs
+++ b/rsvg_internals/src/mask.rs
@@ -59,7 +59,7 @@ impl NodeMask {
&self,
node: &RsvgNode,
affine_before_mask: &cairo::Matrix,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
) -> Result<(), RenderingError> {
let cascaded = node.get_cascaded_values();
let values = cascaded.get();
diff --git a/rsvg_internals/src/node.rs b/rsvg_internals/src/node.rs
index 5ce01b16..edff726a 100644
--- a/rsvg_internals/src/node.rs
+++ b/rsvg_internals/src/node.rs
@@ -116,7 +116,7 @@ pub trait NodeTrait: Downcast {
&self,
_node: &RsvgNode,
_cascaded: &CascadedValues<'_>,
- _draw_ctx: &mut DrawingCtx<'_>,
+ _draw_ctx: &mut DrawingCtx,
_clipping: bool,
) -> Result<(), RenderingError> {
// by default nodes don't draw themselves
@@ -535,7 +535,7 @@ impl Node {
&self,
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
clipping: bool,
) -> Result<(), RenderingError> {
if !self.is_in_error() {
@@ -592,7 +592,7 @@ impl Node {
pub fn draw_children(
&self,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
clipping: bool,
) -> Result<(), RenderingError> {
for child in self.children() {
diff --git a/rsvg_internals/src/paint_server.rs b/rsvg_internals/src/paint_server.rs
index d01e5b0c..0e812fab 100644
--- a/rsvg_internals/src/paint_server.rs
+++ b/rsvg_internals/src/paint_server.rs
@@ -52,7 +52,7 @@ impl Parse for PaintServer {
}
fn set_color(
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
color: &cssparser::Color,
opacity: &UnitInterval,
current_color: &cssparser::RGBA,
@@ -72,18 +72,13 @@ fn set_color(
}
pub trait PaintSource<T> {
- fn resolve(
- &self,
- node: &RsvgNode,
- draw_ctx: &mut DrawingCtx<'_>,
- bbox: &BoundingBox,
- ) -> Option<T>;
+ fn resolve(&self, node: &RsvgNode, draw_ctx: &mut DrawingCtx, bbox: &BoundingBox) -> Option<T>;
fn set_pattern_on_draw_context(
&self,
pattern: &T,
values: &ComputedValues,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
opacity: &UnitInterval,
bbox: &BoundingBox,
) -> Result<bool, RenderingError>;
@@ -91,7 +86,7 @@ pub trait PaintSource<T> {
fn resolve_fallbacks_and_set_pattern(
&self,
node: &RsvgNode,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
opacity: &UnitInterval,
bbox: &BoundingBox,
) -> Result<bool, RenderingError> {
@@ -106,7 +101,7 @@ pub trait PaintSource<T> {
}
pub fn set_source_paint_server(
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
ps: &PaintServer,
opacity: &UnitInterval,
bbox: &BoundingBox,
diff --git a/rsvg_internals/src/pattern.rs b/rsvg_internals/src/pattern.rs
index f599b0e0..df144b59 100644
--- a/rsvg_internals/src/pattern.rs
+++ b/rsvg_internals/src/pattern.rs
@@ -243,7 +243,7 @@ impl PaintSource<Pattern> for NodePattern {
fn resolve(
&self,
node: &RsvgNode,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
_bbox: &BoundingBox,
) -> Option<Pattern> {
let node_pattern = node.get_impl::<NodePattern>().unwrap();
@@ -282,7 +282,7 @@ impl PaintSource<Pattern> for NodePattern {
&self,
pattern: &Pattern,
values: &ComputedValues,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
_opacity: &UnitInterval,
bbox: &BoundingBox,
) -> Result<bool, RenderingError> {
diff --git a/rsvg_internals/src/shapes.rs b/rsvg_internals/src/shapes.rs
index 94763542..1c581721 100644
--- a/rsvg_internals/src/shapes.rs
+++ b/rsvg_internals/src/shapes.rs
@@ -17,7 +17,7 @@ use state::ComputedValues;
fn render_path_builder(
builder: &PathBuilder,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
node: &RsvgNode,
values: &ComputedValues,
render_markers: bool,
@@ -51,7 +51,7 @@ fn render_ellipse(
cy: f64,
rx: f64,
ry: f64,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
node: &RsvgNode,
values: &ComputedValues,
clipping: bool,
@@ -155,7 +155,7 @@ impl NodeTrait for NodePath {
&self,
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
clipping: bool,
) -> Result<(), RenderingError> {
let values = cascaded.get();
@@ -222,7 +222,7 @@ impl NodeTrait for NodePoly {
&self,
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
clipping: bool,
) -> Result<(), RenderingError> {
let values = cascaded.get();
@@ -286,7 +286,7 @@ impl NodeTrait for NodeLine {
&self,
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
clipping: bool,
) -> Result<(), RenderingError> {
let values = cascaded.get();
@@ -377,7 +377,7 @@ impl NodeTrait for NodeRect {
&self,
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
clipping: bool,
) -> Result<(), RenderingError> {
let values = cascaded.get();
@@ -561,7 +561,7 @@ impl NodeTrait for NodeCircle {
&self,
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
clipping: bool,
) -> Result<(), RenderingError> {
let values = cascaded.get();
@@ -625,7 +625,7 @@ impl NodeTrait for NodeEllipse {
&self,
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
clipping: bool,
) -> Result<(), RenderingError> {
let values = cascaded.get();
diff --git a/rsvg_internals/src/structure.rs b/rsvg_internals/src/structure.rs
index 060db1f2..7aaf123f 100644
--- a/rsvg_internals/src/structure.rs
+++ b/rsvg_internals/src/structure.rs
@@ -38,7 +38,7 @@ impl NodeTrait for NodeGroup {
&self,
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
clipping: bool,
) -> Result<(), RenderingError> {
let values = cascaded.get();
@@ -80,7 +80,7 @@ impl NodeTrait for NodeSwitch {
&self,
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
clipping: bool,
) -> Result<(), RenderingError> {
let values = cascaded.get();
@@ -191,7 +191,7 @@ impl NodeTrait for NodeSvg {
&self,
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
clipping: bool,
) -> Result<(), RenderingError> {
let values = cascaded.get();
@@ -289,7 +289,7 @@ impl NodeTrait for NodeUse {
&self,
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
clipping: bool,
) -> Result<(), RenderingError> {
let values = cascaded.get();
diff --git a/rsvg_internals/src/svg.rs b/rsvg_internals/src/svg.rs
new file mode 100644
index 00000000..2c823594
--- /dev/null
+++ b/rsvg_internals/src/svg.rs
@@ -0,0 +1,30 @@
+use std::cell::RefCell;
+
+use css::CssStyles;
+use defs::Defs;
+use tree::Tree;
+
+/// A loaded SVG file and its derived data
+///
+/// This contains the tree of nodes (SVG elements), the mapping
+/// of id to node, and the CSS styles defined for this SVG.
+pub struct Svg {
+ pub tree: Tree,
+
+ // This requires interior mutability because we load the extern
+ // defs all over the place. Eventually we'll be able to do this
+ // once, at loading time, and keep this immutable.
+ pub defs: RefCell<Defs>,
+
+ pub css_styles: CssStyles,
+}
+
+impl Svg {
+ pub fn new(tree: Tree, defs: Defs, css_styles: CssStyles) -> Svg {
+ Svg {
+ tree,
+ defs: RefCell::new(defs),
+ css_styles,
+ }
+ }
+}
diff --git a/rsvg_internals/src/text.rs b/rsvg_internals/src/text.rs
index e3fa4335..5e6a4d41 100644
--- a/rsvg_internals/src/text.rs
+++ b/rsvg_internals/src/text.rs
@@ -90,7 +90,7 @@ impl NodeChars {
&self,
node: &RsvgNode,
values: &ComputedValues,
- draw_ctx: &DrawingCtx<'_>,
+ draw_ctx: &DrawingCtx,
) -> pango::Layout {
self.ensure_normalized_string(node, values);
let norm = self.space_normalized.borrow();
@@ -102,7 +102,7 @@ impl NodeChars {
&self,
node: &RsvgNode,
values: &ComputedValues,
- draw_ctx: &DrawingCtx<'_>,
+ draw_ctx: &DrawingCtx,
length: &mut f64,
) {
let layout = self.create_layout(node, values, draw_ctx);
@@ -115,7 +115,7 @@ impl NodeChars {
&self,
node: &RsvgNode,
values: &ComputedValues,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
x: &mut f64,
y: &mut f64,
clipping: bool,
@@ -189,7 +189,7 @@ impl NodeTrait for NodeText {
&self,
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
clipping: bool,
) -> Result<(), RenderingError> {
let values = cascaded.get();
@@ -243,7 +243,7 @@ impl NodeTRef {
&self,
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
length: &mut f64,
) -> bool {
let link = self.link.borrow();
@@ -273,7 +273,7 @@ impl NodeTRef {
&self,
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
x: &mut f64,
y: &mut f64,
clipping: bool,
@@ -338,7 +338,7 @@ impl NodeTSpan {
&self,
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
length: &mut f64,
usetextonly: bool,
) -> bool {
@@ -363,7 +363,7 @@ impl NodeTSpan {
&self,
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
x: &mut f64,
y: &mut f64,
usetextonly: bool,
@@ -537,7 +537,7 @@ impl From<WritingMode> for pango::Gravity {
}
fn create_pango_layout(
- draw_ctx: &DrawingCtx<'_>,
+ draw_ctx: &DrawingCtx,
values: &ComputedValues,
text: &str,
) -> pango::Layout {
@@ -617,7 +617,7 @@ fn create_pango_layout(
fn anchor_offset(
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
anchor: TextAnchor,
textonly: bool,
) -> f64 {
@@ -640,7 +640,7 @@ fn anchor_offset(
fn measure_children(
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
length: &mut f64,
textonly: bool,
) -> bool {
@@ -665,7 +665,7 @@ fn measure_children(
fn measure_child(
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
length: &mut f64,
textonly: bool,
) -> bool {
@@ -722,7 +722,7 @@ fn measure_child(
fn render_children(
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
x: &mut f64,
y: &mut f64,
textonly: bool,
@@ -742,7 +742,7 @@ fn render_children(
fn render_child(
node: &RsvgNode,
cascaded: &CascadedValues<'_>,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
x: &mut f64,
y: &mut f64,
textonly: bool,
diff --git a/rsvg_internals/src/tree.rs b/rsvg_internals/src/tree.rs
index ad35d089..ceadf0a3 100644
--- a/rsvg_internals/src/tree.rs
+++ b/rsvg_internals/src/tree.rs
@@ -1,16 +1,11 @@
-use glib::translate::*;
-use glib_sys;
-
use std::cell::Cell;
use std::rc::Rc;
-use node::{box_node, Node, NodeType, RsvgNode};
+use node::{Node, NodeType};
use state::ComputedValues;
-pub enum RsvgTree {}
-
pub struct Tree {
- pub root: Rc<Node>,
+ root: Rc<Node>,
already_cascaded: Cell<bool>,
}
@@ -30,53 +25,11 @@ impl Tree {
}
}
- fn root_is_svg(&self) -> bool {
- self.root.get_type() == NodeType::Svg
+ pub fn root(&self) -> Rc<Node> {
+ self.root.clone()
}
-}
-#[no_mangle]
-pub extern "C" fn rsvg_tree_free(tree: *mut RsvgTree) {
- if !tree.is_null() {
- let tree = unsafe { &mut *(tree as *mut Tree) };
- let _ = unsafe { Box::from_raw(tree) };
+ pub fn root_is_svg(&self) -> bool {
+ self.root.get_type() == NodeType::Svg
}
}
-
-#[no_mangle]
-pub extern "C" fn rsvg_tree_cascade(tree: *const RsvgTree) {
- assert!(!tree.is_null());
- let tree = unsafe { &*(tree as *const Tree) };
-
- tree.cascade();
-}
-
-#[no_mangle]
-pub extern "C" fn rsvg_tree_get_root(tree: *const RsvgTree) -> *mut RsvgNode {
- assert!(!tree.is_null());
- let tree = unsafe { &*(tree as *const Tree) };
-
- box_node(tree.root.clone())
-}
-
-#[no_mangle]
-pub extern "C" fn rsvg_tree_is_root(
- tree: *const RsvgTree,
- node: *mut RsvgNode,
-) -> glib_sys::gboolean {
- assert!(!tree.is_null());
- let tree = unsafe { &*(tree as *const Tree) };
-
- assert!(!node.is_null());
- let node: &RsvgNode = unsafe { &*node };
-
- Rc::ptr_eq(&tree.root, node).to_glib()
-}
-
-#[no_mangle]
-pub extern "C" fn rsvg_tree_root_is_svg(tree: *const RsvgTree) -> glib_sys::gboolean {
- assert!(!tree.is_null());
- let tree = unsafe { &*(tree as *const Tree) };
-
- tree.root_is_svg().to_glib()
-}
diff --git a/rsvg_internals/src/viewport.rs b/rsvg_internals/src/viewport.rs
index d19beae1..9d617eba 100644
--- a/rsvg_internals/src/viewport.rs
+++ b/rsvg_internals/src/viewport.rs
@@ -27,9 +27,9 @@ pub fn draw_in_viewport(
node: &RsvgNode,
values: &ComputedValues,
mut affine: cairo::Matrix,
- draw_ctx: &mut DrawingCtx<'_>,
+ draw_ctx: &mut DrawingCtx,
clipping: bool,
- draw_fn: &mut FnMut(&mut DrawingCtx<'_>) -> Result<(), RenderingError>,
+ draw_fn: &mut FnMut(&mut DrawingCtx) -> Result<(), RenderingError>,
) -> Result<(), RenderingError> {
// width or height set to 0 disables rendering of the element
// https://www.w3.org/TR/SVG/struct.html#SVGElementWidthAttribute
diff --git a/rsvg_internals/src/xml.rs b/rsvg_internals/src/xml.rs
index 41fc8e01..aafecb21 100644
--- a/rsvg_internals/src/xml.rs
+++ b/rsvg_internals/src/xml.rs
@@ -12,15 +12,17 @@ use std::str;
use allowed_url::AllowedUrl;
use attributes::Attribute;
use create_node::create_node_and_register_id;
-use css::{self, CssStyles, RsvgCssStyles};
-use defs::{Defs, RsvgDefs};
+use css::{self, CssStyles};
+use defs::Defs;
+use error::set_gerror;
use handle::{self, RsvgHandle};
use node::{node_new, Node, NodeType};
use property_bag::PropertyBag;
use structure::NodeSvg;
use style::NodeStyle;
+use svg::Svg;
use text::NodeChars;
-use tree::{RsvgTree, Tree};
+use tree::Tree;
use util::utf8_cstr;
#[derive(Clone)]
@@ -94,8 +96,8 @@ extern "C" {
/// that context, all XML events will be forwarded to it, and processed in one of the `XmlHandler`
/// trait objects. Normally the context refers to a `NodeCreationContext` implementation which is
/// what creates normal graphical elements.
-struct XmlState {
- tree: Option<Box<Tree>>,
+pub struct XmlState {
+ tree: Option<Tree>,
defs: Option<Defs>,
css_styles: Option<CssStyles>,
context: Context,
@@ -130,19 +132,19 @@ impl XmlState {
}
}
- pub fn set_root(&mut self, root: &Rc<Node>) {
+ fn set_root(&mut self, root: &Rc<Node>) {
if self.tree.is_some() {
panic!("The tree root has already been set");
}
- self.tree = Some(Box::new(Tree::new(root)));
+ self.tree = Some(Tree::new(root));
}
- pub fn steal_result(&mut self) -> (Option<Box<Tree>>, Box<Defs>, Box<CssStyles>) {
- (
- self.tree.take(),
- Box::new(self.defs.take().unwrap()),
- Box::new(self.css_styles.take().unwrap()),
+ pub fn steal_result(&mut self) -> Svg {
+ Svg::new(
+ self.tree.take().unwrap(),
+ self.defs.take().unwrap(),
+ self.css_styles.take().unwrap(),
)
}
@@ -524,31 +526,6 @@ pub extern "C" fn rsvg_xml_state_free(xml: *mut RsvgXmlState) {
}
}
-#[no_mangle]
-pub unsafe extern "C" fn rsvg_xml_state_steal_result(
- xml: *mut RsvgXmlState,
- out_tree: *mut *mut RsvgTree,
- out_defs: *mut *mut RsvgDefs,
- out_css_styles: *mut *mut RsvgCssStyles,
-) {
- assert!(!xml.is_null());
- assert!(!out_tree.is_null());
- assert!(!out_defs.is_null());
- assert!(!out_css_styles.is_null());
-
- let xml = &mut *(xml as *mut XmlState);
-
- let (tree, defs, css_styles) = xml.steal_result();
-
- *out_tree = tree
- .map(|tree| Box::into_raw(tree) as *mut RsvgTree)
- .unwrap_or(ptr::null_mut());
-
- *out_defs = Box::into_raw(defs) as *mut RsvgDefs;
-
- *out_css_styles = Box::into_raw(css_styles) as *mut RsvgCssStyles;
-}
-
#[no_mangle]
pub extern "C" fn rsvg_xml_state_start_element(
xml: *mut RsvgXmlState,
@@ -662,3 +639,24 @@ pub unsafe extern "C" fn rsvg_xml_state_load_css_from_href(
handle::load_css(xml.css_styles.as_mut().unwrap(), handle, &href);
}
+
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_xml_state_tree_is_valid(
+ xml: *mut RsvgXmlState,
+ error: *mut *mut glib_sys::GError,
+) -> glib_sys::gboolean {
+ assert!(!xml.is_null());
+ let xml = &mut *(xml as *mut XmlState);
+
+ if let Some(ref tree) = xml.tree {
+ if tree.root_is_svg() {
+ true.to_glib()
+ } else {
+ set_gerror(error, 0, "root element is not <svg>");
+ false.to_glib()
+ }
+ } else {
+ set_gerror(error, 0, "SVG has no elements");
+ false.to_glib()
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]