summaryrefslogtreecommitdiff
path: root/crates/typst-layout/src/image.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2025-01-09 10:34:16 +0100
committerGitHub <noreply@github.com>2025-01-09 09:34:16 +0000
commite2b37fef33a92a7086790e04fb133472413c0c0a (patch)
treea2bdc638482890183414dce18f8f586786154017 /crates/typst-layout/src/image.rs
parentdacd6acd5e73d35c6e7a7a3b144f16ae70d03daa (diff)
Revamp data loading and deprecate `decode` functions (#5671)
Diffstat (limited to 'crates/typst-layout/src/image.rs')
-rw-r--r--crates/typst-layout/src/image.rs54
1 files changed, 26 insertions, 28 deletions
diff --git a/crates/typst-layout/src/image.rs b/crates/typst-layout/src/image.rs
index 59e2c021..e521b993 100644
--- a/crates/typst-layout/src/image.rs
+++ b/crates/typst-layout/src/image.rs
@@ -1,13 +1,13 @@
use std::ffi::OsStr;
-use typst_library::diag::{bail, warning, At, SourceResult, StrResult};
+use typst_library::diag::{warning, At, SourceResult, StrResult};
use typst_library::engine::Engine;
-use typst_library::foundations::{Packed, Smart, StyleChain};
+use typst_library::foundations::{Bytes, Derived, Packed, Smart, StyleChain};
use typst_library::introspection::Locator;
use typst_library::layout::{
Abs, Axes, FixedAlignment, Frame, FrameItem, Point, Region, Size,
};
-use typst_library::loading::Readable;
+use typst_library::loading::DataSource;
use typst_library::text::families;
use typst_library::visualize::{
Curve, Image, ImageElem, ImageFit, ImageFormat, RasterFormat, VectorFormat,
@@ -26,17 +26,17 @@ pub fn layout_image(
// Take the format that was explicitly defined, or parse the extension,
// or try to detect the format.
- let data = elem.data();
+ let Derived { source, derived: data } = &elem.source;
let format = match elem.format(styles) {
Smart::Custom(v) => v,
- Smart::Auto => determine_format(elem.path().as_str(), data).at(span)?,
+ Smart::Auto => determine_format(source, data).at(span)?,
};
// Warn the user if the image contains a foreign object. Not perfect
// because the svg could also be encoded, but that's an edge case.
if format == ImageFormat::Vector(VectorFormat::Svg) {
let has_foreign_object =
- data.as_str().is_some_and(|s| s.contains("<foreignObject"));
+ data.as_str().is_ok_and(|s| s.contains("<foreignObject"));
if has_foreign_object {
engine.sink.warn(warning!(
@@ -50,7 +50,7 @@ pub fn layout_image(
// Construct the image itself.
let image = Image::with_fonts(
- data.clone().into_bytes(),
+ data.clone(),
format,
elem.alt(styles),
engine.world,
@@ -119,25 +119,23 @@ pub fn layout_image(
Ok(frame)
}
-/// Determine the image format based on path and data.
-fn determine_format(path: &str, data: &Readable) -> StrResult<ImageFormat> {
- let ext = std::path::Path::new(path)
- .extension()
- .and_then(OsStr::to_str)
- .unwrap_or_default()
- .to_lowercase();
-
- Ok(match ext.as_str() {
- "png" => ImageFormat::Raster(RasterFormat::Png),
- "jpg" | "jpeg" => ImageFormat::Raster(RasterFormat::Jpg),
- "gif" => ImageFormat::Raster(RasterFormat::Gif),
- "svg" | "svgz" => ImageFormat::Vector(VectorFormat::Svg),
- _ => match &data {
- Readable::Str(_) => ImageFormat::Vector(VectorFormat::Svg),
- Readable::Bytes(bytes) => match RasterFormat::detect(bytes) {
- Some(f) => ImageFormat::Raster(f),
- None => bail!("unknown image format"),
- },
- },
- })
+/// Try to determine the image format based on the data.
+fn determine_format(source: &DataSource, data: &Bytes) -> StrResult<ImageFormat> {
+ if let DataSource::Path(path) = source {
+ let ext = std::path::Path::new(path.as_str())
+ .extension()
+ .and_then(OsStr::to_str)
+ .unwrap_or_default()
+ .to_lowercase();
+
+ match ext.as_str() {
+ "png" => return Ok(ImageFormat::Raster(RasterFormat::Png)),
+ "jpg" | "jpeg" => return Ok(ImageFormat::Raster(RasterFormat::Jpg)),
+ "gif" => return Ok(ImageFormat::Raster(RasterFormat::Gif)),
+ "svg" | "svgz" => return Ok(ImageFormat::Vector(VectorFormat::Svg)),
+ _ => {}
+ }
+ }
+
+ Ok(ImageFormat::detect(data).ok_or("unknown image format")?)
}