Expand description
Fonts, a bounded glyph cache, line layout and word wrapping.
One TextEngine holds every font an application uses and one GlyphAtlas
that caches what has been rasterised. Measurement and drawing both go through
it, so a label that is measured during layout and drawn a moment later
rasterises its glyphs exactly once.
let mut text = TextEngine::new();
let style = TextStyle::built_in(16);
let extent = text.measure(style, "Kjærlighet på Øy");
text.draw(canvas, style, Point::new(20, 20), "Kjærlighet på Øy", Color::WHITE);§Wrapping
TextEngine::wrap breaks a string into the lines it becomes at a given
width, greedily, returning slices that borrow the input. Explicit \n always
breaks. A word wider than the line overflows on a line of its own rather than
being cut between characters — breaking mid-word means knowing where a
grapheme ends, and half of an æ is nothing.
§Three tiers, and what each costs
Measured as the increase in a stripped, statically linked
aarch64-unknown-linux-musl binary:
| Tier | Feature | Cost | What it buys |
|---|---|---|---|
| Built-in bitmap | none | 0 | Latin plus æøå, whole-number scales |
| TrueType | truetype | +270 KB | Real fonts, proportional metrics, anti-aliasing |
| Baked | none; bake in a build script | the tables | A real face at the sizes it was baked at, no parser on the panel |
| Shaped | shaping | +3.1 MB | Ligatures, bidi, complex scripts, font fallback |
For scale: the whole of Denise, DRM, evdev and the widgets is about 840 KB, so the shaping tier is four times the rest of the toolkit put together. It is there because some panels genuinely need it, and off by default because most do not — a temperature readout and a Norwegian name do not need a shaper.
The baked tier is the TrueType tier’s drawing without its reading: a build
script rasterises the face at the sizes the UI uses, and the panel embeds
the result as tables and links no parser at all. A product that ships one
face wants this; one that lets its user pick a font at run time wants
truetype, and the two coexist. See baked.
§What this is not
Not a text editor’s model: no bidi cursor movement, no grapheme-cluster
segmentation, no line breaking by dictionary. \n breaks a line and nothing
else does. Those belong to whoever turns this into a document viewer.
Re-exports§
pub use atlas::AtlasStats;pub use atlas::GlyphAtlas;pub use atlas::GlyphKey;pub use atlas::Placed;pub use baked::BakedFont;pub use baked::BakedGlyph;pub use baked::BakedSize;pub use baked::BakedSource;pub use bitmap::BitmapSource;pub use engine::PositionedGlyph;pub use engine::TextEngine;pub use engine::TextStyle;pub use shaped::ShapedSource;shapingpub use source::FontId;pub use source::FontMetrics;pub use source::GlyphId;pub use source::GlyphMetrics;pub use source::GlyphSource;pub use source::Rasterised;pub use source::ShapedGlyph;pub use truetype::TrueTypeSource;truetype
Modules§
- atlas
- A bounded glyph cache.
- bake
bake - Turns a face into the tables
BakedSourcedraws from. - baked
- A face rasterised in advance, as a glyph source.
- bitmap
- The built-in bitmap font, as a glyph source.
- engine
- The object an application holds: fonts, a cache, measurement and drawing.
- shaped
shaping - Shaping, bidirectional text and font fallback, behind the
shapingfeature. - source
- What a font has to provide, and what it says about a glyph.
- truetype
truetype - Real TrueType and OpenType fonts, behind the
truetypefeature.