Skip to main content

FontManager

Struct FontManager 

Source
pub struct FontManager<T> {
    pub fc_cache: FcFontCache,
    pub parsed_fonts: Arc<Mutex<HashMap<FontId, T>>>,
    pub font_chain_cache: HashMap<FontChainKey, FontFallbackChain>,
    pub embedded_fonts: Mutex<HashMap<u64, FontRef>>,
    pub font_hash_to_families: HashMap<u64, StyleFontFamilyVec>,
    pub registry: Option<Arc<FcFontRegistry>>,
    pub last_resolved_font_stacks_sig: Option<u64>,
    pub memory_families: HashMap<String, Vec<MemoryFace>>,
    /* private fields */
}

Fields§

§fc_cache: FcFontCache

The font-path cache. FcFontCache in rust-fontconfig 4.1 is already a shared handle internally (Arc<RwLock<_>>), so no further Arc<...> wrapping is needed — clones are cheap and all clones see builder writes instantly.

§parsed_fonts: Arc<Mutex<HashMap<FontId, T>>>

Holds the actual parsed font (usually with the font bytes attached). Wrapped in Arc so multiple FontManager instances can share the same pool of already-parsed fonts (avoids re-reading from disk).

§font_chain_cache: HashMap<FontChainKey, FontFallbackChain>§embedded_fonts: Mutex<HashMap<u64, FontRef>>

Cache for direct FontRefs (embedded fonts like Material Icons) These are fonts referenced via FontStack::Ref that bypass fontconfig

§font_hash_to_families: HashMap<u64, StyleFontFamilyVec>

Reverse map: font_family_hash → actual StyleFontFamilyVec. Accumulated across DOMs. Used by font collection and text shaping to resolve compact cache hashes without get_property_slow.

§registry: Option<Arc<FcFontRegistry>>

Optional link back to the live FcFontRegistry. When present, chain resolution uses rust_fontconfig::registry::FcFontRegistry::request_and_resolve_with_scripts which lazy-parses system fonts as the DOM requests them (scout-on-demand). None falls back to querying whatever is already in the shared cache.

§last_resolved_font_stacks_sig: Option<u64>

FxHash of the prev_font_hashes slice at the moment the last successful collect_and_resolve_font_chains_with_registration call populated font_chain_cache. Lets repeated layouts of the same DOM skip the ~1.5 ms (cold) / ~0.9 ms (warm) chain resolver when the set of font-family hashes has not changed. Cleared whenever font_chain_cache is explicitly emptied.

§memory_families: HashMap<String, Vec<MemoryFace>>

Index of every font registered by FAMILY NAME into fc_cache’s in-memory font table (bundled fonts, embedder fonts, the built-in mock test fonts): normalized family name → the FontMatch the resolver should emit for it.

WHY THIS EXISTS (architectural, see resolve_font_chains_fast): the fast chain resolver in rust-fontconfig 4.4 (FcFontRegistry::request_fonts_fast) resolves families purely against known_paths — i.e. fonts that exist as FILES ON DISK. In-memory fonts are invisible to it, so a family registered with FcFontCache::with_memory_fonts could never be matched by name on the production path (which always has a live registry): it silently fell back to a system font. This index is consulted FIRST, before the disk probe, so a memory-registered family wins exactly as CSS says it should.

Implementations§

Source§

impl<T: ParsedFontTrait> FontManager<T>

Source

pub fn new(fc_cache: FcFontCache) -> Result<Self, LayoutError>

§Errors

Returns a LayoutError if the font cache cannot be initialized.

Source

pub fn register_named_font( &mut self, family: &str, bytes: &[u8], coverage: Vec<UnicodeRange>, ) -> FontId

Register a font by FAMILY NAME from raw bytes, as an in-memory font in the shared FcFontCache.

This is the ONE hook an embedder (or a test) uses to make a font resolvable by font-family: "<family>". It mints one FontId for the font, inserts it into the fontconfig cache’s memory-font table (so get_font_bytes / load_fonts_from_disk find it with no special-casing) and indexes it in Self::memory_families so the fast chain resolver can match it by name.

coverage are the codepoint ranges the font actually covers. Passing the true ranges matters: FontFallbackChain::resolve_char skips any font that reports no coverage, and a font claiming coverage it doesn’t have would render .notdef instead of falling back.

Returns the FontId the family now resolves to.

Source

pub fn register_named_font_in_tier( &mut self, family: &str, bytes: &[u8], coverage: Vec<UnicodeRange>, tier: MemoryFontTier, ) -> FontId

Register an in-memory face under family at an explicit MemoryFontTier.

