# thorvg-rs
[](https://crates.io/crates/thorvg)
[](https://docs.rs/thorvg)
[](https://github.com/goyox86/thorvg-rs/actions/workflows/ci.yml)
[](LICENSE)
> **⚠️ Work in progress** — This crate is under active development and not yet ready for production use. APIs may change without notice.
Rust bindings for [ThorVG](https://github.com/thorvg/thorvg), a production-ready vector graphics engine supporting SVG, Lottie animations, shapes, text, gradients, effects, and more.
## Crates
| [`thorvg-sys`](thorvg-sys/) | Raw FFI bindings generated by bindgen |
| [`thorvg`](thorvg/) | Safe, idiomatic Rust wrapper |
## Quick Start
```rust
use thorvg::{Thorvg, ColorSpace};
let engine = Thorvg::init(0).unwrap();
let mut canvas = engine.sw_canvas(Default::default()).unwrap();
let mut buffer = vec![0u32; 800 * 600];
// SAFETY: `buffer` outlives `canvas`; not moved or reallocated until set_target is called again
unsafe {
canvas.set_target(&mut buffer, 800, 800, 600, ColorSpace::ABGR8888).unwrap();
}
let mut shape = engine.shape().unwrap();
shape.append_rect(thorvg::Rect::new(10.0, 10.0, 200.0, 150.0).corner_radius(10.0)).unwrap();
shape.set_fill_color(thorvg::Rgba::new(255, 0, 0, 255)).unwrap();
canvas.add(shape).unwrap();
canvas.draw(true).unwrap();
canvas.sync().unwrap();
// buffer now contains rendered pixels
```
## Features
### `thorvg` (safe wrapper)
| `std` | ✅ | Enables `std::path::Path`-taking wrappers (`Picture::load`, `Text::load_font`); implies `file-io` |
| `vendored` | ✅ | Build ThorVG from source via the `cc` crate |
| `lottie` | ✅ | Lottie animation loader |
| `svg` | ✅ | SVG loader |
| `png` | ✅ | Built-in PNG loader (lodepng, no system dep) |
| `fonts` | ✅ | SFNT / OTF / TTF font loaders |
| `expressions` | ✅ | Lottie expressions via JerryScript (~200 KB RAM) |
| `threads` | ✅ | Multi-threaded TaskScheduler (`std::thread`) |
| `file-io` | ✅ | Compiles ThorVG's filesystem I/O code path (without `std`, only the byte-slice-taking `load_data` / `load_from_str` variants are exposed) |
`vendored`, `lottie`, `svg`, `png`, `fonts`, `expressions`,
`threads`, and `file-io` are pass-throughs to the corresponding
`thorvg-sys` features. `std` is wrapper-only — it enables
`thorvg-sys/file-io` plus the path-taking wrapper APIs.
### Desktop (default — everything enabled)
```toml
[dependencies]
thorvg = "0.4"
```
### Embedded / `no_std` (pick only what you need)
```toml
[dependencies]
thorvg = { version = "0.4", default-features = false, features = ["vendored", "lottie", "svg"] }
```
This gives you Lottie + SVG playback with no threads, no JerryScript,
no PNG/font loaders — suitable for microcontrollers with limited RAM.
## Cross-Compilation
ThorVG is compiled from C++ source using the [`cc`](https://crates.io/crates/cc) crate, which
picks up the correct cross-compiler from Cargo's target environment.
No meson or ninja required.
Tested targets (⚙️ = exercised in CI):
| `x86_64-unknown-linux-gnu` | system libc | Desktop default ⚙️ |
| `x86_64-pc-windows-msvc` | system libc (MSVC) | Desktop ⚙️ |
| `aarch64-apple-darwin` | system libc | macOS, Apple Silicon ⚙️ |
| `xtensa-esp32s3-espidf` | ESP-IDF | SDK provides libc |
| `xtensa-esp32-espidf` | ESP-IDF | SDK provides libc |
| `riscv32imc-esp-espidf` | ESP-IDF | SDK provides libc |
| `riscv32imac-unknown-none-elf` | bare-metal | Vendored picolibc — see [`thorvg-sys/docs/bare_metal.md`](thorvg-sys/docs/bare_metal.md) ⚙️ |
CI also covers the non-vendored path (linking a system ThorVG via
`pkg-config`) on Linux and macOS.
On `target_os == "none"` targets, `thorvg-sys` vendors and compiles
[picolibc](https://github.com/picolibc/picolibc) as the libc; the
cross toolchain's `libstdc++` / `libgcc` / `libm` are still used.
Wired architectures today: `riscv32`, `riscv64`, `aarch64`, `x86`,
`x86_64`, `powerpc[64]`, `mips[64]`, `sparc[64]`, `m68k`, `msp430`.
See the [bare-metal docs](thorvg-sys/docs/bare_metal.md) for the
build pipeline, runtime stubs, and how to override them.
## API Coverage
157 of the 161 ThorVG C API functions are wrapped (~98%). Unwrapped:
the four `tvg_paint_ref` / `tvg_paint_unref` / `tvg_paint_get_ref` /
`tvg_paint_get_parent` refcount-and-parent helpers (ownership is
already modelled in the Rust types).
- **Canvas** — `SwCanvas` (software, fully wired). `GlCanvas` and
`WgCanvas` type wrappers exist for API parity, but the vendored
build strips the GPU engine — they are not yet runtime-usable
- **Paint** — opacity, visibility, transforms, clipping, masking, blending, hit-testing
- **Shape** — paths, rectangles, circles, fill, stroke, gradients, trim path
- **Gradient** — linear, radial, color stops, spread, transforms
- **Picture** — load SVG / PNG / Lottie / raw from file or memory
(JPG and WebP loaders exist in the upstream tree but are not
compiled by `thorvg-sys`)
- **Scene** — grouping, effects (blur, drop shadow, fill, tint, tritone)
- **Text** — font loading, styling, wrapping, metrics, outline
- **Animation** — frame control, segments, duration
- **LottieAnimation** — slots, markers, tweening, expressions, quality
- **Saver** — export paint/animation to file
- **Accessor** — scene tree traversal with callbacks
## `no_std` Support
Both crates are `no_std` compatible. The safe wrapper requires `alloc`.
File I/O APIs (`Picture::load`, `Text::load_font`, `Saver::save`) are
gated behind the `std` feature. All rendering, shapes, gradients,
scenes, and canvas operations work in `no_std`.
For `target_os == "none"` targets, `thorvg-sys` ships its own libc
(vendored picolibc) — see [`thorvg-sys/docs/bare_metal.md`](thorvg-sys/docs/bare_metal.md).
## Examples
```bash
cargo run --example shapes
cargo run --example stroke
cargo run --example gradient
cargo run --example scene
cargo run --example transforms
cargo run --example blending
cargo run --example opacity
cargo run --example clipping
cargo run --example masking
cargo run --example scene_effects
cargo run --example paths
cargo run --example picture_svg
cargo run --example paint_order
cargo run --example render_to_buffer
```
All examples output PNG files in the current directory.
## Building
ThorVG is vendored as a git submodule and compiled automatically via
the [`cc`](https://crates.io/crates/cc) crate. You need a C++ compiler
(any `g++` or `clang++` will do) plus `libclang` for
[`bindgen`](https://rust-lang.github.io/rust-bindgen/requirements.html)
(typically packaged as `libclang-dev` / `clang-devel` / `llvm` on macOS).
```bash
git clone --recurse-submodules https://github.com/goyox86/thorvg-rs
cd thorvg-rs
cargo build
```
No meson, ninja, or pkg-config required for vendored builds.
## Development
Requires [just](https://github.com/casey/just) for task running:
```bash
just ci-quick # fmt, clippy, test, no_std check
just ci # full CI: above + AddressSanitizer + ThreadSanitizer
just test-asan # run tests under AddressSanitizer
just examples # run all 14 examples
just --list # show all recipes
```
## Acknowledgments
This project provides Rust bindings to [ThorVG](https://github.com/thorvg/thorvg), created and maintained by the [ThorVG project](https://www.thorvg.org/) contributors. ThorVG is a [Linux Foundation](https://www.linuxfoundation.org/) project. All vector graphics rendering is performed by the ThorVG engine — this crate is a thin binding layer.
This project is not affiliated with, endorsed by, or sponsored by the ThorVG project or the Linux Foundation.
Special thanks to [Hermet Park](https://github.com/hermet) and all [ThorVG contributors](https://github.com/thorvg/thorvg/graphs/contributors) for building such an excellent, lightweight, and well-designed vector graphics engine with a clean C API that made these bindings possible.
## License
MIT — same as [ThorVG](https://github.com/thorvg/thorvg/blob/main/LICENSE).