Struct TextSystem

Source
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

Source

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);
Source

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);
Source

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)));
Source

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);
Source

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);
Source

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());
Source

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);
Source

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);
Source

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);
Source

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);

Trait Implementations§

Source§

impl Default for TextSystem

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

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> Same for T

Source§

type Output = T

Should always be Self
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.
§

impl<T> ErasedDestructor for T
where T: 'static,