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

Represents a parsed SVG document containing a tree of SVGElement nodes. More...

#include "donner/svg/SVGDocument.h"

Classes

class  ResourcePolicySnapshot
 Opaque, equality-comparable identity of the current resource-loading and parsing policy. More...
struct  Settings
 Document settings which configure the document behavior. More...

Public Types

using SvgParseCallback
 Callback used to parse external SVG content referenced from within a document.

Public Member Functions

std::optional< ResourcePolicySnapshot > resourcePolicySnapshot () const
 Capture policy identity, or nullopt when the current resource policy is inconsistent.
 SVGDocument ()
 Constructor to create an empty SVGDocument with default settings.
 SVGDocument (Settings settings)
 Constructor to create an empty SVGDocument.
Registry & unsafeRegistry ()
 Get the underlying ECS Registry, which holds all data for the document.
const Registry & unsafeRegistry () const
 Get the underlying ECS Registry, which holds all data for the document.
Registry & registry ()
 Get the underlying ECS Registry, which holds all data for the document, for advanced use.
const Registry & registry () const
 Get the underlying ECS Registry, which holds all data for the document, for advanced use.
SVGDocumentHandle handle () const
 Get the internal shared document handle used by this value facade.
ThreadingMode threadingMode () const
 Current DOM threading policy for this document.
void setThreadingMode (ThreadingMode mode)
 Set the DOM threading policy for this document.
DocumentReadAccess readAccess () const
 Acquire scoped read access to the underlying document state.
std::optional< DocumentReadAccess > tryReadAccess () const
 Attempt to acquire scoped read access without waiting for a concurrent writer.
DocumentWriteAccess writeAccess () const
 Acquire scoped write access to the underlying document state.
std::optional< DocumentWriteAccess > tryWriteAccess () const
 Try to acquire scoped write access without waiting.
template<typename Callback>
decltype(auto) withReadAccess (Callback &&callback) const
 Run a callback with scoped read access to this document.
template<typename Callback>
decltype(auto) withWriteAccess (Callback &&callback) const
 Run a callback with scoped write access to this document.
bool hasSourceStore () const
 Return true if the parsed SVG document has owned XML source text.
bool hasPendingRenderInvalidation () const
 Return true when the document carries render invalidation that the renderer has not yet consumed: per-entity dirty flags, or a queued full render-tree rebuild / style recompute.
bool refreshFontResources ()
 Adopt newly available fonts and invalidate affected geometry/paint without changing source. Call only at a frame boundary, before rendering begins. Returns whether rendering changed.
uint64_t fontResourceRevision () const
 Resolution revision owned by this document's font manager, independent of XML source edits.
bool fontResourcesExceeded () const
 True when font dependency tracking exceeded the document's configured resource budget. Output operations must fail instead of treating an incomplete dependency list as ready.
bool hasUnresolvedFontResources () const
 Cheap readiness query for frame scheduling; does not traverse the render graph.
FontResourcePreflight renderedFontResources () const
 Current font dependencies used by the prepared render tree. Unresolved metrics cannot prove a root is outside the viewport, so these represent conservative visible-document demand. Unused definitions and catalog enumeration do not create dependencies here.
std::vector< FontFaceDependency > renderedFontDependencies () const
 Dependency-only compatibility view; an empty result does not establish readiness.
std::vector< FontFaceDependency > fontDependenciesForElement (const SVGElement &element) const
 Current dependency values for an element and its prepared rendering references. An empty list does not establish output readiness; use preflightFontResourcesForElement.
FontResourcePreflight preflightFontResourcesForElement (const SVGElement &element)
 Prepare a target's text and follow its actual rendering references without changing source. Pending canvas invalidation is preserved and returns NeedsRender; lazy fragment images also require a render before readiness can be established. Does not request network bytes.
std::size_t elementCount () const
 Return the number of SVG element entities currently owned by the document.
std::string_view source () const
 Return the current XML source text owned by this parsed SVG document.
std::uint64_t sourceVersion () const
 Return the current XML source version, or 0 for documents without source text.
xml::XMLDocument xmlDocument () const
 Rehydrate the underlying XML document facade over this SVG document's shared registry.
