Immutable text and logical style for repeated measurement and drawing.
Retain this value (or a cheap clone) while content/style is unchanged, then
construct a new one when either changes. Its hash is computed at construction;
a warm renderer lookup of that retained handle does not scan its payload.
Share clones of one handle between layout and paint; independently constructed
equal handles can require exact comparison when replacing each other’s cache
identity. Promotion from a borrowed entry also respects the payload budget.
Width, renderer text scale, font generation and custom hyphenator versions are
still checked on every call. Colour and transform remain paint-time inputs.
Non-rectangular local-coordinate region used for both line fitting and
exact scene clipping. Concave polygons may produce several independent
spans on one baseline, allowing text to flow around an inset or cutout.
A font family to shape with. The three generic classes resolve to the
system’s default face for that class; Named targets a specific
installed family by name.
The ground text is set on, as far as the face is concerned. Light ink on a
dark ground loses fine hairlines first, so a family drawn in separate
optical cuts keeps its sturdier text cut to larger sizes there
(OpticalSizing::Auto). A theme’s roles carry its content ground; a
surface that paints its own ground (a book’s page) says which it is.
Named weight tiers mapping 1:1 to cosmic_text::fontdb::Weight’s
numeric constants (Tailwind’s font-medium/semibold/bold), so call sites
read declaratively instead of passing raw u16s.
Product-wide primary font families. Tilo ships these exact faces, and the
renderer also assigns them to the CSS-like generic families below. Keeping
the names here makes plain text, rich text, and theme tokens agree instead
of depending on each machine’s fontconfig defaults.
The default reading face, New Computer Modern. Set in this family, text
takes the cut its size calls for: the 8 pt design for footnotes, Book for
body text and Regular for titles (crate::tokens::ReadingFace).
Paragraph hyphenation policy. It is deliberately opt-in: short UI labels
and identifiers should never acquire language-dependent line endings, while
reading text can request TeX/Liang patterns with a BCP-47 language tag.
Application-supplied discretionary hyphenation. Returned offsets are in
the original UTF-8 byte space; invalid, edge, and non-character boundaries
are ignored by the renderer.
Replaceable measurement/painting boundary used by crate::widget::Text.
Implementations keep localization, accessibility, Taffy integration, scene
caching, and inspection supplied by the standard widget. style is always
renderer-relative: implementations which delegate to TextRenderer pass
it through unchanged. For theme-resolved or fixed-size widgets, Text
compensates the font size for the renderer’s current multiplier before this
boundary; renderer-relative letter spacing keeps its established behavior.
Build the process’s font system: the database a host built for it when
there is one, otherwise the product font catalog with the system’s fonts
behind it and Tilo’s script fallback (Android copies its catalog out of
the APK first). A binary run from a checkout, a screenshot and the Tilo
image therefore all set text in the same faces, whether or not the
machine has them installed. Only when no catalog loads does it fall back
to the system’s fonts alone with the generic families pinned to the
product names.
Read the product font catalog into memory and set every renderer this
process makes in it from now on: for a process about to lose the
filesystem (a confined app worker) whose views still lay out text.
Returns whether a catalog loaded.
Build the font database configured_font_system copies into every
renderer now, and throw the font system away: a native launch runs this
in the background from process start, so the main thread’s first
renderer finds the catalog verified and every font file read instead of
doing both itself. The database is a process-wide OnceLock, so
a renderer asked for meanwhile waits for this one: nothing is loaded
twice, and it is the database the main thread would have built.
Run f with a layout-only renderer at text_scale, for widgets that
must measure in apply_layout, which is handed no renderer. Building one
loads every installed font (tens of milliseconds) and layout runs every
frame an animation is live, so renderers are pooled per thread; a nested
call takes its own from the pool rather than borrowing the outer one.