Rust GUI frameworks
2022 Text 2026: Widely adopted text stack
21

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.

cosmic-shape/src/bin/one.rs ✔ compiled · cosmic-text 0.19 · rustc 1.95.0
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());
    }
}
output
line 0 is 92.0px wide with 13 glyphs

Spans 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.

cosmic-shape/src/bin/two.rs ✔ compiled · cosmic-text 0.19 · rustc 1.95.0
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());
}
output
wrapped into 2 lines

Its 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.

crates.io first publish.