usvg-parser
An SVG parser used by usvg.
0.38.0
4.1M downloads/mo
#4971 most downloaded on crates.io
RazrFalcon/resvg
What this package is like to depend on
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
3 years old
9 releases · first in 2023
0 releases in the last 12 months
see the full history below
Release timeline
9 releases · Mar 2023 to Jan 2024
2024
2025
2026
Releases
latest 9-
0.38.021 Jan 2024Release notes
Open source →Added
- Each
usvg::Nodestores its absolute transform now.Node::abs_transform()executes in constant time now. usvg::Tree::calculate_bounding_boxesto calculate all bounding boxes beforehand.usvg::Node::bounding_boxwhich returns a precalculated node's bounding box in object coordinates.usvg::Node::abs_bounding_boxwhich returns a precalculated node's bounding box in canvas coordinates.usvg::Node::stroke_bounding_boxwhich returns a precalculated node's bounding box, including stroke, in object coordinates.usvg::Node::abs_stroke_bounding_boxwhich returns a precalculated node's bounding box, including stroke, in canvas coordinates.- (c-api)
resvg_get_node_stroke_bbox usvg::Node::filters_bounding_boxusvg::Node::abs_filters_bounding_boxusvg::Tree::postprocess
Changed
resvgrendersusvg::Treedirectly again.resvg::Treeis gone.usvgno longer usesrctreefor the nodes tree implementation. The tree is a regularenumnow.- A caller no longer need to use the awkward
*node.borrow(). - No more panics on incorrect mutable
Rc<RefCell>access. - Tree nodes respect tree's mutability rules. Before, one could mutate tree nodes when the tree
itself is not mutable. Because
Rc<RefCell>provides a shared mutable access.
- A caller no longer need to use the awkward
- Filters, clip paths, masks and patterns are stored as
Rc<RefCell<T>>instead ofRc<T>. This is required for proper mutability sinceNodeitself is no longer anRc. - Rename
usvg::NodeKindintousvg::Node. - Upgrade to Rust 2021 edition.
Removed
resvg::Tree. No longer needed.resvgcan renderusvg::Treedirectly once again.rctree::Nodemethods. TheNodeAPI is completely different now.usvg::NodeExt. No longer needed.usvg::Node::calculate_bbox. Useusvg::Node::abs_bounding_boxinstead.usvg::Tree::convert_text. Useusvg::Tree::postprocessinstead.usvg::TreeTextToPathtrait. No longer needed.
Fixed
- Mark
mask-typeas a presentation attribute. - Do not show needless warnings when parsing some attributes.
feImagerendering with a non-default position. Thanks to @LaurenzV.
- Each
-
0.37.016 Dec 2023Release notes
Open source →Added
usvgcan write text back to SVG now. Thanks to @LaurenzV.--preserve-textflag to theusvgCLI tool. Thanks to @LaurenzV.- Support
transform-originproperty. Thanks to @LaurenzV. - Support non-default markers order via
paint-order. Previously, only fill and stroke could have been swapped. Thanks to @LaurenzV. usvg_tree::Text::flattenedthat will contain a flattened/outlined text.usvg_tree::Text::bounding_box. Will be set only after text flattening.- Optimize
usvg_tree::NodeExt::abs_transformby storing absolute transforms in the tree instead of calculating them each time.
Changed
usvg_tree::Text::positionswas replaced withusvg_tree::Text::dxandusvg_tree::Text::dy.<br>usvg_tree::CharacterPosition::xandusvg_tree::CharacterPosition::yare gone. They were redundant and you should useusvg_tree::TextChunk::xandusvg_tree::TextChunk::yinstead.usvg_tree::LinearGradient::idandusvg_tree::RadialGradient::idare moved tousvg_tree::BaseGradient::id.- Do not generate element IDs during parsing. Previously, some elements like
clipPaths andfilters 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. - Text-to-paths conversion via
usvg_text_layout::Tree::convert_textno longer replaces original text elements with paths, but instead puts them intousvg_tree::Text::flattened.
Removed
- The
transformfield fromusvg_tree::Path,usvg_tree::Imageandusvg_tree::Text. Onlyusvg_tree::Groupcan 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. Useusvg_tree::Text::bounding_boxinstead.usvg_text_layout::TextToPathtrait forTextnodes. Only the whole tree can be converted at once.
Fixed
- Path object bounding box calculation. We were using point bounds instead of tight contour bounds. Was broken since v0.34
- Convert text-to-paths in embedded SVGs as well. The one inside the
Imagenode. Thanks to @LaurenzV. - Indirect
text-decorationresolving in some cases. Thanks to @LaurenzV. - (usvg) Clip paths writing to SVG. Thanks to @LaurenzV.
-
0.36.005 Oct 2023Release notes
Open source →Added
stroke-linejoin=miter-clipsupport. SVG2. Thanks to @torokati44.- Quoted FuncIRI support. Like
fill="url('#gradient')". SVG2. Thanks to @romanzes. - Allow float values in
rgb()andrgba()colors. SVG2. Thanks to @yisibl. auto-start-reversevariant support toorientin markers. SVG2. Thanks to @EpicEricEE.
Changed
- Update dependencies.
Fixed
-
0.35.028 Jun 2023Release notes
Open source →Fixed
- Panic when an element is completely outside the viewbox.
Removed
FillPaintandStrokePaintfilter 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_paintandusvg::filter::Filter::stroke_paint.BackgroundImage,BackgroundAlpha,FillPaintandStrokePaintfromusvg::filter::Input.usvg::Group::filter_fill_paintandusvg::Group::filter_stroke_paint.
-
0.34.027 May 2023Release notes
Open source →Changed
usvgusestiny-skiageometry primitives now, including thePathcontainer.<br> The main difference compared to the oldusvgprimitives is thattiny-skiausesf32instead off64. So while in theory we could loose some precision, in practice,f32is used mainly as a storage type and precise math operations are still done usingf64.<br>tiny-skiaprimitives 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 convertusvg::PathDataintotiny-skia::Pathbefore rendering. Which was just a useless reallocation.- All numbers are stored as
f32instead off64now. - Because we use
tiny-skia::Pathnow, we allow quadratic curves as well. This includesusvgCLI output. - Because we allow quadratic curves now, text might render slightly differently (better?). This is because TrueType fonts contain only quadratic curves and we were converting them to cubic before.
usvg::Pathno longer implementsDefault. Useusvg::Path::newinstead.- Replace
usvg::Rectwithtiny_skia::NonZeroRect. - Replace
usvg::PathBboxwithtiny_skia::Rect. - Unlike the old
usvg::PathBbox,tiny_skia::Rectallows both width and height to be zero. This is not an error. usvg::filter::Turbulence::base_frequencywas split intobase_frequency_xandbase_frequency_y.usvg::NodeExt::calculate_bboxno longer includes stroke bbox.- (c-api) Use
floatinstead ofdoubleeverywhere. - The
svgfilterscrate was merged intoresvg. - The
rosvgtreecrate was merged intousvg-parser. usvg::Group::filter_fillmoved tousvg::filter::Filter::fill_paint.usvg::Group::filter_strokemoved tousvg::filter::Filter::stroke_paint.
Remove
usvg::Point. Usetiny_skia::Pointinstead.usvg::FuzzyEq. Useusvg::ApproxEqUlpsinstead.usvg::FuzzyZero. Useusvg::ApproxZeroUlpsinstead.- (c-api)
resvg_path_bbox. Useresvg_rectinstead. svgfilterscrate.rosvgtreecrate.
Fixed
- Write
transformonclipPathchildren inusvgSVG output. - Do not duplicate marker children IDs.
Previously, each element resolved for a marker would preserve its ID.
Affects only
usvgSVG output and doesn't affect rendering.
-
0.33.017 May 2023Release notes
Open source →Added
- A new rendering algorithm.<br>
When rendering isolated groups,
aka layers, we have to know the layer bounding box beforehand, which is ridiculously hard in SVG.<br>
Previously, resvg would simply use the canvas size for all the layers.
Meaning that to render a 10x10px layer on a 1000x1000px canvas, we would have to allocate and then blend
a 1000x1000px layer, which is just a waste of CPU cycles.<br>
The new rendering algorithm is able to calculate layer bounding boxes, which dramatically improves
performance when rendering a lot of tiny layers on a large canvas.<br>
Moreover, it makes performance more linear with a canvas size increase.<br>
The paris-30k.svg
sample from google/forma is rendered 115 times faster on M1 Pro now.
From ~33760ms down to ~290ms. 5269x3593px canvas.<br>
If we restrict the canvas to 1000x1000px, which would contain only the actual
paris-30k.svgcontent, then we're 13 times faster. From ~3252ms down to ~253ms. resvg::Tree, aka a render tree, which is an even simpler version ofusvg::Tree.usvg::Treehad to be converted intoresvg::Treebefore rendering now.
Changed
- Restructure the root directory. All crates are in the
cratesdirectory now. - Restructure tests. New directory structure and naming scheme.
- Use
resvg::Tree::renderinstead ofresvg::render. - resvg's
--export-area-drawingoption uses calculated bounds instead of trimming excessive alpha now. It's faster, but can lead to a slightly different output. - (c-api) Removed
fit_toargument fromresvg_render. - (c-api) Removed
fit_toargument fromresvg_render_node. usvg::ScreenSizemoved toresvg.usvg::ScreenRectmoved toresvg.- Rename
resvg::ScreenSizeintoresvg::IntSize. - Rename
resvg::ScreenRectintoresvg::IntRect.
Removed
filterbuild feature fromresvg. Filters are always enabled now.resvg::FitTousvg::utils::view_box_to_transform_with_clipusvg::Size::to_screen_size. Useresvg::IntSize::from_usvginstead.usvg::Rect::to_screen_size. Useresvg::IntSize::from_usvg(rect.size())instead.usvg::Rect::to_screen_rect. Useresvg::IntRect::from_usvginstead.- (c-api)
resvg_fit_to - (c-api)
resvg_fit_to_type
Fixed
- Double quotes parsing in
font-family.
- A new rendering algorithm.<br>
When rendering isolated groups,
aka layers, we have to know the layer bounding box beforehand, which is ridiculously hard in SVG.<br>
Previously, resvg would simply use the canvas size for all the layers.
Meaning that to render a 10x10px layer on a 1000x1000px canvas, we would have to allocate and then blend
a 1000x1000px layer, which is just a waste of CPU cycles.<br>
The new rendering algorithm is able to calculate layer bounding boxes, which dramatically improves
performance when rendering a lot of tiny layers on a large canvas.<br>
Moreover, it makes performance more linear with a canvas size increase.<br>
The paris-30k.svg
sample from google/forma is rendered 115 times faster on M1 Pro now.
From ~33760ms down to ~290ms. 5269x3593px canvas.<br>
If we restrict the canvas to 1000x1000px, which would contain only the actual
-
0.32.023 Apr 2023Release notes
Open source →Added
- Clipping and masking is up to 20% faster.
mask-typeproperty support. SVG2usvg_tree::MaskTypeusvg_tree::Mask::kind- (rosvgtree) New SVG 2 mask attributes.
Changed
BackgroundImageandBackgroundAlphafilter inputs will produce the same output asSourceGraphicandSourceAlpharespectively.
Removed
enable-backgroundsupport. 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
Fixed
- Improve rectangular clipping anti-aliasing quality.
- Mask's RGB to Luminance converter was ignoring premultiplied alpha.
-
0.31.010 Apr 2023Release notes
Open source →Added
usvg::Tree::paint_serversusvg::Tree::clip_pathsusvg::Tree::masksusvg::Tree::filtersusvg::Node::subroots- (usvg)
--coordinates-precisionand--transforms-precisionwriting options. Thanks to @flxzt.
Fixed
fill-opacityandstroke-opacityresolving.- Double
transformwhen resolvingsymbol. symbolclipping when its viewbox is the same as the document one.- (usvg) Deeply nested gradients, patterns, clip paths, masks and filters were ignored during SVG writing.
- Missing text in nested clip paths and mask, text decoration patterns, filter inputs and feImage.
-
0.30.026 Mar 2023Release notes
Open source →Added
- Readd
usvgCLI tool. Can be installed via cargo as before.
Changed
- Extract most
usvginternals into newusvg-treeandusvg-parsercrates.usvg-treecontains just the SVG tree and all the types.usvg-parserparsers SVG intousvg-tree. Andusvgis just an umbrella crate now. - To use
usvg::Tree::from*methods one should import theusvg::TreeParsingtrait now. - No need to import
usvg-text-layoutmanually anymore. It is part ofusvgnow. rosvgtreeno longer reexportssvgtypes.rosvgtree::Node::attributereturns just a string now.rosvgtree::Node::find_attributereturns just arosvgtree::Nodenow.- Rename
usvg::Stretchintousvg::FontStretch. - Rename
usvg::Styleintousvg::FontStyle. usvg::FitTomoved toresvg::FitTo.usvg::IsDefaulttrait is private now.
Removed
rosvgtree::FromValue. Due to Rust's orphan rules this trait is pretty useless.
Fixed
- Recursive markers detection.
- Skip malformed
transformattributes without skipping the whole element. - Clipping path rectangle calculation for nested
svgelements. Thanks to @LaurenzV. - Panic when applying
text-decorationon text with only one cluster. Thanks to @LaurenzV. - (Qt API) Image size wasn't initialized. Thanks to @missdeer.
resvgCLI allows files with XML DTD again.- (svgtypes) Handle implicit MoveTo after ClosePath segments.
- Readd