xml::ApplySourceEditResult applySourceEdit (const xml::XMLEditIntent &intent)
 Apply an incremental source edit through the underlying XML document and update the SVG semantic projection from emitted XML mutations.
xml::ApplySourceEditResult setElementAttribute (const SVGElement &element, const xml::XMLQualifiedNameRef &name, std::string_view value)
 Set an element attribute and return any XML-owned source edit result.
xml::ApplySourceEditResult removeElementAttribute (const SVGElement &element, const xml::XMLQualifiedNameRef &name)
 Remove an element attribute and return any XML-owned source edit result.
xml::ApplySourceEditResult insertElement (const SVGElement &parent, const SVGElement &element, std::optional< SVGElement > referenceElement=std::nullopt)
 Insert an element into the document tree and return any XML-owned source edit result.
xml::ApplySourceEditResult removeElement (const SVGElement &element)
 Remove an element from the document tree and return any XML-owned source edit result.
xml::ApplySourceEditResult revertElementInsertions (std::span< const SVGElement > elements, std::span< const xml::XMLSourceDelta > insertions)
 Revert element insertions that are the most recent edits to this document's source.
xml::ApplySourceEditResult setElementTextContent (const SVGElement &element, std::string_view text)
 Replace an element's text content through this document and update owned source text.
EntityHandle rootEntityHandle () const
 Get the root ECS Entity of the document, for advanced use.
SVGSVGElement svgElement () const
 Get the root <svg> element of the document.
void setCanvasSize (int width, int height)
 Set the canvas (output image) size to a fixed width and height, in pixels.
void setTime (double seconds)
 Set the current document time for animations, in seconds from the document start.
double currentTime () const
 Get the current document time in seconds.
void restartAnimations ()
 Start a fresh animation session at time zero, including animations with restart="never".
bool dispatchMouseEvent (EventType type, const SVGElement &target)
 Deliver a mouse event to declarative SVG animation begin/end triggers.
bool dispatchAnimationEvent (std::string_view name, const SVGElement &target, bool bubbles=true)
 Deliver a named host event to declarative timing, without executing scripts.
bool beginAnimation (const SVGElement &animation, double offset=0)
 Schedule a begin instance for an attached animation element.
bool endAnimation (const SVGElement &animation, double offset=0)
 Schedule an end instance for an active animation.
SVGAnimationEventBatch animationEvents (double from, double to)
 Query animation lifecycle boundaries in the half-open interval (from, to].
void useAutomaticCanvasSize ()
 Automatically determine the canvas size from the root <svg> element's width, height, and viewBox.
Vector2i canvasSize () const
 Get the size of the rendered output, in pixels.
std::optional< Vector2i > canvasSizeOverride () const
 Return the exact bounds requested by setCanvasSize(), or nullopt for automatic sizing.
int width () const
 Get the width of the SVG document, in pixels.
int height () const
 Get the height of the SVG document, in pixels.
Transform2d canvasFromDocumentTransform () const
 Returns the transform that maps points from the SVG document's viewBox coordinate space into the canvas-scaled output space.
void setUserLanguages (std::vector< RcString > languages)
 Set the user's preferred languages, in priority order, used to evaluate the systemLanguage conditional processing attribute (on <switch> children and on renderable elements).
std::vector< RcString > userLanguages () const
 Get the user's preferred languages used to evaluate the systemLanguage conditional processing attribute.
bool operator== (const SVGDocument &other) const
 Returns true if the two SVGDocument handles reference the same underlying document.
std::optional< SVGElement > querySelector (std::string_view selector)
 Find the first descendant of the root <svg> element, in document order, that matches the given CSS selector.

Static Public Member Functions

static SVGDocument CreateFromHandle (SVGDocumentHandle handle)
 Rehydrate an SVGDocument facade from an internal shared document handle.

Friends

class SVGElement
class parser::SVGParserImpl

Detailed Description

Represents a parsed SVG document containing a tree of SVGElement nodes.

To create a document, parse SVG content with donner::svg::parser::SVGParser::ParseSVG, or construct an empty document and build the tree programmatically. Access the root <svg> element with svgElement(), find elements with querySelector(), and render with donner::svg::Renderer.

