use tiny_skia::{Pixmap, Transform};
use super::svg_document::SvgDocument;
pub struct SvgRasterizer;
impl SvgRasterizer {
pub fn rasterize(doc: &SvgDocument, size: u32) -> Option<Pixmap> {
Self::rasterize_partial(doc, size, doc.shapes().len(), 1.0, None)
}
pub fn rasterize_with_background(
doc: &SvgDocument,
size: u32,
background: Option<(u8, u8, u8)>,
) -> Option<Pixmap> {
Self::rasterize_partial(doc, size, doc.shapes().len(), 1.0, background)
}
pub fn rasterize_partial(
doc: &SvgDocument,
size: u32,
shape_count: usize,
newest_alpha: f64,
background: Option<(u8, u8, u8)>,
) -> Option<Pixmap> {
let mut pixmap = Pixmap::new(size, size)?;
if let Some((r, g, b)) = background {
pixmap.fill(tiny_skia::Color::from_rgba8(r, g, b, 255));
}
let vw = doc.view_width();
let vh = doc.view_height();
let scale = if vw > 0.0 && vh > 0.0 {
(size as f64 / vw).min(size as f64 / vh) as f32
} else {
1.0
};
let tx = ((size as f64 - vw * scale as f64) / 2.0 - doc.view_x() * scale as f64) as f32;
let ty = ((size as f64 - vh * scale as f64) / 2.0 - doc.view_y() * scale as f64) as f32;
let view = Transform::from_scale(scale, scale).post_translate(tx, ty);
let shapes = doc.shapes();
let n = shape_count.min(shapes.len());
for (i, shape) in shapes.iter().take(n).enumerate() {
let alpha = if i == n - 1 { newest_alpha } else { 1.0 };
if alpha >= 1.0 {
shape.paint(&mut pixmap, view);
} else {
shape.with_alpha(alpha).paint(&mut pixmap, view);
}
}
Some(pixmap)
}
}