Self::register_named_font is this with MemoryFontTier::Primary. Use MemoryFontTier::Fallback to offer a face for a family without displacing whatever is installed - a caller that ships stand-in fonts for serif/sans-serif/monospace wants the system’s faces to win on a desktop and its own to be there on wasm, and that is the tier that does both.

Source

pub fn register_builtin_mock_fonts(&mut self)

Register the built-in mock test fonts (see crate::text3::mock_fonts). Called from every constructor: the mock families are only reachable if a stylesheet names them, and having them always present means tests exercise the same font path as production instead of a test-only bypass.

Source

pub fn from_shared(fc_cache: FcFontCache) -> Result<Self, LayoutError>

Create a FontManager sharing the font-path cache handle.

The parsed_fonts pool starts empty. Fonts loaded during the first layout pass are cached and will be available on subsequent calls if you clone the parsed_fonts Arc before creating the next instance. For full sharing, prefer from_arc_shared().

§Errors

Returns a LayoutError if the font cache cannot be initialized.

Source

pub fn from_arc_shared( fc_cache: FcFontCache, parsed_fonts: Arc<Mutex<HashMap<FontId, T>>>, ) -> Result<Self, LayoutError>

Create a FontManager sharing both the font-path cache and the already-parsed font data with another FontManager.

This avoids re-reading and re-parsing font files from disk when rendering multiple documents that use the same fonts.

§Errors

Returns a LayoutError if the font cache cannot be initialized.

Source

pub fn with_registry(self, registry: Arc<FcFontRegistry>) -> Self

Attach a FcFontRegistry to this FontManager so subsequent chain-resolution calls use the on-demand path (rust_fontconfig::registry::FcFontRegistry::request_and_resolve_with_scripts).

Source

pub fn shared_parsed_fonts(&self) -> Arc<Mutex<HashMap<FontId, T>>>

Get a shareable handle to the parsed-font pool.

Pass this to from_arc_shared() to create a new FontManager that reuses already-parsed fonts.

Source

pub fn set_font_chain_cache( &mut self, chains: HashMap<FontChainKey, FontFallbackChain>, )

Set the font chain cache from externally resolved chains

This should be called with the result of resolve_font_chains() or collect_and_resolve_font_chains() from solver3::getters.

Source

pub fn set_font_chain_cache_with_sig( &mut self, chains: HashMap<FontChainKey, FontFallbackChain>, sig: Option<u64>, )

Set the font chain cache and record the input signature so subsequent layouts with the same prev_font_hashes skip the resolver. Pass sig = None if the caller cannot compute a reliable signature — equivalent to the single-arg set_font_chain_cache.

Source

pub fn merge_font_chain_cache( &mut self, chains: HashMap<FontChainKey, FontFallbackChain>, )

Merge additional font chains into the existing cache

Useful when processing multiple DOMs that may have different font requirements.

Source

pub const fn get_font_chain_cache( &self, ) -> &HashMap<FontChainKey, FontFallbackChain>

Get a reference to the font chain cache

Source

pub fn get_embedded_font_by_hash(&self, font_hash: u64) -> Option<FontRef>

Get an embedded font by its hash (used for WebRender registration) Returns the FontRef if it exists in the embedded_fonts cache.

§Panics

Panics if the internal font-cache mutex is poisoned.

Source

pub fn get_font_by_hash(&self, font_hash: u64) -> Option<T>

Get a parsed font by its hash (used for WebRender registration) Returns the parsed font if it exists in the parsed_fonts cache.

§Panics

Panics if the internal font-cache mutex is poisoned.

Source

pub fn resolve_font_by_hash(&self, font_hash: u64) -> Option<FontRef>
where T: Into<FontRef> + Clone,

THE font lookup: resolve a font_hash — the value layout stamps onto every shaped glyph and carries in DisplayListItem::Text — back to the face that produced it.

A FontManager shapes with faces from TWO pools: parsed_fonts (loaded from the resolved font chains) and embedded_fonts (handed to it directly by the DOM as StyleFontFamily::Ref — Material Icons and every other FontStack::Ref). Both can put a hash in the display list, so a renderer that consults only one of them silently drops user-visible text. That is exactly what shipped in 0.2.0: the CPU renderer searched parsed_fonts alone, so every widget icon vanished with [cpurender] Font hash … not found in FontManager while layout had happily measured and positioned it.

Every renderer resolves through this one function, so “layout produced this hash” and “the renderer can draw this hash” cannot disagree.

§Panics

Panics if the internal font-cache mutex is poisoned.

Source

pub fn register_embedded_font(&self, font_ref: &FontRef)

Register an embedded FontRef for later lookup by hash This is called when using FontStack::Ref during shaping

§Panics

Panics if the internal font-cache mutex is poisoned.

Source

