cosmic-text: shaping and layout
System76 builds a text engine for its own desktop.
cosmic-text (October 2022) was written by System76 for the COSMIC desktop. It takes a string, finds fonts on the system, shapes the text (choosing glyphs and positions, including right-to-left scripts and emoji) and lays it out into lines. A Buffer holds the text and its layout. This example mixes English, Hebrew and an emoji.
use cosmic_text::{Attrs, Buffer, FontSystem, Metrics, Shaping};
fn main() {
let mut fonts = FontSystem::new(); // discovers system fonts
let mut buffer = Buffer::new(&mut fonts, Metrics::new(16.0, 20.0));
buffer.set_size(Some(200.0), None);
buffer.set_text("Hello, שלום 👋", &Attrs::new(), Shaping::Advanced, None);
buffer.shape_until_scroll(&mut fonts, false);
for run in buffer.layout_runs() {
println!("line {} is {:.1}px wide with {} glyphs", run.line_i, run.line_w, run.glyphs.len());
}
} line 0 is 92.0px wide with 13 glyphsSpans can carry their own attributes such as family and weight, and the buffer wraps them to the width you give it. Careful with examples online: this API has changed between releases, and older code passes the font system to set_size and set_text. These snippets were compiled against 0.19.
use cosmic_text::{Attrs, Buffer, Family, FontSystem, Metrics, Shaping, Weight};
fn main() {
let mut fonts = FontSystem::new();
let mut buffer = Buffer::new(&mut fonts, Metrics::new(14.0, 18.0));
buffer.set_size(Some(120.0), None);
// Rich text: each span carries its own attributes.
let base = Attrs::new().family(Family::SansSerif);
let bold = base.clone().weight(Weight::BOLD);
buffer.set_rich_text(
[("Bold ", bold), ("and plain text that wraps at 120px", base.clone())],
&base,
Shaping::Advanced,
None,
);
buffer.shape_until_scroll(&mut fonts, false);
println!("wrapped into {} lines", buffer.layout_runs().count());
} wrapped into 2 linesIts dependencies are fontdb (finding system fonts), skrifa and swash, and harfrust for shaping, the Rust port of HarfBuzz that cosmic-text, Parley and egui all adopted within about a year. cosmic-text is one of four maintained text-layout stacks in the ecosystem. In our lockfiles it serves iced (0.15.0), gpui (0.14.2) and Floem (0.12.1), each on a different release, none of which is the current 0.19.