diff options
author | Federico Mena Quintero <federico@gnome.org> | 2023-03-22 12:44:06 -0600 |
---|---|---|
committer | Marge Bot <marge-bot@gnome.org> | 2023-03-23 01:41:14 +0000 |
commit | 50eee1991e092671d7702a6ef7ebd569502cd447 (patch) | |
tree | 626f94849aa6f1bb2e1e2f50fc564101148bb624 | |
parent | ce3b71599a5fa077f85fc19204ebacb5d5e32bb6 (diff) | |
download | librsvg-50eee1991e092671d7702a6ef7ebd569502cd447.tar.gz |
StackingCtx: decide whether there are filters at all right here, not in DrawingCtx
We used to have
struct StackingCtx {
filter: Filter
}
struct Filter {
filter: properties::Filter,
// other gunk
}
and there, Filter.filter can be properties::Filter::None or
properties::Filter::List(FilterValueList).
Resolve this early into an Option<Filter>, like this:
struct StackingCtx {
filter: Option<Filter>
}
struct Filter {
filter_list: FilterValueList,
// other gunk
}
This way, subsequent code in DrawingCtx doesn't have to tear apart the
Filter.filter to see whether there's actually a filter specification
there or just "none".
Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/816>
-rw-r--r-- | src/drawing_ctx.rs | 20 | ||||
-rw-r--r-- | src/layout.rs | 29 |
2 files changed, 27 insertions, 22 deletions
diff --git a/src/drawing_ctx.rs b/src/drawing_ctx.rs index 8ef328a6..cdb84f16 100644 --- a/src/drawing_ctx.rs +++ b/src/drawing_ctx.rs @@ -34,8 +34,8 @@ use crate::paint_server::{PaintSource, UserSpacePaintSource}; use crate::path_builder::*; use crate::pattern::UserSpacePattern; use crate::properties::{ - ClipRule, ComputedValues, FillRule, Filter, MaskType, MixBlendMode, Opacity, Overflow, - PaintTarget, ShapeRendering, StrokeLinecap, StrokeLinejoin, TextRendering, + ClipRule, ComputedValues, FillRule, MaskType, MixBlendMode, Opacity, Overflow, PaintTarget, + ShapeRendering, StrokeLinecap, StrokeLinejoin, TextRendering, }; use crate::rect::{rect_to_transform, IRect, Rect}; use crate::session::Session; @@ -765,12 +765,12 @@ impl DrawingCtx { // Create temporary surface and its cr - let cr = match stacking_ctx.filter.filter { - Filter::None => cairo::Context::new( + let cr = match stacking_ctx.filter { + None => cairo::Context::new( &self .create_similar_surface_for_toplevel_viewport(&self.cr.target())?, )?, - Filter::List(_) => { + Some(_) => { cairo::Context::new(self.create_surface_for_toplevel_viewport()?)? } }; @@ -790,7 +790,7 @@ impl DrawingCtx { BoundingBox::new().with_transform(affines.for_temporary_surface) }; - if let Filter::List(ref filter_list) = stacking_ctx.filter.filter { + if let Some(ref filter) = stacking_ctx.filter { let surface_to_filter = SharedImageSurface::copy_from_surface( &cairo::ImageSurface::try_from(temporary_draw_ctx.cr.target()) .unwrap(), @@ -808,7 +808,7 @@ impl DrawingCtx { .resolve( acquired_nodes, values.stroke_opacity().0, - stacking_ctx.filter.current_color, + filter.current_color, None, None, self.session(), @@ -823,7 +823,7 @@ impl DrawingCtx { .resolve( acquired_nodes, values.fill_opacity().0, - stacking_ctx.filter.current_color, + filter.current_color, None, None, self.session(), @@ -843,13 +843,13 @@ impl DrawingCtx { let filtered_surface = temporary_draw_ctx .run_filters( surface_to_filter, - filter_list, + &filter.filter_list, acquired_nodes, &stacking_ctx.element_name, &user_space_params, stroke_paint_source, fill_paint_source, - stacking_ctx.filter.current_color, + filter.current_color, bbox, )? .into_image_surface()?; diff --git a/src/layout.rs b/src/layout.rs index a65bc1cf..460095b3 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -14,6 +14,7 @@ use crate::coord_units::CoordUnits; use crate::dasharray::Dasharray; use crate::document::AcquiredNodes; use crate::element::{Element, ElementData}; +use crate::filter::FilterValueList; use crate::length::*; use crate::node::*; use crate::paint_server::{PaintSource, UserSpacePaintSource}; @@ -47,7 +48,7 @@ pub struct StackingContext { pub element_name: String, pub transform: Transform, pub opacity: Opacity, - pub filter: Filter, + pub filter: Option<Filter>, pub clip_in_user_space: Option<Node>, pub clip_in_object_space: Option<Node>, pub mask: Option<Node>, @@ -150,10 +151,21 @@ pub struct FontProperties { } pub struct Filter { - pub filter: properties::Filter, + pub filter_list: FilterValueList, pub current_color: RGBA, } +fn get_filter(values: &ComputedValues) -> Option<Filter> { + match values.filter() { + properties::Filter::None => None, + + properties::Filter::List(filter_list) => Some(Filter { + filter_list: filter_list, + current_color: values.color().0, + }), + } +} + impl StackingContext { pub fn new( session: &Session, @@ -167,27 +179,20 @@ impl StackingContext { let opacity; let filter; - let current_color = values.color().0; - match element.element_data { // "The opacity, filter and display properties do not apply to the mask element" // https://drafts.fxtf.org/css-masking-1/#MaskElement ElementData::Mask(_) => { opacity = Opacity(UnitInterval::clamp(1.0)); - filter = properties::Filter::None; + filter = None; } _ => { opacity = values.opacity(); - filter = values.filter(); + filter = get_filter(values); } } - let filter = Filter { - filter, - current_color, - }; - let clip_path = values.clip_path(); let clip_uri = clip_path.0.get(); let (clip_in_user_space, clip_in_object_space) = clip_uri @@ -274,7 +279,7 @@ impl StackingContext { Isolation::Auto => { let is_opaque = approx_eq!(f64, opacity, 1.0); !(is_opaque - && self.filter.filter == properties::Filter::None + && self.filter.is_none() && self.mask.is_none() && self.mix_blend_mode == MixBlendMode::Normal && self.clip_in_object_space.is_none()) |