1use crate::{AssetSource, DevicePixels, IsZero, Result, SharedString, Size};
2use anyhow::anyhow;
3use std::hash::Hash;
4use std::sync::Arc;
5
6#[derive(Clone, PartialEq, Hash, Eq)]
7pub struct RenderSvgParams {
8 pub(crate) path: SharedString,
9 pub(crate) size: Size<DevicePixels>,
10}
11
12pub struct SvgRenderer {
13 asset_source: Arc<dyn AssetSource>,
14}
15
16impl SvgRenderer {
17 pub fn new(asset_source: Arc<dyn AssetSource>) -> Self {
18 Self { asset_source }
19 }
20
21 pub fn render(&self, params: &RenderSvgParams) -> Result<Vec<u8>> {
22 if params.size.is_zero() {
23 return Err(anyhow!("can't render at a zero size"));
24 }
25
26 // Load the tree.
27 let bytes = self.asset_source.load(¶ms.path)?;
28 let tree = usvg::Tree::from_data(&bytes, &usvg::Options::default())?;
29
30 // Render the SVG to a pixmap with the specified width and height.
31 let mut pixmap =
32 tiny_skia::Pixmap::new(params.size.width.into(), params.size.height.into()).unwrap();
33 resvg::render(
34 &tree,
35 usvg::FitTo::Width(params.size.width.into()),
36 pixmap.as_mut(),
37 );
38
39 // Convert the pixmap's pixels into an alpha mask.
40 let alpha_mask = pixmap
41 .pixels()
42 .iter()
43 .map(|p| p.alpha())
44 .collect::<Vec<_>>();
45 Ok(alpha_mask)
46 }
47}