[librsvg: 19/20] fe*Lighting: shorten code by implementing Default and Clone for its parameters
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 19/20] fe*Lighting: shorten code by implementing Default and Clone for its parameters
- Date: Wed, 17 Mar 2021 19:08:06 +0000 (UTC)
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]