[librsvg: 5/23] Resolve filter primitives, then use static dispatch to render them




commit 3dd1911bd3c445e4257e860ecb083f0cfb1ac7a5
Author: Federico Mena Quintero <federico gnome org>
Date:   Thu Mar 11 12:56:11 2021 -0600

    Resolve filter primitives, then use static dispatch to render them
    
    The extremely ugly render_primitive() will get pretty once we are
    finished changing all the primitives to resolve their parameters.

 src/filters/blend.rs              |  6 ++--
 src/filters/color_matrix.rs       |  6 ++--
 src/filters/component_transfer.rs |  6 ++--
 src/filters/composite.rs          |  6 ++--
 src/filters/convolve_matrix.rs    |  6 ++--
 src/filters/displacement_map.rs   |  6 ++--
 src/filters/flood.rs              |  6 ++--
 src/filters/gaussian_blur.rs      |  6 ++--
 src/filters/image.rs              |  6 ++--
 src/filters/lighting.rs           |  6 ++--
 src/filters/merge.rs              |  6 ++--
 src/filters/mod.rs                | 72 +++++++++++++++++++++++++++++----------
 src/filters/morphology.rs         |  6 ++--
 src/filters/offset.rs             |  6 ++--
 src/filters/tile.rs               |  6 ++--
 src/filters/turbulence.rs         |  6 ++--
 16 files changed, 99 insertions(+), 63 deletions(-)
---
diff --git a/src/filters/blend.rs b/src/filters/blend.rs
index 81aa70a8..5940dbad 100755
--- a/src/filters/blend.rs
+++ b/src/filters/blend.rs
@@ -10,7 +10,7 @@ use crate::parsers::{Parse, ParseValue};
 use crate::xml::Attributes;
 
 use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, Input, Primitive, PrimitiveParams};
+use super::{FilterEffect, FilterError, Input, Primitive, PrimitiveParams};
 
 /// Enumeration of the possible blending modes.
 #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
@@ -72,8 +72,8 @@ impl SetAttributes for FeBlend {
     }
 }
 
