[librsvg/librsvg-2.44] 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/librsvg-2.44] filters::render() - Take the computed values of the node being filtered, not the whole node
- Date: Fri, 21 Sep 2018 17:37:15 +0000 (UTC)
commit 7da833917b5633f012b0bdf3fc9c13b0601e589f
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 | 36 ++++++++++++++---------------------
rsvg_internals/src/filters/image.rs | 4 +---
rsvg_internals/src/filters/mod.rs | 12 ++++++++----
4 files changed, 24 insertions(+), 30 deletions(-)
---
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index 5d831c78..2267a7ff 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -360,7 +360,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 ad7c5d80..56a07c84 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();
@@ -195,7 +195,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 {
@@ -248,14 +248,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),
@@ -267,10 +267,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.
@@ -429,10 +429,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.
@@ -444,7 +440,7 @@ impl FilterContext {
rv
} else {
f(Box::new(|length: &Length| {
- length.normalize(values, draw_ctx)
+ length.normalize(&self.computed_from_node_being_filtered, draw_ctx)
}))
}
}
@@ -466,9 +462,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
@@ -477,7 +470,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();
@@ -508,8 +501,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 2dc0360f..f39f2235 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 a685f317..e0c1d9c4 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;
@@ -227,7 +227,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 {
@@ -249,8 +249,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]