[librsvg: 4/8] Replace PrimitiveWithInput with some extra methods in Primitive
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 4/8] Replace PrimitiveWithInput with some extra methods in Primitive
- Date: Thu, 11 Mar 2021 03:13:21 +0000 (UTC)
commit b4bd33b53f532a08be697d3dc6d5b92463945c41
Author: Federico Mena Quintero <federico gnome org>
Date: Wed Mar 10 17:39:32 2021 -0600
Replace PrimitiveWithInput with some extra methods in Primitive
Seeing this inconsitency in the render() methods of filter primtives
was bothering me:
let input = self.base.get_input(ctx, acquired_nodes, draw_ctx)?;
let input_2 = ctx.get_input(acquired_nodes, draw_ctx, &self.in2)?;
With the following changes, the methods that take two inputs now look
like this:
let input_1 = ctx.get_input(acquired_nodes, draw_ctx, &self.in1)?;
let input_2 = ctx.get_input(acquired_nodes, draw_ctx, &self.in2)?;
The changes:
* Remove PrimitiveWithInput, which was just a Primitive that could
parse the "in" attribute.
* Replace that with extra methods in Primitive:
parse_no_inputs() -> Result<(), ...>
parse_one_input() -> Result<Input, ...>
parse_two_inputs() -> Result<(Input, Input), ...>
* All primitives now have a "base: Primitive" field instead of either
that or a "base: PrimitiveWithInput" field.
* Primitives can add their own fields as needed:
in1: Input,
in2: Input,
* Since Primitive no longer has a set_attributes() method, it no
longer implements SetAttributes.
src/filters/blend.rs | 31 +++++++++--------
src/filters/color_matrix.rs | 18 +++++-----
src/filters/component_transfer.rs | 19 ++++++-----
src/filters/composite.rs | 21 +++++++-----
src/filters/convolve_matrix.rs | 20 ++++++-----
src/filters/displacement_map.rs | 21 +++++++-----
src/filters/flood.rs | 2 +-
src/filters/gaussian_blur.rs | 20 ++++++-----
src/filters/image.rs | 2 +-
src/filters/lighting.rs | 24 +++++++------
src/filters/merge.rs | 2 +-
src/filters/mod.rs | 72 ++++++++++++---------------------------
src/filters/morphology.rs | 27 +++++++++------
src/filters/offset.rs | 16 +++++----
src/filters/tile.rs | 15 ++++----
src/filters/turbulence.rs | 2 +-
16 files changed, 157 insertions(+), 155 deletions(-)
---
diff --git a/src/filters/blend.rs b/src/filters/blend.rs
index df94721d..9ff0d41d 100755
--- a/src/filters/blend.rs
+++ b/src/filters/blend.rs
@@ -10,7 +10,7 @@ use crate::parsers::{Parse, ParseValue};
use crate::xml::Attributes;
use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, Input, PrimitiveWithInput};
+use super::{FilterEffect, FilterError, FilterRender, Input, Primitive};
/// Enumeration of the possible blending modes.
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
@@ -37,7 +37,8 @@ enum_default!(Mode, Mode::Normal);
/// The `feBlend` filter primitive.
pub struct FeBlend {
- base: PrimitiveWithInput,
+ base: Primitive,
+ in1: Input,
in2: Input,
mode: Mode,
}
@@ -47,7 +48,8 @@ impl Default for FeBlend {
#[inline]
fn default() -> FeBlend {
FeBlend {
- base: PrimitiveWithInput::new(),
+ base: Primitive::new(),
+ in1: Default::default(),
in2: Default::default(),
mode: Mode::default(),
}
@@ -56,13 +58,13 @@ impl Default for FeBlend {
impl SetAttributes for FeBlend {
fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
- self.base.set_attributes(attrs)?;
+ let (in1, in2) = self.base.parse_two_inputs(attrs)?;
+ self.in1 = in1;
+ self.in2 = in2;
for (attr, value) in attrs.iter() {
- match attr.expanded() {
- expanded_name!("", "in2") => self.in2 = attr.parse(value)?,
- expanded_name!("", "mode") => self.mode = attr.parse(value)?,
- _ => (),
+ if let expanded_name!("", "mode") = attr.expanded() {
+ self.mode = attr.parse(value)?;
}
}
@@ -78,19 +80,20 @@ impl FilterRender for FeBlend {
acquired_nodes: &mut AcquiredNodes<'_>,
draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
- let input = self.base.get_input(ctx, acquired_nodes, draw_ctx)?;
+ let input_1 = ctx.get_input(acquired_nodes, draw_ctx, &self.in1)?;
let input_2 = ctx.get_input(acquired_nodes, draw_ctx, &self.in2)?;
let bounds = self
.base
.get_bounds(ctx)?
- .add_input(&input)
+ .add_input(&input_1)
.add_input(&input_2)
.into_irect(ctx, draw_ctx);
- let surface =
- input
- .surface()
- .compose(input_2.surface(), bounds, cairo::Operator::from(self.mode))?;
+ let surface = input_1.surface().compose(
+ input_2.surface(),
+ bounds,
+ cairo::Operator::from(self.mode),
+ )?;
Ok(FilterResult {
name: self.base.result.clone(),
diff --git a/src/filters/color_matrix.rs b/src/filters/color_matrix.rs
index c56ef141..9cdb0ca1 100644
--- a/src/filters/color_matrix.rs
+++ b/src/filters/color_matrix.rs
@@ -15,7 +15,7 @@ use crate::util::clamp;
use crate::xml::Attributes;
use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, PrimitiveWithInput};
+use super::{FilterEffect, FilterError, FilterRender, Input, Primitive};
/// Color matrix operation types.
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
@@ -30,7 +30,8 @@ enum_default!(OperationType, OperationType::Matrix);
/// The `feColorMatrix` filter primitive.
pub struct FeColorMatrix {
- base: PrimitiveWithInput,
+ base: Primitive,
+ in1: Input,
matrix: Matrix5<f64>,
}
@@ -39,7 +40,8 @@ impl Default for FeColorMatrix {
#[inline]
fn default() -> FeColorMatrix {
FeColorMatrix {
- base: PrimitiveWithInput::new(),
+ base: Primitive::new(),
+ in1: Default::default(),
matrix: Matrix5::identity(),
}
}
@@ -48,7 +50,7 @@ impl Default for FeColorMatrix {
#[rustfmt::skip]
impl SetAttributes for FeColorMatrix {
fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
- self.base.set_attributes(attrs)?;
+ self.in1 = self.base.parse_one_input(attrs)?;
// First, determine the operation type.
let mut operation_type = Default::default();
@@ -145,21 +147,21 @@ impl FilterRender for FeColorMatrix {
acquired_nodes: &mut AcquiredNodes<'_>,
draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
- let input = self.base.get_input(ctx, acquired_nodes, draw_ctx)?;
+ let input_1 = ctx.get_input(acquired_nodes, draw_ctx, &self.in1)?;
let bounds = self
.base
.get_bounds(ctx)?
- .add_input(&input)
+ .add_input(&input_1)
.into_irect(ctx, draw_ctx);
let mut surface = ExclusiveImageSurface::new(
ctx.source_graphic().width(),
ctx.source_graphic().height(),
- input.surface().surface_type(),
+ input_1.surface().surface_type(),
)?;
surface.modify(&mut |data, stride| {
- for (x, y, pixel) in Pixels::within(input.surface(), bounds) {
+ for (x, y, pixel) in Pixels::within(input_1.surface(), bounds) {
let alpha = f64::from(pixel.a) / 255f64;
let pixel_vec = if alpha == 0.0 {
diff --git a/src/filters/component_transfer.rs b/src/filters/component_transfer.rs
index f2745a5b..75d7a85e 100644
--- a/src/filters/component_transfer.rs
+++ b/src/filters/component_transfer.rs
@@ -16,11 +16,12 @@ use crate::util::clamp;
use crate::xml::Attributes;
use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, PrimitiveWithInput};
+use super::{FilterEffect, FilterError, FilterRender, Input, Primitive};
/// The `feComponentTransfer` filter primitive.
pub struct FeComponentTransfer {
- base: PrimitiveWithInput,
+ base: Primitive,
+ in1: Input,
}
impl Default for FeComponentTransfer {
@@ -28,14 +29,16 @@ impl Default for FeComponentTransfer {
#[inline]
fn default() -> FeComponentTransfer {
FeComponentTransfer {
- base: PrimitiveWithInput::new(),
+ base: Primitive::new(),
+ in1: Default::default(),
}
}
}
impl SetAttributes for FeComponentTransfer {
fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
- self.base.set_attributes(attrs)
+ self.in1 = self.base.parse_one_input(attrs)?;
+ Ok(())
}
}
@@ -293,18 +296,18 @@ impl FilterRender for FeComponentTransfer {
) -> Result<FilterResult, FilterError> {
let functions = get_parameters(node)?;
- let input = self.base.get_input(ctx, acquired_nodes, draw_ctx)?;
+ let input_1 = ctx.get_input(acquired_nodes, draw_ctx, &self.in1)?;
let bounds = self
.base
.get_bounds(ctx)?
- .add_input(&input)
+ .add_input(&input_1)
.into_irect(ctx, draw_ctx);
// Create the output surface.
let mut surface = ExclusiveImageSurface::new(
ctx.source_graphic().width(),
ctx.source_graphic().height(),
- input.surface().surface_type(),
+ input_1.surface().surface_type(),
)?;
#[inline]
@@ -338,7 +341,7 @@ impl FilterRender for FeComponentTransfer {
// Do the actual processing.
surface.modify(&mut |data, stride| {
- for (x, y, pixel) in Pixels::within(input.surface(), bounds) {
+ for (x, y, pixel) in Pixels::within(input_1.surface(), bounds) {
let alpha = f64::from(pixel.a) / 255f64;
let new_alpha = compute_a(alpha);
diff --git a/src/filters/composite.rs b/src/filters/composite.rs
index 1d081b6d..0929d571 100644
--- a/src/filters/composite.rs
+++ b/src/filters/composite.rs
@@ -10,7 +10,7 @@ use crate::parsers::{Parse, ParseValue};
use crate::xml::Attributes;
use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, Input, PrimitiveWithInput};
+use super::{FilterEffect, FilterError, FilterRender, Input, Primitive};
/// Enumeration of the possible compositing operations.
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
@@ -25,7 +25,8 @@ enum Operator {
/// The `feComposite` filter primitive.
pub struct FeComposite {
- base: PrimitiveWithInput,
+ base: Primitive,
+ in1: Input,
in2: Input,
operator: Operator,
k1: f64,
@@ -39,7 +40,8 @@ impl Default for FeComposite {
#[inline]
fn default() -> FeComposite {
FeComposite {
- base: PrimitiveWithInput::new(),
+ base: Primitive::new(),
+ in1: Default::default(),
in2: Default::default(),
operator: Operator::Over,
k1: 0.0,
@@ -52,11 +54,12 @@ impl Default for FeComposite {
impl SetAttributes for FeComposite {
fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
- self.base.set_attributes(attrs)?;
+ let (in1, in2) = self.base.parse_two_inputs(attrs)?;
+ self.in1 = in1;
+ self.in2 = in2;
for (attr, value) in attrs.iter() {
match attr.expanded() {
- expanded_name!("", "in2") => self.in2 = attr.parse(value)?,
expanded_name!("", "operator") => self.operator = attr.parse(value)?,
expanded_name!("", "k1") => self.k1 = attr.parse(value)?,
expanded_name!("", "k2") => self.k2 = attr.parse(value)?,
@@ -78,17 +81,17 @@ impl FilterRender for FeComposite {
acquired_nodes: &mut AcquiredNodes<'_>,
draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
- let input = self.base.get_input(ctx, acquired_nodes, draw_ctx)?;
+ let input_1 = ctx.get_input(acquired_nodes, draw_ctx, &self.in1)?;
let input_2 = ctx.get_input(acquired_nodes, draw_ctx, &self.in2)?;
let bounds = self
.base
.get_bounds(ctx)?
- .add_input(&input)
+ .add_input(&input_1)
.add_input(&input_2)
.into_irect(ctx, draw_ctx);
let surface = if self.operator == Operator::Arithmetic {
- input.surface().compose_arithmetic(
+ input_1.surface().compose_arithmetic(
input_2.surface(),
bounds,
self.k1,
@@ -97,7 +100,7 @@ impl FilterRender for FeComposite {
self.k4,
)?
} else {
- input.surface().compose(
+ input_1.surface().compose(
input_2.surface(),
bounds,
cairo::Operator::from(self.operator),
diff --git a/src/filters/convolve_matrix.rs b/src/filters/convolve_matrix.rs
index 5e70d5c4..40449942 100644
--- a/src/filters/convolve_matrix.rs
+++ b/src/filters/convolve_matrix.rs
@@ -20,11 +20,12 @@ use crate::util::clamp;
use crate::xml::Attributes;
use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, PrimitiveWithInput};
+use super::{FilterEffect, FilterError, FilterRender, Input, Primitive};
/// The `feConvolveMatrix` filter primitive.
pub struct FeConvolveMatrix {
- base: PrimitiveWithInput,
+ base: Primitive,
+ in1: Input,
order: (u32, u32),
kernel_matrix: Option<DMatrix<f64>>,
divisor: f64,
@@ -41,7 +42,8 @@ impl Default for FeConvolveMatrix {
#[inline]
fn default() -> FeConvolveMatrix {
FeConvolveMatrix {
- base: PrimitiveWithInput::new(),
+ base: Primitive::new(),
+ in1: Default::default(),
order: (3, 3),
kernel_matrix: None,
divisor: 0.0,
@@ -57,7 +59,7 @@ impl Default for FeConvolveMatrix {
impl SetAttributes for FeConvolveMatrix {
fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
- self.base.set_attributes(attrs)?;
+ self.in1 = self.base.parse_one_input(attrs)?;
for (attr, value) in attrs.iter() {
match attr.expanded() {
@@ -129,11 +131,11 @@ impl FilterRender for FeConvolveMatrix {
) -> Result<FilterResult, FilterError> {
#![allow(clippy::many_single_char_names)]
- let input = self.base.get_input(ctx, acquired_nodes, draw_ctx)?;
+ let input_1 = ctx.get_input(acquired_nodes, draw_ctx, &self.in1)?;
let mut bounds = self
.base
.get_bounds(ctx)?
- .add_input(&input)
+ .add_input(&input_1)
.into_irect(ctx, draw_ctx);
let original_bounds = bounds;
@@ -159,9 +161,9 @@ impl FilterRender for FeConvolveMatrix {
let mut input_surface = if self.preserve_alpha {
// preserve_alpha means we need to premultiply and unpremultiply the values.
- input.surface().unpremultiply(bounds)?
+ input_1.surface().unpremultiply(bounds)?
} else {
- input.surface().clone()
+ input_1.surface().clone()
};
let scale = self
@@ -193,7 +195,7 @@ impl FilterRender for FeConvolveMatrix {
let mut surface = ExclusiveImageSurface::new(
input_surface.width(),
input_surface.height(),
- input.surface().surface_type(),
+ input_1.surface().surface_type(),
)?;
surface.modify(&mut |data, stride| {
diff --git a/src/filters/displacement_map.rs b/src/filters/displacement_map.rs
index ddae001e..6bd557ed 100644
--- a/src/filters/displacement_map.rs
+++ b/src/filters/displacement_map.rs
@@ -11,7 +11,7 @@ use crate::surface_utils::{iterators::Pixels, shared_surface::ExclusiveImageSurf
use crate::xml::Attributes;
use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, Input, PrimitiveWithInput};
+use super::{FilterEffect, FilterError, FilterRender, Input, Primitive};
/// Enumeration of the color channels the displacement map can source.
#[derive(Clone, Copy)]
@@ -24,7 +24,8 @@ enum ColorChannel {
/// The `feDisplacementMap` filter primitive.
pub struct FeDisplacementMap {
- base: PrimitiveWithInput,
+ base: Primitive,
+ in1: Input,
in2: Input,
scale: f64,
x_channel_selector: ColorChannel,
@@ -36,7 +37,8 @@ impl Default for FeDisplacementMap {
#[inline]
fn default() -> FeDisplacementMap {
FeDisplacementMap {
- base: PrimitiveWithInput::new(),
+ base: Primitive::new(),
+ in1: Default::default(),
in2: Default::default(),
scale: 0.0,
x_channel_selector: ColorChannel::A,
@@ -47,11 +49,12 @@ impl Default for FeDisplacementMap {
impl SetAttributes for FeDisplacementMap {
fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
- self.base.set_attributes(attrs)?;
+ let (in1, in2) = self.base.parse_two_inputs(attrs)?;
+ self.in1 = in1;
+ self.in2 = in2;
for (attr, value) in attrs.iter() {
match attr.expanded() {
- expanded_name!("", "in2") => self.in2 = attr.parse(value)?,
expanded_name!("", "scale") => self.scale = attr.parse(value)?,
expanded_name!("", "xChannelSelector") => {
self.x_channel_selector = attr.parse(value)?
@@ -75,12 +78,12 @@ impl FilterRender for FeDisplacementMap {
acquired_nodes: &mut AcquiredNodes<'_>,
draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
- let input = self.base.get_input(ctx, acquired_nodes, draw_ctx)?;
+ let input_1 = ctx.get_input(acquired_nodes, draw_ctx, &self.in1)?;
let displacement_input = ctx.get_input(acquired_nodes, draw_ctx, &self.in2)?;
let bounds = self
.base
.get_bounds(ctx)?
- .add_input(&input)
+ .add_input(&input_1)
.add_input(&displacement_input)
.into_irect(ctx, draw_ctx);
@@ -92,7 +95,7 @@ impl FilterRender for FeDisplacementMap {
let mut surface = ExclusiveImageSurface::new(
ctx.source_graphic().width(),
ctx.source_graphic().height(),
- input.surface().surface_type(),
+ input_1.surface().surface_type(),
)?;
surface.draw(&mut |cr| {
@@ -120,7 +123,7 @@ impl FilterRender for FeDisplacementMap {
cr.reset_clip();
cr.clip();
- input.surface().set_as_source_surface(&cr, -ox, -oy);
+ input_1.surface().set_as_source_surface(&cr, -ox, -oy);
cr.paint();
}
diff --git a/src/filters/flood.rs b/src/filters/flood.rs
index a20d72a7..e461e0c6 100644
--- a/src/filters/flood.rs
+++ b/src/filters/flood.rs
@@ -24,7 +24,7 @@ impl Default for FeFlood {
impl SetAttributes for FeFlood {
fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
- self.base.set_attributes(attrs)
+ self.base.parse_no_inputs(attrs)
}
}
diff --git a/src/filters/gaussian_blur.rs b/src/filters/gaussian_blur.rs
index 5d652d05..5fe342b2 100644
--- a/src/filters/gaussian_blur.rs
+++ b/src/filters/gaussian_blur.rs
@@ -17,7 +17,7 @@ use crate::surface_utils::{
use crate::xml::Attributes;
use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, PrimitiveWithInput};
+use super::{FilterEffect, FilterError, FilterRender, Input, Primitive};
/// The maximum gaussian blur kernel size.
///
@@ -26,7 +26,8 @@ const MAXIMUM_KERNEL_SIZE: usize = 500;
/// The `feGaussianBlur` filter primitive.
pub struct FeGaussianBlur {
- base: PrimitiveWithInput,
+ base: Primitive,
+ in1: Input,
std_deviation: (f64, f64),
}
@@ -35,7 +36,8 @@ impl Default for FeGaussianBlur {
#[inline]
fn default() -> FeGaussianBlur {
FeGaussianBlur {
- base: PrimitiveWithInput::new(),
+ base: Primitive::new(),
+ in1: Default::default(),
std_deviation: (0.0, 0.0),
}
}
@@ -43,7 +45,7 @@ impl Default for FeGaussianBlur {
impl SetAttributes for FeGaussianBlur {
fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
- self.base.set_attributes(attrs)?;
+ self.in1 = self.base.parse_one_input(attrs)?;
for (attr, value) in attrs.iter() {
if let expanded_name!("", "stdDeviation") = attr.expanded() {
@@ -193,11 +195,11 @@ impl FilterRender for FeGaussianBlur {
acquired_nodes: &mut AcquiredNodes<'_>,
draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
- let input = self.base.get_input(ctx, acquired_nodes, draw_ctx)?;
+ let input_1 = ctx.get_input(acquired_nodes, draw_ctx, &self.in1)?;
let bounds = self
.base
.get_bounds(ctx)?
- .add_input(&input)
+ .add_input(&input_1)
.into_irect(ctx, draw_ctx);
let (std_x, std_y) = self.std_deviation;
@@ -214,11 +216,11 @@ impl FilterRender for FeGaussianBlur {
// Horizontal convolution.
let horiz_result_surface = if std_x >= 2.0 {
// The spec says for deviation >= 2.0 three box blurs can be used as an optimization.
- three_box_blurs::<Horizontal>(input.surface(), bounds, std_x)?
+ three_box_blurs::<Horizontal>(input_1.surface(), bounds, std_x)?
} else if std_x != 0.0 {
- gaussian_blur(input.surface(), bounds, std_x, false)?
+ gaussian_blur(input_1.surface(), bounds, std_x, false)?
} else {
- input.surface().clone()
+ input_1.surface().clone()
};
// Vertical convolution.
diff --git a/src/filters/image.rs b/src/filters/image.rs
index 6044dfc7..e328ae98 100644
--- a/src/filters/image.rs
+++ b/src/filters/image.rs
@@ -99,7 +99,7 @@ impl FeImage {
impl SetAttributes for FeImage {
fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
- self.base.set_attributes(attrs)?;
+ self.base.parse_no_inputs(attrs)?;
for (attr, value) in attrs.iter() {
match attr.expanded() {
diff --git a/src/filters/lighting.rs b/src/filters/lighting.rs
index 51042a1d..81132bd9 100644
--- a/src/filters/lighting.rs
+++ b/src/filters/lighting.rs
@@ -12,7 +12,7 @@ use crate::drawing_ctx::DrawingCtx;
use crate::element::{Draw, Element, ElementResult, SetAttributes};
use crate::filters::{
context::{FilterContext, FilterOutput, FilterResult},
- FilterEffect, FilterError, FilterRender, PrimitiveWithInput,
+ FilterEffect, FilterError, FilterRender, Input, Primitive,
};
use crate::node::{CascadedValues, Node, NodeBorrow};
use crate::parsers::{NonNegative, NumberOptionalNumber, ParseValue};
@@ -308,7 +308,8 @@ fn transform_dist(t: Transform, d: f64) -> f64 {
/// The `feDiffuseLighting` filter primitives.
pub struct FeDiffuseLighting {
- base: PrimitiveWithInput,
+ base: Primitive,
+ in1: Input,
surface_scale: f64,
kernel_unit_length: Option<(f64, f64)>,
diffuse_constant: f64,
@@ -317,7 +318,8 @@ pub struct FeDiffuseLighting {
impl Default for FeDiffuseLighting {
fn default() -> Self {
Self {
- base: PrimitiveWithInput::new(),
+ base: Primitive::new(),
+ in1: Default::default(),
surface_scale: 1.0,
kernel_unit_length: None,
diffuse_constant: 1.0,
@@ -327,7 +329,7 @@ impl Default for FeDiffuseLighting {
impl SetAttributes for FeDiffuseLighting {
fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
- self.base.set_attributes(attrs)?;
+ self.in1 = self.base.parse_one_input(attrs)?;
for (attr, value) in attrs.iter() {
match attr.expanded() {
@@ -370,7 +372,8 @@ impl FeDiffuseLighting {
/// The `feSpecularLighting` filter primitives.
pub struct FeSpecularLighting {
- base: PrimitiveWithInput,
+ base: Primitive,
+ in1: Input,
surface_scale: f64,
kernel_unit_length: Option<(f64, f64)>,
specular_constant: f64,
@@ -380,7 +383,8 @@ pub struct FeSpecularLighting {
impl Default for FeSpecularLighting {
fn default() -> Self {
Self {
- base: PrimitiveWithInput::new(),
+ base: Primitive::new(),
+ in1: Default::default(),
surface_scale: 1.0,
kernel_unit_length: None,
specular_constant: 1.0,
@@ -391,7 +395,7 @@ impl Default for FeSpecularLighting {
impl SetAttributes for FeSpecularLighting {
fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
- self.base.set_attributes(attrs)?;
+ self.in1 = self.base.parse_one_input(attrs)?;
for (attr, value) in attrs.iter() {
match attr.expanded() {
@@ -457,11 +461,11 @@ macro_rules! impl_lighting_filter {
acquired_nodes: &mut AcquiredNodes<'_>,
draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
- let input = self.base.get_input(ctx, acquired_nodes, draw_ctx)?;
+ let input_1 = ctx.get_input(acquired_nodes, draw_ctx, &self.in1)?;
let mut bounds = self
.base
.get_bounds(ctx)?
- .add_input(&input)
+ .add_input(&input_1)
.into_irect(ctx, draw_ctx);
let original_bounds = bounds;
@@ -469,7 +473,7 @@ macro_rules! impl_lighting_filter {
.kernel_unit_length
.map(|(dx, dy)| ctx.paffine().transform_distance(dx, dy));
- let mut input_surface = input.surface().clone();
+ let mut input_surface = input_1.surface().clone();
if let Some((ox, oy)) = scale {
// Scale the input surface to match kernel_unit_length.
diff --git a/src/filters/merge.rs b/src/filters/merge.rs
index 478a6510..0ba0d8b1 100644
--- a/src/filters/merge.rs
+++ b/src/filters/merge.rs
@@ -35,7 +35,7 @@ impl Default for FeMerge {
impl SetAttributes for FeMerge {
fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
- self.base.set_attributes(attrs)
+ self.base.parse_no_inputs(attrs)
}
}
diff --git a/src/filters/mod.rs b/src/filters/mod.rs
index d6286720..e69b6d97 100644
--- a/src/filters/mod.rs
+++ b/src/filters/mod.rs
@@ -2,7 +2,6 @@
use cssparser::{BasicParseError, Parser};
use markup5ever::{expanded_name, local_name, namespace_url, ns};
-use std::ops::Deref;
use std::time::Instant;
use crate::bbox::BoundingBox;
@@ -10,7 +9,7 @@ use crate::coord_units::CoordUnits;
use crate::document::AcquiredNodes;
use crate::drawing_ctx::DrawingCtx;
use crate::element::{Draw, ElementResult, SetAttributes};
-use crate::error::{ParseError, RenderingError};
+use crate::error::{ElementError, ParseError, RenderingError};
use crate::length::*;
use crate::node::{CascadedValues, Node, NodeBorrow};
use crate::parsers::{CustomIdent, Parse, ParseValue};
@@ -24,7 +23,7 @@ mod bounds;
use self::bounds::BoundsBuilder;
pub mod context;
-use self::context::{FilterContext, FilterInput, FilterResult};
+use self::context::{FilterContext, FilterResult};
mod error;
use self::error::FilterError;
@@ -122,12 +121,6 @@ impl Parse for Input {
}
}
-/// The base node for filter primitives which accept input.
-struct PrimitiveWithInput {
- base: Primitive,
- in1: Input,
-}
-
impl Primitive {
/// Constructs a new `Primitive` with empty properties.
#[inline]
@@ -179,8 +172,14 @@ fn check_units<N: Normalize, V: Validate>(
}
}
-impl SetAttributes for Primitive {
- fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
+impl Primitive {
+ fn parse_standard_attributes(
+ &mut self,
+ attrs: &Attributes,
+ ) -> Result<(Input, Input), ElementError> {
+ let mut input_1 = Input::Unspecified;
+ let mut input_2 = Input::Unspecified;
+
for (attr, value) in attrs.iter() {
match attr.expanded() {
expanded_name!("", "x") => self.x = attr.parse(value)?,
@@ -188,56 +187,27 @@ impl SetAttributes for Primitive {
expanded_name!("", "width") => self.width = attr.parse(value)?,
expanded_name!("", "height") => self.height = attr.parse(value)?,
expanded_name!("", "result") => self.result = attr.parse(value)?,
+ expanded_name!("", "in") => input_1 = attr.parse(value)?,
+ expanded_name!("", "in2") => input_2 = attr.parse(value)?,
_ => (),
}
}
- Ok(())
- }
-}
-
-impl PrimitiveWithInput {
- /// Constructs a new `PrimitiveWithInput` with empty properties.
- #[inline]
- fn new() -> PrimitiveWithInput {
- PrimitiveWithInput {
- base: Primitive::new(),
- in1: Default::default(),
- }
- }
-
- /// Returns the input Cairo surface for this filter primitive.
- #[inline]
- fn get_input(
- &self,
- ctx: &FilterContext,
- acquired_nodes: &mut AcquiredNodes<'_>,
- draw_ctx: &mut DrawingCtx,
- ) -> Result<FilterInput, FilterError> {
- ctx.get_input(acquired_nodes, draw_ctx, &self.in1)
+ Ok((input_1, input_2))
}
-}
-
-impl SetAttributes for PrimitiveWithInput {
- fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
- self.base.set_attributes(attrs)?;
-
- for (attr, value) in attrs.iter() {
- if let expanded_name!("", "in") = attr.expanded() {
- self.in1 = attr.parse(value)?;
- }
- }
+ pub fn parse_no_inputs(&mut self, attrs: &Attributes) -> ElementResult {
+ let (_, _) = self.parse_standard_attributes(attrs)?;
Ok(())
}
-}
-impl Deref for PrimitiveWithInput {
- type Target = Primitive;
+ pub fn parse_one_input(&mut self, attrs: &Attributes) -> Result<Input, ElementError> {
+ let (input_1, _) = self.parse_standard_attributes(attrs)?;
+ Ok(input_1)
+ }
- #[inline]
- fn deref(&self) -> &Self::Target {
- &self.base
+ pub fn parse_two_inputs(&mut self, attrs: &Attributes) -> Result<(Input, Input), ElementError> {
+ self.parse_standard_attributes(attrs)
}
}
diff --git a/src/filters/morphology.rs b/src/filters/morphology.rs
index 8a1628c7..c88efbea 100644
--- a/src/filters/morphology.rs
+++ b/src/filters/morphology.rs
@@ -18,7 +18,7 @@ use crate::surface_utils::{
use crate::xml::Attributes;
use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, PrimitiveWithInput};
+use super::{FilterEffect, FilterError, FilterRender, Input, Primitive};
/// Enumeration of the possible morphology operations.
enum Operator {
@@ -28,7 +28,8 @@ enum Operator {
/// The `feMorphology` filter primitive.
pub struct FeMorphology {
- base: PrimitiveWithInput,
+ base: Primitive,
+ in1: Input,
operator: Operator,
radius: (f64, f64),
}
@@ -38,7 +39,8 @@ impl Default for FeMorphology {
#[inline]
fn default() -> FeMorphology {
FeMorphology {
- base: PrimitiveWithInput::new(),
+ base: Primitive::new(),
+ in1: Default::default(),
operator: Operator::Erode,
radius: (0.0, 0.0),
}
@@ -47,7 +49,7 @@ impl Default for FeMorphology {
impl SetAttributes for FeMorphology {
fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
- self.base.set_attributes(attrs)?;
+ self.in1 = self.base.parse_one_input(attrs)?;
for (attr, value) in attrs.iter() {
match attr.expanded() {
@@ -72,11 +74,11 @@ impl FilterRender for FeMorphology {
acquired_nodes: &mut AcquiredNodes<'_>,
draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
- let input = self.base.get_input(ctx, acquired_nodes, draw_ctx)?;
+ let input_1 = ctx.get_input(acquired_nodes, draw_ctx, &self.in1)?;
let bounds = self
.base
.get_bounds(ctx)?
- .add_input(&input)
+ .add_input(&input_1)
.into_irect(ctx, draw_ctx);
let (rx, ry) = self.radius;
@@ -88,11 +90,11 @@ impl FilterRender for FeMorphology {
let mut surface = ExclusiveImageSurface::new(
ctx.source_graphic().width(),
ctx.source_graphic().height(),
- input.surface().surface_type(),
+ input_1.surface().surface_type(),
)?;
surface.modify(&mut |data, stride| {
- for (x, y, _pixel) in Pixels::within(input.surface(), bounds) {
+ for (x, y, _pixel) in Pixels::within(input_1.surface(), bounds) {
// Compute the kernel rectangle bounds.
let kernel_bounds = IRect::new(
(f64::from(x) - rx).floor() as i32,
@@ -114,9 +116,12 @@ impl FilterRender for FeMorphology {
a: initial,
};
- for (_x, _y, pixel) in
- PixelRectangle::within(&input.surface(), bounds, kernel_bounds, EdgeMode::None)
- {
+ for (_x, _y, pixel) in PixelRectangle::within(
+ &input_1.surface(),
+ bounds,
+ kernel_bounds,
+ EdgeMode::None,
+ ) {
let op = match self.operator {
Operator::Erode => min,
Operator::Dilate => max,
diff --git a/src/filters/offset.rs b/src/filters/offset.rs
index 3446209a..213a5c77 100644
--- a/src/filters/offset.rs
+++ b/src/filters/offset.rs
@@ -8,11 +8,12 @@ use crate::parsers::ParseValue;
use crate::xml::Attributes;
use super::context::{FilterContext, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, PrimitiveWithInput};
+use super::{FilterEffect, FilterError, FilterRender, Input, Primitive};
/// The `feOffset` filter primitive.
pub struct FeOffset {
- base: PrimitiveWithInput,
+ base: Primitive,
+ in1: Input,
dx: f64,
dy: f64,
}
@@ -22,7 +23,8 @@ impl Default for FeOffset {
#[inline]
fn default() -> FeOffset {
FeOffset {
- base: PrimitiveWithInput::new(),
+ base: Primitive::new(),
+ in1: Default::default(),
dx: 0f64,
dy: 0f64,
}
@@ -31,7 +33,7 @@ impl Default for FeOffset {
impl SetAttributes for FeOffset {
fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
- self.base.set_attributes(attrs)?;
+ self.in1 = self.base.parse_one_input(attrs)?;
for (attr, value) in attrs.iter() {
match attr.expanded() {
@@ -53,16 +55,16 @@ impl FilterRender for FeOffset {
acquired_nodes: &mut AcquiredNodes<'_>,
draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
- let input = self.base.get_input(ctx, acquired_nodes, draw_ctx)?;
+ let input_1 = ctx.get_input(acquired_nodes, draw_ctx, &self.in1)?;
let bounds = self
.base
.get_bounds(ctx)?
- .add_input(&input)
+ .add_input(&input_1)
.into_irect(ctx, draw_ctx);
let (dx, dy) = ctx.paffine().transform_distance(self.dx, self.dy);
- let surface = input.surface().offset(bounds, dx, dy)?;
+ let surface = input_1.surface().offset(bounds, dx, dy)?;
Ok(FilterResult {
name: self.base.result.clone(),
diff --git a/src/filters/tile.rs b/src/filters/tile.rs
index 1638d8dd..986eeff7 100644
--- a/src/filters/tile.rs
+++ b/src/filters/tile.rs
@@ -5,11 +5,12 @@ use crate::node::Node;
use crate::xml::Attributes;
use super::context::{FilterContext, FilterInput, FilterOutput, FilterResult};
-use super::{FilterEffect, FilterError, FilterRender, PrimitiveWithInput};
+use super::{FilterEffect, FilterError, FilterRender, Input, Primitive};
/// The `feTile` filter primitive.
pub struct FeTile {
- base: PrimitiveWithInput,
+ base: Primitive,
+ in1: Input,
}
impl Default for FeTile {
@@ -17,14 +18,16 @@ impl Default for FeTile {
#[inline]
fn default() -> FeTile {
FeTile {
- base: PrimitiveWithInput::new(),
+ base: Primitive::new(),
+ in1: Default::default(),
}
}
}
impl SetAttributes for FeTile {
fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
- self.base.set_attributes(attrs)
+ self.in1 = self.base.parse_one_input(attrs)?;
+ Ok(())
}
}
@@ -36,12 +39,12 @@ impl FilterRender for FeTile {
acquired_nodes: &mut AcquiredNodes<'_>,
draw_ctx: &mut DrawingCtx,
) -> Result<FilterResult, FilterError> {
- let input = self.base.get_input(ctx, acquired_nodes, draw_ctx)?;
+ let input_1 = ctx.get_input(acquired_nodes, draw_ctx, &self.in1)?;
// feTile doesn't consider its inputs in the filter primitive subregion calculation.
let bounds = self.base.get_bounds(ctx)?.into_irect(ctx, draw_ctx);
- let surface = match input {
+ let surface = match input_1 {
FilterInput::StandardInput(input_surface) => input_surface,
FilterInput::PrimitiveOutput(FilterOutput {
surface: input_surface,
diff --git a/src/filters/turbulence.rs b/src/filters/turbulence.rs
index dfdaedb7..eac10500 100644
--- a/src/filters/turbulence.rs
+++ b/src/filters/turbulence.rs
@@ -58,7 +58,7 @@ impl Default for FeTurbulence {
impl SetAttributes for FeTurbulence {
fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
- self.base.set_attributes(attrs)?;
+ self.base.parse_no_inputs(attrs)?;
for (attr, value) in attrs.iter() {
match attr.expanded() {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]