Donner 0.5.0
Embeddable browser-grade SVG2 engine
Loading...
Searching...
No Matches
Getting Started

Adding to Your Bazel Project

Add the following to your MODULE.bazel (bazel 7.0.0 required):

bazel_dep(name = "donner", version = "0.0.0")
git_override(
module_name = "donner",
remote = "https://github.com/jwmcglynn/donner",
commit = "<latest commit>",
)

Adding a Dependency

Donner with the default renderer is available through the @donner dependency, add to your rule like so:

donner_cc_binary(
name = "my_library",
# ...
deps = [
"@donner",
],
)

Loading an SVG

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.

// 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>
)");
// Call ParseSVG to load the SVG file

ParseResult contains either the document or an error, which can be checked with hasError() and error():

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
}

Then get the SVGDocument and start using it. For example, to get the SVGElement for the <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.

The document tree can be traversed via the Donner API, and the SVG can be modified in-memory:

path.setStyle("fill: red");
path.setStyle("stroke: white");
// Get the parsed, cascaded style for this element and output it to the console.
std::cout << "Computed style: " << path.getComputedStyle() << "\n";

Outputs

Computed style: PropertyRegistry {
fill: PaintServer(solid Color(rgba(0, 0, 255, 255))) (set) @ Specificity(0, 0, 0)
stroke-width: 3px (set) @ Specificity(0, 0, 0)
}

Rendering an SVG

Use the backend-agnostic Renderer class, which resolves to the active build backend:

renderer.draw(document);
Backend-agnostic renderer that resolves to the active build backend (Skia or tiny-skia).
Definition Renderer.h:27
void draw(SVGDocument &document) override
Draws the SVG document using the active backend.
Definition Renderer.cc:18

Outputs can be saved to a PNG file:

const bool success = renderer.save("output.png");
bool save(const char *filename)
Saves the last rendered frame to a PNG file.
Definition Renderer.cc:116

Or pixel data can be accessed via snapshot:

std::cout << "Size: " << renderer.width() << "x" << renderer.height() << "\n";
int height() const override
Returns the rendered height in pixels.
Definition Renderer.cc:131
RendererBitmap takeSnapshot() const override
Captures a CPU-readable snapshot of the current frame.
Definition Renderer.cc:112
int width() const override
Returns the rendered width in pixels.
Definition Renderer.cc:127
CPU-readable bitmap produced by a renderer snapshot.
Definition RendererInterface.h:48

The backend is selected at build time. See Building Donner for details on choosing between TinySkia (lightweight default) and Skia (full-featured).

Previous Next
Home Donner API