[librsvg: 8/23] feComponentTransfer - resolve and render separately




commit 23d2edd877e42950a8ed0eb1d13b8f9434e0f077
Author: Federico Mena Quintero <federico gnome org>
Date:   Thu Mar 11 13:25:20 2021 -0600

    feComponentTransfer - resolve and render separately

 src/filters/component_transfer.rs | 49 +++++++++++++++++++++++++--------------
 src/filters/mod.rs                |  5 ++--
 2 files changed, 34 insertions(+), 20 deletions(-)
---
diff --git a/src/filters/component_transfer.rs b/src/filters/component_transfer.rs
index 7b426150..ec8f7403 100644
--- a/src/filters/component_transfer.rs
+++ b/src/filters/component_transfer.rs
@@ -9,6 +9,7 @@ use crate::element::{Draw, Element, ElementResult, SetAttributes};
 use crate::error::*;
 use crate::node::{CascadedValues, Node, NodeBorrow};
 use crate::parsers::{NumberList, NumberListLength, Parse, ParseValue};
+use crate::property_defs::ColorInterpolationFilters;
 use crate::surface_utils::{
     iterators::Pixels, shared_surface::ExclusiveImageSurface, ImageSurfaceDataExt, Pixel,
 };
@@ -24,6 +25,14 @@ pub struct FeComponentTransfer {
     in1: Input,
 }
 
+/// Resolved `feComponentTransfer` primitive for rendering.
+pub struct ComponentTransfer {
+    base: Primitive,
+    in1: Input,
+    functions: Functions,
+    color_interpolation_filters: ColorInterpolationFilters,
+}
+
 impl Default for FeComponentTransfer {
     /// Constructs a new `ComponentTransfer` with empty properties.
     #[inline]
@@ -286,21 +295,19 @@ macro_rules! get_func_x_node {
     };
 }
 
-impl FeComponentTransfer {
+impl ComponentTransfer {
     pub fn render(
         &self,
-        node: &Node,
         ctx: &FilterContext,
         acquired_nodes: &mut AcquiredNodes<'_>,
         draw_ctx: &mut DrawingCtx,
     ) -> Result<FilterResult, FilterError> {
-        let cascaded = CascadedValues::new_from_node(node);
-        let values = cascaded.get();
-        let cif = values.color_interpolation_filters();
-
-        let functions = get_parameters(node)?;
-
-        let input_1 = ctx.get_input(acquired_nodes, draw_ctx, &self.in1, cif)?;
+        let input_1 = ctx.get_input(
+            acquired_nodes,
+            draw_ctx,
+            &self.in1,
+            self.color_interpolation_filters,
+        )?;
         let bounds = self
             .base
             .get_bounds(ctx)?
@@ -334,13 +341,13 @@ impl FeComponentTransfer {
             }
         }
 
-        let compute_r = compute_func::<FeFuncR>(&functions.r);
-        let compute_g = compute_func::<FeFuncG>(&functions.g);
-        let compute_b = compute_func::<FeFuncB>(&functions.b);
+        let compute_r = compute_func::<FeFuncR>(&self.functions.r);
+        let compute_g = compute_func::<FeFuncG>(&self.functions.g);
+        let compute_b = compute_func::<FeFuncB>(&self.functions.b);
 
         // Alpha gets special handling since everything else depends on it.
-        let compute_a = functions.a.function();
-        let params_a = functions.a.function_parameters();
+        let compute_a = self.functions.a.function();
+        let params_a = self.functions.a.function_parameters();
         let compute_a = |alpha| compute_a(&params_a, alpha);
 
         // Do the actual processing.
@@ -372,12 +379,20 @@ impl FeComponentTransfer {
 
 impl FilterEffect for FeComponentTransfer {
     fn resolve(&self, node: &Node) -> Result<PrimitiveParams, FilterError> {
-        Ok(PrimitiveParams::ComponentTransfer(node.clone()))
+        let cascaded = CascadedValues::new_from_node(node);
+        let values = cascaded.get();
+
+        Ok(PrimitiveParams::ComponentTransfer(ComponentTransfer {
+            base: self.base.clone(),
+            in1: self.in1.clone(),
+            functions: get_functions(node)?,
+            color_interpolation_filters: values.color_interpolation_filters(),
+        }))
     }
 }
 
 /// Takes a feComponentTransfer and walks its children to produce the feFuncX arguments.
-fn get_parameters(node: &Node) -> Result<Functions, FilterError> {
+fn get_functions(node: &Node) -> Result<Functions, FilterError> {
     let func_r_node = get_func_x_node!(node, FeFuncR, Channel::R);
     let func_g_node = get_func_x_node!(node, FeFuncG, Channel::G);
     let func_b_node = get_func_x_node!(node, FeFuncB, Channel::B);
@@ -428,7 +443,7 @@ mod tests {
         );
 
         let component_transfer = document.lookup_internal_node("component_transfer").unwrap();
-        let functions = get_parameters(&component_transfer).unwrap();
+        let functions = get_functions(&component_transfer).unwrap();
 
         assert_eq!(
             functions,
diff --git a/src/filters/mod.rs b/src/filters/mod.rs
index 4803d26a..955f572c 100644
--- a/src/filters/mod.rs
+++ b/src/filters/mod.rs
@@ -52,7 +52,6 @@ pub mod offset;
 pub mod tile;
 pub mod turbulence;
 
-use component_transfer::FeComponentTransfer;
 use composite::FeComposite;
 use convolve_matrix::FeConvolveMatrix;
 use displacement_map::FeDisplacementMap;
@@ -75,7 +74,7 @@ use turbulence::FeTurbulence;
 pub enum PrimitiveParams {
     Blend(blend::Blend),
     ColorMatrix(color_matrix::ColorMatrix),
-    ComponentTransfer(Node),
+    ComponentTransfer(component_transfer::ComponentTransfer),
     Composite(Node),
     ConvolveMatrix(Node),
     DiffuseLighting(Node),
@@ -326,7 +325,7 @@ fn render_primitive(
     match (elt, params) {
         (Element::FeBlend(_), Blend(p))                         => p.render(ctx, acquired_nodes, draw_ctx),
         (Element::FeColorMatrix(_), ColorMatrix(p))             => p.render(ctx, acquired_nodes, draw_ctx),
-        (Element::FeComponentTransfer(ref inner), ComponentTransfer(node)) => 
FeComponentTransfer::render(&inner.element_impl, &node, ctx, acquired_nodes, draw_ctx),
+        (Element::FeComponentTransfer(_), ComponentTransfer(p)) => p.render(ctx, acquired_nodes, draw_ctx),
         (Element::FeComposite(ref inner), Composite(node))                 => 
FeComposite::render(&inner.element_impl, &node, ctx, acquired_nodes, draw_ctx),
         (Element::FeConvolveMatrix(ref inner), ConvolveMatrix(node))       => 
FeConvolveMatrix::render(&inner.element_impl, &node, ctx, acquired_nodes, draw_ctx),
         (Element::FeDiffuseLighting(ref inner), DiffuseLighting(node))     => 
FeDiffuseLighting::render(&inner.element_impl, &node, ctx, acquired_nodes, draw_ctx),


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]