diff options
| author | frozolotl <44589151+frozolotl@users.noreply.github.com> | 2025-01-31 10:56:25 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-31 09:56:25 +0000 |
| commit | 3eb6e87af1d8870a38cc5914e345d07373e1e8c1 (patch) | |
| tree | 800de2bc1ed9a5c7f8efc21e2741c0cd5c4728f6 /crates/typst-svg/src/image.rs | |
| parent | be1fa91a00a9bff6c5eb9744266f252b8cc23fe4 (diff) | |
Include images from raw pixmaps and more (#5632)
Co-authored-by: PgBiel <9021226+PgBiel@users.noreply.github.com>
Co-authored-by: Laurenz <laurmaedje@gmail.com>
Diffstat (limited to 'crates/typst-svg/src/image.rs')
| -rw-r--r-- | crates/typst-svg/src/image.rs | 48 |
1 files changed, 38 insertions, 10 deletions
diff --git a/crates/typst-svg/src/image.rs b/crates/typst-svg/src/image.rs index ede4e76e..d7443202 100644 --- a/crates/typst-svg/src/image.rs +++ b/crates/typst-svg/src/image.rs @@ -1,7 +1,11 @@ use base64::Engine; use ecow::{eco_format, EcoString}; +use image::{codecs::png::PngEncoder, ImageEncoder}; +use typst_library::foundations::Smart; use typst_library::layout::{Abs, Axes}; -use typst_library::visualize::{Image, ImageFormat, RasterFormat, VectorFormat}; +use typst_library::visualize::{ + ExchangeFormat, Image, ImageKind, ImageScaling, RasterFormat, +}; use crate::SVGRenderer; @@ -14,6 +18,17 @@ impl SVGRenderer { self.xml.write_attribute("width", &size.x.to_pt()); self.xml.write_attribute("height", &size.y.to_pt()); self.xml.write_attribute("preserveAspectRatio", "none"); + match image.scaling() { + Smart::Auto => {} + Smart::Custom(ImageScaling::Smooth) => { + // This is still experimental and not implemented in all major browsers. + // https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering#browser_compatibility + self.xml.write_attribute("style", "image-rendering: smooth") + } + Smart::Custom(ImageScaling::Pixelated) => { + self.xml.write_attribute("style", "image-rendering: pixelated") + } + } self.xml.end_element(); } } @@ -22,19 +37,32 @@ impl SVGRenderer { /// `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 buf; + let (format, data): (&str, &[u8]) = match image.kind() { + ImageKind::Raster(raster) => match raster.format() { + RasterFormat::Exchange(format) => ( + match format { + ExchangeFormat::Png => "png", + ExchangeFormat::Jpg => "jpeg", + ExchangeFormat::Gif => "gif", + }, + raster.data(), + ), + RasterFormat::Pixel(_) => ("png", { + buf = vec![]; + let mut encoder = PngEncoder::new(&mut buf); + if let Some(icc_profile) = raster.icc() { + encoder.set_icc_profile(icc_profile.to_vec()).ok(); + } + raster.dynamic().write_with_encoder(encoder).unwrap(); + buf.as_slice() + }), }, + ImageKind::Svg(svg) => ("svg+xml", svg.data()), }; let mut url = eco_format!("data:image/{format};base64,"); - let data = base64::engine::general_purpose::STANDARD.encode(image.data()); + let data = base64::engine::general_purpose::STANDARD.encode(data); url.push_str(&data); url } |
