The Pipeline
Pretext splits text layout into a one-time prepare() phase and a near-free layout() phase. Here's every stage your text passes through:
Your Text
Type anything, or pick a preset that exercises a different part of the engine. The entire pipeline re-runs live as you edit.
Whitespace Normalization
CSS white-space: normal collapses runs of spaces, tabs, and newlines into a single space, then trims leading/trailing whitespace. This is the first thing Pretext does — before any segmentation.
Word Segmentation
The browser's built-in Intl.Segmenter splits text into word-like and non-word-like segments. This handles CJK (per-character), Thai (no spaces between words), Arabic, and other scripts correctly — something regex can never do reliably.
Segment Merging & Glue Rules
Raw segments aren't enough. Punctuation like "better." must stay glued to its word (browsers measure them together). Opening quotes attach forward. CJK characters get split into individual graphemes for per-character line breaking. This is where 80% of the language-specific logic lives.
Canvas Measurement
Each merged segment is measured once via canvas.measureText() — the same font shaping engine the browser uses for layout, but without triggering DOM reflow. Results are cached per (segment, font) pair. This is the key trick that makes everything else possible.
Line Breaking — Pure Arithmetic
Now the hot path: walk the cached widths, accumulate along each line, and break when the next segment would overflow maxWidth. Trailing spaces "hang" past the edge (matching CSS). This runs in ~0.0002ms — drag the slider and watch it reflow instantly.
Verification vs. Real DOM
The ultimate test: does our arithmetic match what the browser actually renders? We create a hidden DOM element with the same text, font, width, and CSS rules, measure its height, and compare. The green result below is live — computed right now in your browser.