pub struct TextFontService { /* private fields */ }Expand description
Shared font resources for a text-typeset session.
Owns the font registry, the glyph atlas, the glyph cache, and the
swash scale context. Construct one per process (or one per window
if you really need isolated atlases) and share it by Rc<RefCell<_>>
across every DocumentFlow that renders into the same atlas.
Implementations§
Source§impl TextFontService
impl TextFontService
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a service whose font registry is pre-populated with the operating system’s fonts, so arbitrary documents (CJK, emoji, scripts the host didn’t bundle) still render via glyph fallback.
Still call set_default_font (and
usually register_font for the primary
UI font) before any DocumentFlow lays out content.
Enumerating OS fonts is a one-time startup cost; their bytes load
lazily on first use. Use
new_without_system_fonts to
skip the scan and keep a fully host-controlled font set.
Sourcepub fn new_without_system_fonts() -> Self
pub fn new_without_system_fonts() -> Self
Like new but with no OS font enumeration: only
fonts added via register_font* are available. Use this when the
host ships a controlled font set and wants neither the startup
scan nor implicit system fonts.
Sourcepub fn register_font(&mut self, data: &[u8]) -> FontFaceId
pub fn register_font(&mut self, data: &[u8]) -> FontFaceId
Register a font face from raw TTF/OTF/WOFF bytes.
Parses the font’s name table to extract family, weight, and
style, then indexes it via fontdb for CSS-spec font matching.
Returns the first face ID — font collections (.ttc) may
contain multiple faces.
§Panics
Panics if the font data contains no parseable faces.
Register a font from a pre-built shared byte container,
avoiding the copy that register_font
would perform.
Pass an Arc<Mmap> (or any Arc<dyn AsRef<[u8]> + Sync + Send>)
when the caller already holds the data in a shareable form —
useful for large system fonts (color emoji) where copying to an
owned Vec<u8> would double the resident memory cost.
§Panics
Panics if the font data contains no parseable faces.
Sourcepub fn register_font_as(
&mut self,
data: &[u8],
family: &str,
weight: u16,
italic: bool,
) -> FontFaceId
pub fn register_font_as( &mut self, data: &[u8], family: &str, weight: u16, italic: bool, ) -> FontFaceId
Register a font with explicit metadata, overriding the font’s name table. Use when the font’s internal metadata is unreliable or when aliasing a font to a different family name.
§Panics
Panics if the font data contains no parseable faces.
Like register_font_as but takes a
pre-built shared byte container, avoiding the copy.
§Panics
Panics if the font data contains no parseable faces.
Sourcepub fn set_default_font(&mut self, face: FontFaceId, size_px: f32)
pub fn set_default_font(&mut self, face: FontFaceId, size_px: f32)
Set which face to use as the document default, plus its base
size in logical pixels. This is the fallback font when a
fragment’s TextFormat doesn’t specify a family or when the
requested family isn’t found.
Sourcepub fn set_generic_family(&mut self, generic: &str, family: &str)
pub fn set_generic_family(&mut self, generic: &str, family: &str)
Map a generic family name (e.g. "serif", "monospace") to a
concrete registered family. When text-document emits a fragment
whose font_family matches a generic, the font resolver looks
it up through this table before querying fontdb.
Sourcepub fn font_family_name(&self, face_id: FontFaceId) -> Option<String>
pub fn font_family_name(&self, face_id: FontFaceId) -> Option<String>
Look up the family name of a registered face by id.
Sourcepub fn font_registry(&self) -> &FontRegistry
pub fn font_registry(&self) -> &FontRegistry
Borrow the font registry directly — needed by callers that want to inspect or extend it beyond the helpers exposed here.
Sourcepub fn families(&self) -> Vec<FontFamilyInfo>
pub fn families(&self) -> Vec<FontFamilyInfo>
Enumerate every installed font family, deduplicated and sorted.
Cheap (fontdb metadata only — no font bytes loaded). Collapses
weight/style faces into one entry per family, with monospaced
true when any face of the family is monospaced. The item source for
a font picker.
Sourcepub fn family_names(&self) -> Vec<String>
pub fn family_names(&self) -> Vec<String>
Enumerate installed font family names, deduplicated and sorted — the
simple projection of families.
Sourcepub fn family_is_monospaced(&self, family: &str) -> bool
pub fn family_is_monospaced(&self, family: &str) -> bool
True if any face of the named family is monospaced (fontdb metadata, no bytes loaded). Case-insensitive on the family name.
Sourcepub fn writing_system_index_builder(&self) -> WritingSystemIndexBuilder
pub fn writing_system_index_builder(&self) -> WritingSystemIndexBuilder
Build a Send snapshot of every family’s face byte-sources, to be
moved to a background thread and turned into a writing-system
coverage map (see WritingSystemIndexBuilder).
Cheap on the calling thread; the expensive per-face OS/2 parsing runs
in WritingSystemIndexBuilder::build off-thread.
Sourcepub fn default_line_height(&self) -> f32
pub fn default_line_height(&self) -> f32
Line height (in logical pixels) for the registry’s default
font + size, computed as ascent + descent + leading.
Useful for callers that need to size a widget against the
intrinsic line height before any content has been laid out
(an empty editor that wants to report a min_lines-tall
intrinsic size, for example). Returns 0.0 when no default
font is registered or the face cannot be opened.
Does not apply any per-block line_height_multiplier —
multipliers live on BlockFormat, not on the font, and have
no meaning when there’s no block to multiply against. Use
measure_line_height when you
already have a TextFormat.
Sourcepub fn measure_line_height(&self, format: &TextFormat) -> f32
pub fn measure_line_height(&self, format: &TextFormat) -> f32
Line height (in logical pixels) for an explicit
TextFormat, computed as ascent + descent + leading of
the resolved font at the resolved size. Fields left as None
fall back to the registry’s defaults — same resolution path
as live inline runs (see font::resolve::resolve_font).
Returns 0.0 when the format cannot be resolved (no default
font registered, requested family missing and no fallback,
face fails to open).
Sourcepub fn set_scale_factor(&mut self, scale_factor: f32)
pub fn set_scale_factor(&mut self, scale_factor: f32)
Set the device pixel ratio for HiDPI rasterization.
Layout stays in logical pixels; glyphs are shaped and
rasterized at size_px * scale_factor so text is crisp on
HiDPI displays. Orthogonal to DocumentFlow::set_zoom,
which is a post-layout display transform.
Changing this value invalidates the glyph cache and the
atlas (both are cleared here) and marks every
DocumentFlow that was laid out against this service as
stale via the scale_generation counter. The caller must
then re-run layout_full / layout_blocks on every flow
before the next render — existing shaped advances depended
on the old ppem rounding.
Clamped to 0.25..=8.0. Default is 1.0.
Sourcepub fn scale_factor(&self) -> f32
pub fn scale_factor(&self) -> f32
The current scale factor (default 1.0).
Sourcepub fn scale_generation(&self) -> u64
pub fn scale_generation(&self) -> u64
Monotonic counter bumped by every successful
set_scale_factor call.
DocumentFlow snapshots this during layout so the framework
can ask whether a flow needs to be re-laid out after a HiDPI
change without having to track the transition itself.
Sourcepub fn eviction_epoch(&self) -> u64
pub fn eviction_epoch(&self) -> u64
Monotonic counter bumped every time the atlas drops entries —
LRU eviction triggered by atlas_snapshot,
LRU eviction at the start of every full
render (inside
build_render_frame), or wholesale reset by
set_scale_factor.
This is the single source of truth for “retained glyph quads may be stale”: frameworks should compare it against a last-seen value once per frame and invalidate every retained paint cache when it moves, regardless of which path moved it.
Per-widget crate::DocumentFlows stamp this value on every full
render and refuse to reuse
their cached glyph quads on subsequent
render_cursor_only
or render_block_only
calls when the epoch has advanced — at that point any baked-in
atlas pixel coordinates in those cached quads may reference
slots now owned by unrelated glyphs.
Sourcepub fn atlas_snapshot(&mut self, advance_generation: bool) -> AtlasSnapshot<'_>
pub fn atlas_snapshot(&mut self, advance_generation: bool) -> AtlasSnapshot<'_>
Read the glyph atlas state without triggering a render.
Optionally advances the cache generation and runs eviction.
Returns an AtlasSnapshot the caller can pattern-match
by field. The atlas’s internal dirty flag is cleared here,
so the caller must either upload pixels during the
returned borrow or accept a one-frame delay.
When snapshot.glyphs_evicted is true, callers that cache
glyph positions (e.g. paint caches) must invalidate —
evicted atlas slots may be reused by subsequent allocations
and old UVs would now point to the wrong glyph.
Only advance the generation on frames where actual text work happened; skipping eviction on idle frames prevents aging out glyphs that are still visible but not re-measured this tick.
Sourcepub fn touch_glyphs(&mut self, keys: &[GlyphCacheKey])
pub fn touch_glyphs(&mut self, keys: &[GlyphCacheKey])
Mark the given glyph cache keys as used in the current
generation, preventing them from being evicted. Use this when
glyph quads are cached externally (e.g. per-widget paint
caches) and the normal rasterize_glyph_quad → get() path
is skipped.
Sourcepub fn peek_glyph_rect(&self, key: &GlyphCacheKey) -> Option<[u32; 4]>
pub fn peek_glyph_rect(&self, key: &GlyphCacheKey) -> Option<[u32; 4]>
Current atlas rectangle ([x, y, w, h], atlas pixel coordinates)
for a cached glyph, without refreshing its LRU timestamp.
Returns None when the glyph is not (or no longer) resident.
Intended for debug-build validation of externally retained glyph
quads: a quad whose baked rect no longer matches the live rect is
sampling pixels that belong to another glyph.
Sourcepub fn atlas_dirty(&self) -> bool
pub fn atlas_dirty(&self) -> bool
True if the atlas has pending pixel changes since the last
upload. The atlas is marked clean after every render() that
copies pixels into its RenderFrame; this accessor exposes
the flag for framework paint-cache invalidation decisions.
Sourcepub fn atlas_width(&self) -> u32
pub fn atlas_width(&self) -> u32
Current atlas texture width in pixels.
Sourcepub fn atlas_height(&self) -> u32
pub fn atlas_height(&self) -> u32
Current atlas texture height in pixels.
Sourcepub fn atlas_pixels(&self) -> &[u8] ⓘ
pub fn atlas_pixels(&self) -> &[u8] ⓘ
Raw atlas pixel buffer (RGBA8).
Sourcepub fn mark_atlas_clean(&mut self)
pub fn mark_atlas_clean(&mut self)
Mark the atlas clean after the caller has uploaded its
contents to the GPU. Paired with atlas_dirty + atlas_pixels
for framework adapters that upload directly from the service
instead of consuming RenderFrame::atlas_pixels.