rsvg_drawing_ctx_draw_node_from_stack() - Pass an optional node to cascade from

According to the spec, elements referenced from feImage are suposed to
cascade like the <use> element.  The spec is not very clear on this,
but filters-composite-02-b.svg indicates that the referenced element
cascades from the original element that has the filter applied to it.
For example,

   <defs>
     <path id="foo" .../>

     <filter id="bar">
       <feImage ... xlink:href="#foo"/>
     </filter>
   <defs>

   <path id="baz" ... filter="url(#bar)"/>

Here, baz has a filter applied to it, and the feImage in the filter
references foo.  However, foo should inherit its CSS properties from
baz, not from bar.

This commit lets us give rsvg_drawing_ctx_draw_node_from_stack() a
second, optional node to cascade from.  If it is NULL, then the node
to draw will use its own default cascade.
parent c5bfd649
......@@ -485,7 +485,7 @@ rsvg_drawing_ctx_draw_node_on_surface (RsvgDrawingCtx *ctx,
ctx->rect.width = width;
ctx->rect.height = height;
rsvg_drawing_ctx_draw_node_from_stack (ctx, node, FALSE);
rsvg_drawing_ctx_draw_node_from_stack (ctx, node, NULL, FALSE);
cairo_destroy (ctx->cr);
ctx->cr = save_cr;
......
......@@ -96,6 +96,7 @@ void rsvg_drawing_ctx_restore_stack (RsvgDrawingCtx *ctx,
G_GNUC_INTERNAL
void rsvg_drawing_ctx_draw_node_from_stack (RsvgDrawingCtx *ctx,
RsvgNode *node,
RsvgNode *cascade_from_node,
gboolean clipping);
G_GNUC_INTERNAL
......
......@@ -824,7 +824,7 @@ rsvg_handle_render_cairo_sub (RsvgHandle * handle, cairo_t * cr, const char *id)
cairo_save (cr);
rsvg_handle_cascade (handle);
rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->treebase, FALSE);
rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->treebase, NULL, FALSE);
cairo_restore (cr);
......@@ -952,7 +952,7 @@ rsvg_handle_get_dimensions_sub (RsvgHandle * handle, RsvgDimensionData * dimensi
rsvg_drawing_ctx_add_node_and_ancestors_to_stack (draw, sself);
rsvg_handle_cascade (handle);
rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->treebase, FALSE);
rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->treebase, NULL, FALSE);
bbox = rsvg_drawing_ctx_get_bbox (draw);
rsvg_bbox_get_rect (bbox, NULL, &ink_rect);
......@@ -1039,7 +1039,7 @@ rsvg_handle_get_position_sub (RsvgHandle * handle, RsvgPositionData * position_d
rsvg_drawing_ctx_add_node_and_ancestors_to_stack (draw, node);
rsvg_handle_cascade (handle);
rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->treebase, FALSE);
rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->treebase, NULL, FALSE);
bbox = rsvg_drawing_ctx_get_bbox (draw);
rsvg_bbox_get_rect (bbox, NULL, &ink_rect);
rsvg_drawing_ctx_free (draw);
......
......@@ -514,6 +514,7 @@ pub fn draw_node_from_stack(
pub extern "C" fn rsvg_drawing_ctx_draw_node_from_stack(
draw_ctx: *mut RsvgDrawingCtx,
raw_node: *const RsvgNode,
raw_cascade_from: *const RsvgNode,
clipping: glib_sys::gboolean,
) {
assert!(!draw_ctx.is_null());
......@@ -521,9 +522,24 @@ pub extern "C" fn rsvg_drawing_ctx_draw_node_from_stack(
assert!(!raw_node.is_null());
let node = unsafe { &*raw_node };
let cascade_from = if raw_cascade_from.is_null() {
None
} else {
Some (unsafe { &*raw_cascade_from })
};
let clipping: bool = from_glib(clipping);
draw_node_from_stack(draw_ctx, &node.get_cascaded_values(), node, true, clipping);
let cascaded = match cascade_from {
None => node.get_cascaded_values(),
Some(n) => {
let c = n.get_cascaded_values();
let v = c.get();
CascadedValues::new_from_values(node, v)
}
};
draw_node_from_stack(draw_ctx, &cascaded, node, true, clipping);
}
pub struct AcquiredNode(*const RsvgDrawingCtx, *mut RsvgNode);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment