1// Copyright 2019 the Resvg Authors
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3
4use crate::render::Context;
5
6pub fn apply(
7 mask: &usvg::Mask,
8 ctx: &Context,
9 transform: tiny_skia::Transform,
10 pixmap: &mut tiny_skia::Pixmap,
11) {
12 if mask.root().children().is_empty() {
13 pixmap.fill(tiny_skia::Color::TRANSPARENT);
14 return;
15 }
16
17 let mut mask_pixmap = tiny_skia::Pixmap::new(pixmap.width(), pixmap.height()).unwrap();
18
19 {
20 // TODO: only when needed
21 // Mask has to be clipped by mask.region
22 let mut alpha_mask = tiny_skia::Mask::new(pixmap.width(), pixmap.height()).unwrap();
23 alpha_mask.fill_path(
24 &tiny_skia::PathBuilder::from_rect(mask.rect().to_rect()),
25 tiny_skia::FillRule::Winding,
26 true,
27 transform,
28 );
29
30 crate::render::render_nodes(mask.root(), ctx, transform, &mut mask_pixmap.as_mut());
31
32 mask_pixmap.apply_mask(&alpha_mask);
33 }
34
35 if let Some(mask) = mask.mask() {
36 self::apply(mask, ctx, transform, pixmap);
37 }
38
39 let mask_type = match mask.kind() {
40 usvg::MaskType::Luminance => tiny_skia::MaskType::Luminance,
41 usvg::MaskType::Alpha => tiny_skia::MaskType::Alpha,
42 };
43
44 let mask = tiny_skia::Mask::from_pixmap(mask_pixmap.as_ref(), mask_type);
45 pixmap.apply_mask(&mask);
46}
47