SVGDocument and SVGElement expose a familiar DOM API for traversal and manipulation (e.g., firstChild(), appendChild(), querySelector()). Elements are lightweight value types that can be copied and passed on the stack.

SVGDocument defaults to donner::svg::ThreadingMode::SingleThreaded. To access the DOM from multiple threads, opt into donner::svg::ThreadingMode::ConcurrentDom and use the DOM facade APIs or scoped access helpers. Direct ECS access through registry() and entityHandle() is only conditionally safe while the caller holds an explicit document access guard.

Note
Internally, data is stored using an Entity Component System (ECS) for cache-friendly access during rendering. The registry() and entityHandle() accessors expose this for advanced use cases, but most users can ignore the ECS layer entirely.
See also
SVGElement
Examples
svg_filter_interaction.cc, svg_text_interaction.cc, and svg_to_png.cc.

Class Documentation

◆ SVGDocument::Settings

struct SVGDocument::Settings

Document settings which configure the document behavior.

Class Members
ProcessingMode processingMode = ProcessingMode::DynamicInteractive Processing mode for this document. Defaults to donner::svg::ProcessingMode::DynamicInteractive.
shared_ptr< DocumentResourceFamilyBudget > resourceFamilyBudget Shared live-memory envelope for this document and parsed external SVG subdocuments.
unique_ptr< ResourceLoaderInterface > resourceLoader Resource loader to use for loading external resources.
SvgParseCallback svgParseCallback Callback to parse SVG content into sub-documents.

Member Typedef Documentation

◆ SvgParseCallback

Initial value:
std::function<std::optional<SVGDocumentHandle>(
const std::vector<uint8_t>& svgContent, ParseWarningSink& warningSink)>

Callback used to parse external SVG content referenced from within a document.

Constructor & Destructor Documentation

◆ SVGDocument()

donner::svg::SVGDocument::SVGDocument ( Settings settings)
explicit

Constructor to create an empty SVGDocument.

To load a document from an SVG file, use donner::svg::parser::SVGParser::ParseSVG.

Parameters
settingsSettings to configure the document.

Member Function Documentation

◆ animationEvents()

SVGAnimationEventBatch donner::svg::SVGDocument::animationEvents ( double from,
double to )

Query animation lifecycle boundaries in the half-open interval (from, to].

Events are returned as values; no callback runs under document access. The query does not change the document clock. Queries exceeding 4096 boundaries return an incomplete empty batch.

Parameters
fromExclusive start time, finite.
toInclusive end time, finite and not less than from.
Returns
Chronological lifecycle boundaries, or an incomplete batch when bounded out.

◆ applySourceEdit()

xml::ApplySourceEditResult donner::svg::SVGDocument::applySourceEdit ( const xml::XMLEditIntent & intent)

Apply an incremental source edit through the underlying XML document and update the SVG semantic projection from emitted XML mutations.

Documents without XML source text are not modified, and the result carries a diagnostic.

Elements that the edit inserts, or moves into the SVG namespace by changing an xmlns declaration, are built through the same element factory and attribute parsing as the parser, so they get the element type a fresh parse of the new source would give them, at the edit's incremental scope.

Parameters
intentSource edit request.

◆ beginAnimation()

bool donner::svg::SVGDocument::beginAnimation ( const SVGElement & animation,
double offset = 0 )

Schedule a begin instance for an attached animation element.

Parameters
animationAnimation element in this document.
offsetSeconds relative to the current document time, including negative offsets.
Returns
Whether a runtime instance was retained. Secure documents reject host control.

◆ canvasFromDocumentTransform()

Returns the transform that maps points from the SVG document's viewBox coordinate space into the canvas-scaled output space.

This bakes in the preserveAspectRatio fit (scale plus alignment offset) between the viewBox and the current canvas size.

Naming: per the destFromSource convention, applying this transform to a viewBox-space point yields a canvas-space point - i.e. it is canvasFromDocument. Callers that need the opposite direction (canvas pixel to document viewBox coordinate, e.g. click math in editors and viewers) should invert it.

◆ canvasSize()

Get the size of the rendered output, in pixels.

