valo
Reference

Paragraph

Lay out styled text, then record it like any other draw.

Paragraph is the API for laying out and drawing text. A ParagraphBuilder assembles styled spans against a FontCollection. Call layout before drawing or reading metrics.

use valo::{Color, DrawParagraphExt, ParagraphBuilder, TextStyle};

let mut paragraph = ParagraphBuilder::new(&mut fonts)
    .add_text("Hello, Valo", &TextStyle::new("Inter", 24.0, Color::WHITE))
    .build();
paragraph.layout(320.0);
builder.draw_paragraph(&paragraph, (40.0, 40.0));
const style = new TextStyle('Inter', 24);
style.setColor(1, 1, 1, 1);
const paragraphs = new ParagraphBuilder();
paragraphs.addText('Hello, Valo', style);
const paragraph = paragraphs.build(fonts);
paragraph.layout(320);
builder.drawParagraph(paragraph, 40, 40);

The scene is JavaScript and uses Fira Sans, which this page registered. Change size, weight, align, or layout width.

scene.jsplayground
loading editor
liveacquiring device

TextStyle defaults to opaque black, weight 400, and no italic. align is 0 left, 1 center, 2 right, 3 justify. The one-span Paragraph constructor still exists for the Canvas2D adapter; prefer the builder in new code.

Layout and metrics

layout(max_width) wraps to that width. Repeating the same width reuses the existing layout. Width, height, and line metrics are zero before the first layout.

Use draw_paragraph_with (JavaScript drawParagraphWith) to stroke or blend every run with a paint. Shadows and decorations still come from the paragraph's styles. Valo's C paint has no shader, so gradient-filled text from C is not available; Rust and JavaScript paints may carry a shader.

Queries

Caret rectangles, hit-testing a point to a byte offset, selection boxes, and word boundaries use UTF-8 byte offsets. An empty paragraph returns offset 0 and a zero caret.

const caret = paragraph.caretForOffset(0);
const hit = paragraph.glyphPositionAt(12, 8);
const word = paragraph.wordBoundary(hit.offset);

Unanswered families and codepoints are on demandFamilies and demandCodepoints after build, so the host can fetch more faces and rebuild.

Next: platform setup in Rust on native platforms or the JavaScript engine API.

On this page