[librsvg: 3/15] ResolvedPrimitive - length values are now in user space coordinates




commit 04a7a1d8116e609651f6d25b878af563918faa0d
Author: Federico Mena Quintero <federico gnome org>
Date:   Wed Apr 7 17:58:21 2021 -0500

    ResolvedPrimitive - length values are now in user space coordinates
    
    We normalize a Primitive's Length values into user space coordinates
    in Primitive::resolve().
    
    This also lets BoundsBuilder maintain only user space coordinates.

 src/filters/blend.rs              |  2 +-
 src/filters/bounds.rs             | 35 +++++++++++-------------
 src/filters/color_matrix.rs       |  2 +-
 src/filters/component_transfer.rs |  2 +-
 src/filters/composite.rs          |  2 +-
 src/filters/convolve_matrix.rs    |  2 +-
 src/filters/displacement_map.rs   |  2 +-
 src/filters/flood.rs              |  4 +--
 src/filters/gaussian_blur.rs      |  2 +-
 src/filters/image.rs              |  2 +-
 src/filters/lighting.rs           |  2 +-
 src/filters/merge.rs              |  2 +-
 src/filters/mod.rs                | 56 +++++++++++++++++++++++++--------------
 src/filters/morphology.rs         |  2 +-
 src/filters/offset.rs             |  2 +-
 src/filters/tile.rs               |  2 +-
 src/filters/turbulence.rs         |  4 +--
 17 files changed, 68 insertions(+), 57 deletions(-)
