diff options
author | John Ledbetter <john.ledbetter@gmail.com> | 2021-06-10 09:21:09 -0400 |
---|---|---|
committer | Federico Mena Quintero <federico@gnome.org> | 2023-02-09 13:15:53 -0600 |
commit | c5025d955b364b46a8062764e9057123d6fe8a58 (patch) | |
tree | f9660434c7adff9d72ada34832f97dc7dd3d96dc | |
parent | 91c059331352775e879f3dea13c68b52965ae901 (diff) | |
download | librsvg-c5025d955b364b46a8062764e9057123d6fe8a58.tar.gz |
FilterEffect::resolve: return Array of ResolvedPrimitives
This change allows us to return filters composed of multiple
ResolvedPrimitives, specifically for the FeDropShadow filter element.
Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/793>
-rw-r--r-- | src/filter.rs | 52 | ||||
-rw-r--r-- | src/filters/blend.rs | 6 | ||||
-rw-r--r-- | src/filters/color_matrix.rs | 6 | ||||
-rw-r--r-- | src/filters/component_transfer.rs | 6 | ||||
-rw-r--r-- | src/filters/composite.rs | 6 | ||||
-rw-r--r-- | src/filters/convolve_matrix.rs | 6 | ||||
-rw-r--r-- | src/filters/displacement_map.rs | 6 | ||||
-rw-r--r-- | src/filters/flood.rs | 6 | ||||
-rw-r--r-- | src/filters/gaussian_blur.rs | 6 | ||||
-rw-r--r-- | src/filters/image.rs | 6 | ||||
-rw-r--r-- | src/filters/lighting.rs | 18 | ||||
-rw-r--r-- | src/filters/merge.rs | 9 | ||||
-rw-r--r-- | src/filters/mod.rs | 2 | ||||
-rw-r--r-- | src/filters/morphology.rs | 6 | ||||
-rw-r--r-- | src/filters/offset.rs | 6 | ||||
-rw-r--r-- | src/filters/tile.rs | 6 | ||||
-rw-r--r-- | src/filters/turbulence.rs | 6 |
17 files changed, 83 insertions, 76 deletions
diff --git a/src/filter.rs b/src/filter.rs index ebab3099..9f7d5312 100644 --- a/src/filter.rs +++ b/src/filter.rs @@ -10,7 +10,7 @@ use crate::drawing_ctx::{DrawingCtx, ViewParams}; use crate::element::{set_attribute, Draw, Element, SetAttributes}; use crate::error::ValueErrorKind; use crate::filter_func::FilterFunction; -use crate::filters::{FilterResolveError, FilterSpec, UserSpacePrimitive}; +use crate::filters::{FilterResolveError, FilterSpec}; use crate::length::*; use crate::node::{Node, NodeBorrow}; use crate::parsers::{Parse, ParseValue}; @@ -179,38 +179,44 @@ fn extract_filter_from_filter_node( let primitive_view_params = filter_view_params.get(user_space_filter.primitive_units); - let primitives = filter_node + let primitive_nodes = filter_node .children() .filter(|c| c.is_element()) // Keep only filter primitives (those that implement the Filter trait) - .filter(|c| c.borrow_element().as_filter_effect().is_some()) - .map(|primitive_node| { - let elt = primitive_node.borrow_element(); - let effect = elt.as_filter_effect().unwrap(); + .filter(|c| c.borrow_element().as_filter_effect().is_some()); - let primitive_name = format!("{primitive_node}"); + let mut user_space_primitives = Vec::new(); - let primitive_values = elt.get_computed_values(); - let params = NormalizeParams::new(primitive_values, primitive_view_params); + for primitive_node in primitive_nodes { + let elt = primitive_node.borrow_element(); + let effect = elt.as_filter_effect().unwrap(); - effect - .resolve(acquired_nodes, &primitive_node) - .map_err(|e| { - rsvg_log!( - session, - "(filter primitive {} returned an error: {})", - primitive_name, - e - ); + let primitive_name = format!("{primitive_node}"); + + let primitive_values = elt.get_computed_values(); + let params = NormalizeParams::new(primitive_values, primitive_view_params); + + let primitives = match effect.resolve(acquired_nodes, &primitive_node) { + Ok(primitives) => primitives, + Err(e) => { + rsvg_log!( + session, + "(filter primitive {} returned an error: {})", + primitive_name, e - }) - .map(|primitive| primitive.into_user_space(¶ms)) - }) - .collect::<Result<Vec<UserSpacePrimitive>, FilterResolveError>>()?; + ); + return Err(e); + } + }; + + for p in primitives { + user_space_primitives.push(p.into_user_space(¶ms)); + } + } Ok(FilterSpec { user_space_filter, - primitives, + primitives: user_space_primitives, }) } diff --git a/src/filters/blend.rs b/src/filters/blend.rs index 4baf4476..28a8be25 100644 --- a/src/filters/blend.rs +++ b/src/filters/blend.rs @@ -113,17 +113,17 @@ impl FilterEffect for FeBlend { &self, _acquired_nodes: &mut AcquiredNodes<'_>, node: &Node, - ) -> Result<ResolvedPrimitive, FilterResolveError> { + ) -> Result<Vec<ResolvedPrimitive>, FilterResolveError> { let cascaded = CascadedValues::new_from_node(node); let values = cascaded.get(); let mut params = self.params.clone(); params.color_interpolation_filters = values.color_interpolation_filters(); - Ok(ResolvedPrimitive { + Ok(vec![ResolvedPrimitive { primitive: self.base.clone(), params: PrimitiveParams::Blend(params), - }) + }]) } } diff --git a/src/filters/color_matrix.rs b/src/filters/color_matrix.rs index 7bb3689f..b06cac1f 100644 --- a/src/filters/color_matrix.rs +++ b/src/filters/color_matrix.rs @@ -315,17 +315,17 @@ impl FilterEffect for FeColorMatrix { &self, _acquired_nodes: &mut AcquiredNodes<'_>, node: &Node, - ) -> Result<ResolvedPrimitive, FilterResolveError> { + ) -> Result<Vec<ResolvedPrimitive>, FilterResolveError> { let cascaded = CascadedValues::new_from_node(node); let values = cascaded.get(); let mut params = self.params.clone(); params.color_interpolation_filters = values.color_interpolation_filters(); - Ok(ResolvedPrimitive { + Ok(vec![ResolvedPrimitive { primitive: self.base.clone(), params: PrimitiveParams::ColorMatrix(params), - }) + }]) } } diff --git a/src/filters/component_transfer.rs b/src/filters/component_transfer.rs index 02efa6ca..ae358d72 100644 --- a/src/filters/component_transfer.rs +++ b/src/filters/component_transfer.rs @@ -385,7 +385,7 @@ impl FilterEffect for FeComponentTransfer { &self, _acquired_nodes: &mut AcquiredNodes<'_>, node: &Node, - ) -> Result<ResolvedPrimitive, FilterResolveError> { + ) -> Result<Vec<ResolvedPrimitive>, FilterResolveError> { let cascaded = CascadedValues::new_from_node(node); let values = cascaded.get(); @@ -393,10 +393,10 @@ impl FilterEffect for FeComponentTransfer { params.functions = get_functions(node)?; params.color_interpolation_filters = values.color_interpolation_filters(); - Ok(ResolvedPrimitive { + Ok(vec![ResolvedPrimitive { primitive: self.base.clone(), params: PrimitiveParams::ComponentTransfer(params), - }) + }]) } } diff --git a/src/filters/composite.rs b/src/filters/composite.rs index c05468e8..2be0e261 100644 --- a/src/filters/composite.rs +++ b/src/filters/composite.rs @@ -133,17 +133,17 @@ impl FilterEffect for FeComposite { &self, _acquired_nodes: &mut AcquiredNodes<'_>, node: &Node, - ) -> Result<ResolvedPrimitive, FilterResolveError> { + ) -> Result<Vec<ResolvedPrimitive>, FilterResolveError> { let cascaded = CascadedValues::new_from_node(node); let values = cascaded.get(); let mut params = self.params.clone(); params.color_interpolation_filters = values.color_interpolation_filters(); - Ok(ResolvedPrimitive { + Ok(vec![ResolvedPrimitive { primitive: self.base.clone(), params: PrimitiveParams::Composite(params), - }) + }]) } } diff --git a/src/filters/convolve_matrix.rs b/src/filters/convolve_matrix.rs index db9dc047..a445e733 100644 --- a/src/filters/convolve_matrix.rs +++ b/src/filters/convolve_matrix.rs @@ -321,17 +321,17 @@ impl FilterEffect for FeConvolveMatrix { &self, _acquired_nodes: &mut AcquiredNodes<'_>, node: &Node, - ) -> Result<ResolvedPrimitive, FilterResolveError> { + ) -> Result<Vec<ResolvedPrimitive>, FilterResolveError> { let cascaded = CascadedValues::new_from_node(node); let values = cascaded.get(); let mut params = self.params.clone(); params.color_interpolation_filters = values.color_interpolation_filters(); - Ok(ResolvedPrimitive { + Ok(vec![ResolvedPrimitive { primitive: self.base.clone(), params: PrimitiveParams::ConvolveMatrix(params), - }) + }]) } } diff --git a/src/filters/displacement_map.rs b/src/filters/displacement_map.rs index d8781d80..e3396e5a 100644 --- a/src/filters/displacement_map.rs +++ b/src/filters/displacement_map.rs @@ -168,17 +168,17 @@ impl FilterEffect for FeDisplacementMap { &self, _acquired_nodes: &mut AcquiredNodes<'_>, node: &Node, - ) -> Result<ResolvedPrimitive, FilterResolveError> { + ) -> Result<Vec<ResolvedPrimitive>, FilterResolveError> { let cascaded = CascadedValues::new_from_node(node); let values = cascaded.get(); let mut params = self.params.clone(); params.color_interpolation_filters = values.color_interpolation_filters(); - Ok(ResolvedPrimitive { + Ok(vec![ResolvedPrimitive { primitive: self.base.clone(), params: PrimitiveParams::DisplacementMap(params), - }) + }]) } } diff --git a/src/filters/flood.rs b/src/filters/flood.rs index 50838207..cd158f62 100644 --- a/src/filters/flood.rs +++ b/src/filters/flood.rs @@ -52,11 +52,11 @@ impl FilterEffect for FeFlood { &self, _acquired_nodes: &mut AcquiredNodes<'_>, node: &Node, - ) -> Result<ResolvedPrimitive, FilterResolveError> { + ) -> Result<Vec<ResolvedPrimitive>, FilterResolveError> { let cascaded = CascadedValues::new_from_node(node); let values = cascaded.get(); - Ok(ResolvedPrimitive { + Ok(vec![ResolvedPrimitive { primitive: self.base.clone(), params: PrimitiveParams::Flood(Flood { color: resolve_color( @@ -65,6 +65,6 @@ impl FilterEffect for FeFlood { values.color().0, ), }), - }) + }]) } } diff --git a/src/filters/gaussian_blur.rs b/src/filters/gaussian_blur.rs index d44e5ae0..e6ae3b68 100644 --- a/src/filters/gaussian_blur.rs +++ b/src/filters/gaussian_blur.rs @@ -271,16 +271,16 @@ impl FilterEffect for FeGaussianBlur { &self, _acquired_nodes: &mut AcquiredNodes<'_>, node: &Node, - ) -> Result<ResolvedPrimitive, FilterResolveError> { + ) -> Result<Vec<ResolvedPrimitive>, FilterResolveError> { let cascaded = CascadedValues::new_from_node(node); let values = cascaded.get(); let mut params = self.params.clone(); params.color_interpolation_filters = values.color_interpolation_filters(); - Ok(ResolvedPrimitive { + Ok(vec![ResolvedPrimitive { primitive: self.base.clone(), params: PrimitiveParams::GaussianBlur(params), - }) + }]) } } diff --git a/src/filters/image.rs b/src/filters/image.rs index a926c952..c3f19c8f 100644 --- a/src/filters/image.rs +++ b/src/filters/image.rs @@ -180,7 +180,7 @@ impl FilterEffect for FeImage { &self, acquired_nodes: &mut AcquiredNodes<'_>, node: &Node, - ) -> Result<ResolvedPrimitive, FilterResolveError> { + ) -> Result<Vec<ResolvedPrimitive>, FilterResolveError> { let cascaded = CascadedValues::new_from_node(node); let feimage_values = cascaded.get().clone(); @@ -199,13 +199,13 @@ impl FilterEffect for FeImage { } }; - Ok(ResolvedPrimitive { + Ok(vec![ResolvedPrimitive { primitive: self.base.clone(), params: PrimitiveParams::Image(Image { aspect: self.params.aspect, source, feimage_values: Box::new(feimage_values), }), - }) + }]) } } diff --git a/src/filters/lighting.rs b/src/filters/lighting.rs index e222de22..6a0b52ee 100644 --- a/src/filters/lighting.rs +++ b/src/filters/lighting.rs @@ -705,7 +705,7 @@ macro_rules! impl_lighting_filter { &self, _acquired_nodes: &mut AcquiredNodes<'_>, node: &Node, - ) -> Result<ResolvedPrimitive, FilterResolveError> { + ) -> Result<Vec<ResolvedPrimitive>, FilterResolveError> { let mut sources = node.children().rev().filter(|c| { c.is_element() && matches!( @@ -740,7 +740,7 @@ macro_rules! impl_lighting_filter { let cascaded = CascadedValues::new_from_node(node); let values = cascaded.get(); - Ok(ResolvedPrimitive { + Ok(vec![ResolvedPrimitive { primitive: self.base.clone(), params: PrimitiveParams::$params_name($params_name { params: self.params.clone(), @@ -754,7 +754,7 @@ macro_rules! impl_lighting_filter { color_interpolation_filters: values.color_interpolation_filters(), }, }), - }) + }]) } } }; @@ -1045,8 +1045,8 @@ mod tests { let node = document.lookup_internal_node("diffuse_distant").unwrap(); let lighting = borrow_element_as!(node, FeDiffuseLighting); - let ResolvedPrimitive { params, .. } = - lighting.resolve(&mut acquired_nodes, &node).unwrap(); + let resolved = lighting.resolve(&mut acquired_nodes, &node).unwrap(); + let ResolvedPrimitive { params, .. } = resolved.first().unwrap(); let diffuse_lighting = match params { PrimitiveParams::DiffuseLighting(l) => l, _ => unreachable!(), @@ -1061,8 +1061,8 @@ mod tests { let node = document.lookup_internal_node("specular_point").unwrap(); let lighting = borrow_element_as!(node, FeSpecularLighting); - let ResolvedPrimitive { params, .. } = - lighting.resolve(&mut acquired_nodes, &node).unwrap(); + let resolved = lighting.resolve(&mut acquired_nodes, &node).unwrap(); + let ResolvedPrimitive { params, .. } = resolved.first().unwrap(); let specular_lighting = match params { PrimitiveParams::SpecularLighting(l) => l, _ => unreachable!(), @@ -1078,8 +1078,8 @@ mod tests { let node = document.lookup_internal_node("diffuse_spot").unwrap(); let lighting = borrow_element_as!(node, FeDiffuseLighting); - let ResolvedPrimitive { params, .. } = - lighting.resolve(&mut acquired_nodes, &node).unwrap(); + let resolved = lighting.resolve(&mut acquired_nodes, &node).unwrap(); + let ResolvedPrimitive { params, .. } = resolved.first().unwrap(); let diffuse_lighting = match params { PrimitiveParams::DiffuseLighting(l) => l, _ => unreachable!(), diff --git a/src/filters/merge.rs b/src/filters/merge.rs index 56292406..f76f9dd0 100644 --- a/src/filters/merge.rs +++ b/src/filters/merge.rs @@ -145,13 +145,13 @@ impl FilterEffect for FeMerge { &self, _acquired_nodes: &mut AcquiredNodes<'_>, node: &Node, - ) -> Result<ResolvedPrimitive, FilterResolveError> { - Ok(ResolvedPrimitive { + ) -> Result<Vec<ResolvedPrimitive>, FilterResolveError> { + Ok(vec![ResolvedPrimitive { primitive: self.base.clone(), params: PrimitiveParams::Merge(Merge { merge_nodes: resolve_merge_nodes(node)?, }), - }) + }]) } } @@ -199,7 +199,8 @@ mod tests { let node = document.lookup_internal_node("merge").unwrap(); let merge = borrow_element_as!(node, FeMerge); - let ResolvedPrimitive { params, .. } = merge.resolve(&mut acquired_nodes, &node).unwrap(); + let resolved = merge.resolve(&mut acquired_nodes, &node).unwrap(); + let ResolvedPrimitive { params, .. } = resolved.first().unwrap(); let params = match params { PrimitiveParams::Merge(m) => m, _ => unreachable!(), diff --git a/src/filters/mod.rs b/src/filters/mod.rs index 0bd1cefa..8b0f37d5 100644 --- a/src/filters/mod.rs +++ b/src/filters/mod.rs @@ -37,7 +37,7 @@ pub trait FilterEffect: SetAttributes + Draw { &self, acquired_nodes: &mut AcquiredNodes<'_>, node: &Node, - ) -> Result<ResolvedPrimitive, FilterResolveError>; + ) -> Result<Vec<ResolvedPrimitive>, FilterResolveError>; } // Filter Effects do not need to draw themselves diff --git a/src/filters/morphology.rs b/src/filters/morphology.rs index 519efca7..b69b01d4 100644 --- a/src/filters/morphology.rs +++ b/src/filters/morphology.rs @@ -181,11 +181,11 @@ impl FilterEffect for FeMorphology { &self, _acquired_nodes: &mut AcquiredNodes<'_>, _node: &Node, - ) -> Result<ResolvedPrimitive, FilterResolveError> { - Ok(ResolvedPrimitive { + ) -> Result<Vec<ResolvedPrimitive>, FilterResolveError> { + Ok(vec![ResolvedPrimitive { primitive: self.base.clone(), params: PrimitiveParams::Morphology(self.params.clone()), - }) + }]) } } diff --git a/src/filters/offset.rs b/src/filters/offset.rs index 27698b05..49a2be19 100644 --- a/src/filters/offset.rs +++ b/src/filters/offset.rs @@ -91,10 +91,10 @@ impl FilterEffect for FeOffset { &self, _acquired_nodes: &mut AcquiredNodes<'_>, _node: &Node, - ) -> Result<ResolvedPrimitive, FilterResolveError> { - Ok(ResolvedPrimitive { + ) -> Result<Vec<ResolvedPrimitive>, FilterResolveError> { + Ok(vec![ResolvedPrimitive { primitive: self.base.clone(), params: PrimitiveParams::Offset(self.params.clone()), - }) + }]) } } diff --git a/src/filters/tile.rs b/src/filters/tile.rs index e3bf940a..358b996b 100644 --- a/src/filters/tile.rs +++ b/src/filters/tile.rs @@ -100,10 +100,10 @@ impl FilterEffect for FeTile { &self, _acquired_nodes: &mut AcquiredNodes<'_>, _node: &Node, - ) -> Result<ResolvedPrimitive, FilterResolveError> { - Ok(ResolvedPrimitive { + ) -> Result<Vec<ResolvedPrimitive>, FilterResolveError> { + Ok(vec![ResolvedPrimitive { primitive: self.base.clone(), params: PrimitiveParams::Tile(self.params.clone()), - }) + }]) } } diff --git a/src/filters/turbulence.rs b/src/filters/turbulence.rs index 32035f5d..191c51ae 100644 --- a/src/filters/turbulence.rs +++ b/src/filters/turbulence.rs @@ -432,17 +432,17 @@ impl FilterEffect for FeTurbulence { &self, _acquired_nodes: &mut AcquiredNodes<'_>, node: &Node, - ) -> Result<ResolvedPrimitive, FilterResolveError> { + ) -> Result<Vec<ResolvedPrimitive>, FilterResolveError> { let cascaded = CascadedValues::new_from_node(node); let values = cascaded.get(); let mut params = self.params.clone(); params.color_interpolation_filters = values.color_interpolation_filters(); - Ok(ResolvedPrimitive { + Ok(vec![ResolvedPrimitive { primitive: self.base.clone(), params: PrimitiveParams::Turbulence(params), - }) + }]) } } |