Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upSVG drawing
For drawing custom graphics, azul has a high-performance 2D vector API. It also allows you to load and draw SVG files (with the exceptions of gradients: gradients in SVG files are not yet supported). But azul itself does not know about SVG shapes at all - so how the SVG widget implemented?
The solution is to draw the SVG to an OpenGL texture and hand that to azul. This way, the SVG drawing component could even be implemented in an external crate, if you really wanted to. This mechanism also allows for completely custom drawing (let's say: a game, a 3D viewer, etc.) to be drawn.
The SVG component currently uses the resvg parser, usvg simplification and the
lyon triangulation libraries). Of course you can also add custom shapes
(bezier curves, circles, lines, whatever) programmatically, without going through
the SVG parser:
const TEST_SVG: &str = include_str!("tiger.svg");
impl Layout for Model {
fn layout() {
if let Some((svg_cache, svg_layers)) = self.svg {
Svg::with_layers(svg_layers).dom(&info.window, &svg_cache)
} else {
Button::labeled("Load SVG file").dom()
.with_callback(load_svg)
}
}
}
fn load_svg(app_state: &mut AppState<MyAppData>, _: WindowEvent<MyAppData>) -> UpdateScreen {
let mut svg_cache = SvgCache::empty();
let svg_layers = svg_cache.add_svg(TEST_SVG).unwrap();
app_state.data.modify(|data| data.svg = Some((svg_cache, svg_layers)));
UpdateScreen::Redraw
}This is one of the few exceptions where azul allows persistent data across frames
since it wouldn't be performant enough otherwise. Ideally you'd have to load, triangulate
and draw the SVG file on every frame, but this isn't performant. You might have
noticed that the .dom() function takes in an extra parameter: The svg_cache
and the info.window. This way, the svg_cache handles everything necessary to
cache vertex buffers / the triangulated layers and shapes, only the drawing itself
is done on every frame.
Additionally, you can also register callbacks on any item inside the SVG using the
SvgCallbacks, i.e. when someone clicks on or hovers over a certain shape. In order
to draw your own vector data (for example in order to make a vector graphics editor),
you can build the "SVG layers" yourself (ex. from the SVG data). Each layer is
batch-rendered, so you can draw many lines or polygons in one draw call, as long as
they share the same SvgStyle.