mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
More robust SVG auto-detection (#5878)
This commit is contained in:
parent
e294fe85a5
commit
d48708c5d5
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -2966,6 +2966,7 @@ dependencies = [
|
||||
"kamadak-exif",
|
||||
"kurbo",
|
||||
"lipsum",
|
||||
"memchr",
|
||||
"palette",
|
||||
"phf",
|
||||
"png",
|
||||
|
@ -73,6 +73,7 @@ kamadak-exif = "0.6"
|
||||
kurbo = "0.11"
|
||||
libfuzzer-sys = "0.4"
|
||||
lipsum = "0.9"
|
||||
memchr = "2"
|
||||
miniz_oxide = "0.8"
|
||||
native-tls = "0.2"
|
||||
notify = "8"
|
||||
|
@ -38,6 +38,7 @@ indexmap = { workspace = true }
|
||||
kamadak-exif = { workspace = true }
|
||||
kurbo = { workspace = true }
|
||||
lipsum = { workspace = true }
|
||||
memchr = { workspace = true }
|
||||
palette = { workspace = true }
|
||||
phf = { workspace = true }
|
||||
png = { workspace = true }
|
||||
|
@ -398,8 +398,7 @@ impl ImageFormat {
|
||||
return Some(Self::Raster(RasterFormat::Exchange(format)));
|
||||
}
|
||||
|
||||
// SVG or compressed SVG.
|
||||
if data.starts_with(b"<svg") || data.starts_with(&[0x1f, 0x8b]) {
|
||||
if is_svg(data) {
|
||||
return Some(Self::Vector(VectorFormat::Svg));
|
||||
}
|
||||
|
||||
@ -407,6 +406,21 @@ impl ImageFormat {
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks whether the data looks like an SVG or a compressed SVG.
|
||||
fn is_svg(data: &[u8]) -> bool {
|
||||
// Check for the gzip magic bytes. This check is perhaps a bit too
|
||||
// permissive as other formats than SVGZ could use gzip.
|
||||
if data.starts_with(&[0x1f, 0x8b]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the first 2048 bytes contain the SVG namespace declaration, we assume
|
||||
// that it's an SVG. Note that, if the SVG does not contain a namespace
|
||||
// declaration, usvg will reject it.
|
||||
let head = &data[..data.len().min(2048)];
|
||||
memchr::memmem::find(head, b"http://www.w3.org/2000/svg").is_some()
|
||||
}
|
||||
|
||||
/// A vector graphics format.
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Cast)]
|
||||
pub enum VectorFormat {
|
||||
|
@ -99,8 +99,7 @@ description: Changes slated to appear in Typst 0.13.0
|
||||
- Fixed interaction of clipping and outset on [`box`] and [`block`]
|
||||
- Fixed panic with [`path`] of infinite length
|
||||
- Fixed non-solid (e.g. tiling) text fills in clipped blocks
|
||||
- Auto-detection of image formats from a raw buffer now has basic support for
|
||||
SVGs
|
||||
- Auto-detection of image formats from a raw buffer now has support for SVGs
|
||||
|
||||
## Scripting
|
||||
- Functions that accept [file paths]($syntax/#paths) now also accept raw
|
||||
|
BIN
tests/ref/image-svg-auto-detection.png
Normal file
BIN
tests/ref/image-svg-auto-detection.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 129 B |
@ -65,6 +65,17 @@ A #box(image("/assets/images/tiger.jpg", height: 1cm, width: 80%)) B
|
||||
caption: [Bilingual text]
|
||||
)
|
||||
|
||||
--- image-svg-auto-detection ---
|
||||
#image(bytes(
|
||||
```
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- An SVG -->
|
||||
<svg width="200" height="150" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect fill="red" stroke="black" x="25" y="25" width="150" height="100"/>
|
||||
</svg>
|
||||
```.text
|
||||
))
|
||||
|
||||
--- image-pixmap-rgb8 ---
|
||||
#image(
|
||||
bytes((
|
||||
@ -152,8 +163,8 @@ A #box(image("/assets/images/tiger.jpg", height: 1cm, width: 80%)) B
|
||||
#image("path/does/not/exist")
|
||||
|
||||
--- image-bad-format ---
|
||||
// Error: 2-22 unknown image format
|
||||
#image("./image.typ")
|
||||
// Error: 2-37 unknown image format
|
||||
#image("/assets/plugins/hello.wasm")
|
||||
|
||||
--- image-bad-svg ---
|
||||
// Error: 2-33 failed to parse SVG (found closing tag 'g' instead of 'style' in line 4)
|
||||
|
Loading…
x
Reference in New Issue
Block a user