-
-
Notifications
You must be signed in to change notification settings - Fork 72
Description
Summary
SixLabors.Fonts eagerly loads and parses all glyph data during Add() / LoadFont().
For many real-world applications, this creates major performance and memory problems, especially with large CJK or emoji fonts (30–100+ MB).
In many software scenarios, the application may only need 1–2 glyphs from a large font, yet the entire font’s glyph tables (glyf, CFF, loca, kerning, metrics) are parsed upfront.
This leads to unnecessary CPU work, high memory usage, and slow startup times.
I would like to request support for on-demand glyph loading (lazy glyph parsing) so that glyph outlines are only parsed when they are actually used during rendering or layout.
Problem Description
Currently:
FileFontMetricsandStreamFontMetricseagerly parse all glyphs.FontMetricsmaterializes glyph-related data for every glyph.- This happens at
FontCollection.Add(path)orAdd(stream). - Even if the application renders a single glyph, the entire font must be parsed.
This results in:
- High initial loading cost
- Increased memory consumption
- Poor performance with large fonts (CJK, emoji, TTC collections)
- Trouble in UI/design tools loading many fonts
- Poor scaling in image-generation or rendering servers
Examples of real usage where only a very small subset of glyphs is needed:
- Rendering a single icon from an icon font
- Using one Chinese character in a design tool
- Stamping/labeling with 2–5 glyphs
- Rendering one emoji from a large emoji font
Yet the entire font must still be parsed, which is wasteful.
Why On-Demand Glyph Loading Is Important
Other text engines like:
- FreeType / FreeType2
- Skia
- HarfBuzz (via FreeType callbacks)
perform:
- Upfront: Parse only top-level tables (
cmap,maxp,loca, metrics) - Lazy: Parse individual glyph outlines only when needed
This drastically improves loading time and reduces memory for large fonts.
SixLabors.Fonts currently has no mechanism such as:
- A lazy
GlyphTable - A glyph resolver callback
- Deferred glyf/CFF parsing
- A “load glyph on demand” pipeline
So performance for large fonts is significantly worse than necessary.
Proposed Feature
Support a way to load glyph outlines only when they are needed.
Option A — Lazy Glyph Table
Provide an interface such as:
interface IGlyphLoader
{
GlyphData LoadGlyph(int glyphIndex);
}Allow FontMetrics to use a loader instead of fully materializing glyphs.
Option B — Lazy Font Loading API
Example:
FontCollection.AddLazy(path, glyphLoader: index => LoadGlyphData(index));Option C — Partial Font Loading Strategy
- Parse only required global tables upfront (
head,maxp,cmap,loca) - Defer glyf/CFF parsing until a glyph is accessed
Benefits
- Much lower memory usage
- Faster font loading, especially for large CJK/emoji fonts
- More responsive UI and design tools
- Better scaling when many fonts are loaded
- Suitable for high-performance image-generation servers
- Avoids unnecessary work when only a few glyphs are actually needed