|
|
Donner SVG Editor & Engine
SVG-native editor and embeddable SVG2 + CSS3 engine in C++20, with GPU (WebGPU) and compact CPU renderers, built for correctness, security, and performance.
|
Add the following to your MODULE.bazel (bazel 7.0.0 required):
Donner with the default renderer is available through the @donner dependency, add to your rule like so:
CMake support is generated from Donner's Bazel build metadata. Start from a Donner source checkout and generate the CMake files once before configuring your application:
Then add Donner to your own CMakeLists.txt with add_subdirectory() and link the exported donner target:
Use the same public headers as the Bazel build:
The complete runnable example is under examples/cmake_consumer/. It parses a small SVG, queries the DOM, renders it, and exits non-zero if any step fails. From the Donner checkout:
From another source tree, pass the Donner checkout explicitly:
Regenerate the CMake files after updating Donner or changing its Bazel build graph. Generated CMakeLists.txt files are intentionally ignored by Git; handwritten examples under examples/ are the exception.
First include the core SVG module with:
Use SVGParser to load an SVG from a string, which may be loaded from a file. Note that the string needs to be mutable as it is modified by the parser.
ParseResult contains either the document or an error, which can be checked with hasError() and error():
Then get the SVGDocument and start using it. For example, to get the SVGElement for the <path>:
The document tree can be traversed via the Donner API, and the SVG can be modified in-memory:
For multi-threaded DOM access and removed-element lifetime behavior, see SVG DOM Threading And Lifetime.
Outputs
Use the backend-agnostic Renderer class, which resolves to the active build backend:
Outputs can be saved to a PNG file:
Or pixel data can be accessed via snapshot:
The backend is selected at build time. See Building Donner for details on choosing between TinySkia (lightweight default) and Skia (full-featured).
Donner bundles several third-party libraries (EnTT, stb, tiny-skia-cpp, zlib, libpng, FreeType, HarfBuzz, woff2, brotli, Skia). Most are under permissive licenses that require you to reproduce their copyright notice and license text when redistributing binaries built from Donner. To make this painless, Donner ships a donner_notice_file rule that aggregates every required license into a single NOTICE.txt you can embed in your application.
Pick the variant that matches your build configuration:
| Variant | Bazel target |
|---|---|
| Default (TinySkia) | @donner//third_party/licenses:notice_default |
| TinySkia + --config=text-full | @donner//third_party/licenses:notice_text_full |
| Skia + --config=text-full | @donner//third_party/licenses:notice_skia_text_full |
To see exactly what text your users will receive, build the variant target and print its output. When Donner is a dependency of your project the files land under bazel-bin/external/donner+/third_party/licenses/:
When working inside the Donner repo itself, drop the external/donner+ prefix:
Each variant produces two files next to each other:
Wire the notice target into your own binary as a data dependency, then load it at runtime. The donner_notice_file rule exposes its NOTICE.txt under an output_group = "notice", so you can pick it out cleanly with filegroup and feed it through //tools:embed_resources (a helper Donner already exposes) to produce a linkable C++ symbol:
The generated .cpp filename mirrors the input filename with non-alphanumerics turned into underscores (so notice_default.txt becomes notice_default_txt.cpp).
embed_resources generates a header that exposes each resource as a std::span<const unsigned char> inside the donner::embedded namespace, so you can surface it behind an --about flag or a menu item:
If you prefer a simpler approach, you can also declare the notice target as a data dependency on your binary and read the file at runtime via Bazel runfiles — whichever fits your distribution model.
The variant lists live in third_party/licenses/BUILD.bazel and are kept in sync with Donner's //examples:svg_to_png dependency graph. When you change build configs (enabling --config=text-full, switching to Skia), update your consumer BUILD files to reference the matching notice_* target. The build report enumerates every third-party dep per variant alongside its SPDX identifier and upstream link.