Egui::Backend::AtlasFonts
Inherits Egui::Fonts < Reference < Object
The Egui::Fonts implementation shared by the font backends:
CrystalFonts (crystalfonts.cr, primary) and FreetypeFonts
(freetype.cr, C-FFI dev accelerator). One RGBA atlas + glyph
cache, one walk (fractional advances + kerning) for both measure
and draw; a backend implements glyph production and metrics.
Constants
Memoized kerning in front of the backend FFI: kerning is a constant per (glyph pair, size) of the immutable font file, so no invalidation is ever needed. Real text touches a few hundred distinct pairs; the cap exists only as a hard bound (a sythetic sweep over every glyph pair of a CJK font would be huge) — clear-on-overflow like the measure cache.
Memoized measure for STATIC text (labels, captions, button
texts — strings that return frame after frame unchanged).
Anything the user types into (TextEdit/TextArea/…) keeps calling
#measure: its content churns per keystroke, and dead entries
would only pollute the map.
The same (text, physical size, tracking) always walks to the same width — advances and kerning are per-glyph constants of the font — so no invalidation is ever needed for correctness: every width input (draw size = size * scale, letter_spacing) rides the key. Memory is bounded by TWO guards: a LENGTH filter (unbounded distinct strings — buffer lines, caret prefixes — must never land here) and a COUNT cap with clear-on-overflow (every dropped entry rebuilds in one walk, cheaper than LRU bookkeeping on every hit).
Constructors
Instance methods
The atlas this stack bakes into: its OWN (default — specs, standalone tools) or a SHARED one owned by the backend registry (sokol.cr: one GPU texture for every stack the registry creates, so a font picker flipping through hundreds of families cannot exhaust the shim's atlas cap or VRAM).
Acknowledge an overflow WITHOUT touching the atlas: the registry already reset the SHARED atlas this stack bakes into — the epoch mismatch invalidates the glyph cache lazily in #glyph.
Rasterized coverage bitmap as text (debug/tests) — works for every backend: glyphs land in the shared atlas either way.
Coverage bytes of a baked glyph's atlas slot (specs/tests); nil for blank glyphs.
Kerning between two glyph ids (px) at the given size.
Extra spacing between letters (px) — added BETWEEN glyphs only,
never after the last one, so measure widths stay exact.
Backends whose glyph placement reads tighter than their
reference open this up (live-tunable: fontpreview exposes it).
Extra spacing between letters (px) — added BETWEEN glyphs only,
never after the last one, so measure widths stay exact.
Backends whose glyph placement reads tighter than their
reference open this up (live-tunable: fontpreview exposes it).
Memoized measure for STATIC text (label-like widgets — see
AtlasFonts#measure_cached for the cache design). The base class
and every non-AtlasFonts backend just measure; only the real
font stacks gain a cache, so headless specs see identical
behavior either way.
{ascender, descender} in px for a size (descender negative).
Did a frame's baking overflow the atlas? (Registry-level reset in sokol.cr polls this across every live stack.)
Wipe the atlas and the glyph cache when a frame overflowed it
(fontstash's texture reset): everything visible re-bakes on
demand, so dropped letters come back instead of staying blank
forever (dropped glyphs are cached as blanks otherwise). Call
before flush, outside a render pass; a true result means the
caller should re-touch this frame's text commands. For stacks
on a SHARED atlas the registry resets the atlas itself and calls
#clear_overflow_flag instead (one wipe covers every stack; the
epoch bump invalidates the caches lazily in #glyph).
Pixels per point the draw path rasterizes at (set by the backend
each frame; 1.0 headless). Hinted advances are per-ppem, NOT
linear in size — SF Mono advances 7.0px at 14pt but 15px at the
retina draw size (28px) — so measure must walk the run at the
same physical size the glyphs will be drawn at and fold the
width back to points, or every widget lays out on advances the
painter then exceeds (in a terminal grid the cursor visibly
drifts off the text).
Pixels per point the draw path rasterizes at (set by the backend
each frame; 1.0 headless). Hinted advances are per-ppem, NOT
linear in size — SF Mono advances 7.0px at 14pt but 15px at the
retina draw size (28px) — so measure must walk the run at the
same physical size the glyphs will be drawn at and fold the
width back to points, or every widget lays out on advances the
painter then exceeds (in a terminal grid the cursor visibly
drifts off the text).
Rasterize every glyph a text command needs. Called before the render
pass: sg_update_image is illegal inside a pass, so the atlas must be
uploaded first (see flush). scale = framebuffer pixels per point —
glyphs are rasterized at the physical size (crisp on retina); 1.0
for callers without a window (specs, fontpreview tabs).
Walk the run exactly like the draw path does (fractional advances + kerning), yielding (pen_x, glyph) per char. Returns the final pen.