1# llimphi-svg
2
3A thin bridge between `vello_svg` and Llimphi.
4
5`llimphi-icons` covers the canonical set of ~50 hand-made icons (a `BezPath` on a
624×24 grid). For everything else — arbitrary `.desktop` app icons, logos, brand
7assets, vector exports from pineal/cosmos — you need to load real SVG. This crate
8is the bridge: it parses once with `vello_svg` and stamps the resulting
9`vello::Scene` into any `View`, scaling it to the node's rect.
10
11## Use
12
13```ignore
14use llimphi_svg::SvgAsset;
15
16// Parse ONCE (when loading the app or the icon):
17let svg = SvgAsset::from_str(include_str!("logo.svg")).expect("valid logo");
18
19// Paint it in a View as many times as you like (it scales to the rect):
20View::new(style).children(vec![svg.view::<Msg>()])
21```
22
23The parse costs something — `view()` does not. If you are going to stamp the same
24SVG in many nodes (an app list sharing a fallback icon), parse once and clone the
25`SvgAsset` (it is cheap: `Arc` internally).
26
27## Why not parse on every paint
28
29`vello_svg::render` runs `usvg`'s parser (~ms for a non-trivial SVG). In a list
30of 80 `.desktop` icons, parsing every frame kills the UI thread. The rule: **the
31asset is parsed once**, the resulting `Scene` is retained in memory and stamped
32with `scene.append(&inner, Some(xf))` — which costs the same as drawing the rest
33of the UI.
34
35## Errors
36
37`SvgAsset::from_str` returns `Result<Self, SvgError>` — for corrupt XML or
38features `usvg` does not support. Typical apps treat the error as "fall back to a
39generic glyph" — they do not break.
40
41---
42
43Part of **llimphi** — see [llimphi](../README.md).
README.md
llimphi-svg
A thin bridge between vello_svg and Llimphi.
llimphi-icons covers the canonical set of ~50 hand-made icons (a BezPath on a
24×24 grid). For everything else — arbitrary .desktop app icons, logos, brand
assets, vector exports from pineal/cosmos — you need to load real SVG. This crate
is the bridge: it parses once with vello_svg and stamps the resulting
vello::Scene into any View, scaling it to the node's rect.
Use
use llimphi_svg::SvgAsset;
// Parse ONCE (when loading the app or the icon):
let svg = SvgAsset::from_str(include_str!("logo.svg")).expect("valid logo");
// Paint it in a View as many times as you like (it scales to the rect):
View::new(style).children(vec![svg.view::<Msg>()])
The parse costs something — view() does not. If you are going to stamp the same
SVG in many nodes (an app list sharing a fallback icon), parse once and clone the
SvgAsset (it is cheap: Arc internally).
Why not parse on every paint
vello_svg::render runs usvg's parser (~ms for a non-trivial SVG). In a list
of 80 .desktop icons, parsing every frame kills the UI thread. The rule: the
asset is parsed once, the resulting Scene is retained in memory and stamped
with scene.append(&inner, Some(xf)) — which costs the same as drawing the rest
of the UI.
Errors
SvgAsset::from_str returns Result<Self, SvgError> — for corrupt XML or
features usvg does not support. Typical apps treat the error as "fall back to a
generic glyph" — they do not break.
Part of llimphi — see llimphi.