1 | // This Source Code Form is subject to the terms of the Mozilla Public |
2 | // License, v. 2.0. If a copy of the MPL was not distributed with this |
3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. |
4 | |
5 | use crate::render::Context; |
6 | |
7 | pub fn apply( |
8 | mask: &usvg::Mask, |
9 | ctx: &Context, |
10 | transform: tiny_skia::Transform, |
11 | pixmap: &mut tiny_skia::Pixmap, |
12 | ) { |
13 | if mask.root().children().is_empty() { |
14 | pixmap.fill(tiny_skia::Color::TRANSPARENT); |
15 | return; |
16 | } |
17 | |
18 | let mut mask_pixmap = tiny_skia::Pixmap::new(pixmap.width(), pixmap.height()).unwrap(); |
19 | |
20 | { |
21 | // TODO: only when needed |
22 | // Mask has to be clipped by mask.region |
23 | let mut alpha_mask = tiny_skia::Mask::new(pixmap.width(), pixmap.height()).unwrap(); |
24 | alpha_mask.fill_path( |
25 | &tiny_skia::PathBuilder::from_rect(mask.rect().to_rect()), |
26 | tiny_skia::FillRule::Winding, |
27 | true, |
28 | transform, |
29 | ); |
30 | |
31 | crate::render::render_nodes(mask.root(), ctx, transform, &mut mask_pixmap.as_mut()); |
32 | |
33 | mask_pixmap.apply_mask(&alpha_mask); |
34 | } |
35 | |
36 | if let Some(mask) = mask.mask() { |
37 | self::apply(mask, ctx, transform, pixmap); |
38 | } |
39 | |
40 | let mask_type = match mask.kind() { |
41 | usvg::MaskType::Luminance => tiny_skia::MaskType::Luminance, |
42 | usvg::MaskType::Alpha => tiny_skia::MaskType::Alpha, |
43 | }; |
44 | |
45 | let mask = tiny_skia::Mask::from_pixmap(mask_pixmap.as_ref(), mask_type); |
46 | pixmap.apply_mask(&mask); |
47 | } |
48 | |