Donner SVG 0.8.0
0.8.0 ยท ebf353960.8.0 main
SVG editor and embeddable C⁠+⁠+⁠20 engine.
Loading...
Searching...
No Matches
Introduction

Donner SVG Editor & Engine is a native SVG editor and the embeddable C++20 engine underneath it. The engine renders SVG2 with CSS3 styling through either Geode (a GPU renderer) or a compact CPU backend. Conformance is tracked against the resvg test suite, and all input is treated as untrusted: the parser, style, and text subsystems are fuzzed continuously.

These pages document both the engine and the editor. Start with the core document model below, or see Editor and Editor Architecture for the editor application.

Donner splash image

Donner supports:

  • SVG2 core functionality, such as shapes, fills, strokes, and gradients.
  • Text rendering with <text>, <tspan>, and <textPath>, including WOFF2 web fonts and optional HarfBuzz shaping.
  • All 17 SVG filter primitives (feGaussianBlur, feColorMatrix, feComposite, and the rest).
  • CSS3 parsing and cascading, implemented in-house.
  • Detailed validation and diagnostics; errors report the exact source location.
  • A document tree optimized for inspection, mutation, and rendering.
  • An SVG DOM-style API for traversing, inspecting, and modifying documents in memory.
  • A two-phase renderer that builds and caches a rendering tree for efficient per-frame rendering.
  • Two renderer backends: tiny_skia (a compact CPU software renderer) and Geode (a GPU renderer).

Security and performance work is backed by code coverage and continuous fuzzing.

Try It Out: Render an SVG to PNG

bazel run //examples:svg_to_png -- donner_splash.svg

How it works: svg_to_png.cc

API Demo

//! [svg_string]
// This is the base SVG we are loading, a simple path containing a line
const std::string_view svgContents(R"(
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 10 10">
<path d="M 1 1 L 4 5" stroke="blue" />
</svg>
)");
//! [svg_string]
//! [svg_parse]
// Call ParseSVG to load the SVG file
//! [svg_parse]
//! [error_handling]
if (maybeResult.hasError()) {
std::cerr << "Parse Error " << maybeResult.error() << "\n"; // Includes line:column and reason
std::abort();
// - or - handle the error per your project's conventions
}
//! [error_handling]
//! [get_path]
donner::svg::SVGDocument document = std::move(maybeResult.result());
// querySelector supports standard CSS selectors, anything that's valid when defining a CSS rule
// works here too, for example querySelector("svg > path[fill='blue']") is also valid and will
// match the same element.
std::optional<donner::svg::SVGElement> maybePath = document.querySelector("path");
UTILS_RELEASE_ASSERT_MSG(maybePath, "Failed to find path element");
// The result of querySelector is a generic SVGElement, but we know it's a path, so we can cast
// it. If the cast fails, an assertion will be triggered.
//! [get_path]
if (std::optional<donner::Path> spline = path.computedSpline()) {
std::cout << "Path: " << *spline << "\n";
std::cout << "Length: " << spline->pathLength() << " userspace units\n";
} else {
std::cout << "Path is empty\n";
}

Detailed docs: svg_tree_interaction.cc

Documentation

Project Goals

  • Keep dependencies minimal so the engine can be integrated into existing applications with a modern compiler.
  • Expose the SVG DOM so applications can manipulate documents dynamically.
  • Implement the SVG 2 Specification.

Status

Building

Donner builds with Bazel and is tested on Linux and macOS. See Building Donner for details.

Previous Next
Getting Started