Donner SVG 0.8.0-pre
SVG editor and embeddable C⁠+⁠+⁠20 engine.
Loading...
Searching...
No Matches
donner::svg::FontManager Class Reference

Manages font loading, caching, and lookup for text rendering. More...

#include "donner/svg/resources/FontManager.h"

Classes

struct  GlyphOutlineComplexity
 Validation-time allocation/work bound for one font outline. More...

Public Member Functions

 FontManager (Registry &registry, size_t maximumLoadedFontBytes=kDefaultMaximumLoadedFontBytes, size_t maximumLoadedFonts=kDefaultMaximumLoadedFonts, size_t maximumFontValidationWork=kDefaultMaximumFontValidationWork)
 Construct a FontManager tied to the provided ECS registry.
 ~FontManager ()
 Destructor.
 FontManager (const FontManager &)=delete
FontManageroperator= (const FontManager &)=delete
 FontManager (FontManager &&)=delete
FontManageroperator= (FontManager &&)=delete
void addFontFace (const css::FontFace &face)
 Register a @font-face declaration.
void setGenericFamilyMapping (std::string_view genericName, std::string_view realFamily)
 Register a mapping from a CSS generic family name (serif, sans-serif, monospace, cursive, fantasy) to a real font family name registered via addFontFace().
FontHandle findFont (std::string_view family)
 Find or load a font matching the given family name.
FontHandle findFont (std::string_view family, int weight)
 Find or load a font matching the given family name and weight.
FontHandle findFont (std::string_view family, int weight, int style, int stretch)
 Find or load a font matching the given family name, weight, style, and stretch.
FontHandle loadFontData (std::span< const uint8_t > data, FontDataTrust trust=FontDataTrust::Untrusted)
 Load a font from raw TTF/OTF/WOFF data.
std::span< const uint8_t > fontData (FontHandle handle) const
 Get the raw font data bytes for a handle.
bool isTrustedFont (FontHandle handle) const
 Returns whether handle was loaded from an explicitly trusted source.
std::optional< GlyphOutlineComplexityglyphOutlineComplexity (FontHandle handle, int glyphIndex) const
 Return a lifetime-safe O(1) pre-decode bound for a validated glyph.
std::optional< std::span< const uint8_t > > sfntTable (FontHandle handle, std::string_view tag) const
 Get a table from the cached, validated sfnt directory for a handle.
bool isValidatedFont (FontHandle handle) const
 Return true when handle has a cached validated sfnt directory.
size_t loadedFontBytes () const
 Exact font-data and cached-index bytes currently charged to this registry's budget.
size_t numLoadedFonts () const
 Number of loaded font components currently charged to this registry's budget.
size_t fontValidationWork () const
 CFF validation work permanently consumed by load attempts in this registry.
size_t compressedFontDecompressionAttempts () const
 Compressed-font decompression attempts performed for this registry.
size_t numFaces () const
 Get the number of registered @font-face rules.
std::string_view faceFamilyName (size_t index) const
 Get the family name of a registered @font-face rule by index.
FontHandle fallbackFont ()
 Get the handle for the embedded fallback font (Public Sans).
void setFontProvider (const FontFamilyProvider *provider)
 Attach an external font provider (typically a FontCatalog) consulted during findFont() for family names not satisfied by a registered @font-face rule, before falling back to the embedded Public Sans font.

Static Public Member Functions

static void SetDefaultFontProvider (const FontFamilyProvider *provider)
 Set the process-wide default font provider.
static const FontFamilyProviderDefaultFontProvider ()
 Returns the current process-wide default font provider (may be nullptr).

Static Public Attributes

static constexpr size_t kDefaultMaximumLoadedFontBytes = 64 * 1024 * 1024
 Default aggregate byte budget for font data loaded into one registry.
static constexpr size_t kDefaultMaximumLoadedFonts = 1024
 Default maximum number of font byte streams retained in one registry.
static constexpr size_t kDefaultMaximumFontValidationWork
 Default aggregate CFF validation work admitted for one registry.

Friends

struct FontManagerTestAccess

Detailed Description

Manages font loading, caching, and lookup for text rendering.

FontManager is the shared font infrastructure used by both the Skia and TinySkia backends. It handles:

  • Loading raw TTF/OTF font data.
  • Loading WOFF 1.0 fonts via the existing WoffParser, reconstructing the sfnt byte stream, then storing the reconstructed sfnt bytes.
  • Resolving @font-face source cascades.
  • Caching resolved family/style lookups to avoid repeated face scans.
  • Falling back to the embedded Public Sans font when no match is found.
  • Storing backend caches on the same font entity as the loaded bytes.

FontManager uses entt entities to store font data, with one entity per registered @font-face rule or directly-loaded font. Text backends can cache parsed backend objects directly on the same entity.

FontManager follows the registry's access discipline rather than providing internal locking. Const queries may run in parallel while the registry is held for reading; loads and other mutations require serialized write access. The registry must outlive every stack-local manager.


Class Documentation

◆ donner::svg::FontManager::GlyphOutlineComplexity

struct donner::svg::FontManager::GlyphOutlineComplexity

Validation-time allocation/work bound for one font outline.

Class Members
size_t maximumVertices = 0
size_t work = 0

Constructor & Destructor Documentation

◆ FontManager()

donner::svg::FontManager::FontManager ( Registry & registry,
size_t maximumLoadedFontBytes = kDefaultMaximumLoadedFontBytes,
size_t maximumLoadedFonts = kDefaultMaximumLoadedFonts,
size_t maximumFontValidationWork = kDefaultMaximumFontValidationWork )
explicit

Construct a FontManager tied to the provided ECS registry.

The first manager to perform a serialized font load for a registry establishes its aggregate byte, item, and untrusted CFF-validation limits. Read-only queries never establish or replace that state. Later manager instances for the same registry share it so loaded components and validation attempts remain accounted across manager lifetimes.

Construction does not access the registry context, so a FontManager can itself be safely constructed by registry.ctx().emplace<FontManager>(registry).

Member Function Documentation

◆ addFontFace()

void donner::svg::FontManager::addFontFace ( const css::FontFace & face)

Register a @font-face declaration.

Sources are resolved lazily on first findFont() call for the corresponding family name.

Registration is idempotent: re-registering a declaration that is byte-for-byte the same rule (same family, weight, style, stretch, and the same ordered source list pointing at the same payloads) reuses the entity minted the first time and leaves the resolution cache intact. Callers that re-announce a document's whole @font-face set on every style recompute therefore keep stable font entities, which keeps every downstream per-font cache (rendered glyph outlines, backend face objects) valid across unrelated document mutations. A rule that differs in any of those fields is a different declaration and mints a new entity, so newly loaded font data is never served from a stale entity.

Family names are compared case-insensitively, matching how findFont() selects a face, so two declarations differing only in the casing of their family name are one declaration here and numFaces() counts them once.

Parameters
faceThe parsed @font-face rule.

◆ faceFamilyName()

std::string_view donner::svg::FontManager::faceFamilyName ( size_t index) const

Get the family name of a registered @font-face rule by index.

Parameters
indexIndex into the registered faces (0 to numFaces()-1).
Returns
The family name, or empty string_view if index is out of range.

◆ findFont() [1/3]

FontHandle donner::svg::FontManager::findFont ( std::string_view family)

Find or load a font matching the given family name.

Resolution order:

  1. If the family is a CSS generic name with a registered mapping, resolve to the real name.
  2. Return an already-loaded entity if the best matching face has already been resolved.
  3. Walk registered @font-face rules whose font-family matches, trying each source.
  4. Fall back to the embedded Public Sans font.
Parameters
familyFont family name to look up.
Returns
A valid FontHandle, or an invalid handle if even the fallback fails.

◆ findFont() [2/3]

FontHandle donner::svg::FontManager::findFont ( std::string_view family,
int weight )

Find or load a font matching the given family name and weight.

Parameters
familyFont family name to look up.
weightCSS font-weight value (100-900, 400=normal, 700=bold).
Returns
A valid FontHandle, or falls back to findFont(family) if no weight match.

◆ findFont() [3/3]

FontHandle donner::svg::FontManager::findFont ( std::string_view family,
int weight,
int style,
int stretch )