---
diff --git a/src/filters/blend.rs b/src/filters/blend.rs
index 16c56a89..84b2e9df 100755
--- a/src/filters/blend.rs
+++ b/src/filters/blend.rs
@@ -92,7 +92,7 @@ impl Blend {
             .get_bounds(ctx)?
             .add_input(&input_1)
             .add_input(&input_2)
-            .into_irect(ctx, draw_ctx);
+            .into_irect(ctx);
 
         let surface = input_1.surface().compose(
             input_2.surface(),
diff --git a/src/filters/bounds.rs b/src/filters/bounds.rs
index bdfd6885..c8d946e9 100644
--- a/src/filters/bounds.rs
+++ b/src/filters/bounds.rs
@@ -1,6 +1,4 @@
 //! Filter primitive subregion computation.
-use crate::drawing_ctx::DrawingCtx;
-use crate::length::*;
 use crate::rect::{IRect, Rect};
 use crate::transform::Transform;
 
@@ -9,10 +7,10 @@ use super::context::{FilterContext, FilterInput};
 /// A helper type for filter primitive subregion computation.
 pub struct BoundsBuilder {
     /// Filter primitive properties.
-    x: Option<Length<Horizontal>>,
-    y: Option<Length<Vertical>>,
-    width: Option<ULength<Horizontal>>,
-    height: Option<ULength<Vertical>>,
+    x: Option<f64>,
+    y: Option<f64>,
+    width: Option<f64>,
+    height: Option<f64>,
 
     /// The transform to use when generating the rect
     transform: Transform,
@@ -31,10 +29,10 @@ impl BoundsBuilder {
     /// Constructs a new `BoundsBuilder`.
     #[inline]
     pub fn new(
-        x: Option<Length<Horizontal>>,
-        y: Option<Length<Vertical>>,
-        width: Option<ULength<Horizontal>>,
-        height: Option<ULength<Vertical>>,
+        x: Option<f64>,
+        y: Option<f64>,
+        width: Option<f64>,
+        height: Option<f64>,
         transform: Transform,
     ) -> Self {
         // We panic if transform is not invertible. This is checked in the caller.
@@ -73,7 +71,7 @@ impl BoundsBuilder {
     }
 
     /// Returns the final exact bounds, both with and without clipping to the effects region.
-    pub fn into_rect(self, ctx: &FilterContext, draw_ctx: &mut DrawingCtx) -> (Rect, Rect) {
+    pub fn into_rect(self, ctx: &FilterContext) -> (Rect, Rect) {
         let effects_region = ctx.effects_region();
 
         // The default value is the filter effects region converted into
@@ -86,24 +84,21 @@ impl BoundsBuilder {
         // If any of the properties were specified, we need to respect them.
         // These replacements are possible because of the primitive coordinate system.
         if self.x.is_some() || self.y.is_some() || self.width.is_some() || self.height.is_some() {
-            let params = draw_ctx.push_coord_units(ctx.primitive_units());
-            let values = ctx.get_computed_values_from_node_being_filtered();
-
             if let Some(x) = self.x {
                 let w = rect.width();
-                rect.x0 = x.normalize(values, &params);
+                rect.x0 = x;
                 rect.x1 = rect.x0 + w;
             }
             if let Some(y) = self.y {
                 let h = rect.height();
-                rect.y0 = y.normalize(values, &params);
+                rect.y0 = y;
                 rect.y1 = rect.y0 + h;
             }
             if let Some(width) = self.width {
-                rect.x1 = rect.x0 + width.normalize(values, &params);
+                rect.x1 = rect.x0 + width;
             }
             if let Some(height) = self.height {
-                rect.y1 = rect.y0 + height.normalize(values, &params);
+                rect.y1 = rect.y0 + height;
             }
         }
 
@@ -118,7 +113,7 @@ impl BoundsBuilder {
     }
 
     /// Returns the final pixel bounds, clipped to the effects region.
-    pub fn into_irect(self, ctx: &FilterContext, draw_ctx: &mut DrawingCtx) -> IRect {
-        self.into_rect(ctx, draw_ctx).0.into()
+    pub fn into_irect(self, ctx: &FilterContext) -> IRect {
+        self.into_rect(ctx).0.into()
     }
 }
diff --git a/src/filters/color_matrix.rs b/src/filters/color_matrix.rs
index 5f6fbac9..e7781c90 100644
--- a/src/filters/color_matrix.rs
+++ b/src/filters/color_matrix.rs
@@ -165,7 +165,7 @@ impl ColorMatrix {
         let bounds = primitive
             .get_bounds(ctx)?
             .add_input(&input_1)
-            .into_irect(ctx, draw_ctx);
+            .into_irect(ctx);
 
         let mut surface = ExclusiveImageSurface::new(
             ctx.source_graphic().width(),
diff --git a/src/filters/component_transfer.rs b/src/filters/component_transfer.rs
index 82ecd959..380a6d86 100644
--- a/src/filters/component_transfer.rs
+++ b/src/filters/component_transfer.rs
@@ -302,7 +302,7 @@ impl ComponentTransfer {
         let bounds = primitive
             .get_bounds(ctx)?
             .add_input(&input_1)
-            .into_irect(ctx, draw_ctx);
+            .into_irect(ctx);
 
         // Create the output surface.
         let mut surface = ExclusiveImageSurface::new(
diff --git a/src/filters/composite.rs b/src/filters/composite.rs
index 5d6cbad3..f059f736 100644
--- a/src/filters/composite.rs
+++ b/src/filters/composite.rs
@@ -91,7 +91,7 @@ impl Composite {
             .get_bounds(ctx)?
             .add_input(&input_1)
             .add_input(&input_2)
-            .into_irect(ctx, draw_ctx);
+            .into_irect(ctx);
 
         let surface = if self.operator == Operator::Arithmetic {
             input_1.surface().compose_arithmetic(
diff --git a/src/filters/convolve_matrix.rs b/src/filters/convolve_matrix.rs
index 60dacceb..4daceeed 100644
--- a/src/filters/convolve_matrix.rs
+++ b/src/filters/convolve_matrix.rs
@@ -152,7 +152,7 @@ impl ConvolveMatrix {
         let mut bounds = primitive
             .get_bounds(ctx)?
             .add_input(&input_1)
-            .into_irect(ctx, draw_ctx);
+            .into_irect(ctx);
         let original_bounds = bounds;
 
         let target_x = match self.target_x {
diff --git a/src/filters/displacement_map.rs b/src/filters/displacement_map.rs
index cffd6a79..03446f4e 100644
--- a/src/filters/displacement_map.rs
+++ b/src/filters/displacement_map.rs
@@ -96,7 +96,7 @@ impl DisplacementMap {
             .get_bounds(ctx)?
             .add_input(&input_1)
             .add_input(&displacement_input)
-            .into_irect(ctx, draw_ctx);
+            .into_irect(ctx);
 
         // Displacement map's values need to be non-premultiplied.
         let displacement_surface = displacement_input.surface().unpremultiply(bounds)?;
diff --git a/src/filters/flood.rs b/src/filters/flood.rs
index 7b0db376..1a316494 100644
--- a/src/filters/flood.rs
+++ b/src/filters/flood.rs
@@ -31,9 +31,9 @@ impl Flood {
         primitive: &ResolvedPrimitive,
         ctx: &FilterContext,
         _acquired_nodes: &mut AcquiredNodes<'_>,
-        draw_ctx: &mut DrawingCtx,
+        _draw_ctx: &mut DrawingCtx,
     ) -> Result<FilterResult, FilterError> {
-        let bounds = primitive.get_bounds(ctx)?.into_irect(ctx, draw_ctx);
+        let bounds = primitive.get_bounds(ctx)?.into_irect(ctx);
 
         let surface = ctx.source_graphic().flood(bounds, self.color)?;
 
diff --git a/src/filters/gaussian_blur.rs b/src/filters/gaussian_blur.rs
index 2b47559f..5ae3b835 100644
--- a/src/filters/gaussian_blur.rs
+++ b/src/filters/gaussian_blur.rs
@@ -201,7 +201,7 @@ impl GaussianBlur {
         let bounds = primitive
             .get_bounds(ctx)?
             .add_input(&input_1)
-            .into_irect(ctx, draw_ctx);
+            .into_irect(ctx);
 
         let (std_x, std_y) = self.std_deviation;
         let (std_x, std_y) = ctx.paffine().transform_distance(std_x, std_y);
diff --git a/src/filters/image.rs b/src/filters/image.rs
index 02e88b47..f144bca8 100644
--- a/src/filters/image.rs
+++ b/src/filters/image.rs
@@ -124,7 +124,7 @@ impl Image {
         draw_ctx: &mut DrawingCtx,
     ) -> Result<FilterResult, FilterError> {
         let bounds_builder = primitive.get_bounds(ctx)?;
-        let (bounds, unclipped_bounds) = bounds_builder.into_rect(ctx, draw_ctx);
+        let (bounds, unclipped_bounds) = bounds_builder.into_rect(ctx);
 
         let href = self.href.as_ref().ok_or(FilterError::InvalidInput)?;
 
diff --git a/src/filters/lighting.rs b/src/filters/lighting.rs
index 972781e2..f6301404 100644
--- a/src/filters/lighting.rs
+++ b/src/filters/lighting.rs
@@ -451,7 +451,7 @@ macro_rules! impl_lighting_filter {
                 let mut bounds = primitive
                     .get_bounds(ctx)?
                     .add_input(&input_1)
-                    .into_irect(ctx, draw_ctx);
+                    .into_irect(ctx);
                 let original_bounds = bounds;
 
                 let scale = self
diff --git a/src/filters/merge.rs b/src/filters/merge.rs
index efdcc70a..1ca7f09f 100644
--- a/src/filters/merge.rs
+++ b/src/filters/merge.rs
@@ -114,7 +114,7 @@ impl Merge {
             bounds = bounds.add_input(&input);
         }
 
-        let bounds = bounds.into_irect(ctx, draw_ctx);
+        let bounds = bounds.into_irect(ctx);
 
         // Now merge them all.
         let mut output_surface = None;
diff --git a/src/filters/mod.rs b/src/filters/mod.rs
index 7ac2c4bb..66729353 100644
--- a/src/filters/mod.rs
+++ b/src/filters/mod.rs
@@ -88,10 +88,10 @@ pub struct Primitive {
 }
 
 pub struct ResolvedPrimitive {
-    x: Option<Length<Horizontal>>,
-    y: Option<Length<Vertical>>,
-    width: Option<ULength<Horizontal>>,
-    height: Option<ULength<Vertical>>,
+    x: Option<f64>,
+    y: Option<f64>,
+    width: Option<f64>,
+    height: Option<f64>,
     result: Option<CustomIdent>,
 }
 
@@ -132,21 +132,11 @@ impl Parse for Input {
 }
 
 impl Primitive {
-    fn resolve(&self) -> ResolvedPrimitive {
-        ResolvedPrimitive {
-            x: self.x,
-            y: self.y,
-            width: self.width,
-            height: self.height,
-            result: self.result.clone(),
-        }
-    }
-}
-
-impl ResolvedPrimitive {
-    /// Validates attributes and returns the `BoundsBuilder` for bounds computation.
-    #[inline]
-    fn get_bounds(&self, ctx: &FilterContext) -> Result<BoundsBuilder, FilterError> {
+    fn resolve(
+        &self,
+        ctx: &FilterContext,
+        draw_ctx: &DrawingCtx,
+    ) -> Result<ResolvedPrimitive, FilterError> {
         // With ObjectBoundingBox, only fractions and percents are allowed.
         if ctx.primitive_units() == CoordUnits::ObjectBoundingBox {
             check_px_or_percent_units(self.x)?;
@@ -155,6 +145,28 @@ impl ResolvedPrimitive {
             check_px_or_percent_units(self.height)?;
         }
 
+        let params = draw_ctx.push_coord_units(ctx.primitive_units());
+        let values = ctx.get_computed_values_from_node_being_filtered();
+
+        let x = self.x.map(|l| l.normalize(values, &params));
+        let y = self.y.map(|l| l.normalize(values, &params));
+        let width = self.width.map(|l| l.normalize(values, &params));
+        let height = self.height.map(|l| l.normalize(values, &params));
+
+        Ok(ResolvedPrimitive {
+            x,
+            y,
+            width,
+            height,
+            result: self.result.clone(),
+        })
+    }
+}
+
+impl ResolvedPrimitive {
+    /// Validates attributes and returns the `BoundsBuilder` for bounds computation.
+    #[inline]
+    fn get_bounds(&self, ctx: &FilterContext) -> Result<BoundsBuilder, FilterError> {
         Ok(BoundsBuilder::new(
             self.x,
             self.y,
@@ -282,8 +294,12 @@ pub fn render(
             if let Err(err) = filter
                 .resolve(&c)
                 .and_then(|(primitive, params)| {
+                    let resolved_primitive = primitive.resolve(&filter_ctx, draw_ctx)?;
+                    Ok((resolved_primitive, params))
+                })
+                .and_then(|(resolved_primitive, params)| {
                     render_primitive(
-                        &primitive.resolve(),
+                        &resolved_primitive,
                         &params,
                         &filter_ctx,
                         acquired_nodes,
diff --git a/src/filters/morphology.rs b/src/filters/morphology.rs
index f97d31ee..183872d6 100644
--- a/src/filters/morphology.rs
+++ b/src/filters/morphology.rs
@@ -89,7 +89,7 @@ impl Morphology {
         let bounds = primitive
             .get_bounds(ctx)?
             .add_input(&input_1)
-            .into_irect(ctx, draw_ctx);
+            .into_irect(ctx);
 
         let (rx, ry) = self.radius;
         let (rx, ry) = ctx.paffine().transform_distance(rx, ry);
diff --git a/src/filters/offset.rs b/src/filters/offset.rs
index 9f2be567..e316c552 100644
--- a/src/filters/offset.rs
+++ b/src/filters/offset.rs
@@ -66,7 +66,7 @@ impl Offset {
         let bounds = primitive
             .get_bounds(ctx)?
             .add_input(&input_1)
-            .into_irect(ctx, draw_ctx);
+            .into_irect(ctx);
 
         let (dx, dy) = ctx.paffine().transform_distance(self.dx, self.dy);
 
diff --git a/src/filters/tile.rs b/src/filters/tile.rs
index 96d7dcac..d36aca69 100644
--- a/src/filters/tile.rs
+++ b/src/filters/tile.rs
@@ -51,7 +51,7 @@ impl Tile {
         )?;
 
         // feTile doesn't consider its inputs in the filter primitive subregion calculation.
-        let bounds = primitive.get_bounds(ctx)?.into_irect(ctx, draw_ctx);
+        let bounds = primitive.get_bounds(ctx)?.into_irect(ctx);
 
         let surface = match input_1 {
             FilterInput::StandardInput(input_surface) => input_surface,
diff --git a/src/filters/turbulence.rs b/src/filters/turbulence.rs
index d3c79116..f0fab058 100644
--- a/src/filters/turbulence.rs
+++ b/src/filters/turbulence.rs
@@ -344,9 +344,9 @@ impl Turbulence {
         primitive: &ResolvedPrimitive,
         ctx: &FilterContext,
         _acquired_nodes: &mut AcquiredNodes<'_>,
-        draw_ctx: &mut DrawingCtx,
+        _draw_ctx: &mut DrawingCtx,
     ) -> Result<FilterResult, FilterError> {
-        let bounds = primitive.get_bounds(ctx)?.into_irect(ctx, draw_ctx);
+        let bounds = primitive.get_bounds(ctx)?.into_irect(ctx);
 
         let affine = ctx.paffine().invert().unwrap();
 


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