pub fn get_loaded_fonts(&self) -> LoadedFonts<T>

Get a snapshot of all currently loaded fonts

This returns a copy of all parsed fonts, which can be passed to the shaper. No locking is required after this call - the returned HashMap is independent.

NOTE: This should be called AFTER loading all required fonts for a layout pass.

§Panics

Panics if the internal font-cache mutex is poisoned.

Source

pub fn get_loaded_font_ids(&self) -> HashSet<FontId>

Get the set of FontIds that are currently loaded

This is useful for computing which fonts need to be loaded (diff with required fonts).

§Panics

Panics if the internal font-cache mutex is poisoned.

Source

pub fn insert_font(&self, font_id: FontId, font: T) -> Option<T>

Insert a loaded font into the cache

Returns the old font if one was already present for this FontId.

§Panics

Panics if the internal font-cache mutex is poisoned.

Source

pub fn insert_fonts(&self, fonts: impl IntoIterator<Item = (FontId, T)>)

Insert multiple loaded fonts into the cache

This is more efficient than calling insert_font multiple times because it only acquires the lock once.

§Panics

Panics if the internal font-cache mutex is poisoned.

Source

pub fn load_missing_for_chains<F>( &self, chains: &ResolvedFontChains, load_fn: F, ) -> Vec<(FontId, String)>
where F: Fn(Arc<FontBytes>, usize) -> Result<T, LayoutError>,

One-shot helper that resolves “what fonts does chains need that this manager hasn’t loaded yet” and loads them via the supplied load_fn closure (typically PathLoader::load_font_shared for the production lazy-decode path). Updates parsed_fonts in place and returns any failures for the caller to log.

Replaces the same four-step collect → compute_diff → load_from_disk → insert_fonts dance previously inlined in LayoutWindow::layout_document, the CPU rasterizer pre-fill in cpurender.rs, and FontContext::load_fonts_for_chains.

Source

pub fn replace_fc_cache(&mut self, fc_cache: FcFontCache)

Replace the backing FcFontCache and re-register the built-in memory fonts.

Memory fonts (the mock test fonts, and any register_named_font bytes) live ONLY inside the cache. A bare self.fc_cache = new therefore strands them: their FontIds stay in memory_families but their bytes are gone with the old cache, so chain resolution matches them yet loading fails and text silently falls back (e.g. font-family: "Azul Mock Mono" measuring with the fallback font’s metrics). Use this whenever the cache is swapped for a fresh snapshot (registry handle, rebuilt system cache) instead of assigning the field directly.

Source

pub fn remove_font(&self, font_id: &FontId) -> Option<T>

Remove a font from the cache

Returns the removed font if it was present.

§Panics

Panics if the internal font-cache mutex is poisoned.

Source

pub fn garbage_collect_fonts( &mut self, keep_ids: &HashSet<FontId>, keep_hashes: &HashSet<u64>, ) -> usize

FONT GC — evict everything the CURRENT document no longer references.

keep_ids are the FontIds reachable from the font chains just resolved for this document; keep_hashes are the font-family hashes present in its CSS property cache. Anything else belonged to a node that is gone.

Without this, parsed_fonts / font_hash_to_families only ever GREW: a font loaded for one node stayed resident for the life of the window even after the node (and every other user of that family) disappeared — an app that cycles fonts (font picker, editor, live CSS) leaked every font it ever touched.

Eviction is always safe: load_missing_for_chains re-loads any font a later layout turns out to need. The cost of a wrong guess is one re-parse, never a missing glyph.

Returns the number of parsed fonts evicted.

§Panics

Panics if the internal font-cache mutex is poisoned.

Source§

impl FontManager<FontRef>

Source

pub fn evict_unused(&self, idle: Duration) -> usize

Evict the cached LocaGlyf for every face that hasn’t had a get_or_decode_glyph call within the last idle duration. Only LocaGlyfState::Deferred faces (the production lazy path) can be evicted — they keep their source Arc<[u8]> so the next glyph access re-parses cheaply. LocaGlyfState::Loaded faces from the eager path stay put.

Returns the number of faces evicted. Embedders can call this from a memory-pressure hook or on a timer; servo-shot exposes it via --azul-evict-after-each for measurement.

Trait Implementations§

Source§

impl<T: Debug> Debug for FontManager<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T> !Freeze for FontManager<T>

§

impl<T> RefUnwindSafe for FontManager<T>

§

impl<T> Send for FontManager<T>
where T: Send,

§

impl<T> Sync for FontManager<T>
where T: Send,

§

impl<T> Unpin for FontManager<T>

§

impl<T> UnsafeUnpin for FontManager<T>

§

impl<T> UnwindSafe for FontManager<T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.