pub struct TextSystem { /* private fields */ }Expand description
Retained text system: one instance per window (or shared app-wide).
One system owns mutable Parley contexts, a 2048-entry LRU layout cache, and
an unbounded registry of font-face byte blobs encountered by prepared
layouts. Methods require &mut self while shaping or updating LRU recency;
external synchronization is required for shared concurrent use.
§Examples
use ailloli_ui_text::TextSystem;
let system = TextSystem::new();
assert_eq!(system.cached_layout_count(), 0);
assert_eq!(system.metrics_revision(), 1);Implementations§
Source§impl TextSystem
impl TextSystem
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates a new system with an empty LRU cache (capacity 2048 entries).
The bundled monospace font is registered in the internal engine, while
the renderer-facing face registry remains empty until the first layout
produces glyphs. The metrics revision starts at the nonzero sentinel 1.
Construction may scan the relative assets/fonts directory through the
legacy Parley constructor.
§Panics
Panics only if the fixed cache-capacity constant is changed from 2048 to zero.
§Examples
use ailloli_ui_text::TextSystem;
let system = TextSystem::new();
assert_eq!(system.cached_layout_count(), 0);
assert!(system.face_blobs().is_empty());
assert_eq!(system.metrics_revision(), 1);Sourcepub fn layout_cached(
&mut self,
params: TextLayoutParams<'_>,
) -> TextLayoutHandle
pub fn layout_cached( &mut self, params: TextLayoutParams<'_>, ) -> TextLayoutHandle
Lays out text with LRU caching; skips relayout when the key and text match.
A hit clones the stored Arc and updates LRU recency. Full source-text
equality guards text-hash collisions, but other lossy key components are
not secondarily compared. In particular, uniform color and decoration
are paint-only and reuse the same entry, so PreparedTextLayout::style
on a hit can be the style from the request that populated the cache.
Widths differing by less than key quantization may likewise share a layout.
The cache evicts least-recently-used layouts after 2048 distinct keys;
registered font blobs are not evicted.
§Examples
use std::sync::Arc;
use ailloli_ui_core::{Color, FontId, TextStyle};
use ailloli_ui_text::{TextLayoutParams, TextSystem};
let mut system = TextSystem::new();
let params = TextLayoutParams::new("cached", TextStyle::new(FontId::Ui, 14, Color::WHITE));
let first = system.layout_cached(params);
let second = system.layout_cached(params);
assert!(Arc::ptr_eq(&first, &second));
assert_eq!(system.cached_layout_count(), 1);Sourcepub fn layout_styled_cached(
&mut self,
params: StyledTextLayoutParams<'_>,
) -> TextLayoutHandle
pub fn layout_styled_cached( &mut self, params: StyledTextLayoutParams<'_>, ) -> TextLayoutHandle
Lays out styled text with LRU caching.
Spans are first clamped, validated, overlap-resolved with later input winning, stripped when equal to the base style, and merged when adjacent. If none remain, this delegates to the uniform cache. Styled keys include RGBA8 colors but omit decoration, so sub-byte color differences and decorations can reuse the first prepared entry. A cache hit also verifies exact source text. Output glyphs carry their effective run colors.
§Examples
use std::sync::Arc;
use ailloli_ui_core::{Color, FontId, TextStyle};
use ailloli_ui_text::{StyledTextLayoutParams, StyledTextSpan, TextSystem, WrapMode};
let mut system = TextSystem::new();
let base = TextStyle::new(FontId::Mono, 13, Color::WHITE);
let accent = TextStyle::new(FontId::Mono, 13, Color::BLACK);
let spans = [StyledTextSpan { range: 0..2, style: accent }];
let params = StyledTextLayoutParams { text: "fn main", base_style: base, spans: &spans, max_width: None, wrap_mode: WrapMode::NoWrap };
let first = system.layout_styled_cached(params);
let second = system.layout_styled_cached(params);
assert!(Arc::ptr_eq(&first, &second));
assert!(first.glyphs().iter().any(|glyph| glyph.color == Some(accent.color)));Sourcepub fn parley_engine_mut(&mut self) -> &mut ParleyEngine
pub fn parley_engine_mut(&mut self) -> &mut ParleyEngine
Direct access to the Parley engine (migration / diagnostics).
Layouts created directly through this reference bypass this system’s LRU
and face-blob registration. Mutating fonts or shaping state can make
cached metrics stale; call Self::invalidate_metrics afterward when
the change can affect existing results.
§Examples
use ailloli_ui_text::{ParleyEngine, TextSystem};
let mut system = TextSystem::new();
let _: &mut ParleyEngine = system.parley_engine_mut();
system.invalidate_metrics();
assert_eq!(system.cached_layout_count(), 0);Sourcepub fn face_blob(&self, face_id: u64) -> Option<&[u8]>
pub fn face_blob(&self, face_id: u64) -> Option<&[u8]>
Font bytes for a Parley face_id, if registered.
A face becomes registered only after a cached prepared layout emits at
least one glyph using it. None means the system has not encountered the
ID. The returned slice is borrowed from retained reference-counted data.
§Examples
use ailloli_ui_core::{Color, FontId, TextStyle};
use ailloli_ui_text::{TextLayoutParams, TextSystem};
let mut system = TextSystem::new();
let layout = system.layout_cached(TextLayoutParams::new("x", TextStyle::new(FontId::Ui, 14, Color::WHITE)));
let face_id = layout.glyphs()[0].face_id;
assert!(!system.face_blob(face_id).unwrap().is_empty());
assert_eq!(system.face_blob(u64::MAX), None);Sourcepub fn face_blobs(&self) -> &HashMap<u64, Arc<[u8]>>
pub fn face_blobs(&self) -> &HashMap<u64, Arc<[u8]>>
All registered face blobs (for renderer lookup).
The borrowed map grows as new faces are shaped and is not pruned by LRU eviction or metric invalidation. Keys are Parley face IDs; values hold complete font bytes shared with snapshots.
§Examples
use ailloli_ui_core::{Color, FontId, TextStyle};
use ailloli_ui_text::{TextLayoutParams, TextSystem};
let mut system = TextSystem::new();
assert!(system.face_blobs().is_empty());
let _ = system.layout_cached(TextLayoutParams::new("x", TextStyle::new(FontId::Mono, 14, Color::WHITE)));
assert!(!system.face_blobs().is_empty());Sourcepub fn face_blobs_snapshot(&self) -> Arc<HashMap<u64, Arc<[u8]>>>
pub fn face_blobs_snapshot(&self) -> Arc<HashMap<u64, Arc<[u8]>>>
Cheap snapshot for the GPU renderer (Arc values inside).
This allocates and clones the hash-map structure in O(number of faces), but only increments reference counts for the potentially large font byte buffers. Later registrations do not appear in an existing snapshot.
§Examples
use std::sync::Arc;
use ailloli_ui_text::TextSystem;
let system = TextSystem::new();
let snapshot = system.face_blobs_snapshot();
assert!(snapshot.is_empty());
assert_eq!(Arc::strong_count(&snapshot), 1);Sourcepub fn cached_layout_count(&self) -> usize
pub fn cached_layout_count(&self) -> usize
Returns the number of resident LRU entries, from zero through 2048.
Styled requests that normalize to no spans share the uniform cache and do not necessarily add a distinct entry.
§Examples
use ailloli_ui_core::{Color, FontId, TextStyle};
use ailloli_ui_text::{TextLayoutParams, TextSystem};
let mut system = TextSystem::new();
assert_eq!(system.cached_layout_count(), 0);
let _ = system.layout_cached(TextLayoutParams::new("x", TextStyle::new(FontId::Ui, 14, Color::WHITE)));
assert_eq!(system.cached_layout_count(), 1);Sourcepub const fn metrics_revision(&self) -> u64
pub const fn metrics_revision(&self) -> u64
Nonzero revision of inputs that can alter text metrics.
The value starts at one and never returns zero. It increases on
Self::invalidate_metrics until u64 overflow, at which point it wraps
back to one; consumers should compare for inequality rather than ordering.
§Examples
use ailloli_ui_text::TextSystem;
let mut system = TextSystem::new();
let before = system.metrics_revision();
system.invalidate_metrics();
assert_ne!(system.metrics_revision(), before);Sourcepub fn invalidate_metrics(&mut self)
pub fn invalidate_metrics(&mut self)
Invalidates metric-dependent caches after a font or shaping change.
This clears every prepared layout and advances the nonzero wrapping revision. It deliberately retains registered face blobs and all internal Parley/font caches; memory associated with those resources is not freed.
§Examples
use ailloli_ui_core::{Color, FontId, TextStyle};
use ailloli_ui_text::{TextLayoutParams, TextSystem};
let mut system = TextSystem::new();
let _ = system.layout_cached(TextLayoutParams::new("x", TextStyle::new(FontId::Ui, 14, Color::WHITE)));
let faces = system.face_blobs().len();
system.invalidate_metrics();
assert_eq!(system.cached_layout_count(), 0);
assert_eq!(system.face_blobs().len(), faces);