summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/typst/src/visualize/image/svg.rs36
1 files changed, 22 insertions, 14 deletions
diff --git a/crates/typst/src/visualize/image/svg.rs b/crates/typst/src/visualize/image/svg.rs
index d5cae6fe..de53a858 100644
--- a/crates/typst/src/visualize/image/svg.rs
+++ b/crates/typst/src/visualize/image/svg.rs
@@ -4,8 +4,9 @@ use std::sync::Arc;
use comemo::Tracked;
use ecow::EcoString;
+use once_cell::sync::Lazy;
use siphasher::sip128::Hasher128;
-use usvg::{Node, PostProcessingSteps, TreeParsing, TreePostProc};
+use usvg::{ImageHrefResolver, Node, PostProcessingSteps, TreeParsing, TreePostProc};
use crate::diag::{format_xml_like_error, StrResult};
use crate::foundations::Bytes;
@@ -31,7 +32,7 @@ impl SvgImage {
#[comemo::memoize]
pub fn new(data: Bytes) -> StrResult<SvgImage> {
let mut tree =
- usvg::Tree::from_data(&data, &options()).map_err(format_usvg_error)?;
+ usvg::Tree::from_data(&data, &OPTIONS).map_err(format_usvg_error)?;
tree.calculate_bounding_boxes();
Ok(Self(Arc::new(Repr {
data,
@@ -50,7 +51,7 @@ impl SvgImage {
families: &[String],
) -> StrResult<SvgImage> {
let mut tree =
- usvg::Tree::from_data(&data, &options()).map_err(format_usvg_error)?;
+ usvg::Tree::from_data(&data, &OPTIONS).map_err(format_usvg_error)?;
let mut font_hash = 0;
if tree.has_text_nodes() {
let (fontdb, hash) = load_svg_fonts(world, &mut tree, families);
@@ -124,20 +125,27 @@ impl Hash for Repr {
}
/// The conversion options.
-fn options() -> usvg::Options {
+static OPTIONS: Lazy<usvg::Options> = Lazy::new(|| usvg::Options {
// Disable usvg's default to "Times New Roman". Instead, we default to
// the empty family and later, when we traverse the SVG, we check for
// empty and non-existing family names and replace them with the true
- // fallback family. This way, we can memoize SVG decoding with and without
- // fonts if the SVG does not contain text.
- usvg::Options {
- font_family: String::new(),
- // We override the DPI here so that we get the correct the size when
- // scaling the image to its natural size.
- dpi: Image::DEFAULT_DPI as f32,
- ..Default::default()
- }
-}
+ // fallback family. This way, we can memoize SVG decoding with and
+ // without fonts if the SVG does not contain text.
+ font_family: String::new(),
+
+ // We override the DPI here so that we get the correct the size when
+ // scaling the image to its natural size.
+ dpi: Image::DEFAULT_DPI as f32,
+
+ // Override usvg's resource loading defaults.
+ resources_dir: None,
+ image_href_resolver: ImageHrefResolver {
+ resolve_data: ImageHrefResolver::default_data_resolver(),
+ resolve_string: Box::new(|_, _| None),
+ },
+
+ ..Default::default()
+});
/// Discover and load the fonts referenced by an SVG.
fn load_svg_fonts(