experimental SVG-based video rendering engine made for music videos. React to MIDI or arbitrary signals from your DAW through "probe" VSTs
1use anyhow::Result;
2use measure_time::debug_time;
3use resvg::usvg;
4use std::sync::Arc;
5
6pub fn create_pixmap(width: u32, height: u32) -> tiny_skia::Pixmap {
7 debug_time!("create_pixmap");
8 tiny_skia::Pixmap::new(width, height).expect("Failed to create pixmap")
9}
10
11pub fn paint_svg_on_pixmap(
12 pixmap: tiny_skia::PixmapMut<'_>,
13 svg_contents: &str,
14 canvas_dimensions: (usize, usize),
15 fontdb: &Option<Arc<usvg::fontdb::Database>>,
16) -> Result<()> {
17 debug_time!("paint_svg_on_pixmap");
18 let parsed_svg = &svg_to_usvg_tree(svg_contents, fontdb)?;
19
20 usvg_tree_to_pixmap(canvas_dimensions, pixmap, parsed_svg);
21
22 Ok(())
23}
24
25pub fn usvg_tree_to_pixmap(
26 canvas_dimensions: (usize, usize),
27 mut pixmap_mut: tiny_skia::PixmapMut<'_>,
28 parsed_svg: &resvg::usvg::Tree,
29) {
30 debug_time!("usvg_tree_to_pixmap");
31
32 let (canvas_width, canvas_height) = canvas_dimensions;
33 let (target_width, target_height) = (pixmap_mut.width(), pixmap_mut.height());
34
35 resvg::render(
36 parsed_svg,
37 tiny_skia::Transform::from_scale(
38 target_width as f32 / canvas_width as f32,
39 target_height as f32 / canvas_height as f32,
40 ),
41 &mut pixmap_mut,
42 );
43}
44
45pub fn svg_to_usvg_tree(
46 svg: &str,
47 fontdb: &Option<Arc<usvg::fontdb::Database>>,
48) -> anyhow::Result<resvg::usvg::Tree> {
49 debug_time!("svg_to_usvg_tree");
50 Ok(resvg::usvg::Tree::from_str(
51 svg,
52 &match fontdb {
53 Some(fontdb) => resvg::usvg::Options {
54 fontdb: fontdb.clone(),
55 ..Default::default()
56 },
57 None => resvg::usvg::Options::default(),
58 },
59 )?)
60}
61
62pub fn pixmap_to_png_data(pixmap: tiny_skia::Pixmap) -> anyhow::Result<Vec<u8>> {
63 debug_time!("pixmap_to_png_data");
64 Ok(pixmap.encode_png()?)
65}
66
67pub fn write_png_data(data: Vec<u8>, at: &str) -> anyhow::Result<()> {
68 debug_time!("write_png_data");
69 std::fs::write(at, data)?;
70 Ok(())
71}