[librsvg/drawing-ctx-wip] Don't keep a &DrawingCtx in FilterContext; pass it around to filter render functions
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/drawing-ctx-wip] Don't keep a &DrawingCtx in FilterContext; pass it around to filter render functions
- Date: Fri, 22 Jun 2018 00:24:05 +0000 (UTC)
commit 1fe859986c0224ae36ac3f6db7686fad77e73842
Author: Federico Mena Quintero <federico gnome org>
Date: Thu Jun 21 19:10:53 2018 -0500
Don't keep a &DrawingCtx in FilterContext; pass it around to filter render functions
This changes a lot of code, because all filter rendering functions now
take a &mut DrawingCtx as an argument. This not only makes them
consistent with the normal node rendering functions, but it lets us
avoid double mutable borrows if the draw_ctx needed to be kept in the
FilterContext.
librsvg/filters/color_matrix.c | 9 +-
librsvg/filters/common.c | 60 --------
librsvg/filters/common.h | 42 ++----
librsvg/filters/convolve_matrix.c | 9 +-
librsvg/filters/diffuse_lighting.c | 15 +-
librsvg/filters/displacement_map.c | 12 +-
librsvg/filters/erode.c | 10 +-
librsvg/filters/gaussian_blur.c | 10 +-
librsvg/filters/specular_lighting.c | 15 +-
librsvg/filters/tile.c | 10 +-
librsvg/filters/turbulence.c | 10 +-
rsvg_internals/src/drawing_ctx.rs | 13 +-
rsvg_internals/src/filters/blend.rs | 14 +-
rsvg_internals/src/filters/bounds.rs | 15 +-
rsvg_internals/src/filters/component_transfer.rs | 16 +-
rsvg_internals/src/filters/composite.rs | 14 +-
rsvg_internals/src/filters/context.rs | 178 +++++++----------------
rsvg_internals/src/filters/ffi.rs | 7 +-
rsvg_internals/src/filters/flood.rs | 10 +-
rsvg_internals/src/filters/image.rs | 30 ++--
rsvg_internals/src/filters/merge.rs | 22 ++-
rsvg_internals/src/filters/mod.rs | 12 +-
rsvg_internals/src/filters/offset.rs | 16 +-
rsvg_internals/src/lib.rs | 6 -
rsvg_internals/src/structure.rs | 6 +-
25 files changed, 248 insertions(+), 313 deletions(-)
---
diff --git a/librsvg/filters/color_matrix.c b/librsvg/filters/color_matrix.c
index 9fc83960..69331d2d 100644
--- a/librsvg/filters/color_matrix.c
+++ b/librsvg/filters/color_matrix.c
@@ -38,7 +38,10 @@ struct _RsvgFilterPrimitiveColorMatrix {
};
static void
-rsvg_filter_primitive_color_matrix_render (RsvgNode *node, RsvgComputedValues *values, RsvgFilterPrimitive
*primitive, RsvgFilterContext *ctx)
+rsvg_filter_primitive_color_matrix_render (RsvgNode *node, RsvgComputedValues *values,
+ RsvgFilterPrimitive *primitive,
+ RsvgFilterContext *ctx,
+ RsvgDrawingCtx *draw_ctx)
{
RsvgFilterPrimitiveColorMatrix *color_matrix = (RsvgFilterPrimitiveColorMatrix *) primitive;
@@ -55,9 +58,9 @@ rsvg_filter_primitive_color_matrix_render (RsvgNode *node, RsvgComputedValues *v
int sum;
- boundarys = rsvg_filter_primitive_get_bounds (primitive, ctx);
+ boundarys = rsvg_filter_primitive_get_bounds (primitive, ctx, draw_ctx);
- in = rsvg_filter_get_in (primitive->in, ctx);
+ in = rsvg_filter_get_in (primitive->in, ctx, draw_ctx);
if (in == NULL)
return;
diff --git a/librsvg/filters/common.c b/librsvg/filters/common.c
index c4e7946d..2f080b9f 100644
--- a/librsvg/filters/common.c
+++ b/librsvg/filters/common.c
@@ -86,12 +86,6 @@ filter_primitive_set_x_y_width_height_atts (RsvgFilterPrimitive *prim, RsvgPrope
rsvg_property_bag_iter_end (iter);
}
-static void
-rsvg_filter_primitive_render (RsvgNode *node, RsvgComputedValues *values, RsvgFilterPrimitive *primitive,
RsvgFilterContext *ctx)
-{
- primitive->render (node, values, primitive, ctx);
-}
-
// RsvgIRect
// rsvg_filter_primitive_get_bounds (RsvgFilterPrimitive * self, RsvgFilterContext * ctx)
// {
@@ -462,25 +456,6 @@ rsvg_art_affine_image (cairo_surface_t *img,
// g_free (ctx);
// }
-static gboolean
-node_is_filter_primitive (RsvgNode *node)
-{
- RsvgNodeType type = rsvg_node_get_type (node);
-
- return type > RSVG_NODE_TYPE_FILTER_PRIMITIVE_FIRST && type < RSVG_NODE_TYPE_FILTER_PRIMITIVE_LAST;
-}
-
-void
-render_child_if_filter_primitive (RsvgNode *node, RsvgComputedValues *values, RsvgFilterContext *filter_ctx)
-{
- if (node_is_filter_primitive (node)) {
- RsvgFilterPrimitive *primitive;
-
- primitive = rsvg_rust_cnode_get_impl (node);
- rsvg_filter_primitive_render (node, values, primitive, filter_ctx);
- }
-}
-
/**
* rsvg_filter_store_result:
* @name: The name of the result
@@ -524,41 +499,6 @@ render_child_if_filter_primitive (RsvgNode *node, RsvgComputedValues *values, Rs
// rsvg_filter_store_output (name, output, ctx);
// }
-static cairo_surface_t *
-surface_get_alpha (cairo_surface_t *source,
- RsvgFilterContext * ctx)
-{
- guchar *data;
- guchar *pbdata;
- gsize i, pbsize;
- cairo_surface_t *surface;
-
- if (source == NULL)
- return NULL;
-
- cairo_surface_flush (source);
-
- pbsize = cairo_image_surface_get_width (source) *
- cairo_image_surface_get_height (source);
-
- surface = _rsvg_image_surface_new (cairo_image_surface_get_width (source),
- cairo_image_surface_get_height (source));
- if (surface == NULL)
- return NULL;
-
- data = cairo_image_surface_get_data (surface);
- pbdata = cairo_image_surface_get_data (source);
-
- const int *ctx_channelmap = rsvg_filter_context_get_channelmap(ctx);
-
- /* FIXMEchpe: rewrite this into nested width, height loops */
- for (i = 0; i < pbsize; i++)
- data[i * 4 + ctx_channelmap[3]] = pbdata[i * 4 + ctx_channelmap[3]];
-
- cairo_surface_mark_dirty (surface);
- return surface;
-}
-
// static cairo_surface_t *
// rsvg_compile_bg (RsvgDrawingCtx * ctx)
// {
diff --git a/librsvg/filters/common.h b/librsvg/filters/common.h
index 4e4a600d..5e5854f1 100644
--- a/librsvg/filters/common.h
+++ b/librsvg/filters/common.h
@@ -72,7 +72,11 @@ struct _RsvgFilterPrimitive {
GString *in;
GString *result;
- void (*render) (RsvgNode *node, RsvgComputedValues *values, RsvgFilterPrimitive *primitive,
RsvgFilterContext *ctx);
+ void (*render) (RsvgNode *node,
+ RsvgComputedValues *values,
+ RsvgFilterPrimitive *primitive,
+ RsvgFilterContext *ctx,
+ RsvgDrawingCtx *draw_ctx);
};
G_GNUC_INTERNAL
@@ -85,9 +89,6 @@ G_GNUC_INTERNAL
guchar get_interp_pixel (guchar * src, gdouble ox, gdouble oy, guchar ch, RsvgIRect boundarys,
guint rowstride);
-G_GNUC_INTERNAL
-void render_child_if_filter_primitive (RsvgNode *node, RsvgComputedValues *values, RsvgFilterContext
*filter_ctx);
-
G_GNUC_INTERNAL
void rsvg_alpha_blt (cairo_surface_t *src,
gint srcx,
@@ -124,7 +125,7 @@ gboolean rsvg_art_affine_image (cairo_surface_t *img,
/* Implemented in rust/src/filters/context.rs */
G_GNUC_INTERNAL
-cairo_surface_t *rsvg_filter_get_in (GString * name, RsvgFilterContext * ctx);
+cairo_surface_t *rsvg_filter_get_in (GString * name, RsvgFilterContext * ctx, RsvgDrawingCtx *draw_ctx);
/**
* rsvg_filter_get_result:
@@ -138,7 +139,9 @@ cairo_surface_t *rsvg_filter_get_in (GString * name, RsvgFilterContext * ctx);
**/
/* Implemented in rust/src/filters/context.rs */
G_GNUC_INTERNAL
-RsvgFilterPrimitiveOutput rsvg_filter_get_result (GString * name, RsvgFilterContext * ctx);
+RsvgFilterPrimitiveOutput rsvg_filter_get_result (GString *name,
+ RsvgFilterContext *ctx,
+ RsvgDrawingCtx *draw_ctx);
// G_GNUC_INTERNAL
// void rsvg_filter_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag atts);
@@ -153,7 +156,9 @@ void rsvg_filter_primitive_free (gpointer impl);
/* Implemented in rust/src/filters/context.rs */
G_GNUC_INTERNAL
-RsvgIRect rsvg_filter_primitive_get_bounds (const RsvgFilterPrimitive * self, const RsvgFilterContext * ctx);
+RsvgIRect rsvg_filter_primitive_get_bounds (const RsvgFilterPrimitive * self,
+ const RsvgFilterContext * ctx,
+ RsvgDrawingCtx *draw_ctx);
/* Implemented in rust/src/filters/context.rs */
G_GNUC_INTERNAL
@@ -162,35 +167,12 @@ gint rsvg_filter_context_get_width (const RsvgFilterContext *ctx);
G_GNUC_INTERNAL
gint rsvg_filter_context_get_height (const RsvgFilterContext *ctx);
-G_GNUC_INTERNAL
-cairo_surface_t *rsvg_filter_context_get_source_surface (RsvgFilterContext *ctx);
-
-G_GNUC_INTERNAL
-cairo_surface_t *rsvg_filter_context_get_bg_surface (RsvgFilterContext *ctx);
-
-G_GNUC_INTERNAL
-RsvgFilterPrimitiveOutput rsvg_filter_context_get_lastresult (RsvgFilterContext *ctx);
-
-G_GNUC_INTERNAL
-cairo_matrix_t rsvg_filter_context_get_affine (const RsvgFilterContext *ctx);
-
G_GNUC_INTERNAL
cairo_matrix_t rsvg_filter_context_get_paffine (const RsvgFilterContext *ctx);
G_GNUC_INTERNAL
const int *rsvg_filter_context_get_channelmap (const RsvgFilterContext *ctx);
-G_GNUC_INTERNAL
-RsvgDrawingCtx *rsvg_filter_context_get_drawing_ctx (RsvgFilterContext *ctx);
-
-G_GNUC_INTERNAL
-RsvgNode *rsvg_filter_context_get_node_being_filtered (RsvgFilterContext *ctx);
-
-G_GNUC_INTERNAL
-int rsvg_filter_context_get_previous_result (GString *name,
- const RsvgFilterContext *ctx,
- RsvgFilterPrimitiveOutput *output);
-
G_GNUC_INTERNAL
void rsvg_filter_store_output (GString * name, RsvgFilterPrimitiveOutput result, RsvgFilterContext * ctx);
diff --git a/librsvg/filters/convolve_matrix.c b/librsvg/filters/convolve_matrix.c
index 8f22ddfb..6ba933ff 100644
--- a/librsvg/filters/convolve_matrix.c
+++ b/librsvg/filters/convolve_matrix.c
@@ -51,7 +51,10 @@ struct _RsvgFilterPrimitiveConvolveMatrix {
};
static void
-rsvg_filter_primitive_convolve_matrix_render (RsvgNode *node, RsvgComputedValues *values,
RsvgFilterPrimitive *primitive, RsvgFilterContext *ctx)
+rsvg_filter_primitive_convolve_matrix_render (RsvgNode *node, RsvgComputedValues *values,
+ RsvgFilterPrimitive *primitive,
+ RsvgFilterContext *ctx,
+ RsvgDrawingCtx *draw_ctx)
{
RsvgFilterPrimitiveConvolveMatrix *convolve = (RsvgFilterPrimitiveConvolveMatrix *) primitive;
@@ -73,9 +76,9 @@ rsvg_filter_primitive_convolve_matrix_render (RsvgNode *node, RsvgComputedValues
gint tempresult;
- boundarys = rsvg_filter_primitive_get_bounds (primitive, ctx);
+ boundarys = rsvg_filter_primitive_get_bounds (primitive, ctx, draw_ctx);
- in = rsvg_filter_get_in (primitive->in, ctx);
+ in = rsvg_filter_get_in (primitive->in, ctx, draw_ctx);
if (in == NULL)
return;
diff --git a/librsvg/filters/diffuse_lighting.c b/librsvg/filters/diffuse_lighting.c
index 0b67736c..24d2b3ef 100644
--- a/librsvg/filters/diffuse_lighting.c
+++ b/librsvg/filters/diffuse_lighting.c
@@ -41,7 +41,11 @@ struct _RsvgFilterPrimitiveDiffuseLighting {
};
static void
-rsvg_filter_primitive_diffuse_lighting_render (RsvgNode *node, RsvgComputedValues *values,
RsvgFilterPrimitive *primitive, RsvgFilterContext *ctx)
+rsvg_filter_primitive_diffuse_lighting_render (RsvgNode *node,
+ RsvgComputedValues *values,
+ RsvgFilterPrimitive *primitive,
+ RsvgFilterContext *ctx,
+ RsvgDrawingCtx *draw_ctx)
{
RsvgFilterPrimitiveDiffuseLighting *diffuse_lighting = (RsvgFilterPrimitiveDiffuseLighting *) primitive;
@@ -71,9 +75,9 @@ rsvg_filter_primitive_diffuse_lighting_render (RsvgNode *node, RsvgComputedValue
if (cairo_matrix_invert (&iaffine) != CAIRO_STATUS_SUCCESS)
return;
- boundarys = rsvg_filter_primitive_get_bounds (primitive, ctx);
+ boundarys = rsvg_filter_primitive_get_bounds (primitive, ctx, draw_ctx);
- in = rsvg_filter_get_in (primitive->in, ctx);
+ in = rsvg_filter_get_in (primitive->in, ctx, draw_ctx);
if (in == NULL)
return;
@@ -118,16 +122,15 @@ rsvg_filter_primitive_diffuse_lighting_render (RsvgNode *node, RsvgComputedValue
}
const int *ctx_channelmap = rsvg_filter_context_get_channelmap(ctx);
- RsvgDrawingCtx *drawing_ctx = rsvg_filter_context_get_drawing_ctx(ctx);
for (y = boundarys.y0; y < boundarys.y1; y++)
for (x = boundarys.x0; x < boundarys.x1; x++) {
z = surfaceScale * (double) in_pixels[y * rowstride + x * 4 + ctx_channelmap[3]];
- L = get_light_direction (values, source, x, y, z, &iaffine, drawing_ctx);
+ L = get_light_direction (values, source, x, y, z, &iaffine, draw_ctx);
N = get_surface_normal (in_pixels, boundarys, x, y,
dx, dy, rawdx, rawdy, diffuse_lighting->surfaceScale,
rowstride, ctx_channelmap[3]);
- lightcolor = get_light_color (values, source, color, x, y, z, &iaffine, drawing_ctx);
+ lightcolor = get_light_color (values, source, color, x, y, z, &iaffine, draw_ctx);
factor = dotproduct (N, L);
output_pixels[y * rowstride + x * 4 + ctx_channelmap[0]] =
diff --git a/librsvg/filters/displacement_map.c b/librsvg/filters/displacement_map.c
index d95d0a3d..75f65e1f 100644
--- a/librsvg/filters/displacement_map.c
+++ b/librsvg/filters/displacement_map.c
@@ -41,7 +41,11 @@ struct _RsvgFilterPrimitiveDisplacementMap {
};
static void
-rsvg_filter_primitive_displacement_map_render (RsvgNode *node, RsvgComputedValues *values,
RsvgFilterPrimitive *primitive, RsvgFilterContext *ctx)
+rsvg_filter_primitive_displacement_map_render (RsvgNode *node,
+ RsvgComputedValues *values,
+ RsvgFilterPrimitive *primitive,
+ RsvgFilterContext *ctx,
+ RsvgDrawingCtx *draw_ctx)
{
RsvgFilterPrimitiveDisplacementMap *displacement_map = (RsvgFilterPrimitiveDisplacementMap *) primitive;
guchar ch, xch, ych;
@@ -57,15 +61,15 @@ rsvg_filter_primitive_displacement_map_render (RsvgNode *node, RsvgComputedValue
double ox, oy;
- boundarys = rsvg_filter_primitive_get_bounds (primitive, ctx);
+ boundarys = rsvg_filter_primitive_get_bounds (primitive, ctx, draw_ctx);
- in = rsvg_filter_get_in (primitive->in, ctx);
+ in = rsvg_filter_get_in (primitive->in, ctx, draw_ctx);
if (in == NULL)
return;
cairo_surface_flush (in);
- in2 = rsvg_filter_get_in (displacement_map->in2, ctx);
+ in2 = rsvg_filter_get_in (displacement_map->in2, ctx, draw_ctx);
if (in2 == NULL) {
cairo_surface_destroy (in);
return;
diff --git a/librsvg/filters/erode.c b/librsvg/filters/erode.c
index f15a6c33..d2e9dde1 100644
--- a/librsvg/filters/erode.c
+++ b/librsvg/filters/erode.c
@@ -40,7 +40,11 @@ struct _RsvgFilterPrimitiveErode {
};
static void
-rsvg_filter_primitive_erode_render (RsvgNode *node, RsvgComputedValues *values, RsvgFilterPrimitive
*primitive, RsvgFilterContext *ctx)
+rsvg_filter_primitive_erode_render (RsvgNode *node,
+ RsvgComputedValues *values,
+ RsvgFilterPrimitive *primitive,
+ RsvgFilterContext *ctx,
+ RsvgDrawingCtx *draw_ctx)
{
RsvgFilterPrimitiveErode *erode = (RsvgFilterPrimitiveErode *) primitive;
@@ -58,9 +62,9 @@ rsvg_filter_primitive_erode_render (RsvgNode *node, RsvgComputedValues *values,
gint kx, ky;
guchar val;
- boundarys = rsvg_filter_primitive_get_bounds (primitive, ctx);
+ boundarys = rsvg_filter_primitive_get_bounds (primitive, ctx, draw_ctx);
- in = rsvg_filter_get_in (primitive->in, ctx);
+ in = rsvg_filter_get_in (primitive->in, ctx, draw_ctx);
if (in == NULL)
return;
diff --git a/librsvg/filters/gaussian_blur.c b/librsvg/filters/gaussian_blur.c
index c0d0615c..dfd3f63a 100644
--- a/librsvg/filters/gaussian_blur.c
+++ b/librsvg/filters/gaussian_blur.c
@@ -581,7 +581,11 @@ gaussian_blur_surface (cairo_surface_t *in,
}
static void
-rsvg_filter_primitive_gaussian_blur_render (RsvgNode *node, RsvgComputedValues *values, RsvgFilterPrimitive
*primitive, RsvgFilterContext *ctx)
+rsvg_filter_primitive_gaussian_blur_render (RsvgNode *node,
+ RsvgComputedValues *values,
+ RsvgFilterPrimitive *primitive,
+ RsvgFilterContext *ctx,
+ RsvgDrawingCtx *draw_ctx)
{
RsvgFilterPrimitiveGaussianBlur *gaussian = (RsvgFilterPrimitiveGaussianBlur *) primitive;
@@ -592,9 +596,9 @@ rsvg_filter_primitive_gaussian_blur_render (RsvgNode *node, RsvgComputedValues *
RsvgFilterPrimitiveOutput op;
cairo_t *cr;
- boundarys = rsvg_filter_primitive_get_bounds (primitive, ctx);
+ boundarys = rsvg_filter_primitive_get_bounds (primitive, ctx, draw_ctx);
- in = rsvg_filter_get_in (primitive->in, ctx);
+ in = rsvg_filter_get_in (primitive->in, ctx, draw_ctx);
if (in == NULL) {
return;
}
diff --git a/librsvg/filters/specular_lighting.c b/librsvg/filters/specular_lighting.c
index e0770687..2e19d0e4 100644
--- a/librsvg/filters/specular_lighting.c
+++ b/librsvg/filters/specular_lighting.c
@@ -41,7 +41,11 @@ struct _RsvgFilterPrimitiveSpecularLighting {
};
static void
-rsvg_filter_primitive_specular_lighting_render (RsvgNode *node, RsvgComputedValues *values,
RsvgFilterPrimitive *primitive, RsvgFilterContext *ctx)
+rsvg_filter_primitive_specular_lighting_render (RsvgNode *node,
+ RsvgComputedValues *values,
+ RsvgFilterPrimitive *primitive,
+ RsvgFilterContext *ctx,
+ RsvgDrawingCtx *draw_ctx)
{
RsvgFilterPrimitiveSpecularLighting *specular_lighting = (RsvgFilterPrimitiveSpecularLighting *)
primitive;
@@ -71,9 +75,9 @@ rsvg_filter_primitive_specular_lighting_render (RsvgNode *node, RsvgComputedValu
if (cairo_matrix_invert (&iaffine) != CAIRO_STATUS_SUCCESS)
return;
- boundarys = rsvg_filter_primitive_get_bounds (primitive, ctx);
+ boundarys = rsvg_filter_primitive_get_bounds (primitive, ctx, draw_ctx);
- in = rsvg_filter_get_in (primitive->in, ctx);
+ in = rsvg_filter_get_in (primitive->in, ctx, draw_ctx);
if (in == NULL)
return;
@@ -104,16 +108,15 @@ rsvg_filter_primitive_specular_lighting_render (RsvgNode *node, RsvgComputedValu
surfaceScale = specular_lighting->surfaceScale / 255.0;
const int *ctx_channelmap = rsvg_filter_context_get_channelmap(ctx);
- RsvgDrawingCtx *drawing_ctx = rsvg_filter_context_get_drawing_ctx(ctx);
for (y = boundarys.y0; y < boundarys.y1; y++)
for (x = boundarys.x0; x < boundarys.x1; x++) {
z = in_pixels[y * rowstride + x * 4 + 3] * surfaceScale;
- L = get_light_direction (values, source, x, y, z, &iaffine, drawing_ctx);
+ L = get_light_direction (values, source, x, y, z, &iaffine, draw_ctx);
L.z += 1;
L = normalise (L);
- lightcolor = get_light_color (values, source, color, x, y, z, &iaffine, drawing_ctx);
+ lightcolor = get_light_color (values, source, color, x, y, z, &iaffine, draw_ctx);
base = dotproduct (get_surface_normal (in_pixels, boundarys, x, y,
1, 1, 1.0 / ctx_paffine.xx,
1.0 / ctx_paffine.yy, specular_lighting->surfaceScale,
diff --git a/librsvg/filters/tile.c b/librsvg/filters/tile.c
index d973b97f..c7a85e7c 100644
--- a/librsvg/filters/tile.c
+++ b/librsvg/filters/tile.c
@@ -45,7 +45,11 @@ mod (int a, int b)
}
static void
-rsvg_filter_primitive_tile_render (RsvgNode *node, RsvgComputedValues *values, RsvgFilterPrimitive
*primitive, RsvgFilterContext *ctx)
+rsvg_filter_primitive_tile_render (RsvgNode *node,
+ RsvgComputedValues *values,
+ RsvgFilterPrimitive *primitive,
+ RsvgFilterContext *ctx,
+ RsvgDrawingCtx *draw_ctx)
{
guchar i;
gint x, y, rowstride;
@@ -58,9 +62,9 @@ rsvg_filter_primitive_tile_render (RsvgNode *node, RsvgComputedValues *values, R
cairo_surface_t *output, *in;
- oboundarys = rsvg_filter_primitive_get_bounds (primitive, ctx);
+ oboundarys = rsvg_filter_primitive_get_bounds (primitive, ctx, draw_ctx);
- input = rsvg_filter_get_result (primitive->in, ctx);
+ input = rsvg_filter_get_result (primitive->in, ctx, draw_ctx);
in = input.surface;
if (in == NULL) {
return;
diff --git a/librsvg/filters/turbulence.c b/librsvg/filters/turbulence.c
index cf8d2e97..35e51f63 100644
--- a/librsvg/filters/turbulence.c
+++ b/librsvg/filters/turbulence.c
@@ -266,7 +266,11 @@ feTurbulence_turbulence (RsvgFilterPrimitiveTurbulence * filter,
}
static void
-rsvg_filter_primitive_turbulence_render (RsvgNode *node, RsvgComputedValues *values, RsvgFilterPrimitive
*primitive, RsvgFilterContext *ctx)
+rsvg_filter_primitive_turbulence_render (RsvgNode *node,
+ RsvgComputedValues *values,
+ RsvgFilterPrimitive *primitive,
+ RsvgFilterContext *ctx,
+ RsvgDrawingCtx *draw_ctx)
{
RsvgFilterPrimitiveTurbulence *turbulence = (RsvgFilterPrimitiveTurbulence *) primitive;
@@ -281,7 +285,7 @@ rsvg_filter_primitive_turbulence_render (RsvgNode *node, RsvgComputedValues *val
if (cairo_matrix_invert (&affine) != CAIRO_STATUS_SUCCESS)
return;
- in = rsvg_filter_get_in (primitive->in, ctx);
+ in = rsvg_filter_get_in (primitive->in, ctx, draw_ctx);
if (in == NULL)
return;
@@ -291,7 +295,7 @@ rsvg_filter_primitive_turbulence_render (RsvgNode *node, RsvgComputedValues *val
width = cairo_image_surface_get_width (in);
rowstride = cairo_image_surface_get_stride (in);
- boundarys = rsvg_filter_primitive_get_bounds (primitive, ctx);
+ boundarys = rsvg_filter_primitive_get_bounds (primitive, ctx, draw_ctx);
tileWidth = (boundarys.x1 - boundarys.x0);
tileHeight = (boundarys.y1 - boundarys.y0);
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index 2563fd5e..33820b03 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -193,7 +193,11 @@ impl<'a> DrawingCtx {
}
fn acquired_nodes_contains(&self, node: &RsvgNode) -> bool {
- self.acquired_nodes.borrow().iter().find(|n| rc_node_ptr_eq(n, node)).is_some()
+ self.acquired_nodes
+ .borrow()
+ .iter()
+ .find(|n| rc_node_ptr_eq(n, node))
+ .is_some()
}
// Use this function when looking up urls to other nodes, and when you expect
@@ -247,7 +251,8 @@ impl<'a> DrawingCtx {
let affine = original_cr.get_matrix();
let (clip_node, clip_units) = {
- let clip_node = self.get_acquired_node_of_type(clip_uri, NodeType::ClipPath)
+ let clip_node = self
+ .get_acquired_node_of_type(clip_uri, NodeType::ClipPath)
.and_then(|acquired| Some(acquired.get()));
let mut clip_units = Default::default();
@@ -270,7 +275,9 @@ impl<'a> DrawingCtx {
}
}
- let needs_temporary_surface = !(opacity == 1.0 && filter.is_none() && mask.is_none()
+ let needs_temporary_surface = !(opacity == 1.0
+ && filter.is_none()
+ && mask.is_none()
&& (clip_units == None || clip_units == Some(CoordUnits::UserSpaceOnUse))
&& comp_op == CompOp::SrcOver
&& enable_background == EnableBackground::Accumulate);
diff --git a/rsvg_internals/src/filters/blend.rs b/rsvg_internals/src/filters/blend.rs
index 327d5c08..efd6d0f9 100644
--- a/rsvg_internals/src/filters/blend.rs
+++ b/rsvg_internals/src/filters/blend.rs
@@ -3,6 +3,7 @@ use std::cell::{Cell, RefCell};
use cairo;
use attributes::Attribute;
+use drawing_ctx::DrawingCtx;
use error::NodeError;
use handle::RsvgHandle;
use node::{NodeResult, NodeTrait, RsvgCNodeImpl, RsvgNode};
@@ -72,15 +73,20 @@ impl NodeTrait for Blend {
}
impl Filter for Blend {
- fn render(&self, _node: &RsvgNode, ctx: &FilterContext) -> Result<FilterResult, FilterError> {
- let input = make_result(self.base.get_input(ctx))?;
- let input_2 = make_result(ctx.get_input(self.in2.borrow().as_ref()))?;
+ fn render(
+ &self,
+ _node: &RsvgNode,
+ ctx: &FilterContext,
+ draw_ctx: &mut DrawingCtx,
+ ) -> Result<FilterResult, FilterError> {
+ let input = make_result(self.base.get_input(ctx, draw_ctx))?;
+ let input_2 = make_result(ctx.get_input(draw_ctx, self.in2.borrow().as_ref()))?;
let bounds = self
.base
.get_bounds(ctx)
.add_input(&input)
.add_input(&input_2)
- .into_irect();
+ .into_irect(draw_ctx);
// It's important to linearize sRGB before doing any blending, since otherwise the colors
// will be darker than they should be.
diff --git a/rsvg_internals/src/filters/bounds.rs b/rsvg_internals/src/filters/bounds.rs
index 7de53872..4c629cbc 100644
--- a/rsvg_internals/src/filters/bounds.rs
+++ b/rsvg_internals/src/filters/bounds.rs
@@ -2,6 +2,7 @@
use cairo::{self, MatrixTrait};
use bbox::BoundingBox;
+use drawing_ctx::DrawingCtx;
use length::RsvgLength;
use super::context::{FilterContext, FilterInput, FilterOutput, IRect};
@@ -10,7 +11,7 @@ use super::context::{FilterContext, FilterInput, FilterOutput, IRect};
#[derive(Clone, Copy)]
pub struct BoundsBuilder<'a> {
/// The filter context.
- ctx: &'a FilterContext<'a>,
+ ctx: &'a FilterContext,
/// The current bounding box.
bbox: BoundingBox,
@@ -82,8 +83,8 @@ impl<'a> BoundsBuilder<'a> {
/// Returns the final pixel bounds.
#[inline]
- pub fn into_irect(self) -> IRect {
- let (mut bbox, needs_clipping) = self.apply_properties();
+ pub fn into_irect(self, draw_ctx: &mut DrawingCtx) -> IRect {
+ let (mut bbox, needs_clipping) = self.apply_properties(draw_ctx);
if needs_clipping {
let effects_region = self.ctx.effects_region();
@@ -97,12 +98,12 @@ impl<'a> BoundsBuilder<'a> {
///
/// Used by feImage.
#[inline]
- pub fn into_irect_without_clipping(self) -> IRect {
- self.apply_properties().0.rect.unwrap().into()
+ pub fn into_irect_without_clipping(self, draw_ctx: &mut DrawingCtx) -> IRect {
+ self.apply_properties(draw_ctx).0.rect.unwrap().into()
}
/// Applies the filter primitive properties.
- fn apply_properties(mut self) -> (BoundingBox, bool) {
+ fn apply_properties(mut self, draw_ctx: &mut DrawingCtx) -> (BoundingBox, bool) {
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();
@@ -117,7 +118,7 @@ impl<'a> BoundsBuilder<'a> {
// If any of the properties were specified, we need to respect them.
if self.x.is_some() || self.y.is_some() || self.width.is_some() || self.height.is_some() {
- self.ctx.with_primitive_units(|normalize| {
+ self.ctx.with_primitive_units(draw_ctx, |normalize| {
// These replacements are correct only because self.bbox is used with the paffine
// matrix.
let rect = self.bbox.rect.as_mut().unwrap();
diff --git a/rsvg_internals/src/filters/component_transfer.rs
b/rsvg_internals/src/filters/component_transfer.rs
index 15cf8725..10b969b3 100644
--- a/rsvg_internals/src/filters/component_transfer.rs
+++ b/rsvg_internals/src/filters/component_transfer.rs
@@ -4,6 +4,7 @@ use std::cmp::min;
use cairo::{self, ImageSurface};
use attributes::Attribute;
+use drawing_ctx::DrawingCtx;
use error::NodeError;
use handle::RsvgHandle;
use node::{NodeResult, NodeTrait, NodeType, RsvgCNodeImpl, RsvgNode};
@@ -272,9 +273,18 @@ impl NodeTrait for FuncX {
}
impl Filter for ComponentTransfer {
- fn render(&self, node: &RsvgNode, ctx: &FilterContext) -> Result<FilterResult, FilterError> {
- let input = make_result(self.base.get_input(ctx))?;
- let bounds = self.base.get_bounds(ctx).add_input(&input).into_irect();
+ fn render(
+ &self,
+ node: &RsvgNode,
+ ctx: &FilterContext,
+ draw_ctx: &mut DrawingCtx,
+ ) -> Result<FilterResult, FilterError> {
+ let input = make_result(self.base.get_input(ctx, draw_ctx))?;
+ let bounds = self
+ .base
+ .get_bounds(ctx)
+ .add_input(&input)
+ .into_irect(draw_ctx);
let input_surface =
linearize_surface(input.surface(), bounds).map_err(FilterError::BadInputSurfaceStatus)?;
diff --git a/rsvg_internals/src/filters/composite.rs b/rsvg_internals/src/filters/composite.rs
index 9b4a995a..4bc3f067 100644
--- a/rsvg_internals/src/filters/composite.rs
+++ b/rsvg_internals/src/filters/composite.rs
@@ -4,6 +4,7 @@ use cairo::{self, ImageSurface};
use cssparser::{CowRcStr, Parser, Token};
use attributes::Attribute;
+use drawing_ctx::DrawingCtx;
use error::{AttributeError, NodeError};
use handle::RsvgHandle;
use node::{NodeResult, NodeTrait, RsvgCNodeImpl, RsvgNode};
@@ -96,15 +97,20 @@ impl NodeTrait for Composite {
}
impl Filter for Composite {
- fn render(&self, _node: &RsvgNode, ctx: &FilterContext) -> Result<FilterResult, FilterError> {
- let input = make_result(self.base.get_input(ctx))?;
- let input_2 = make_result(ctx.get_input(self.in2.borrow().as_ref()))?;
+ fn render(
+ &self,
+ _node: &RsvgNode,
+ ctx: &FilterContext,
+ draw_ctx: &mut DrawingCtx,
+ ) -> Result<FilterResult, FilterError> {
+ let input = make_result(self.base.get_input(ctx, draw_ctx))?;
+ let input_2 = make_result(ctx.get_input(draw_ctx, self.in2.borrow().as_ref()))?;
let bounds = self
.base
.get_bounds(ctx)
.add_input(&input)
.add_input(&input_2)
- .into_irect();
+ .into_irect(draw_ctx);
// It's important to linearize sRGB before doing any blending, since otherwise the colors
// will be darker than they should be.
diff --git a/rsvg_internals/src/filters/context.rs b/rsvg_internals/src/filters/context.rs
index b9a26184..b2c2e8e0 100644
--- a/rsvg_internals/src/filters/context.rs
+++ b/rsvg_internals/src/filters/context.rs
@@ -1,6 +1,5 @@
use std::cell::UnsafeCell;
use std::collections::HashMap;
-use std::ffi::CStr;
use std::{mem, ptr};
use cairo::prelude::SurfaceExt;
@@ -13,7 +12,7 @@ use bbox::BoundingBox;
use coord_units::CoordUnits;
use drawing_ctx::{DrawingCtx, RsvgDrawingCtx};
use length::RsvgLength;
-use node::{box_node, RsvgNode};
+use node::RsvgNode;
use paint_server::{self, PaintServer};
use unitinterval::UnitInterval;
@@ -73,10 +72,10 @@ pub enum FilterInput {
PrimitiveOutput(FilterOutput),
}
-pub type RsvgFilterContext<'a> = FilterContext<'a>;
+pub type RsvgFilterContext = FilterContext;
/// The filter rendering context.
-pub struct FilterContext<'a> {
+pub struct FilterContext {
/// The <filter> node.
node: RsvgNode,
/// The node which referenced this filter.
@@ -89,8 +88,6 @@ pub struct FilterContext<'a> {
previous_results: HashMap<String, FilterOutput>,
/// The background surface. Computed lazily.
background_surface: UnsafeCell<Option<Result<cairo::ImageSurface, cairo::Status>>>,
- /// The drawing context.
- draw_ctx: &'a mut DrawingCtx,
/// The filter effects region.
effects_region: BoundingBox,
@@ -220,13 +217,13 @@ impl IRect {
}
}
-impl<'a> FilterContext<'a> {
+impl FilterContext {
/// Creates a new `FilterContext`.
pub fn new(
filter_node: &RsvgNode,
node_being_filtered: &RsvgNode,
source_surface: cairo::ImageSurface,
- draw_ctx: &'a mut DrawingCtx,
+ draw_ctx: &mut DrawingCtx,
channelmap: [i32; 4],
) -> Self {
let cr_affine = draw_ctx.get_cairo_context().get_matrix();
@@ -284,7 +281,6 @@ impl<'a> FilterContext<'a> {
last_result: None,
previous_results: HashMap::new(),
background_surface: UnsafeCell::new(None),
- draw_ctx,
effects_region,
affine,
paffine,
@@ -331,19 +327,22 @@ impl<'a> FilterContext<'a> {
}
/// Computes and returns the background image snapshot.
- fn compute_background_image(&self) -> Result<cairo::ImageSurface, cairo::Status> {
+ fn compute_background_image(
+ &self,
+ draw_ctx: &DrawingCtx,
+ ) -> Result<cairo::ImageSurface, cairo::Status> {
let surface = cairo::ImageSurface::create(
cairo::Format::ARgb32,
self.source_surface.get_width(),
self.source_surface.get_height(),
)?;
- let (x, y) = self.draw_ctx.get_raw_offset();
- let stack = self.draw_ctx.get_cr_stack();
+ let (x, y) = draw_ctx.get_raw_offset();
+ let stack = draw_ctx.get_cr_stack();
let cr = cairo::Context::new(&surface);
for draw in stack.into_iter().rev() {
- let nested = self.draw_ctx.is_cairo_context_nested(&draw);
+ let nested = draw_ctx.is_cairo_context_nested(&draw);
cr.set_source_surface(
&draw.get_target(),
if nested { 0f64 } else { -x },
@@ -356,7 +355,10 @@ impl<'a> FilterContext<'a> {
}
/// Returns the surface corresponding to the background image snapshot.
- pub fn background_image(&self) -> Result<&cairo::ImageSurface, cairo::Status> {
+ pub fn background_image(
+ &self,
+ draw_ctx: &DrawingCtx,
+ ) -> Result<&cairo::ImageSurface, cairo::Status> {
{
// At this point either no, or only immutable references to background_surface exist, so
// it's ok to make an immutable reference.
@@ -373,7 +375,7 @@ impl<'a> FilterContext<'a> {
// no references to it and we can create a mutable reference.
let bg = unsafe { &mut *self.background_surface.get() };
- *bg = Some(self.compute_background_image());
+ *bg = Some(self.compute_background_image(draw_ctx));
// Return the only existing reference as immutable.
bg.as_ref().unwrap().as_ref().map_err(|&s| s)
@@ -381,8 +383,12 @@ impl<'a> FilterContext<'a> {
/// Returns the surface containing the background image snapshot alpha.
#[inline]
- pub fn background_alpha(&self, bounds: IRect) -> Result<cairo::ImageSurface, cairo::Status> {
- self.background_image()
+ pub fn background_alpha(
+ &self,
+ draw_ctx: &DrawingCtx,
+ bounds: IRect,
+ ) -> Result<cairo::ImageSurface, cairo::Status> {
+ self.background_image(draw_ctx)
.and_then(|surface| extract_alpha(surface, bounds))
}
@@ -411,12 +417,6 @@ impl<'a> FilterContext<'a> {
self.last_result = Some(result.output);
}
- /// Returns the drawing context for this filter context.
- #[inline]
- pub fn draw_context(&mut self) -> &mut DrawingCtx {
- self.draw_ctx
- }
-
/// Returns the paffine matrix.
#[inline]
pub fn paffine(&self) -> cairo::Matrix {
@@ -430,7 +430,7 @@ impl<'a> FilterContext<'a> {
}
/// Calls the given function with correct behavior for the value of `primitiveUnits`.
- pub fn with_primitive_units<F, T>(&self, 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(&RsvgLength) -> f64 + 'b>) -> T,
@@ -443,21 +443,22 @@ impl<'a> FilterContext<'a> {
// See comments in compute_effects_region() for how this works.
if filter.primitiveunits.get() == CoordUnits::ObjectBoundingBox {
- self.draw_ctx.push_view_box(1.0, 1.0);
+ draw_ctx.push_view_box(1.0, 1.0);
let rv = f(Box::new(RsvgLength::get_unitless));
- self.draw_ctx.pop_view_box();
+ draw_ctx.pop_view_box();
rv
} else {
f(Box::new(|length: &RsvgLength| {
- length.normalize(values, self.draw_ctx)
+ length.normalize(values, draw_ctx)
}))
}
}
/// Computes and returns a surface corresponding to the given paint server.
fn get_paint_server_surface(
- &mut self,
+ &self,
+ draw_ctx: &mut DrawingCtx,
paint_server: &PaintServer,
opacity: UnitInterval,
) -> Result<cairo::ImageSurface, cairo::Status> {
@@ -467,17 +468,17 @@ impl<'a> FilterContext<'a> {
self.source_surface.get_height(),
)?;
- let cr_save = self.draw_ctx.get_cairo_context();
+ let cr_save = draw_ctx.get_cairo_context();
let cr = cairo::Context::new(&surface);
- self.draw_ctx.set_cairo_context(&cr);
+ draw_ctx.set_cairo_context(&cr);
let cascaded = self.node_being_filtered.get_cascaded_values();
let values = cascaded.get();
- let bbox = self.draw_ctx.get_bbox().clone();
+ let bbox = draw_ctx.get_bbox().clone();
if paint_server::set_source_paint_server(
- self.draw_ctx,
+ draw_ctx,
paint_server,
&opacity,
&bbox,
@@ -486,12 +487,12 @@ impl<'a> FilterContext<'a> {
cr.paint();
}
- self.draw_ctx.set_cairo_context(&cr_save);
+ draw_ctx.set_cairo_context(&cr_save);
Ok(surface)
}
/// Retrieves the filter input surface according to the SVG rules.
- pub fn get_input(&self, in_: Option<&Input>) -> Option<FilterInput> {
+ pub fn get_input(&self, draw_ctx: &mut DrawingCtx, in_: Option<&Input>) -> Option<FilterInput> {
if in_.is_none() {
// No value => use the last result.
// As per the SVG spec, if the filter primitive is the first in the chain, return the
@@ -513,21 +514,21 @@ impl<'a> FilterContext<'a> {
.ok()
.map(FilterInput::StandardInput),
Input::BackgroundImage => self
- .background_image()
+ .background_image(draw_ctx)
.ok()
.cloned()
.map(FilterInput::StandardInput),
Input::BackgroundAlpha => self
- .background_alpha(self.effects_region().rect.unwrap().into())
+ .background_alpha(draw_ctx, self.effects_region().rect.unwrap().into())
.ok()
.map(FilterInput::StandardInput),
Input::FillPaint => self
- .get_paint_server_surface(&values.fill.0, values.fill_opacity.0)
+ .get_paint_server_surface(draw_ctx, &values.fill.0, values.fill_opacity.0)
.ok()
.map(FilterInput::StandardInput),
Input::StrokePaint => self
- .get_paint_server_surface(&values.stroke.0, values.stroke_opacity.0)
+ .get_paint_server_surface(draw_ctx, &values.stroke.0, values.stroke_opacity.0)
.ok()
.map(FilterInput::StandardInput),
@@ -569,15 +570,6 @@ impl From<cairo::Rectangle> for IRect {
}
}
-#[no_mangle]
-pub unsafe extern "C" fn rsvg_filter_context_get_affine(
- ctx: *const RsvgFilterContext,
-) -> cairo::Matrix {
- assert!(!ctx.is_null());
-
- (*ctx).affine
-}
-
#[no_mangle]
pub unsafe extern "C" fn rsvg_filter_context_get_paffine(
ctx: *const RsvgFilterContext,
@@ -587,15 +579,6 @@ pub unsafe extern "C" fn rsvg_filter_context_get_paffine(
(*ctx).paffine
}
-#[no_mangle]
-pub unsafe extern "C" fn rsvg_filter_context_get_drawing_ctx(
- ctx: *mut RsvgFilterContext,
-) -> *mut RsvgDrawingCtx {
- assert!(!ctx.is_null());
-
- (*ctx).draw_ctx as *const _ as *mut RsvgDrawingCtx
-}
-
#[no_mangle]
pub unsafe extern "C" fn rsvg_filter_context_get_width(ctx: *const RsvgFilterContext) -> i32 {
assert!(!ctx.is_null());
@@ -610,15 +593,6 @@ pub unsafe extern "C" fn rsvg_filter_context_get_height(ctx: *const RsvgFilterCo
(*ctx).source_surface.get_height()
}
-#[no_mangle]
-pub unsafe extern "C" fn rsvg_filter_context_get_node_being_filtered(
- ctx: *const RsvgFilterContext,
-) -> *mut RsvgNode {
- assert!(!ctx.is_null());
-
- box_node((*ctx).get_node_being_filtered())
-}
-
#[no_mangle]
pub unsafe extern "C" fn rsvg_filter_context_get_channelmap(
ctx: *const RsvgFilterContext,
@@ -637,66 +611,6 @@ pub unsafe extern "C" fn rsvg_filter_context_get_source_surface(
(*ctx).source_surface.to_glib_none().0
}
-#[no_mangle]
-pub unsafe extern "C" fn rsvg_filter_context_get_bg_surface(
- ctx: *mut RsvgFilterContext,
-) -> *mut cairo_surface_t {
- assert!(!ctx.is_null());
-
- (*ctx)
- .background_image()
- .map(|surface| surface.to_glib_none().0)
- .unwrap_or_else(|_| ptr::null_mut())
-}
-
-#[no_mangle]
-pub unsafe extern "C" fn rsvg_filter_context_get_lastresult(
- ctx: *mut RsvgFilterContext,
-) -> RsvgFilterPrimitiveOutput {
- assert!(!ctx.is_null());
-
- let ctx = &*ctx;
-
- match ctx.last_result {
- Some(FilterOutput {
- ref surface,
- ref bounds,
- }) => RsvgFilterPrimitiveOutput {
- surface: surface.to_glib_none().0,
- bounds: *bounds,
- },
- None => RsvgFilterPrimitiveOutput {
- surface: ctx.source_surface.to_glib_none().0,
- bounds: ctx.effects_region().rect.unwrap().into(),
- },
- }
-}
-
-#[no_mangle]
-pub unsafe extern "C" fn rsvg_filter_context_get_previous_result(
- name: *mut GString,
- ctx: *mut RsvgFilterContext,
- output: *mut RsvgFilterPrimitiveOutput,
-) -> i32 {
- assert!(!name.is_null());
- assert!(!ctx.is_null());
- assert!(!output.is_null());
-
- if let Some(&FilterOutput {
- ref surface,
- ref bounds,
- }) = (*ctx).filter_output(&CStr::from_ptr((*name).str).to_string_lossy())
- {
- *output = RsvgFilterPrimitiveOutput {
- surface: surface.to_glib_none().0,
- bounds: *bounds,
- };
- 1
- } else {
- 0
- }
-}
-
#[no_mangle]
pub unsafe extern "C" fn rsvg_filter_store_output(
name: *mut GString,
@@ -728,10 +642,13 @@ pub unsafe extern "C" fn rsvg_filter_store_output(
pub unsafe extern "C" fn rsvg_filter_primitive_get_bounds(
primitive: *const RsvgFilterPrimitive,
ctx: *const RsvgFilterContext,
+ raw_draw_ctx: *mut RsvgDrawingCtx,
) -> IRect {
assert!(!ctx.is_null());
+ assert!(!raw_draw_ctx.is_null());
let ctx = &*ctx;
+ let draw_ctx = &mut *(raw_draw_ctx as *mut DrawingCtx);
let mut x = None;
let mut y = None;
@@ -757,16 +674,20 @@ pub unsafe extern "C" fn rsvg_filter_primitive_get_bounds(
}
// Doesn't take referenced nodes into account, which is wrong.
- BoundsBuilder::new(ctx, x, y, width, height).into_irect()
+ BoundsBuilder::new(ctx, x, y, width, height).into_irect(draw_ctx)
}
#[no_mangle]
pub unsafe extern "C" fn rsvg_filter_get_result(
name: *const GString,
ctx: *const RsvgFilterContext,
+ raw_draw_ctx: *const RsvgDrawingCtx,
) -> RsvgFilterPrimitiveOutput {
assert!(!name.is_null());
assert!(!ctx.is_null());
+ assert!(!raw_draw_ctx.is_null());
+
+ let draw_ctx = &mut *(raw_draw_ctx as *mut DrawingCtx);
let name: String = from_glib_none((*name).str);
let input = match &name[..] {
@@ -782,7 +703,7 @@ pub unsafe extern "C" fn rsvg_filter_get_result(
let ctx = &*ctx;
- match ctx.get_input(input.as_ref()) {
+ match ctx.get_input(draw_ctx, input.as_ref()) {
None => RsvgFilterPrimitiveOutput {
surface: ptr::null_mut(),
bounds: IRect {
@@ -815,8 +736,9 @@ pub unsafe extern "C" fn rsvg_filter_get_result(
pub unsafe extern "C" fn rsvg_filter_get_in(
name: *const GString,
ctx: *const RsvgFilterContext,
+ raw_draw_ctx: *mut RsvgDrawingCtx,
) -> *mut cairo_surface_t {
- rsvg_filter_get_result(name, ctx).surface
+ rsvg_filter_get_result(name, ctx, raw_draw_ctx).surface
}
#[cfg(test)]
diff --git a/rsvg_internals/src/filters/ffi.rs b/rsvg_internals/src/filters/ffi.rs
index 36920004..6c703025 100644
--- a/rsvg_internals/src/filters/ffi.rs
+++ b/rsvg_internals/src/filters/ffi.rs
@@ -40,14 +40,15 @@ pub struct RsvgFilterPrimitive {
/// The type of the render function below.
pub(super) type RenderFunctionType =
- fn(&RsvgNode, &FilterContext) -> Result<FilterResult, FilterError>;
+ fn(&RsvgNode, &FilterContext, &mut DrawingCtx) -> Result<FilterResult, FilterError>;
/// Downcasts the given `node` to the type `T` and calls `Filter::render()` on it.
pub(super) fn render<T: Filter>(
node: &RsvgNode,
ctx: &FilterContext,
+ draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
- node.with_impl(|filter: &T| filter.render(node, ctx))
+ node.with_impl(|filter: &T| filter.render(node, ctx, draw_ctx))
}
/// Creates a new surface applied the filter. This function will create a context for itself, set up
@@ -98,7 +99,7 @@ pub fn filter_render(
let render = unsafe {
*(&c.get_c_impl() as *const *const RsvgCNodeImpl as *const RenderFunctionType)
};
- match render(&c, &filter_ctx) {
+ match render(&c, &filter_ctx, draw_ctx) {
Ok(result) => filter_ctx.store_result(result),
Err(_) => { /* Do nothing for now */ }
}
diff --git a/rsvg_internals/src/filters/flood.rs b/rsvg_internals/src/filters/flood.rs
index f5189d80..3f1e14c2 100644
--- a/rsvg_internals/src/filters/flood.rs
+++ b/rsvg_internals/src/filters/flood.rs
@@ -1,6 +1,7 @@
use cairo::{self, ImageSurface};
use cssparser;
+use drawing_ctx::DrawingCtx;
use handle::RsvgHandle;
use node::{NodeResult, NodeTrait, RsvgCNodeImpl, RsvgNode};
use property_bag::PropertyBag;
@@ -41,8 +42,13 @@ impl NodeTrait for Flood {
}
impl Filter for Flood {
- fn render(&self, node: &RsvgNode, ctx: &FilterContext) -> Result<FilterResult, FilterError> {
- let bounds = self.base.get_bounds(ctx).into_irect();
+ fn render(
+ &self,
+ node: &RsvgNode,
+ ctx: &FilterContext,
+ draw_ctx: &mut DrawingCtx,
+ ) -> Result<FilterResult, FilterError> {
+ let bounds = self.base.get_bounds(ctx).into_irect(draw_ctx);
let output_surface = ImageSurface::create(
cairo::Format::ARgb32,
diff --git a/rsvg_internals/src/filters/image.rs b/rsvg_internals/src/filters/image.rs
index 38fcc970..a0729476 100644
--- a/rsvg_internals/src/filters/image.rs
+++ b/rsvg_internals/src/filters/image.rs
@@ -10,6 +10,7 @@ use libc;
use aspect_ratio::AspectRatio;
use attributes::Attribute;
+use drawing_ctx::DrawingCtx;
use handle::RsvgHandle;
use node::{CascadedValues, NodeResult, NodeTrait, RsvgCNodeImpl, RsvgNode};
use parsers::parse;
@@ -47,12 +48,12 @@ impl Image {
fn render_node(
&self,
ctx: &FilterContext,
+ draw_ctx: &mut DrawingCtx,
bounds: IRect,
href: &str,
) -> Result<ImageSurface, FilterError> {
// TODO: Port more of this to Rust.
// Currently this is essentially a direct port of the C function.
- let draw_ctx = ctx.draw_context();
let acquired_drawable = draw_ctx
.get_acquired_node(href)
.ok_or(FilterError::InvalidInput)?;
@@ -66,10 +67,11 @@ impl Image {
draw_ctx.get_cairo_context().set_matrix(ctx.paffine());
- let cascaded = CascadedValues::new_from_values(
- &drawable,
- ctx.get_node_being_filtered().get_cascaded_values().get(),
- );
+ let node_being_filtered = ctx.get_node_being_filtered();
+ let node_being_filtered_cascaded = node_being_filtered.get_cascaded_values();
+ let node_being_filtered_values = node_being_filtered_cascaded.get();
+
+ let cascaded = CascadedValues::new_from_values(&drawable, node_being_filtered_values);
draw_ctx.draw_node_on_surface(
&drawable,
@@ -104,6 +106,7 @@ impl Image {
fn render_external_image(
&self,
ctx: &FilterContext,
+ draw_ctx: &mut DrawingCtx,
bounds_builder: BoundsBuilder,
href: &str,
) -> Result<ImageSurface, FilterError> {
@@ -141,7 +144,7 @@ impl Image {
).map_err(FilterError::OutputSurfaceCreation)?;
// TODO: this goes through a f64->i32->f64 conversion.
- let render_bounds = bounds_builder.into_irect_without_clipping();
+ let render_bounds = bounds_builder.into_irect_without_clipping(draw_ctx);
let aspect = self.aspect.get();
let (x, y, w, h) = aspect.compute(
f64::from(surface.get_width()),
@@ -165,7 +168,7 @@ impl Image {
matrix.invert();
ptn.set_matrix(matrix);
- let bounds = bounds_builder.into_irect();
+ let bounds = bounds_builder.into_irect(draw_ctx);
let cr = cairo::Context::new(&output_surface);
cr.rectangle(
f64::from(bounds.x0),
@@ -217,16 +220,21 @@ impl NodeTrait for Image {
}
impl Filter for Image {
- fn render(&self, _node: &RsvgNode, ctx: &FilterContext) -> Result<FilterResult, FilterError> {
+ fn render(
+ &self,
+ _node: &RsvgNode,
+ ctx: &FilterContext,
+ draw_ctx: &mut DrawingCtx,
+ ) -> Result<FilterResult, FilterError> {
let href = self.href.borrow();
let href = href.as_ref().ok_or(FilterError::InvalidInput)?;
let bounds_builder = self.base.get_bounds(ctx);
- let bounds = bounds_builder.into_irect();
+ let bounds = bounds_builder.into_irect(draw_ctx);
- let output_surface = match self.render_node(ctx, bounds, href) {
+ let output_surface = match self.render_node(ctx, draw_ctx, bounds, href) {
Err(FilterError::InvalidInput) => {
- self.render_external_image(ctx, bounds_builder, href)?
+ self.render_external_image(ctx, draw_ctx, bounds_builder, href)?
}
Err(err) => return Err(err),
Ok(surface) => surface,
diff --git a/rsvg_internals/src/filters/merge.rs b/rsvg_internals/src/filters/merge.rs
index ef29f992..59cf3526 100644
--- a/rsvg_internals/src/filters/merge.rs
+++ b/rsvg_internals/src/filters/merge.rs
@@ -3,6 +3,7 @@ use std::cell::RefCell;
use cairo::{self, ImageSurface};
use attributes::Attribute;
+use drawing_ctx::DrawingCtx;
use handle::RsvgHandle;
use node::{NodeResult, NodeTrait, NodeType, RsvgCNodeImpl, RsvgNode};
use property_bag::PropertyBag;
@@ -84,10 +85,11 @@ impl MergeNode {
fn render(
&self,
ctx: &FilterContext,
+ draw_ctx: &mut DrawingCtx,
bounds: IRect,
output_surface: Option<ImageSurface>,
) -> Result<ImageSurface, FilterError> {
- let input = make_result(ctx.get_input(self.in_.borrow().as_ref()))?;
+ let input = make_result(ctx.get_input(draw_ctx, self.in_.borrow().as_ref()))?;
let input_surface = input.surface();
let input_surface =
linearize_surface(&input_surface, bounds).map_err(FilterError::BadInputSurfaceStatus)?;
@@ -114,18 +116,23 @@ impl MergeNode {
}
impl Filter for Merge {
- fn render(&self, node: &RsvgNode, ctx: &FilterContext) -> Result<FilterResult, FilterError> {
+ fn render(
+ &self,
+ node: &RsvgNode,
+ ctx: &FilterContext,
+ 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);
for child in node
.children()
.filter(|c| c.get_type() == NodeType::FilterPrimitiveMergeNode)
{
- bounds = bounds.add_input(&child.with_impl(move |c: &MergeNode| {
- make_result(ctx.get_input(c.in_.borrow().as_ref()))
+ bounds = bounds.add_input(&child.with_impl(|c: &MergeNode| {
+ make_result(ctx.get_input(draw_ctx, c.in_.borrow().as_ref()))
})?);
}
- let bounds = bounds.into_irect();
+ let bounds = bounds.into_irect(draw_ctx);
// Now merge them all.
let mut output_surface = None;
@@ -133,8 +140,9 @@ impl Filter for Merge {
.children()
.filter(|c| c.get_type() == NodeType::FilterPrimitiveMergeNode)
{
- output_surface =
- Some(child.with_impl(move |c: &MergeNode| c.render(ctx, bounds, output_surface))?);
+ output_surface = Some(
+ child.with_impl(|c: &MergeNode| c.render(ctx, draw_ctx, bounds, output_surface))?,
+ );
}
let output_surface = output_surface
diff --git a/rsvg_internals/src/filters/mod.rs b/rsvg_internals/src/filters/mod.rs
index d7ab25a2..e363ef34 100644
--- a/rsvg_internals/src/filters/mod.rs
+++ b/rsvg_internals/src/filters/mod.rs
@@ -3,6 +3,7 @@ use std::ops::Deref;
use attributes::Attribute;
use coord_units::CoordUnits;
+use drawing_ctx::DrawingCtx;
use error::AttributeError;
use handle::RsvgHandle;
use length::{LengthDir, LengthUnit, RsvgLength};
@@ -44,7 +45,12 @@ trait Filter: NodeTrait {
///
/// If this filter primitive can't be rendered for whatever reason (for instance, a required
/// property hasn't been provided), an error is returned.
- fn render(&self, node: &RsvgNode, ctx: &FilterContext) -> Result<FilterResult, FilterError>;
+ fn render(
+ &self,
+ node: &RsvgNode,
+ ctx: &FilterContext,
+ draw_ctx: &mut DrawingCtx,
+ ) -> Result<FilterResult, FilterError>;
}
/// The base filter primitive node containing common properties.
@@ -184,8 +190,8 @@ impl PrimitiveWithInput {
/// Returns the input Cairo surface for this filter primitive.
#[inline]
- fn get_input(&self, ctx: &FilterContext) -> Option<FilterInput> {
- ctx.get_input(self.in_.borrow().as_ref())
+ fn get_input(&self, ctx: &FilterContext, draw_ctx: &mut DrawingCtx) -> Option<FilterInput> {
+ ctx.get_input(draw_ctx, self.in_.borrow().as_ref())
}
}
diff --git a/rsvg_internals/src/filters/offset.rs b/rsvg_internals/src/filters/offset.rs
index 8a8b33cf..e1a16f3a 100644
--- a/rsvg_internals/src/filters/offset.rs
+++ b/rsvg_internals/src/filters/offset.rs
@@ -3,6 +3,7 @@ use std::cell::Cell;
use cairo::{self, ImageSurface};
use attributes::Attribute;
+use drawing_ctx::DrawingCtx;
use error::NodeError;
use handle::RsvgHandle;
use node::{NodeResult, NodeTrait, RsvgCNodeImpl, RsvgNode};
@@ -63,9 +64,18 @@ impl NodeTrait for Offset {
}
impl Filter for Offset {
- fn render(&self, _node: &RsvgNode, ctx: &FilterContext) -> Result<FilterResult, FilterError> {
- let input = make_result(self.base.get_input(ctx))?;
- let bounds = self.base.get_bounds(ctx).add_input(&input).into_irect();
+ fn render(
+ &self,
+ _node: &RsvgNode,
+ ctx: &FilterContext,
+ draw_ctx: &mut DrawingCtx,
+ ) -> Result<FilterResult, FilterError> {
+ let input = make_result(self.base.get_input(ctx, draw_ctx))?;
+ let bounds = self
+ .base
+ .get_bounds(ctx)
+ .add_input(&input)
+ .into_irect(draw_ctx);
let dx = self.dx.get();
let dy = self.dy.get();
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index cfd6eaf3..f085d87f 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -37,15 +37,9 @@ pub use drawing_ctx::{
};
pub use filters::context::{
- rsvg_filter_context_get_affine,
- rsvg_filter_context_get_bg_surface,
rsvg_filter_context_get_channelmap,
- rsvg_filter_context_get_drawing_ctx,
rsvg_filter_context_get_height,
- rsvg_filter_context_get_lastresult,
- rsvg_filter_context_get_node_being_filtered,
rsvg_filter_context_get_paffine,
- rsvg_filter_context_get_previous_result,
rsvg_filter_context_get_source_surface,
rsvg_filter_context_get_width,
rsvg_filter_get_in,
diff --git a/rsvg_internals/src/structure.rs b/rsvg_internals/src/structure.rs
index 62b02891..aaf48071 100644
--- a/rsvg_internals/src/structure.rs
+++ b/rsvg_internals/src/structure.rs
@@ -80,11 +80,7 @@ impl NodeTrait for NodeSwitch {
draw_ctx.with_discrete_layer(node, values, clipping, &mut |dc| {
if let Some(child) = node.children().find(|c| c.get_cond()) {
- dc.draw_node_from_stack(
- &CascadedValues::new(cascaded, &child),
- &child,
- clipping,
- );
+ dc.draw_node_from_stack(&CascadedValues::new(cascaded, &child), &child, clipping);
}
});
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]