Without an explicit canvas size, this is the document size from the root <svg> element's width, height, and viewBox, or 512x512 if those do not define a size. With a size from setCanvasSize, this is the document size scaled uniformly to fit within it.

◆ canvasSizeOverride()

std::optional< Vector2i > donner::svg::SVGDocument::canvasSizeOverride ( ) const

Return the exact bounds requested by setCanvasSize(), or nullopt for automatic sizing.

Unlike canvasSize(), this value is not reduced to fit the document's aspect ratio.

◆ CreateFromHandle()

SVGDocument donner::svg::SVGDocument::CreateFromHandle ( SVGDocumentHandle handle)
inlinestatic

Rehydrate an SVGDocument facade from an internal shared document handle.

Parameters
handleShared document-state handle to wrap.
Returns
A new SVGDocument facade referencing the same underlying document state.

◆ dispatchAnimationEvent()

bool donner::svg::SVGDocument::dispatchAnimationEvent ( std::string_view name,
const SVGElement & target,
bool bubbles = true )

Deliver a named host event to declarative timing, without executing scripts.

Parameters
nameEvent name, at most 128 bytes.
targetAttached target belonging to this document.
bubblesWhether the event also reaches ancestors.
Returns
Whether a runtime timing instance was retained; secure documents reject events.

◆ dispatchMouseEvent()

bool donner::svg::SVGDocument::dispatchMouseEvent ( EventType type,
const SVGElement & target )

Deliver a mouse event to declarative SVG animation begin/end triggers.

Supports event names such as click and mouseover, optionally prefixed by an element ID (button.click). Bubbling events also reach ancestors. Does not execute scripts or edit source. Secure documents ignore interactive events.

Parameters
typeEvent being delivered.
targetElement under the pointer, belonging to this document.
Returns
True if an animation interval changed; false for ignored events or invalid targets.

◆ endAnimation()

bool donner::svg::SVGDocument::endAnimation ( const SVGElement & animation,
double offset = 0 )

Schedule an end instance for an active animation.

Parameters
animationAnimation element in this document.
offsetSeconds relative to the current document time.
Returns
Whether a runtime instance was retained. Secure documents reject host control.

◆ handle()

SVGDocumentHandle donner::svg::SVGDocument::handle ( ) const
inline

Get the internal shared document handle used by this value facade.

Returns
Shared document-state handle backing this SVGDocument.

◆ hasPendingRenderInvalidation()

Return true when the document carries render invalidation that the renderer has not yet consumed: per-entity dirty flags, or a queued full render-tree rebuild / style recompute.

Always false before the render tree has been built for the first time.

