diff options
author | Federico Mena Quintero <federico@gnome.org> | 2022-09-23 20:13:50 -0500 |
---|---|---|
committer | Federico Mena Quintero <federico@gnome.org> | 2022-09-23 20:13:50 -0500 |
commit | d113483f159a00222349f1b6c852b81a0c64e7a7 (patch) | |
tree | a141559c285e737a38fce530e1e8a97762e834f7 | |
parent | 193efe7d4519df7bbae5dca1ec2f599183116ba8 (diff) | |
download | librsvg-d113483f159a00222349f1b6c852b81a0c64e7a7.tar.gz |
Log an error when a filter value cannot be resolved
Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/753>
-rw-r--r-- | src/drawing_ctx.rs | 58 |
1 files changed, 39 insertions, 19 deletions
diff --git a/src/drawing_ctx.rs b/src/drawing_ctx.rs index 6eb200b3..3a617e06 100644 --- a/src/drawing_ctx.rs +++ b/src/drawing_ctx.rs @@ -970,7 +970,15 @@ impl DrawingCtx { current_color: RGBA, node_bbox: BoundingBox, ) -> Result<SharedImageSurface, RenderingError> { - let surface = if let Ok(specs) = filter_list + // We try to convert each item in the filter_list to a FilterSpec. + // + // However, the spec mentions, "If the filter references a non-existent object or + // the referenced object is not a filter element, then the whole filter chain is + // ignored." - https://www.w3.org/TR/filter-effects/#FilterProperty + // + // So, run through the filter_list and collect into a Result<Vec<FilterSpec>>. + // This will return an Err if any of the conversions failed. + let filter_specs = filter_list .iter() .map(|filter_value| { filter_value.to_filter_spec( @@ -981,25 +989,37 @@ impl DrawingCtx { node_name, ) }) - .collect::<Result<Vec<FilterSpec>, _>>() - { - specs.iter().try_fold(surface_to_filter, |surface, spec| { - filters::render( - spec, - stroke_paint_source.clone(), - fill_paint_source.clone(), - surface, - acquired_nodes, - self, - self.get_transform(), - node_bbox, - ) - })? - } else { - surface_to_filter - }; + .collect::<Result<Vec<FilterSpec>, _>>(); + + match filter_specs { + Ok(specs) => { + // Start with the surface_to_filter, and apply each filter spec in turn; + // the final result is our return value. + specs.iter().try_fold(surface_to_filter, |surface, spec| { + filters::render( + spec, + stroke_paint_source.clone(), + fill_paint_source.clone(), + surface, + acquired_nodes, + self, + self.get_transform(), + node_bbox, + ) + }) + } - Ok(surface) + Err(e) => { + rsvg_log!( + self.session, + "not rendering filter list on node {} because it was in error: {}", + node_name, + e + ); + // just return the original surface without filtering it + Ok(surface_to_filter) + } + } } fn set_gradient(&mut self, gradient: &UserSpaceGradient) -> Result<(), cairo::Error> { |