1
use markup5ever::{expanded_name, local_name, namespace_url, ns};
2

            
3
use crate::document::AcquiredNodes;
4
use crate::element::{set_attribute, ElementTrait};
5
use crate::filter_func::drop_shadow_primitives;
6
use crate::node::{CascadedValues, Node};
7
use crate::paint_server::resolve_color;
8
use crate::parsers::{NumberOptionalNumber, ParseValue};
9
use crate::session::Session;
10
use crate::xml::Attributes;
11

            
12
use super::{FilterEffect, FilterResolveError, Input, Primitive, ResolvedPrimitive};
13

            
14
/// The `feDropShadow` element.
15
1
#[derive(Default)]
16
pub struct FeDropShadow {
17
1
    base: Primitive,
18
1
    params: DropShadow,
19
}
20

            
21
/// Resolved `feDropShadow` parameters for rendering.
22
pub struct DropShadow {
23
    pub in1: Input,
24
    pub dx: f64,
25
    pub dy: f64,
26
    pub std_deviation: NumberOptionalNumber<f64>,
27
}
28

            
29
impl Default for DropShadow {
30
    /// Defaults come from <https://www.w3.org/TR/filter-effects/#feDropShadowElement>
31
1
    fn default() -> Self {
32
1
        Self {
33
1
            in1: Default::default(),
34
            dx: 2.0,
35
            dy: 2.0,
36
1
            std_deviation: NumberOptionalNumber(2.0, 2.0),
37
        }
38
1
    }
39
}
40

            
41
impl ElementTrait for FeDropShadow {
42
1
    fn set_attributes(&mut self, attrs: &Attributes, session: &Session) {
43
1
        self.params.in1 = self.base.parse_one_input(attrs, session);
44

            
45
6
        for (attr, value) in attrs.iter() {
46
5
            match attr.expanded() {
47
                expanded_name!("", "dx") => {
48
1
                    set_attribute(&mut self.params.dx, attr.parse(value), session);
49
                }
50

            
51
                expanded_name!("", "dy") => {
52
1
                    set_attribute(&mut self.params.dy, attr.parse(value), session);
53
                }
54

            
55
                expanded_name!("", "stdDeviation") => {
56
1
                    set_attribute(&mut self.params.std_deviation, attr.parse(value), session);
57
                }
58

            
59
                _ => (),
60
            }
61
5
        }
62
1
    }
63
}
64

            
65
impl FilterEffect for FeDropShadow {
66
1
    fn resolve(
67
        &self,
68
        _acquired_nodes: &mut AcquiredNodes<'_>,
69
        node: &Node,
70
    ) -> Result<Vec<ResolvedPrimitive>, FilterResolveError> {
71
1
        let cascaded = CascadedValues::new_from_node(node);
72
1
        let values = cascaded.get();
73

            
74
1
        let color = resolve_color(
75
1
            &values.flood_color().0,
76
1
            values.flood_opacity().0,
77
1
            &values.color().0,
78
        );
79

            
80
1
        Ok(drop_shadow_primitives(
81
1
            self.params.dx,
82
1
            self.params.dy,
83
1
            self.params.std_deviation,
84
            color,
85
        ))
86
1
    }
87
}