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 |
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.
| struct donner::svg::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. |
Callback used to parse external SVG content referenced from within a document.
|
explicit |
Constructor to create an empty SVGDocument.
To load a document from an SVG file, use donner::svg::parser::SVGParser::ParseSVG.
| settings | Settings to configure the document. |
| 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.
| from | Exclusive start time, finite. |
| to | Inclusive end time, finite and not less than from. |
| 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.
| intent | Source edit request. |
| bool donner::svg::SVGDocument::beginAnimation | ( | const SVGElement & | animation, |
| double | offset = 0 ) |
Schedule a begin instance for an attached animation element.
| animation | Animation element in this document. |
| offset | Seconds relative to the current document time, including negative offsets. |
| Transform2d donner::svg::SVGDocument::canvasFromDocumentTransform | ( | ) | const |
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.
| Vector2i donner::svg::SVGDocument::canvasSize | ( | ) | const |
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.
| 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.
|
inlinestatic |
Rehydrate an SVGDocument facade from an internal shared document handle.
| handle | Shared document-state handle to wrap. |
| 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.
| name | Event name, at most 128 bytes. |
| target | Attached target belonging to this document. |
| bubbles | Whether the event also reaches ancestors. |
| 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.
| type | Event being delivered. |
| target | Element under the pointer, belonging to this document. |
| bool donner::svg::SVGDocument::endAnimation | ( | const SVGElement & | animation, |
| double | offset = 0 ) |
Schedule an end instance for an active animation.
| animation | Animation element in this document. |
| offset | Seconds relative to the current document time. |
|
inline |
Get the internal shared document handle used by this value facade.
| bool donner::svg::SVGDocument::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.
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.
|
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.
| 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.
| parent | Element that receives element as a child. |
| element | Element to insert. |
| referenceElement | Optional existing child to insert before. |
| 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.
Complex selectors are supported:
| selector | CSS selector to match. |
| 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.
| element | Element to remove. |
| 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.
| element | Element whose attribute should be removed. |
| name | Attribute name to remove. |
| void donner::svg::SVGDocument::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.
| 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.
| elements | Inserted elements, oldest first. |
| insertions | Source delta for each element, in the same order. |
| 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.
| width | Width of the canvas, in pixels. Must be positive. |
| height | Height of the canvas, in pixels. Must be positive. |
| 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.
| element | Element whose attribute should be set. |
| name | Attribute name to set. |
| value | Raw unescaped attribute value. |
| 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.
| element | Element whose text content to replace. |
| text | New text content (raw, unescaped). An empty string clears the content. |
|
inline |
Set the DOM threading policy for this document.
| mode | New threading mode. |
| 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.
| seconds | Document time in seconds. |
| 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.
| languages | User's preferred languages, in priority order. |
| 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.
|
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 or mutating the returned registry.
|
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.
| void donner::svg::SVGDocument::useAutomaticCanvasSize | ( | ) |
| 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"}.
|
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.
|
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.
| callback | Callable invoked as callback(DocumentReadAccess&). |
| 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.
| callback | Callable invoked as callback(DocumentWriteAccess&) or callback(SVGDocumentMutation&). |
| 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.