UI surfaces that prepare the document for auxiliary rendering (for example the editor's layer-thumbnail refresh) use this to avoid consuming pending invalidation ahead of the canvas renderer.

◆ height()

int donner::svg::SVGDocument::height ( ) const
inline

Get the height of the SVG document, in pixels.

This is the height of the canvas, which may be different from the height of the SVG content.

◆ insertElement()

xml::ApplySourceEditResult donner::svg::SVGDocument::insertElement ( const SVGElement & parent,
const SVGElement & element,
std::optional< SVGElement > referenceElement = std::nullopt )

Insert an element into the document tree and return any XML-owned source edit result.

This only edits source-backed documents. If the document has no source text, or parent has no XML source identity, the tree is not modified and the result is unapplied; use SVGElement::insertBefore or SVGElement::appendChild instead.

Parameters
parentElement that receives element as a child.
elementElement to insert.
referenceElementOptional existing child to insert before.

◆ querySelector()

std::optional< SVGElement > donner::svg::SVGDocument::querySelector ( std::string_view selector)

Find the first descendant of the root <svg> element, in document order, that matches the given CSS selector.

The root element itself is not matched; use svgElement for it.

This method performs its own scoped read. For repeated DOM reads in donner::svg::ThreadingMode::ConcurrentDom, wrap the whole scan in withReadAccess so nested reads reuse the same document access.

auto element = document.querySelector("#elementId");

Complex selectors are supported:

auto element = document.querySelector("svg > g:nth-child(2) > rect");
Parameters
selectorCSS selector to match.
Returns
The first matching element, or std::nullopt if no element matches or the selector is invalid.
Examples
svg_filter_interaction.cc, and svg_text_interaction.cc.

◆ removeElement()

xml::ApplySourceEditResult donner::svg::SVGDocument::removeElement ( const SVGElement & element)

Remove an element from the document tree and return any XML-owned source edit result.

The root svgElement cannot be removed: the result is unapplied and carries a diagnostic, and the document and its source are unchanged.

Parameters
elementElement to remove.

◆ removeElementAttribute()

xml::ApplySourceEditResult donner::svg::SVGDocument::removeElementAttribute ( const SVGElement & element,
const xml::XMLQualifiedNameRef & name )

Remove an element attribute and return any XML-owned source edit result.

Parameters
elementElement whose attribute should be removed.
nameAttribute name to remove.

◆ restartAnimations()

Start a fresh animation session at time zero, including animations with restart="never".

Preserves the authored document and element identity. The next render evaluates time zero.

◆ revertElementInsertions()

xml::ApplySourceEditResult donner::svg::SVGDocument::revertElementInsertions ( std::span< const SVGElement > elements,
std::span< const xml::XMLSourceDelta > insertions )

Revert element insertions that are the most recent edits to this document's source.

Each element must have been inserted by insertElement as a new, unparented element, oldest first, and insertions holds the single source delta each insertion returned. The source returns byte for byte to its state before the first insertion and each element is detached from its parent. See donner::xml::XMLDocument::revertNodeInsertions for the conditions; when they do not hold, nothing changes and the result carries a diagnostic.

Parameters
elementsInserted elements, oldest first.
insertionsSource delta for each element, in the same order.

◆ setCanvasSize()

void donner::svg::SVGDocument::setCanvasSize ( int width,
int height )

Set the canvas (output image) size to a fixed width and height, in pixels.

This controls the rendered output dimensions and may differ from the SVG's viewBox. The document is scaled uniformly to fit within this size, so canvasSize may be smaller than the requested size in one dimension. If not set (or after useAutomaticCanvasSize), the size comes from the root <svg> element's width, height, and viewBox, falling back to 512x512.

Parameters
widthWidth of the canvas, in pixels. Must be positive.
heightHeight of the canvas, in pixels. Must be positive.
Examples
svg_to_png.cc.

◆ setElementAttribute()

xml::ApplySourceEditResult donner::svg::SVGDocument::setElementAttribute ( const SVGElement & element,
const xml::XMLQualifiedNameRef & name,
std::string_view value )

Set an element attribute and return any XML-owned source edit result.

Source-backed documents mutate through the underlying XML document, then project emitted XML mutations back into SVG semantics. Programmatic documents without source text still mutate the SVG element and return an unapplied result.

Parameters
elementElement whose attribute should be set.
nameAttribute name to set.
valueRaw unescaped attribute value.

◆ setElementTextContent()

xml::ApplySourceEditResult donner::svg::SVGDocument::setElementTextContent ( const SVGElement & element,
std::string_view text )

Replace an element's text content through this document and update owned source text.

This is the DOM-side structured editing entry point for text-content writes: it replaces the element's text through donner::xml::XMLSourceStore so source deltas are emitted, then updates the parsed text of text-content and <style> elements to match. Only text-only content is edited: if the element has child elements (e.g. <tspan>), or the document has no source text, nothing changes and the result is unapplied without a diagnostic.

Parameters
elementElement whose text content to replace.
textNew text content (raw, unescaped). An empty string clears the content.

◆ setThreadingMode()

void donner::svg::SVGDocument::setThreadingMode ( ThreadingMode mode)
inline

Set the DOM threading policy for this document.

Parameters
modeNew threading mode.

◆ setTime()

void donner::svg::SVGDocument::setTime ( double seconds)

Set the current document time for animations, in seconds from the document start.

Advancing the document time causes the animation system to update animated attribute values on the next render. This invalidates the render tree. Non-finite values are ignored.

Donner has no animation clock of its own: the host supplies every sample time, typically from its frame clock. Any finite time is accepted, including an earlier one; seeking backward samples the intervals that already exist at that time rather than restarting animations. Use restartAnimations to replay from time zero. Documents parsed with donner::svg::ProcessingMode::SecureStatic keep their clock but never apply animated values.

Parameters
secondsDocument time in seconds.

◆ setUserLanguages()

void donner::svg::SVGDocument::setUserLanguages ( std::vector< RcString > languages)

Set the user's preferred languages, in priority order, used to evaluate the systemLanguage conditional processing attribute (on <switch> children and on renderable elements).

Each entry is a BCP 47 language tag such as "en" or "en-US". A systemLanguage value matches when it equals (case-insensitive) one of these languages, or begins with one of these languages followed by - (e.g. user language "en" matches systemLanguage="en-GB"). <switch> selects the child matching the earliest entry in this list; other elements render when any entry matches.

Defaults to {"en"} when not set. Passing an empty list disables all systemLanguage matches.

Parameters
languagesUser's preferred languages, in priority order.

◆ source()

std::string_view donner::svg::SVGDocument::source ( ) const

Return the current XML source text owned by this parsed SVG document.

Programmatically-created documents may not have source text; in that case this returns an empty view.

This, sourceVersion and hasSourceStore report the document's current source store, including one that donner::xml::XMLDocument::setSource installed through xmlDocument after the document was built. They do not touch the registry, so the thread that edits the source may call them without document access while another thread holds write access; any other thread needs read access. The view is valid until the source next changes, through a source edit or donner::xml::XMLDocument::setSource; copy it to keep it longer.

◆ unsafeRegistry() [1/2]

Get the underlying ECS Registry, which holds all data for the document.

This is an unsafe advanced escape hatch. In donner::svg::ThreadingMode::ConcurrentDom, callers must hold an explicit document access guard while reading or mutating the returned registry.

◆ unsafeRegistry() [2/2]

const Registry & donner::svg::SVGDocument::unsafeRegistry ( ) const
inline

Get the underlying ECS Registry, which holds all data for the document.

This is an unsafe advanced escape hatch. In donner::svg::ThreadingMode::ConcurrentDom, callers must hold an explicit document access guard while reading the returned registry.

◆ useAutomaticCanvasSize()

Automatically determine the canvas size from the root <svg> element's width, height, and viewBox.

If those do not define a size, falls back to the default size (512x512).

◆ userLanguages()

std::vector< RcString > donner::svg::SVGDocument::userLanguages ( ) const

Get the user's preferred languages used to evaluate the systemLanguage conditional processing attribute.

Defaults to {"en"}.

◆ width()

int donner::svg::SVGDocument::width ( ) const
inline

Get the width of the SVG document, in pixels.

This is the width of the canvas, which may be different from the width of the SVG content.

◆ withReadAccess()

template<typename Callback>
decltype(auto) donner::svg::SVGDocument::withReadAccess ( Callback && callback) const
inline

Run a callback with scoped read access to this document.

In donner::svg::ThreadingMode::ConcurrentDom, use this to batch repeated reads such as traversal or selector scans under one document read lock.

Parameters
callbackCallable invoked as callback(DocumentReadAccess&).

◆ withWriteAccess()

template<typename Callback>
decltype(auto) donner::svg::SVGDocument::withWriteAccess ( Callback && callback) const

Run a callback with scoped write access to this document.

Nested DOM setters called by the callback reuse this write access and coalesce their mutation revision bumps into one revision increment for the whole callback. Callbacks can accept either donner::svg::DocumentWriteAccess for raw ECS work or donner::svg::SVGDocumentMutation for typed DOM mutation helpers.

Parameters
callbackCallable invoked as callback(DocumentWriteAccess&) or callback(SVGDocumentMutation&).

◆ xmlDocument()

xml::XMLDocument donner::svg::SVGDocument::xmlDocument ( ) const

Rehydrate the underlying XML document facade over this SVG document's shared registry.

The returned facade exposes the parsed XML tree, including source locations for source-backed documents. When donner::xml::XMLDocument::sourceDiagnostic reports a pending diagnostic, the tree reflects the last valid parse and is stale relative to source; consumers that slice current source bytes must refuse rather than use stale ranges.


The documentation for this class was generated from the following file: