|
|
Donner SVG 0.8.0-pre
SVG editor and embeddable C++20 engine.
|
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 ®istry, 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 | |
| FontManager & | operator= (const FontManager &)=delete |
| FontManager (FontManager &&)=delete | |
| FontManager & | operator= (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< GlyphOutlineComplexity > | glyphOutlineComplexity (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 FontFamilyProvider * | DefaultFontProvider () |
| 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 |
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:
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.
| struct donner::svg::FontManager::GlyphOutlineComplexity |
|
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).
| 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.
| face | The parsed @font-face rule. |
| std::string_view donner::svg::FontManager::faceFamilyName | ( | size_t | index | ) | const |
Get the family name of a registered @font-face rule by index.
| index | Index into the registered faces (0 to numFaces()-1). |
| FontHandle donner::svg::FontManager::findFont | ( | std::string_view | family | ) |
Find or load a font matching the given family name.
Resolution order:
| family | Font family name to look up. |
| FontHandle donner::svg::FontManager::findFont | ( | std::string_view | family, |
| int | weight ) |
Find or load a font matching the given family name and weight.
| family | Font family name to look up. |
| weight | CSS font-weight value (100-900, 400=normal, 700=bold). |
| 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.
| family | Font family name to look up. |
| weight | CSS font-weight value (100-900, 400=normal, 700=bold). |
| style | CSS font-style value (0=normal, 1=italic, 2=oblique). |
| stretch | CSS font-stretch value (1-9, 5=normal, matching FontStretch enum). |
| 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.
| handle | A valid FontHandle. |
| 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.
| data | Raw font file bytes (TTF, OTF, or WOFF 1.0). |
| trust | Whether the source is trusted enough for length-unaware font backends. |
|
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.
|
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):
| 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.
| genericName | The CSS generic family name (case-insensitive). |
| realFamily | The real family name to resolve to. |
| 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.
| handle | A valid FontHandle. |
| tag | Four-byte sfnt table tag. |
|
staticconstexpr |
Default aggregate CFF validation work admitted for one registry.