summaryrefslogtreecommitdiff
path: root/crates/typst-svg/src/image.rs
diff options
context:
space:
mode:
authorfrozolotl <44589151+frozolotl@users.noreply.github.com>2025-01-31 10:56:25 +0100
committerGitHub <noreply@github.com>2025-01-31 09:56:25 +0000
commit3eb6e87af1d8870a38cc5914e345d07373e1e8c1 (patch)
tree800de2bc1ed9a5c7f8efc21e2741c0cd5c4728f6 /crates/typst-svg/src/image.rs
parentbe1fa91a00a9bff6c5eb9744266f252b8cc23fe4 (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.rs48
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
}