NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #5114 most downloaded on crates.io
An SVG tree representation used by usvg.
Last release 3 years ago
no release in 18 months
Release timing varies
gaps range from 9 days to 3 months
Nearly every release is documented
notes for 9 of 9 stable releases
Nothing withdrawn
no release was ever pulled
4 years old
9 releases · first in 2023
One column per quarter.
Each usvg::Node stores its absolute transform now. Node::abs_transform() executes in constant time now.
usvg::Node stores its absolute transform now.
Node::abs_transform() executes in constant time now.usvg::Tree::calculate_bounding_boxes to calculate all bounding boxes beforehand.usvg::Node::bounding_box which returns a precalculated node's bounding box in object coordinates.usvg::Node::abs_bounding_box which returns a precalculated node's bounding box in canvas coordinates.usvg::Node::stroke_bounding_box which returns a precalculated node's bounding box,
including stroke, in object coordinates.usvg::Node::abs_stroke_bounding_box which returns a precalculated node's bounding box,
including stroke, in canvas coordinates.resvg_get_node_stroke_bboxusvg::Node::filters_bounding_boxusvg::Node::abs_filters_bounding_boxusvg::Tree::postprocessresvg renders usvg::Tree directly again. resvg::Tree is gone.usvg no longer uses rctree for the nodes tree implementation.
The tree is a regular enum now.
*node.borrow().Rc<RefCell> access.Rc<RefCell> provides a shared mutable access.Rc<RefCell<T>> instead of Rc<T>.
This is required for proper mutability since Node itself is no longer an Rc.usvg::NodeKind into usvg::Node.resvg::Tree. No longer needed. resvg can render usvg::Tree directly once again.rctree::Node methods. The Node API is completely different now.usvg::NodeExt. No longer needed.usvg::Node::calculate_bbox. Use usvg::Node::abs_bounding_box instead.usvg::Tree::convert_text. Use usvg::Tree::postprocess instead.usvg::TreeTextToPath trait. No longer needed.mask-type as a presentation attribute.feImage rendering with a non-default position.
Thanks to @LaurenzV.usvg can write text back to SVG now. Thanks to @LaurenzV.
usvg can write text back to SVG now.
Thanks to @LaurenzV.--preserve-text flag to the usvg CLI tool.
Thanks to @LaurenzV.transform-origin
property.
Thanks to @LaurenzV.paint-order.
Previously, only fill and stroke could have been swapped.
Thanks to @LaurenzV.usvg_tree::Text::flattened that will contain a flattened/outlined text.usvg_tree::Text::bounding_box. Will be set only after text flattening.usvg_tree::NodeExt::abs_transform by storing absolute transforms in the tree
instead of calculating them each time.usvg_tree::Text::positions was replaced with usvg_tree::Text::dx and usvg_tree::Text::dy.<br>
usvg_tree::CharacterPosition::x and usvg_tree::CharacterPosition::y are gone.
They were redundant and you should use usvg_tree::TextChunk::x
and usvg_tree::TextChunk::y instead.usvg_tree::LinearGradient::id and usvg_tree::RadialGradient::id are moved to
usvg_tree::BaseGradient::id.clipPaths
and filters could have generated IDs, but it wasn't very reliable and mostly unnecessary.
Renderer doesn't rely on them and usvg writer would generate them anyway.usvg_text_layout::Tree::convert_text no longer replaces
original text elements with paths, but instead puts them into usvg_tree::Text::flattened.transform field from usvg_tree::Path, usvg_tree::Image and usvg_tree::Text.
Only usvg_tree::Group can have it.<br>
It doesn't break anything, because those properties were never used before anyway.<br>
Thanks to @LaurenzV.usvg_tree::CharacterPositionusvg_tree::Path::text_bbox. Use usvg_tree::Text::bounding_box instead.usvg_text_layout::TextToPath trait for Text nodes.
Only the whole tree can be converted at once.Image node.
Thanks to @LaurenzV.text-decoration resolving in some cases.
Thanks to @LaurenzV.stroke-linejoin=miter-clip support. SVG2. Thanks to @torokati44.
stroke-linejoin=miter-clip support. SVG2.
Thanks to @torokati44.fill="url('#gradient')". SVG2.
Thanks to @romanzes.rgb() and rgba() colors. SVG2.
Thanks to @yisibl.auto-start-reverse variant support to orient in markers. SVG2.
Thanks to @EpicEricEE.Panic when an element is completely outside the viewbox.
FillPaint and StrokePaint filter inputs support.
It's a mostly undocumented SVG feature that no one supports and no one uses.
And it was adding a significant complexity to the codebase.usvg::filter::Filter::fill_paint and usvg::filter::Filter::stroke_paint.BackgroundImage, BackgroundAlpha, FillPaint and StrokePaint from usvg::filter::Input.usvg::Group::filter_fill_paint and usvg::Group::filter_stroke_paint.usvg uses tiny-skia geometry primitives now, including the Path container. The main difference compared to the old usvg primitives is that tiny-skia u
usvg uses tiny-skia geometry primitives now, including the Path container.<br>
The main difference compared to the old usvg primitives
is that tiny-skia uses f32 instead of f64.
So while in theory we could loose some precision, in practice, f32 is used mainly
as a storage type and precise math operations are still done using f64.<br>
tiny-skia primitives are move robust, strict and have a nicer API.<br>
More importantly, this change reduces the peak memory usages for SVGs with large paths
(in terms of the number of segments).
And removes the need to convert usvg::PathData into tiny-skia::Path before rendering.
Which was just a useless reallocation.f32 instead of f64 now.tiny-skia::Path now, we allow quadratic curves as well.
This includes usvg CLI output.usvg::Path no longer implements Default. Use usvg::Path::new instead.usvg::Rect with tiny_skia::NonZeroRect.usvg::PathBbox with tiny_skia::Rect.usvg::PathBbox, tiny_skia::Rect allows both width and height to be zero.
This is not an error.usvg::filter::Turbulence::base_frequency was split into base_frequency_x and base_frequency_y.usvg::NodeExt::calculate_bbox no longer includes stroke bbox.float instead of double everywhere.svgfilters crate was merged into resvg.rosvgtree crate was merged into usvg-parser.usvg::Group::filter_fill moved to usvg::filter::Filter::fill_paint.usvg::Group::filter_stroke moved to usvg::filter::Filter::stroke_paint.usvg::Point. Use tiny_skia::Point instead.usvg::FuzzyEq. Use usvg::ApproxEqUlps instead.usvg::FuzzyZero. Use usvg::ApproxZeroUlps instead.resvg_path_bbox. Use resvg_rect instead.svgfilters crate.rosvgtree crate.transform on clipPath children in usvg SVG output.usvg SVG output and doesn't affect rendering.A new rendering algorithm. When rendering isolated groups, aka layers, we have to know the layer bounding box beforehand, which is ridiculously hard i
paris-30k.svg content,
then we're 13 times faster. From ~3252ms down to ~253ms.resvg::Tree, aka a render tree, which is an even simpler version of usvg::Tree.
usvg::Tree had to be converted into resvg::Tree before rendering now.crates directory now.resvg::Tree::render instead of resvg::render.--export-area-drawing option uses calculated bounds instead of trimming
excessive alpha now. It's faster, but can lead to a slightly different output.fit_to argument from resvg_render.fit_to argument from resvg_render_node.usvg::ScreenSize moved to resvg.usvg::ScreenRect moved to resvg.resvg::ScreenSize into resvg::IntSize.resvg::ScreenRect into resvg::IntRect.filter build feature from resvg. Filters are always enabled now.resvg::FitTousvg::utils::view_box_to_transform_with_clipusvg::Size::to_screen_size. Use resvg::IntSize::from_usvg instead.usvg::Rect::to_screen_size. Use resvg::IntSize::from_usvg(rect.size()) instead.usvg::Rect::to_screen_rect. Use resvg::IntRect::from_usvg instead.resvg_fit_toresvg_fit_to_typefont-family.enable-background support. This feature was never supported by browsers and was deprecated in SVG 2. To my knowledge, only Batik has a good support of…
mask-type property support. SVG2usvg_tree::MaskTypeusvg_tree::Mask::kindBackgroundImage and BackgroundAlpha filter inputs will produce the same output
as SourceGraphic and SourceAlpha respectively.enable-background support. This feature was never supported by browsers
and was deprecated in SVG 2. To my knowledge, only Batik has a good support of it.
Also, it's a performance nightmare, which caused multiple issues in resvg already.usvg_tree::EnableBackgroundusvg_tree::Group::enable_backgroundusvg_tree::NodeExt::filter_background_start_node(usvg) --coordinates-precision and --transforms-precision writing options. Thanks to @flxzt.
usvg::Tree::paint_serversusvg::Tree::clip_pathsusvg::Tree::masksusvg::Tree::filtersusvg::Node::subroots--coordinates-precision and --transforms-precision writing options.
Thanks to @flxzt.fill-opacity and stroke-opacity resolving.transform when resolving symbol.symbol clipping when its viewbox is the same as the document one.Readd usvg CLI tool. Can be installed via cargo as before.
usvg CLI tool. Can be installed via cargo as before.usvg internals into new usvg-tree and usvg-parser crates.
usvg-tree contains just the SVG tree and all the types.
usvg-parser parsers SVG into usvg-tree.
And usvg is just an umbrella crate now.usvg::Tree::from* methods one should import the usvg::TreeParsing trait now.usvg-text-layout manually anymore. It is part of usvg now.rosvgtree no longer reexports svgtypes.rosvgtree::Node::attribute returns just a string now.rosvgtree::Node::find_attribute returns just a rosvgtree::Node now.usvg::Stretch into usvg::FontStretch.usvg::Style into usvg::FontStyle.usvg::FitTo moved to resvg::FitTo.usvg::IsDefault trait is private now.rosvgtree::FromValue. Due to Rust's orphan rules this trait is pretty useless.transform attributes without skipping the whole element.svg elements.
Thanks to @LaurenzV.text-decoration on text with only one cluster.
Thanks to @LaurenzV.resvg CLI allows files with XML DTD again.Your coding agent can read these notes before it upgrades. Set up the MCP server →