use std::borrow::Cow;
use crate::common::Result;
use crate::{BufferedImageLuminanceSource, Exceptions, LuminanceSource};
use image::{DynamicImage, RgbaImage};
use resvg::{self, usvg::Options};
pub struct SVGLuminanceSource(BufferedImageLuminanceSource);
impl LuminanceSource for SVGLuminanceSource {
fn get_row(&'_ self, y: usize) -> Option<Cow<'_, [u8]>> {
self.0.get_row(y)
}
fn get_column(&self, x: usize) -> Vec<u8> {
self.0.get_column(x)
}
fn get_matrix(&self) -> Vec<u8> {
self.0.get_matrix()
}
fn get_width(&self) -> usize {
self.0.get_width()
}
fn get_height(&self) -> usize {
self.0.get_height()
}
fn is_crop_supported(&self) -> bool {
self.0.is_crop_supported()
}
fn crop(&self, left: usize, top: usize, width: usize, height: usize) -> Result<Self> {
self.0.crop(left, top, width, height).map(Self)
}
fn is_rotate_supported(&self) -> bool {
self.0.is_rotate_supported()
}
fn invert(&mut self) {
self.0.invert()
}
fn rotate_counter_clockwise(&self) -> Result<Self> {
self.0.rotate_counter_clockwise().map(Self)
}
fn rotate_counter_clockwise_45(&self) -> Result<Self> {
self.0.rotate_counter_clockwise_45().map(Self)
}
fn get_luma8_point(&self, x: usize, y: usize) -> u8 {
self.0.get_luma8_point(x, y)
}
}
impl SVGLuminanceSource {
pub fn new(svg_data: &[u8]) -> Result<Self> {
let Ok(tree) = resvg::usvg::Tree::from_data(svg_data, &Options::default()) else {
return Err(Exceptions::format_with(format!(
"could not parse svg data: {}",
"err"
)));
};
let Some(mut pixmap) =
resvg::tiny_skia::Pixmap::new(tree.size().width() as u32, tree.size().height() as u32)
else {
return Err(Exceptions::format_with("could not create pixmap"));
};
resvg::render(
&tree,
resvg::tiny_skia::Transform::default(),
&mut pixmap.as_mut(),
);
let Some(buffer) = RgbaImage::from_raw(
tree.size().width() as u32,
tree.size().height() as u32,
pixmap.data().to_vec(),
) else {
return Err(Exceptions::format_with("could not create image buffer"));
};
Ok(Self(BufferedImageLuminanceSource::new(DynamicImage::from(
buffer,
))))
}
}