2024-05-07 09:55:59 +00:00

41 lines
1.3 KiB
Rust

use base64::Engine;
use ecow::{eco_format, EcoString};
use typst::layout::{Abs, Axes};
use typst::visualize::{Image, ImageFormat, RasterFormat, VectorFormat};
use crate::SVGRenderer;
impl SVGRenderer {
/// Render an image element.
pub(super) fn render_image(&mut self, image: &Image, size: &Axes<Abs>) {
let url = convert_image_to_base64_url(image);
self.xml.start_element("image");
self.xml.write_attribute("xlink:href", &url);
self.xml.write_attribute("width", &size.x.to_pt());
self.xml.write_attribute("height", &size.y.to_pt());
self.xml.write_attribute("preserveAspectRatio", "none");
self.xml.end_element();
}
}
/// Encode an image into a data URL. The format of the URL is
/// `data:image/{format};base64,`.
#[comemo::memoize]
pub fn convert_image_to_base64_url(image: &Image) -> EcoString {
let format = match image.format() {
ImageFormat::Raster(f) => match f {
RasterFormat::Png => "png",
RasterFormat::Jpg => "jpeg",
RasterFormat::Gif => "gif",
},
ImageFormat::Vector(f) => match f {
VectorFormat::Svg => "svg+xml",
},
};
let mut url = eco_format!("data:image/{format};base64,");
let data = base64::engine::general_purpose::STANDARD.encode(image.data());
url.push_str(&data);
url
}