Find or load a font matching the given family name, weight, style, and stretch.

Parameters
familyFont family name to look up.
weightCSS font-weight value (100-900, 400=normal, 700=bold).
styleCSS font-style value (0=normal, 1=italic, 2=oblique).
stretchCSS font-stretch value (1-9, 5=normal, matching FontStretch enum).
Returns
A valid FontHandle, or falls back to findFont(family, weight) if no match.

◆ fontData()

std::span< const uint8_t > donner::svg::FontManager::fontData ( FontHandle handle) const

Get the raw font data bytes for a handle.

This is useful for backends (like Skia) that need to create their own font objects from the raw data.

Parameters
handleA valid FontHandle.
Returns
Span of the raw font data, or empty span if the handle is invalid.

◆ loadFontData()

FontHandle donner::svg::FontManager::loadFontData ( std::span< const uint8_t > data,
FontDataTrust trust = FontDataTrust::Untrusted )

Load a font from raw TTF/OTF/WOFF data.

The data is copied internally. The font is not associated with any family name; callers should use findFont() for name-based lookup.

The default treats the bytes as untrusted. The simple text backend refuses to pass untrusted bytes to stb_truetype because that parser does not accept a buffer length. Use FontDataTrust::Trusted only for application-controlled embedded or local-system fonts.

Parameters
dataRaw font file bytes (TTF, OTF, or WOFF 1.0).
trustWhether the source is trusted enough for length-unaware font backends.
Returns
A valid FontHandle on success, or an invalid handle on failure.

◆ SetDefaultFontProvider()

void donner::svg::FontManager::SetDefaultFontProvider ( const FontFamilyProvider * provider)
static

Set the process-wide default font provider.

Every FontManager constructed afterwards adopts it (existing instances are unaffected). The editor installs its FontCatalog here so document render paths that create their own FontManager resolve embedded and system fonts without threading the catalog through every call site.

The provider is borrowed, not owned, and must outlive all FontManagers that adopt it.

◆ setFontProvider()

void donner::svg::FontManager::setFontProvider ( const FontFamilyProvider * provider)
inline

Attach an external font provider (typically a FontCatalog) consulted during findFont() for family names not satisfied by a registered @font-face rule, before falling back to the embedded Public Sans font.

The provider is borrowed, not owned, and must outlive this FontManager. Pass nullptr to detach.

Attaching a different provider abandons every font resolved through the previous one, since another provider may answer the same family with different bytes. Those fonts keep their entities and their share of the aggregate budget: handles to them may still be held by text runs and by backend caches keyed on the handle, so their bytes have to stay valid. The budget is released when the entities are destroyed, normally with the registry.

Resolution order for findFont(family):

  1. Matching @font-face rule registered via addFontFace() (document-provided fonts win).
  2. The attached provider (a FontCatalog tries Embedded families, then System families).
  3. Embedded Public Sans fallback.

◆ setGenericFamilyMapping()

void donner::svg::FontManager::setGenericFamilyMapping ( std::string_view genericName,
std::string_view realFamily )

Register a mapping from a CSS generic family name (serif, sans-serif, monospace, cursive, fantasy) to a real font family name registered via addFontFace().

This allows findFont("sans-serif") to resolve to the specified family.

Parameters
genericNameThe CSS generic family name (case-insensitive).
realFamilyThe real family name to resolve to.

◆ sfntTable()

std::optional< std::span< const uint8_t > > donner::svg::FontManager::sfntTable ( FontHandle handle,
std::string_view tag ) const

Get a table from the cached, validated sfnt directory for a handle.

Parameters
handleA valid FontHandle.
tagFour-byte sfnt table tag.
Returns
A bounded table span, or std::nullopt if the handle or tag is invalid or absent.

Member Data Documentation

◆ kDefaultMaximumFontValidationWork

size_t donner::svg::FontManager::kDefaultMaximumFontValidationWork
staticconstexpr
Initial value:
=
constexpr std::size_t kMaximumCffOutlineValidationWork
Default whole-font work ceiling for one bounded CFF validation.
Definition CffOutlineComplexity.h:12

Default aggregate CFF validation work admitted for one registry.


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