diff --git a/Cargo.lock b/Cargo.lock index 0f75c9445..ea98dac41 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -806,13 +806,14 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fontdb" -version = "0.13.1" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "237ff9f0813bbfc9de836016472e0c9ae7802f174a51594607e5f4ff334cb2f5" +checksum = "af8d8cbea8f21307d7e84bca254772981296f058a1d36b461bf4d83a7499fc9e" dependencies = [ "log", "slotmap", - "ttf-parser 0.18.1", + "tinyvec", + "ttf-parser 0.19.2", ] [[package]] @@ -1148,9 +1149,9 @@ dependencies = [ [[package]] name = "imagesize" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b72ad49b554c1728b1e83254a1b1565aea4161e28dabbfa171fc15fe62299caf" +checksum = "029d73f573d8e8d63e6d5020011d3255b28c3ba85d6cf870a07184ed23de9284" [[package]] name = "include_dir" @@ -2033,9 +2034,9 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "resvg" -version = "0.32.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "142e83d8ae8c8c639f304698a5567b229ba65caba867bf4387bbc0ae158827cf" +checksum = "b6554f47c38eca56827eea7f285c2a3018b4e12e0e195cc105833c008be338f1" dependencies = [ "gif", "jpeg-decoder", @@ -2078,19 +2079,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316" -[[package]] -name = "rosvgtree" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad747e7384940e7bf33b15ba433b7bad9f44c0c6d5287a67c2cb22cd1743d497" -dependencies = [ - "log", - "roxmltree", - "simplecss", - "siphasher", - "svgtypes", -] - [[package]] name = "roxmltree" version = "0.18.0" @@ -2467,9 +2455,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "svg2pdf" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c966e59fd4afd959edcc226687f751a7d05c94d0477cca1a4c2b15a7220f2b24" +checksum = "0c267ce43e1b46631a121481ae2d7dc00dda163d486f0f600be772bbe24d6037" dependencies = [ "image", "miniz_oxide", @@ -2652,9 +2640,9 @@ dependencies = [ [[package]] name = "tiny-skia" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce2986c82f77818c7b9144c70818fdde98db15308e329ae2f7204d767808fd3c" +checksum = "7db11798945fa5c3e5490c794ccca7c6de86d3afdd54b4eb324109939c6f37bc" dependencies = [ "arrayref", "arrayvec", @@ -2667,9 +2655,9 @@ dependencies = [ [[package]] name = "tiny-skia-path" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7acb0ccda1ac91084353a56d0b69b0e29c311fd809d2088b1ed2f9ae1841c47" +checksum = "2f60aa35c89ac2687ace1a2556eaaea68e8c0d47408a2e3e7f5c98a489e7281c" dependencies = [ "arrayref", "bytemuck", @@ -3027,7 +3015,7 @@ dependencies = [ "oxipng", "rayon", "tiny-skia", - "ttf-parser 0.19.2", + "ttf-parser 0.18.1", "typst", "typst-library", "unscanny", @@ -3197,9 +3185,9 @@ dependencies = [ [[package]] name = "usvg" -version = "0.32.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b44e14b7678bcc5947b397991432d0c4e02a103958a0ed5e1b9b961ddd08b21" +checksum = "14d09ddfb0d93bf84824c09336d32e42f80961a9d1680832eb24fdf249ce11e6" dependencies = [ "base64", "log", @@ -3212,26 +3200,27 @@ dependencies = [ [[package]] name = "usvg-parser" -version = "0.32.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90c8251d965c2882a636ffcc054340b1f13a6bce68779cb5b2084d8ffc2535be" +checksum = "d19bf93d230813599927d88557014e0908ecc3531666d47c634c6838bc8db408" dependencies = [ "data-url", "flate2", "imagesize", "kurbo", "log", - "rosvgtree", - "strict-num", + "roxmltree", + "simplecss", + "siphasher", "svgtypes", "usvg-tree", ] [[package]] name = "usvg-text-layout" -version = "0.32.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c4fed019d1af07bfe0f3bac13d120d7b51bc65b38cb24809cf4ed0b8b631138" +checksum = "035044604e89652c0a2959b8b356946997a52649ba6cade45928c2842376feb4" dependencies = [ "fontdb", "kurbo", @@ -3245,14 +3234,14 @@ dependencies = [ [[package]] name = "usvg-tree" -version = "0.32.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7371265c467cdae0ccc3655e2e3f310c695fb9f717c0d25187bf3b333f7b5159" +checksum = "7939a7e4ed21cadb5d311d6339730681c3e24c3e81d60065be80e485d3fc8b92" dependencies = [ - "kurbo", "rctree", "strict-num", "svgtypes", + "tiny-skia-path", ] [[package]] diff --git a/crates/typst/Cargo.toml b/crates/typst/Cargo.toml index d9918b110..78f920e32 100644 --- a/crates/typst/Cargo.toml +++ b/crates/typst/Cargo.toml @@ -24,7 +24,7 @@ bytemuck = "1" comemo = "0.3" ecow = { version = "0.1.2", features = ["serde"] } flate2 = "1" -fontdb = { version = "0.13", default-features = false } +fontdb = { version = "0.14", default-features = false } if_chain = "1" image = { version = "0.24", default-features = false, features = ["png", "jpeg", "gif"] } indexmap = { version = "2", features = ["serde"] } @@ -35,14 +35,14 @@ once_cell = "1" pdf-writer = "0.8.1" pixglyph = "0.2" regex = "1" -resvg = { version = "0.32", default-features = false, features = ["raster-images"] } +resvg = { version = "0.35.0", default-features = false, features = ["raster-images"] } roxmltree = "0.18" rustybuzz = "0.7" serde = { version = "1.0.184", features = ["derive"] } siphasher = "0.3" subsetter = "0.1.1" -svg2pdf = "0.6" -tiny-skia = "0.9.0" +svg2pdf = "0.7" +tiny-skia = "0.10.0" toml = { version = "0.8", default-features = false, features = ["parse"] } tracing = "0.1.37" ttf-parser = "0.19.2" @@ -51,7 +51,7 @@ unicode-ident = "1.0" unicode-math-class = "0.1" unicode-segmentation = "1" unscanny = "0.1" -usvg = { version = "0.32", default-features = false, features = ["text"] } +usvg = { version = "0.35", default-features = false, features = ["text"] } xmlwriter = "0.1.0" xmp-writer = "0.1" time = { version = "0.3.20", features = ["std", "formatting", "macros"] } diff --git a/crates/typst/src/export/render.rs b/crates/typst/src/export/render.rs index ac2a8b3dc..262bb2e23 100644 --- a/crates/typst/src/export/render.rs +++ b/crates/typst/src/export/render.rs @@ -6,7 +6,7 @@ use std::sync::Arc; use image::imageops::FilterType; use image::{GenericImageView, Rgba}; use pixglyph::Bitmap; -use resvg::FitTo; +use resvg::tiny_skia::IntRect; use tiny_skia as sk; use ttf_parser::{GlyphId, OutlineBuilder}; use usvg::{NodeExt, TreeParsing}; @@ -213,7 +213,8 @@ fn render_svg_glyph( // Parse SVG. let opts = usvg::Options::default(); - let tree = usvg::Tree::from_xmltree(&document, &opts).ok()?; + let usvg_tree = usvg::Tree::from_xmltree(&document, &opts).ok()?; + let tree = resvg::Tree::from_usvg(&usvg_tree); let view_box = tree.view_box.rect; // If there's no viewbox defined, use the em square for our scale @@ -223,12 +224,12 @@ fn render_svg_glyph( // ... but if there's a viewbox or width, use that. if root.has_attribute("viewBox") || root.has_attribute("width") { - width = view_box.width() as f32; + width = view_box.width(); } // Same as for width. if root.has_attribute("viewBox") || root.has_attribute("height") { - height = view_box.height() as f32; + height = view_box.height(); } let size = text.size.to_f32(); @@ -237,41 +238,30 @@ fn render_svg_glyph( // Compute the space we need to draw our glyph. // See https://github.com/RazrFalcon/resvg/issues/602 for why // using the svg size is problematic here. - let mut bbox = usvg::Rect::new_bbox(); - for node in tree.root.descendants() { - if let Some(rect) = node.calculate_bbox().and_then(|b| b.to_rect()) { + let mut bbox = usvg::BBox::default(); + for node in usvg_tree.root.descendants() { + if let Some(rect) = node.calculate_bbox() { bbox = bbox.expand(rect); } } - let canvas_rect = usvg::ScreenRect::new(0, 0, canvas.width(), canvas.height())?; - // Compute the bbox after the transform is applied. // We add a nice 5px border along the bounding box to // be on the safe size. We also compute the intersection // with the canvas rectangle - let svg_ts = usvg::Transform::new( - ts.sx.into(), - ts.kx.into(), - ts.ky.into(), - ts.sy.into(), - ts.tx.into(), - ts.ty.into(), - ); - let bbox = bbox.transform(&svg_ts)?.to_screen_rect(); - let bbox = usvg::ScreenRect::new( + let bbox = bbox.transform(ts)?.to_rect()?.round_out()?; + let bbox = IntRect::from_xywh( bbox.left() - 5, bbox.y() - 5, bbox.width() + 10, bbox.height() + 10, - )? - .fit_to_rect(canvas_rect); + )?; let mut pixmap = sk::Pixmap::new(bbox.width(), bbox.height())?; // We offset our transform so that the pixmap starts at the edge of the bbox. let ts = ts.post_translate(-bbox.left() as f32, -bbox.top() as f32); - resvg::render(&tree, FitTo::Original, ts, pixmap.as_mut())?; + tree.render(ts, &mut pixmap.as_mut()); canvas.draw_pixmap( bbox.left(), @@ -411,7 +401,8 @@ fn render_outline_glyph( // Premultiply the text color. let Paint::Solid(color) = text.fill; let c = color.to_rgba(); - let color = sk::ColorU8::from_rgba(c.r, c.g, c.b, 255).premultiply().get(); + let color = + bytemuck::cast(sk::ColorU8::from_rgba(c.r, c.g, c.b, 255).premultiply()); // Blend the glyph bitmap with the existing pixels on the canvas. let pixels = bytemuck::cast_slice_mut::(canvas.data_mut()); @@ -601,12 +592,12 @@ fn scaled_texture(image: &Image, w: u32, h: u32) -> Option> { } } DecodedImage::Svg(tree) => { - resvg::render( - tree, - FitTo::Size(w, h), - sk::Transform::identity(), - pixmap.as_mut(), - )?; + let tree = resvg::Tree::from_usvg(tree); + let ts = tiny_skia::Transform::from_scale( + w as f32 / tree.size.width(), + h as f32 / tree.size.height(), + ); + tree.render(ts, &mut pixmap.as_mut()) } } Some(Arc::new(pixmap)) diff --git a/tests/Cargo.toml b/tests/Cargo.toml index efacea19b..2e8727ad5 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -16,7 +16,7 @@ iai = { git = "https://github.com/typst/iai" } once_cell = "1" oxipng = { git = "https://github.com/typst/oxipng", rev = "b8ec65b", default-features = false, features = ["filetime", "parallel", "zopfli"] } rayon = "1.7.0" -tiny-skia = "0.9.0" +tiny-skia = "0.10.0" ttf-parser = "0.19.2" unscanny = "0.1" walkdir = "2" diff --git a/tests/ref/bugs/args-sink.png b/tests/ref/bugs/args-sink.png index 35f5021ad..564c59a2b 100644 Binary files a/tests/ref/bugs/args-sink.png and b/tests/ref/bugs/args-sink.png differ diff --git a/tests/ref/bugs/new-cm-svg.png b/tests/ref/bugs/new-cm-svg.png index c011bbfce..2d445c3ab 100644 Binary files a/tests/ref/bugs/new-cm-svg.png and b/tests/ref/bugs/new-cm-svg.png differ diff --git a/tests/ref/compiler/show-node.png b/tests/ref/compiler/show-node.png index cae9b9327..396e5429e 100644 Binary files a/tests/ref/compiler/show-node.png and b/tests/ref/compiler/show-node.png differ diff --git a/tests/ref/compiler/show-text.png b/tests/ref/compiler/show-text.png index 4d5033bbc..d09c606b8 100644 Binary files a/tests/ref/compiler/show-text.png and b/tests/ref/compiler/show-text.png differ diff --git a/tests/ref/layout/clip.png b/tests/ref/layout/clip.png index 11c486819..53565a982 100644 Binary files a/tests/ref/layout/clip.png and b/tests/ref/layout/clip.png differ diff --git a/tests/ref/layout/place-float-figure.png b/tests/ref/layout/place-float-figure.png index 2cecb5ffe..b2755f126 100644 Binary files a/tests/ref/layout/place-float-figure.png and b/tests/ref/layout/place-float-figure.png differ diff --git a/tests/ref/layout/stack-2.png b/tests/ref/layout/stack-2.png index 047a73af8..6cb0aad2f 100644 Binary files a/tests/ref/layout/stack-2.png and b/tests/ref/layout/stack-2.png differ diff --git a/tests/ref/math/content.png b/tests/ref/math/content.png index e7ec48fef..162514450 100644 Binary files a/tests/ref/math/content.png and b/tests/ref/math/content.png differ diff --git a/tests/ref/math/frac.png b/tests/ref/math/frac.png index b4d52fc84..a4873d201 100644 Binary files a/tests/ref/math/frac.png and b/tests/ref/math/frac.png differ diff --git a/tests/ref/math/style.png b/tests/ref/math/style.png index d2e6776ac..5df5a3836 100644 Binary files a/tests/ref/math/style.png and b/tests/ref/math/style.png differ diff --git a/tests/ref/meta/heading.png b/tests/ref/meta/heading.png index 065f8e68e..28b419072 100644 Binary files a/tests/ref/meta/heading.png and b/tests/ref/meta/heading.png differ diff --git a/tests/ref/text/copy-paste.png b/tests/ref/text/copy-paste.png index cbbad9405..ae4a5ad99 100644 Binary files a/tests/ref/text/copy-paste.png and b/tests/ref/text/copy-paste.png differ diff --git a/tests/ref/text/emoji.png b/tests/ref/text/emoji.png index 715cc30f8..1dbbba79a 100644 Binary files a/tests/ref/text/emoji.png and b/tests/ref/text/emoji.png differ diff --git a/tests/ref/text/escape.png b/tests/ref/text/escape.png index 47677745e..c94bc52f9 100644 Binary files a/tests/ref/text/escape.png and b/tests/ref/text/escape.png differ diff --git a/tests/ref/text/fallback.png b/tests/ref/text/fallback.png index 544a04340..7f1e3e385 100644 Binary files a/tests/ref/text/fallback.png and b/tests/ref/text/fallback.png differ diff --git a/tests/ref/text/font.png b/tests/ref/text/font.png index cb5ad984f..d3893ce8f 100644 Binary files a/tests/ref/text/font.png and b/tests/ref/text/font.png differ diff --git a/tests/ref/text/symbol.png b/tests/ref/text/symbol.png index 8848a89ed..3340bd9c4 100644 Binary files a/tests/ref/text/symbol.png and b/tests/ref/text/symbol.png differ diff --git a/tests/ref/visualize/svg-text.png b/tests/ref/visualize/svg-text.png index e9f02aeac..106d1c16b 100644 Binary files a/tests/ref/visualize/svg-text.png and b/tests/ref/visualize/svg-text.png differ