-impl FilterRender for FeBlend {
-    fn render(
+impl FeBlend {
+    pub fn render(
         &self,
         node: &Node,
         ctx: &FilterContext,
diff --git a/src/filters/color_matrix.rs b/src/filters/color_matrix.rs
index 439e67e4..b318831f 100644
--- a/src/filters/color_matrix.rs
+++ b/src/filters/color_matrix.rs
@@ -15,7 +15,7 @@ use crate::util::clamp;
 use crate::xml::Attributes;
 
 use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, Input, Primitive, PrimitiveParams};
+use super::{FilterEffect, FilterError, Input, Primitive, PrimitiveParams};
 
 /// Color matrix operation types.
 #[derive(Debug, Clone, Copy, Eq, PartialEq)]
@@ -139,8 +139,8 @@ impl SetAttributes for FeColorMatrix {
     }
 }
 
-impl FilterRender for FeColorMatrix {
-    fn render(
+impl FeColorMatrix {
+    pub fn render(
         &self,
         node: &Node,
         ctx: &FilterContext,
diff --git a/src/filters/component_transfer.rs b/src/filters/component_transfer.rs
index ac670947..7b426150 100644
--- a/src/filters/component_transfer.rs
+++ b/src/filters/component_transfer.rs
@@ -16,7 +16,7 @@ use crate::util::clamp;
 use crate::xml::Attributes;
 
 use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, Input, Primitive, PrimitiveParams};
+use super::{FilterEffect, FilterError, Input, Primitive, PrimitiveParams};
 
 /// The `feComponentTransfer` filter primitive.
 pub struct FeComponentTransfer {
@@ -286,8 +286,8 @@ macro_rules! get_func_x_node {
     };
 }
 
-impl FilterRender for FeComponentTransfer {
-    fn render(
+impl FeComponentTransfer {
+    pub fn render(
         &self,
         node: &Node,
         ctx: &FilterContext,
diff --git a/src/filters/composite.rs b/src/filters/composite.rs
index 4efe68f2..d5fe198d 100644
--- a/src/filters/composite.rs
+++ b/src/filters/composite.rs
@@ -10,7 +10,7 @@ use crate::parsers::{Parse, ParseValue};
 use crate::xml::Attributes;
 
 use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, Input, Primitive, PrimitiveParams};
+use super::{FilterEffect, FilterError, Input, Primitive, PrimitiveParams};
 
 /// Enumeration of the possible compositing operations.
 #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
@@ -73,8 +73,8 @@ impl SetAttributes for FeComposite {
     }
 }
 
-impl FilterRender for FeComposite {
-    fn render(
+impl FeComposite {
+    pub fn render(
         &self,
         node: &Node,
         ctx: &FilterContext,
diff --git a/src/filters/convolve_matrix.rs b/src/filters/convolve_matrix.rs
index be66d3dd..fbc33546 100644
--- a/src/filters/convolve_matrix.rs
+++ b/src/filters/convolve_matrix.rs
@@ -20,7 +20,7 @@ use crate::util::clamp;
 use crate::xml::Attributes;
 
 use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, Input, Primitive, PrimitiveParams};
+use super::{FilterEffect, FilterError, Input, Primitive, PrimitiveParams};
 
 /// The `feConvolveMatrix` filter primitive.
 pub struct FeConvolveMatrix {
@@ -121,8 +121,8 @@ impl SetAttributes for FeConvolveMatrix {
     }
 }
 
-impl FilterRender for FeConvolveMatrix {
-    fn render(
+impl FeConvolveMatrix {
+    pub fn render(
         &self,
         node: &Node,
         ctx: &FilterContext,
diff --git a/src/filters/displacement_map.rs b/src/filters/displacement_map.rs
index 9641fd5a..f2aee635 100644
--- a/src/filters/displacement_map.rs
+++ b/src/filters/displacement_map.rs
@@ -12,7 +12,7 @@ use crate::surface_utils::{iterators::Pixels, shared_surface::ExclusiveImageSurf
 use crate::xml::Attributes;
 
 use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, Input, Primitive, PrimitiveParams};
+use super::{FilterEffect, FilterError, Input, Primitive, PrimitiveParams};
 
 /// Enumeration of the color channels the displacement map can source.
 #[derive(Clone, Copy)]
@@ -71,8 +71,8 @@ impl SetAttributes for FeDisplacementMap {
     }
 }
 
-impl FilterRender for FeDisplacementMap {
-    fn render(
+impl FeDisplacementMap {
+    pub fn render(
         &self,
         node: &Node,
         ctx: &FilterContext,
diff --git a/src/filters/flood.rs b/src/filters/flood.rs
index b4ac7925..6dece7b6 100644
--- a/src/filters/flood.rs
+++ b/src/filters/flood.rs
@@ -5,7 +5,7 @@ use crate::node::{CascadedValues, Node};
 use crate::xml::Attributes;
 
 use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, Primitive, PrimitiveParams};
+use super::{FilterEffect, FilterError, Primitive, PrimitiveParams};
 
 /// The `feFlood` filter primitive.
 pub struct FeFlood {
@@ -28,8 +28,8 @@ impl SetAttributes for FeFlood {
     }
 }
 
-impl FilterRender for FeFlood {
-    fn render(
+impl FeFlood {
+    pub fn render(
         &self,
         node: &Node,
         ctx: &FilterContext,
diff --git a/src/filters/gaussian_blur.rs b/src/filters/gaussian_blur.rs
index 4df2a86b..3351f9c4 100644
--- a/src/filters/gaussian_blur.rs
+++ b/src/filters/gaussian_blur.rs
@@ -17,7 +17,7 @@ use crate::surface_utils::{
 use crate::xml::Attributes;
 
 use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, Input, Primitive, PrimitiveParams};
+use super::{FilterEffect, FilterError, Input, Primitive, PrimitiveParams};
 
 /// The maximum gaussian blur kernel size.
 ///
@@ -187,8 +187,8 @@ fn gaussian_blur(
     )?)
 }
 
-impl FilterRender for FeGaussianBlur {
-    fn render(
+impl FeGaussianBlur {
+    pub fn render(
         &self,
         node: &Node,
         ctx: &FilterContext,
diff --git a/src/filters/image.rs b/src/filters/image.rs
index ddb6aca4..db2987a8 100644
--- a/src/filters/image.rs
+++ b/src/filters/image.rs
@@ -13,7 +13,7 @@ use crate::viewbox::ViewBox;
 use crate::xml::Attributes;
 
 use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, Primitive, PrimitiveParams};
+use super::{FilterEffect, FilterError, Primitive, PrimitiveParams};
 
 /// The `feImage` filter primitive.
 pub struct FeImage {
@@ -118,8 +118,8 @@ impl SetAttributes for FeImage {
     }
 }
 
-impl FilterRender for FeImage {
-    fn render(
+impl FeImage {
+    pub fn render(
         &self,
         _node: &Node,
         ctx: &FilterContext,
diff --git a/src/filters/lighting.rs b/src/filters/lighting.rs
index eb4a34bd..d23737a5 100644
--- a/src/filters/lighting.rs
+++ b/src/filters/lighting.rs
@@ -12,7 +12,7 @@ use crate::drawing_ctx::DrawingCtx;
 use crate::element::{Draw, Element, ElementResult, SetAttributes};
 use crate::filters::{
     context::{FilterContext, FilterOutput, FilterResult},
-    FilterEffect, FilterError, FilterRender, Input, Primitive, PrimitiveParams,
+    FilterEffect, FilterError, Input, Primitive, PrimitiveParams,
 };
 use crate::node::{CascadedValues, Node, NodeBorrow};
 use crate::parsers::{NonNegative, NumberOptionalNumber, ParseValue};
@@ -451,8 +451,8 @@ impl FeSpecularLighting {
 
 macro_rules! impl_lighting_filter {
     ($lighting_type:ty, $params_name:ident, $alpha_func:ident) => {
-        impl FilterRender for $lighting_type {
-            fn render(
+        impl $lighting_type {
+            pub fn render(
                 &self,
                 node: &Node,
                 ctx: &FilterContext,
diff --git a/src/filters/merge.rs b/src/filters/merge.rs
index d235b4d6..b1e0094e 100644
--- a/src/filters/merge.rs
+++ b/src/filters/merge.rs
@@ -11,7 +11,7 @@ use crate::surface_utils::shared_surface::{SharedImageSurface, SurfaceType};
 use crate::xml::Attributes;
 
 use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, Input, Primitive, PrimitiveParams};
+use super::{FilterEffect, FilterError, Input, Primitive, PrimitiveParams};
 
 /// The `feMerge` filter primitive.
 pub struct FeMerge {
@@ -83,8 +83,8 @@ impl FeMergeNode {
     }
 }
 
-impl FilterRender for FeMerge {
-    fn render(
+impl FeMerge {
+    pub fn render(
         &self,
         node: &Node,
         ctx: &FilterContext,
diff --git a/src/filters/mod.rs b/src/filters/mod.rs
index 3d6145e9..66e364f9 100644
--- a/src/filters/mod.rs
+++ b/src/filters/mod.rs
@@ -8,7 +8,7 @@ use crate::bbox::BoundingBox;
 use crate::coord_units::CoordUnits;
 use crate::document::AcquiredNodes;
 use crate::drawing_ctx::DrawingCtx;
-use crate::element::{Draw, ElementResult, SetAttributes};
+use crate::element::{Draw, Element, ElementResult, SetAttributes};
 use crate::error::{ElementError, ParseError, RenderingError};
 use crate::length::*;
 use crate::node::{Node, NodeBorrow};
@@ -28,23 +28,8 @@ use self::context::{FilterContext, FilterResult};
 mod error;
 use self::error::FilterError;
 
-/// Trait to render filter effect primitives.
-pub trait FilterRender {
-    /// Renders this filter primitive.
-    ///
-    /// 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: &Node,
-        ctx: &FilterContext,
-        acquired_nodes: &mut AcquiredNodes<'_>,
-        draw_ctx: &mut DrawingCtx,
-    ) -> Result<FilterResult, FilterError>;
-}
-
 /// A filter primitive interface.
-pub trait FilterEffect: SetAttributes + Draw + FilterRender {
+pub trait FilterEffect: SetAttributes + Draw {
     fn resolve(&self, node: &Node) -> Result<PrimitiveParams, FilterError>;
 }
 
@@ -67,6 +52,22 @@ pub mod offset;
 pub mod tile;
 pub mod turbulence;
 
+use blend::FeBlend;
+use color_matrix::FeColorMatrix;
+use component_transfer::FeComponentTransfer;
+use composite::FeComposite;
+use convolve_matrix::FeConvolveMatrix;
+use displacement_map::FeDisplacementMap;
+use flood::FeFlood;
+use gaussian_blur::FeGaussianBlur;
+use image::FeImage;
+use lighting::{FeDiffuseLighting, FeSpecularLighting};
+use merge::FeMerge;
+use morphology::FeMorphology;
+use offset::FeOffset;
+use tile::FeTile;
+use turbulence::FeTurbulence;
+
 /// Resolved parameters for each filter primitive.
 ///
 /// These gather all the data that a primitive may need during rendering:
@@ -287,7 +288,8 @@ pub fn render(
         let start = Instant::now();
 
         if let Err(err) = filter
-            .render(&c, &filter_ctx, acquired_nodes, draw_ctx)
+            .resolve(&c)
+            .and_then(|params| render_primitive(&c, params, &filter_ctx, acquired_nodes, draw_ctx))
             .and_then(|result| filter_ctx.store_result(result))
         {
             rsvg_log!("(filter primitive {} returned an error: {})", c, err);
@@ -309,6 +311,40 @@ pub fn render(
     Ok(filter_ctx.into_output()?)
 }
 
+#[rustfmt::skip]
+fn render_primitive(
+    node: &Node,
+    params: PrimitiveParams,
+    ctx: &FilterContext,
+    acquired_nodes: &mut AcquiredNodes<'_>,
+    draw_ctx: &mut DrawingCtx,
+) -> Result<FilterResult, FilterError> {
+    use PrimitiveParams::*;
+
+    let elt = node.borrow_element();
+    let elt = &*elt;
+
+    match (elt, params) {
+        (Element::FeBlend(ref inner), Blend(node))                         => 
FeBlend::render(&inner.element_impl, &node, ctx, acquired_nodes, draw_ctx),
+        (Element::FeColorMatrix(ref inner), ColorMatrix(node))             => 
FeColorMatrix::render(&inner.element_impl, &node, ctx, acquired_nodes, draw_ctx),
+        (Element::FeComponentTransfer(ref inner), ComponentTransfer(node)) => 
FeComponentTransfer::render(&inner.element_impl, &node, 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),
+        (Element::FeDisplacementMap(ref inner), DisplacementMap(node))     => 
FeDisplacementMap::render(&inner.element_impl, &node, ctx, acquired_nodes, draw_ctx),
+        (Element::FeFlood(ref inner), Flood(node))                         => 
FeFlood::render(&inner.element_impl, &node, ctx, acquired_nodes, draw_ctx),
+        (Element::FeGaussianBlur(ref inner), GaussianBlur(node))           => 
FeGaussianBlur::render(&inner.element_impl, &node, ctx, acquired_nodes, draw_ctx),
+        (Element::FeImage(ref inner), Image(node))                         => 
FeImage::render(&inner.element_impl, &node, ctx, acquired_nodes, draw_ctx),
+        (Element::FeMerge(ref inner), Merge(node))                         => 
FeMerge::render(&inner.element_impl, &node, ctx, acquired_nodes, draw_ctx),
+        (Element::FeMorphology(ref inner), Morphology(node))               => 
FeMorphology::render(&inner.element_impl, &node, ctx, acquired_nodes, draw_ctx),
+        (Element::FeOffset(ref inner), Offset(node))                       => 
FeOffset::render(&inner.element_impl, &node, ctx, acquired_nodes, draw_ctx),
+        (Element::FeSpecularLighting(ref inner), SpecularLighting(node))   => 
FeSpecularLighting::render(&inner.element_impl, &node, ctx, acquired_nodes, draw_ctx),
+        (Element::FeTile(ref inner), Tile(node))                           => 
FeTile::render(&inner.element_impl, &node, ctx, acquired_nodes, draw_ctx),
+        (Element::FeTurbulence(ref inner), Turbulence(node))               => 
FeTurbulence::render(&inner.element_impl, &node, ctx, acquired_nodes, draw_ctx),
+        (_, _) => unreachable!(),
+    }
+}
+
 impl From<ColorInterpolationFilters> for SurfaceType {
     fn from(c: ColorInterpolationFilters) -> Self {
         match c {
diff --git a/src/filters/morphology.rs b/src/filters/morphology.rs
index b45fe5d1..93c19641 100644
--- a/src/filters/morphology.rs
+++ b/src/filters/morphology.rs
@@ -19,7 +19,7 @@ use crate::surface_utils::{
 use crate::xml::Attributes;
 
 use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, Input, Primitive, PrimitiveParams};
+use super::{FilterEffect, FilterError, Input, Primitive, PrimitiveParams};
 
 /// Enumeration of the possible morphology operations.
 enum Operator {
@@ -67,8 +67,8 @@ impl SetAttributes for FeMorphology {
     }
 }
 
-impl FilterRender for FeMorphology {
-    fn render(
+impl FeMorphology {
+    pub fn render(
         &self,
         _node: &Node,
         ctx: &FilterContext,
diff --git a/src/filters/offset.rs b/src/filters/offset.rs
index f661d8c1..2109b677 100644
--- a/src/filters/offset.rs
+++ b/src/filters/offset.rs
@@ -9,7 +9,7 @@ use crate::property_defs::ColorInterpolationFilters;
 use crate::xml::Attributes;
 
 use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, Input, Primitive, PrimitiveParams};
+use super::{FilterEffect, FilterError, Input, Primitive, PrimitiveParams};
 
 /// The `feOffset` filter primitive.
 pub struct FeOffset {
@@ -48,8 +48,8 @@ impl SetAttributes for FeOffset {
     }
 }
 
-impl FilterRender for FeOffset {
-    fn render(
+impl FeOffset {
+    pub fn render(
         &self,
         _node: &Node,
         ctx: &FilterContext,
diff --git a/src/filters/tile.rs b/src/filters/tile.rs
index 0b15126a..102104b1 100644
--- a/src/filters/tile.rs
+++ b/src/filters/tile.rs
@@ -6,7 +6,7 @@ use crate::property_defs::ColorInterpolationFilters;
 use crate::xml::Attributes;
 
 use super::context::{FilterContext, FilterInput, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, Input, Primitive, PrimitiveParams};
+use super::{FilterEffect, FilterError, Input, Primitive, PrimitiveParams};
 
 /// The `feTile` filter primitive.
 pub struct FeTile {
@@ -32,8 +32,8 @@ impl SetAttributes for FeTile {
     }
 }
 
-impl FilterRender for FeTile {
-    fn render(
+impl FeTile {
+    pub fn render(
         &self,
         _node: &Node,
         ctx: &FilterContext,
diff --git a/src/filters/turbulence.rs b/src/filters/turbulence.rs
index 13c30fa9..be0c71b5 100644
--- a/src/filters/turbulence.rs
+++ b/src/filters/turbulence.rs
@@ -15,7 +15,7 @@ use crate::util::clamp;
 use crate::xml::Attributes;
 
 use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, Primitive, PrimitiveParams};
+use super::{FilterEffect, FilterError, Primitive, PrimitiveParams};
 
 /// Enumeration of the tile stitching modes.
 #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
@@ -323,8 +323,8 @@ impl NoiseGenerator {
     }
 }
 
-impl FilterRender for FeTurbulence {
-    fn render(
+impl FeTurbulence {
+    pub fn render(
         &self,
         node: &Node,
         ctx: &FilterContext,


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