| 1 | // Copyright 2019 the Resvg Authors |
| 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT |
| 3 | |
| 4 | use crate::render::Context; |
| 5 | |
| 6 | pub 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 | |