[librsvg] filters::render() - Take the computed values of the node being filtered, not the whole node
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] filters::render() - Take the computed values of the node being filtered, not the whole node
- Date: Fri, 21 Sep 2018 00:35:18 +0000 (UTC)
commit 580beabe535e6d852b4bc69b8ddc7d6ded49ceec
Author: Federico Mena Quintero <federico gnome org>
Date: Thu Sep 20 19:11:04 2018 -0500
filters::render() - Take the computed values of the node being filtered, not the whole node
Some time soon I want to merge Artem Vorotnikov's work to replace the
ubiquitous Rc<Node> with a Rc<NodeTrait>, to have a "real" inheritance
scheme rather our awkward node.with_impl().
In the meantime, it turns out that the filters code doesn't need the
actual node that is being filtered; just a set of computed values to
pass around while rendering the filter. So, let's do that.
rsvg_internals/src/drawing_ctx.rs | 2 +-
rsvg_internals/src/filters/context.rs | 40 ++++++++++++++++-------------------
rsvg_internals/src/filters/image.rs | 4 +---
rsvg_internals/src/filters/mod.rs | 12 +++++++----
4 files changed, 28 insertions(+), 30 deletions(-)
---
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index 805baa08..076c047c 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -437,7 +437,7 @@ impl<'a> DrawingCtx<'a> {
if !filter_node.is_in_error() {
// FIXME: deal with out of memory here
- Some(filters::render(&filter_node, node, &output, self))
+ Some(filters::render(&filter_node, values, &output, self))
} else {
rsvg_log!(
"(ignoring filter element {} because it is in error)",
diff --git a/rsvg_internals/src/filters/context.rs b/rsvg_internals/src/filters/context.rs
index 905aa38a..b75a4a1e 100644
--- a/rsvg_internals/src/filters/context.rs
+++ b/rsvg_internals/src/filters/context.rs
@@ -10,6 +10,7 @@ use drawing_ctx::DrawingCtx;
use length::Length;
use node::RsvgNode;
use paint_server::{self, PaintServer};
+use state::ComputedValues;
use surface_utils::shared_surface::{SharedImageSurface, SurfaceType};
use unitinterval::UnitInterval;
@@ -58,8 +59,8 @@ pub enum FilterInput {
pub struct FilterContext {
/// The <filter> node.
node: RsvgNode,
- /// The node which referenced this filter.
- node_being_filtered: RsvgNode,
+ /// Values from the node which referenced this filter.
+ computed_from_node_being_filtered: ComputedValues,
/// The source graphic surface.
source_surface: SharedImageSurface,
/// Output of the last filter primitive.
@@ -102,15 +103,14 @@ pub struct FilterContext {
/// Computes and returns the filter effects region.
fn compute_effects_region(
filter_node: &RsvgNode,
- target_node: &RsvgNode,
+ computed_from_target_node: &ComputedValues,
draw_ctx: &mut DrawingCtx<'_>,
affine: cairo::Matrix,
width: f64,
height: f64,
) -> BoundingBox {
// Filters use the properties of the target node.
- let cascaded = target_node.get_cascaded_values();
- let values = cascaded.get();
+ let values = computed_from_target_node;
let filter = filter_node.get_impl::<NodeFilter>().unwrap();
@@ -193,7 +193,7 @@ impl FilterContext {
/// Creates a new `FilterContext`.
pub fn new(
filter_node: &RsvgNode,
- node_being_filtered: &RsvgNode,
+ computed_from_node_being_filtered: &ComputedValues,
source_surface: SharedImageSurface,
draw_ctx: &mut DrawingCtx<'_>,
) -> Self {
@@ -246,14 +246,14 @@ impl FilterContext {
Self {
node: filter_node.clone(),
- node_being_filtered: node_being_filtered.clone(),
+ computed_from_node_being_filtered: computed_from_node_being_filtered.clone(),
source_surface,
last_result: None,
previous_results: HashMap::new(),
background_surface: UnsafeCell::new(None),
effects_region: compute_effects_region(
filter_node,
- node_being_filtered,
+ computed_from_node_being_filtered,
draw_ctx,
affine,
f64::from(width),
@@ -265,10 +265,10 @@ impl FilterContext {
}
}
- /// Returns the node that referenced this filter.
+ /// Returns the computed values from the node that referenced this filter.
#[inline]
- pub fn get_node_being_filtered(&self) -> RsvgNode {
- self.node_being_filtered.clone()
+ pub fn get_computed_values_from_node_being_filtered(&self) -> &ComputedValues {
+ &self.computed_from_node_being_filtered
}
/// Returns the surface corresponding to the last filter primitive's result.
@@ -427,10 +427,6 @@ impl FilterContext {
where
for<'b> F: FnOnce(Box<Fn(&Length) -> f64 + 'b>) -> T,
{
- // Filters use the properties of the target node.
- let cascaded = self.node_being_filtered.get_cascaded_values();
- let values = cascaded.get();
-
let filter = self.node.get_impl::<NodeFilter>().unwrap();
// See comments in compute_effects_region() for how this works.
@@ -441,7 +437,11 @@ impl FilterContext {
rv
} else {
f(Box::new(|length: &Length| {
- length.normalize(values, &draw_ctx.get_view_params())
+ // Filters use the properties of the target node.
+ length.normalize(
+ &self.computed_from_node_being_filtered,
+ &draw_ctx.get_view_params(),
+ )
}))
}
}
@@ -463,9 +463,6 @@ impl FilterContext {
let cr = cairo::Context::new(&surface);
draw_ctx.set_cairo_context(&cr);
- let cascaded = self.node_being_filtered.get_cascaded_values();
- let values = cascaded.get();
-
let bbox = draw_ctx.get_bbox().clone();
// FIXME: we are ignoring the following error; propagate it upstream
@@ -474,7 +471,7 @@ impl FilterContext {
paint_server,
&opacity,
&bbox,
- &values.color.0,
+ &self.computed_from_node_being_filtered.color.0,
).and_then(|had_paint_server| {
if had_paint_server {
cr.paint();
@@ -505,8 +502,7 @@ impl FilterContext {
}
}
- let cascaded = self.node_being_filtered.get_cascaded_values();
- let values = cascaded.get();
+ let values = &self.computed_from_node_being_filtered;
match *in_.unwrap() {
Input::SourceGraphic => Ok(FilterInput::StandardInput(self.source_graphic().clone())),
diff --git a/rsvg_internals/src/filters/image.rs b/rsvg_internals/src/filters/image.rs
index 47177e04..6d7e103a 100644
--- a/rsvg_internals/src/filters/image.rs
+++ b/rsvg_internals/src/filters/image.rs
@@ -69,9 +69,7 @@ impl Image {
draw_ctx.get_cairo_context().set_matrix(ctx.paffine());
- 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 node_being_filtered_values = ctx.get_computed_values_from_node_being_filtered();
let cascaded = CascadedValues::new_from_values(&drawable, node_being_filtered_values);
diff --git a/rsvg_internals/src/filters/mod.rs b/rsvg_internals/src/filters/mod.rs
index c3d70541..4cdccac3 100644
--- a/rsvg_internals/src/filters/mod.rs
+++ b/rsvg_internals/src/filters/mod.rs
@@ -14,7 +14,7 @@ use length::{Length, LengthDir, LengthUnit};
use node::{NodeResult, NodeTrait, NodeType, RsvgNode};
use parsers::{parse_and_validate, ParseError};
use property_bag::PropertyBag;
-use state::ColorInterpolationFilters;
+use state::{ColorInterpolationFilters, ComputedValues};
use surface_utils::shared_surface::{SharedImageSurface, SurfaceType};
mod bounds;
@@ -232,7 +232,7 @@ impl Deref for PrimitiveWithInput {
/// Applies a filter and returns the resulting surface.
pub fn render(
filter_node: &RsvgNode,
- node_being_filtered: &RsvgNode,
+ computed_from_node_being_filtered: &ComputedValues,
source: &cairo::ImageSurface,
draw_ctx: &mut DrawingCtx<'_>,
) -> cairo::ImageSurface {
@@ -254,8 +254,12 @@ pub fn render(
}
let source_surface = SharedImageSurface::new(source_surface, SurfaceType::SRgb).unwrap();
- let mut filter_ctx =
- FilterContext::new(filter_node, node_being_filtered, source_surface, draw_ctx);
+ let mut filter_ctx = FilterContext::new(
+ filter_node,
+ computed_from_node_being_filtered,
+ source_surface,
+ draw_ctx,
+ );
// If paffine is non-invertible, we won't draw anything. Also bbox combining in bounds
// computations will panic due to non-invertible martrix.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]