[librsvg: 19/20] fe*Lighting: shorten code by implementing Default and Clone for its parameters




commit 0503a70f9786c76235466dcd388166383c2ff5a6
Author: Federico Mena Quintero <federico gnome org>
Date:   Tue Mar 16 17:11:32 2021 -0600

    fe*Lighting: shorten code by implementing Default and Clone for its parameters

 src/filters/lighting.rs | 222 ++++++++++++++++++++++++------------------------
 1 file changed, 112 insertions(+), 110 deletions(-)
---
diff --git a/src/filters/lighting.rs b/src/filters/lighting.rs
index 6b32b567..972781e2 100644
--- a/src/filters/lighting.rs
+++ b/src/filters/lighting.rs
@@ -28,6 +28,72 @@ use crate::unit_interval::UnitInterval;
 use crate::util::clamp;
 use crate::xml::Attributes;
 
+/// The `feDiffuseLighting` filter primitives.
+#[derive(Default)]
+pub struct FeDiffuseLighting {
+    base: Primitive,
+    params: DiffuseLightingParams,
+}
+
+#[derive(Clone)]
+pub struct DiffuseLightingParams {
+    in1: Input,
+    surface_scale: f64,
+    kernel_unit_length: Option<(f64, f64)>,
+    diffuse_constant: f64,
+}
+
+impl Default for DiffuseLightingParams {
+    fn default() -> Self {
+        Self {
+            in1: Default::default(),
+            surface_scale: 1.0,
+            kernel_unit_length: None,
+            diffuse_constant: 1.0,
+        }
+    }
+}
+
+/// The `feSpecularLighting` filter primitives.
+#[derive(Default)]
+pub struct FeSpecularLighting {
+    base: Primitive,
+    params: SpecularLightingParams,
+}
+
+#[derive(Clone)]
+pub struct SpecularLightingParams {
+    in1: Input,
+    surface_scale: f64,
+    kernel_unit_length: Option<(f64, f64)>,
+    specular_constant: f64,
+    specular_exponent: f64,
+}
+
+impl Default for SpecularLightingParams {
+    fn default() -> Self {
+        Self {
+            in1: Default::default(),
+            surface_scale: 1.0,
+            kernel_unit_length: None,
+            specular_constant: 1.0,
+            specular_exponent: 1.0,
+        }
+    }
+}
+
+/// Resolved `feDiffuseLighting` primitive for rendering.
+pub struct DiffuseLighting {
+    params: DiffuseLightingParams,
+    light: Light,
+}
+
+/// Resolved `feSpecularLighting` primitive for rendering.
+pub struct SpecularLighting {
+    params: SpecularLightingParams,
+    light: Light,
+}
+
 /// A light source before applying affine transformations, straight out of the SVG.
 #[derive(Debug, PartialEq)]
 enum UntransformedLightSource {
@@ -69,25 +135,6 @@ struct Light {
     color_interpolation_filters: ColorInterpolationFilters,
 }
 
-/// Resolved `feDiffuseLighting` primitive for rendering.
-pub struct DiffuseLighting {
-    in1: Input,
-    surface_scale: f64,
-    kernel_unit_length: Option<(f64, f64)>,
-    diffuse_constant: f64,
-    light: Light,
-}
-
-/// Resolved `feSpecularLighting` primitive for rendering.
-pub struct SpecularLighting {
-    in1: Input,
-    surface_scale: f64,
-    kernel_unit_length: Option<(f64, f64)>,
-    specular_constant: f64,
-    specular_exponent: f64,
-    light: Light,
-}
-
 impl Light {
     /// Returns the color and unit (or null) vector from the image sample to the light.
     #[inline]
@@ -282,41 +329,22 @@ fn transform_dist(t: Transform, d: f64) -> f64 {
     d * (t.xx.powi(2) + t.yy.powi(2)).sqrt() / std::f64::consts::SQRT_2
 }
 
-/// The `feDiffuseLighting` filter primitives.
-pub struct FeDiffuseLighting {
-    base: Primitive,
-    in1: Input,
-    surface_scale: f64,
-    kernel_unit_length: Option<(f64, f64)>,
-    diffuse_constant: f64,
-}
-
-impl Default for FeDiffuseLighting {
-    fn default() -> Self {
-        Self {
-            base: Default::default(),
-            in1: Default::default(),
-            surface_scale: 1.0,
-            kernel_unit_length: None,
-            diffuse_constant: 1.0,
-        }
-    }
-}
-
 impl SetAttributes for FeDiffuseLighting {
     fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
-        self.in1 = self.base.parse_one_input(attrs)?;
+        self.params.in1 = self.base.parse_one_input(attrs)?;
 
         for (attr, value) in attrs.iter() {
             match attr.expanded() {
-                expanded_name!("", "surfaceScale") => self.surface_scale = attr.parse(value)?,
+                expanded_name!("", "surfaceScale") => {
+                    self.params.surface_scale = attr.parse(value)?
+                }
                 expanded_name!("", "kernelUnitLength") => {
                     let NumberOptionalNumber(NonNegative(x), NonNegative(y)) = attr.parse(value)?;
-                    self.kernel_unit_length = Some((x, y));
+                    self.params.kernel_unit_length = Some((x, y));
                 }
                 expanded_name!("", "diffuseConstant") => {
                     let NonNegative(c) = attr.parse(value)?;
-                    self.diffuse_constant = c;
+                    self.params.diffuse_constant = c;
                 }
                 _ => (),
             }
@@ -335,57 +363,36 @@ impl DiffuseLighting {
         } else {
             let mut n = normal
                 .normal
-                .map(|x| f64::from(x) * self.surface_scale / 255.);
+                .map(|x| f64::from(x) * self.params.surface_scale / 255.);
             n.component_mul_assign(&normal.factor);
             let normal = Vector3::new(n.x, n.y, 1.0);
 
             normal.dot(&light_vector) / normal.norm()
         };
 
-        self.diffuse_constant * k
-    }
-}
-
-/// The `feSpecularLighting` filter primitives.
-pub struct FeSpecularLighting {
-    base: Primitive,
-    in1: Input,
-    surface_scale: f64,
-    kernel_unit_length: Option<(f64, f64)>,
-    specular_constant: f64,
-    specular_exponent: f64,
-}
-
-impl Default for FeSpecularLighting {
-    fn default() -> Self {
-        Self {
-            base: Default::default(),
-            in1: Default::default(),
-            surface_scale: 1.0,
-            kernel_unit_length: None,
-            specular_constant: 1.0,
-            specular_exponent: 1.0,
-        }
+        self.params.diffuse_constant * k
     }
 }
 
 impl SetAttributes for FeSpecularLighting {
     fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
-        self.in1 = self.base.parse_one_input(attrs)?;
+        self.params.in1 = self.base.parse_one_input(attrs)?;
 
         for (attr, value) in attrs.iter() {
             match attr.expanded() {
-                expanded_name!("", "surfaceScale") => self.surface_scale = attr.parse(value)?,
+                expanded_name!("", "surfaceScale") => {
+                    self.params.surface_scale = attr.parse(value)?
+                }
                 expanded_name!("", "kernelUnitLength") => {
                     let NumberOptionalNumber(NonNegative(x), NonNegative(y)) = attr.parse(value)?;
-                    self.kernel_unit_length = Some((x, y));
+                    self.params.kernel_unit_length = Some((x, y));
                 }
                 expanded_name!("", "specularConstant") => {
                     let NonNegative(c) = attr.parse(value)?;
-                    self.specular_constant = c;
+                    self.params.specular_constant = c;
                 }
                 expanded_name!("", "specularExponent") => {
-                    self.specular_exponent = attr.parse(value)?;
+                    self.params.specular_exponent = attr.parse(value)?;
                 }
                 _ => (),
             }
@@ -411,22 +418,22 @@ impl SpecularLighting {
         } else {
             let mut n = normal
                 .normal
-                .map(|x| f64::from(x) * self.surface_scale / 255.);
+                .map(|x| f64::from(x) * self.params.surface_scale / 255.);
             n.component_mul_assign(&normal.factor);
             let normal = Vector3::new(n.x, n.y, 1.0);
             normal.dot(&h) / normal.norm() / h_norm
         };
 
-        if approx_eq!(f64, self.specular_exponent, 1.0) {
-            self.specular_constant * n_dot_h
+        if approx_eq!(f64, self.params.specular_exponent, 1.0) {
+            self.params.specular_constant * n_dot_h
         } else {
-            self.specular_constant * n_dot_h.powf(self.specular_exponent)
+            self.params.specular_constant * n_dot_h.powf(self.params.specular_exponent)
         }
     }
 }
 
 macro_rules! impl_lighting_filter {
-    ($lighting_type:ty, $params_name:ident, $alpha_func:ident, $($specific_fields:ident,)+) => {
+    ($lighting_type:ty, $params_name:ident, $alpha_func:ident) => {
         impl $params_name {
             pub fn render(
                 &self,
@@ -438,7 +445,7 @@ macro_rules! impl_lighting_filter {
                 let input_1 = ctx.get_input(
                     acquired_nodes,
                     draw_ctx,
-                    &self.in1,
+                    &self.params.in1,
                     self.light.color_interpolation_filters,
                 )?;
                 let mut bounds = primitive
@@ -448,6 +455,7 @@ macro_rules! impl_lighting_filter {
                 let original_bounds = bounds;
 
                 let scale = self
+                    .params
                     .kernel_unit_length
                     .map(|(dx, dy)| ctx.paffine().transform_distance(dx, dy));
 
@@ -491,7 +499,7 @@ macro_rules! impl_lighting_filter {
 
                             let scaled_x = f64::from(x) * ox;
                             let scaled_y = f64::from(y) * oy;
-                            let z = f64::from(pixel.a) / 255.0 * self.surface_scale;
+                            let z = f64::from(pixel.a) / 255.0 * self.params.surface_scale;
 
                             let (color, vector) =
                                 self.light.color_and_vector(&source, scaled_x, scaled_y, z);
@@ -647,7 +655,9 @@ macro_rules! impl_lighting_filter {
                     c.is_element()
                         && matches!(
                             *c.borrow_element(),
-                            Element::FeDistantLight(_) | Element::FePointLight(_) | Element::FeSpotLight(_)
+                            Element::FeDistantLight(_)
+                                | Element::FePointLight(_)
+                                | Element::FeSpotLight(_)
                         )
                 });
 
@@ -667,8 +677,12 @@ macro_rules! impl_lighting_filter {
                     Element::FeDistantLight(ref l) => {
                         UntransformedLightSource::Distant(l.element_impl.clone())
                     }
-                    Element::FePointLight(ref l) => UntransformedLightSource::Point(l.element_impl.clone()),
-                    Element::FeSpotLight(ref l) => UntransformedLightSource::Spot(l.element_impl.clone()),
+                    Element::FePointLight(ref l) => {
+                        UntransformedLightSource::Point(l.element_impl.clone())
+                    }
+                    Element::FeSpotLight(ref l) => {
+                        UntransformedLightSource::Spot(l.element_impl.clone())
+                    }
                     _ => unreachable!(),
                 };
 
@@ -678,18 +692,17 @@ macro_rules! impl_lighting_filter {
                 Ok((
                     self.base.clone(),
                     PrimitiveParams::$params_name($params_name {
-                        in1: self.in1.clone(),
-                        surface_scale: self.surface_scale.clone(),
-                        kernel_unit_length: self.kernel_unit_length.clone(),
-
-                        $($specific_fields: self.$specific_fields.clone(),)+
-
-                            light: Light {
-                                source,
-                                lighting_color: resolve_color(&values.lighting_color().0, 
UnitInterval::clamp(1.0), values.color().0),
-                                color_interpolation_filters: values.color_interpolation_filters(),
-                            }
-                    })
+                        params: self.params.clone(),
+                        light: Light {
+                            source,
+                            lighting_color: resolve_color(
+                                &values.lighting_color().0,
+                                UnitInterval::clamp(1.0),
+                                values.color().0,
+                            ),
+                            color_interpolation_filters: values.color_interpolation_filters(),
+                        },
+                    }),
                 ))
             }
         }
@@ -704,20 +717,9 @@ fn specular_alpha(r: u8, g: u8, b: u8) -> u8 {
     max(max(r, g), b)
 }
 
-impl_lighting_filter!(
-    FeDiffuseLighting,
-    DiffuseLighting,
-    diffuse_alpha,
-    diffuse_constant,
-);
-
-impl_lighting_filter!(
-    FeSpecularLighting,
-    SpecularLighting,
-    specular_alpha,
-    specular_constant,
-    specular_exponent,
-);
+impl_lighting_filter!(FeDiffuseLighting, DiffuseLighting, diffuse_alpha);
+
+impl_lighting_filter!(FeSpecularLighting, SpecularLighting, specular_alpha);
 
 /// 2D normal and factor stored separately.
 ///


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