Skip to main content

Crate denise_text

Crate denise_text 

Source
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:

TierFeatureCostWhat it buys
Built-in bitmapnone0Latin plus æøå, whole-number scales
TrueTypetruetype+270 KBReal fonts, proportional metrics, anti-aliasing
Bakednone; bake in a build scriptthe tablesA real face at the sizes it was baked at, no parser on the panel
Shapedshaping+3.1 MBLigatures, 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;shaping
pub 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.
bakebake
Turns a face into the tables BakedSource draws 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.
shapedshaping
Shaping, bidirectional text and font fallback, behind the shaping feature.
source
What a font has to provide, and what it says about a glyph.
truetypetruetype
Real TrueType and OpenType fonts, behind the truetype feature.