1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
use cairo::{self, ImageSurface};
use cssparser;
use handle::RsvgHandle;
use node::{NodeResult, NodeTrait, RsvgCNodeImpl, RsvgNode};
use property_bag::PropertyBag;
use surface_utils::shared_surface::SharedImageSurface;
use super::context::{FilterContext, FilterOutput, FilterResult};
use super::{Filter, FilterError, Primitive};
/// The `feFlood` filter primitive.
pub struct Flood {
base: Primitive,
}
impl Flood {
/// Constructs a new `Flood` with empty properties.
#[inline]
pub fn new() -> Flood {
Flood {
base: Primitive::new::<Self>(),
}
}
}
impl NodeTrait for Flood {
#[inline]
fn set_atts(
&self,
node: &RsvgNode,
handle: *const RsvgHandle,
pbag: &PropertyBag,
) -> NodeResult {
self.base.set_atts(node, handle, pbag)
}
#[inline]
fn get_c_impl(&self) -> *const RsvgCNodeImpl {
self.base.get_c_impl()
}
}
impl Filter for Flood {
fn render(&self, node: &RsvgNode, ctx: &FilterContext) -> Result<FilterResult, FilterError> {
let bounds = self.base.get_bounds(ctx).into_irect();
let output_surface = ImageSurface::create(
cairo::Format::ARgb32,
ctx.source_graphic().width(),
ctx.source_graphic().height(),
).map_err(FilterError::OutputSurfaceCreation)?;
let cascaded = node.get_cascaded_values();
let values = cascaded.get();
let color = match values.flood_color.0 {
cssparser::Color::CurrentColor => values.color.0,
cssparser::Color::RGBA(rgba) => rgba,
};
let opacity = (values.flood_opacity.0).0;
if opacity > 0f64 {
let cr = cairo::Context::new(&output_surface);
cr.rectangle(
bounds.x0 as f64,
bounds.y0 as f64,
(bounds.x1 - bounds.x0) as f64,
(bounds.y1 - bounds.y0) as f64,
);
cr.clip();
cr.set_source_rgba(
f64::from(color.red) / 255f64,
f64::from(color.green) / 255f64,
f64::from(color.blue) / 255f64,
opacity,
);
cr.paint();
}
Ok(FilterResult {
name: self.base.result.borrow().clone(),
output: FilterOutput {
surface: SharedImageSurface::new(output_surface).unwrap(),
bounds,
},
})
}
}
|