Expand description
Vertical rhythm typography for gpui, ported from rhythm-sass.
gpui’s WrappedLine paint path follows the model in math:
the ascent + descent box is centered in the line height and the baseline
sits at (line_height - ascent - descent) / 2 + ascent.
This crate resolves real font metrics through gpui’s text system, so
baseline-anchored text lands on the rhythm grid without the manually measured
baseline-ratio that the original Sass library required. Cap-anchored helpers
instead align the capitals’ ink while preserving whole-row block geometry, and
the ICF anchors do the same for the CJK ideographic character face.
§Feature flags
-
gpui(default) — the gpui integration:RhythmGrid,RhythmFont(withRhythmFontSpeccache keys), measuredRhythmIcfAnchors,RhythmDropCap, theRhythmStyledextension trait, therhythm_framemedia container (with theRhythmFitpad/crop mode), and the configurablerhythm_overlay/RhythmOverlaydebug grid. -
Disable default features to build only the dependency-free rhythm math (
Rhythm,FontRhythm,RhythmLineMetrics,RhythmBlockMetrics,DropCapRhythm,snap), usable from any renderer that centersascent + descentinside the line height:rhythm-gpui = { version = "0.2", default-features = false }
§Example
use gpui::{div, font, px, prelude::*};
use rhythm_gpui::{RhythmGrid, RhythmStyled};
fn body(text_system: &gpui::TextSystem) -> impl IntoElement {
let grid = RhythmGrid::new(px(8.));
let para = grid.font(text_system, font("Georgia"), px(16.), 3);
div()
.rhythm_block(¶, 3, 1)
.child("Aligned to the grid.")
}The repository’s recipes example doubles as a recipe collection: a page
scaffold, baseline- and cap-anchored openings, a drop cap with true
wrap-around, fluid-width media padded or cropped to whole rhythm rows, and
mixed fonts (sizes, families, scripts) sharing one alphabetic baseline.
§Custom renderers
Document renderers that shape text themselves and paint cached
WrappedLines skip the element layer entirely: build RhythmLineMetrics
from each shaped line’s reported ascent() / descent() — the maxima over
its explicit font runs, which is how lines mixing bold, inline code, CJK, or
emoji faces actually shape. Those are line metrics, not a guarantee that
platform-selected fallback glyph ink stays inside the box. Lay blocks out
with RhythmBlockMetrics and place every baseline with
paint_origin_for. Under the gpui feature, the four values that stay
inside a paint path’s Pixels chain have Pixels-typed _px mirrors. The
direct_paint example is the complete non-virtualized shape/cache/paint
recipe. A virtualizer additionally accumulates first_rows /
middle_rows / last_rows in an i64 and rebases that row cursor near
the viewport before converting visible positions to f32.
§Performance contract
Rhythm,FontRhythm, and line/block geometry are smallCopyvalues. Their pure geometry and spacing methods are O(1), allocation-free (enforced by a counting-allocator test), and lock-free by construction, with hot methods#[inline]across the crate boundary.- gpui
TextSystemaccess is confined to font/spec/drop-cap resolution and optional ICF measurement; geometry and spacing on stored values never query it. - The shaped-line adapter reads a line’s already-computed ascent/descent and never walks glyphs.
cargo bench --bench resolvetracks warm font resolution (gpui’s request cache hit plus metric reads). There is deliberately no ns-level CI threshold: puref32math varies below measurement noise, so the guarantees above are structural, not benchmarked.
§Platform scope
The math layer is renderer- and platform-agnostic, and the resolved-font
path uses cross-platform gpui API. The default integration is compile-checked
on Linux and Windows. The mixed-run maximum and glyph-fallback behaviors are
verified against macOS/CoreText by the shaping integration suite; the
DirectWrite and cosmic-text runtime behaviors are not yet verified and must
not be assumed identical.
Structs§
- Drop
CapRhythm - A drop cap solved by
FontRhythm::drop_cap: the cap face’s metrics at the solved size plus the offset anchoring its baseline. - Font
Rhythm - Vertical metrics of one text style participating in the rhythm grid.
- Rhythm
- The vertical rhythm grid: a stack of rows, each
sizelogical pixels tall. - Rhythm
Block Metrics - A text block on the rhythm grid as pure geometry: one line’s metrics plus
baseline or ink-top anchors, with both fragment geometry and the exact row
arithmetic a virtualized renderer needs.
newis the pure form ofrhythm_block;ink_anchoredpairs an ink opening with its whole-row close. Either mode spans a whole number of rhythm rows for any number of lines, so blocks and fragments compose without breaking the page rhythm. - Rhythm
Drop Cap gpui - A drop cap bound to the grid: the cap face at the size solved by
FontRhythm::drop_cap, plus the inset anchoring its baseline. Apply withRhythmStyled::rhythm_drop_cap; for wrap-around text, measure the letter withshape_line(seedrop_cap_paragraphin therecipesexample). - Rhythm
Font gpui - A requested gpui font bound to the rhythm grid, with vertical metrics from
the font gpui actually resolved. When the requested family is unavailable,
that may be a fallback font; see
Self::resolve. - Rhythm
Font Spec gpui - The pre-resolve identity of a
RhythmFont: the requestedFont, size, line rhythms, and grid size as one hashable value — the cache key for caller-owned typography catalogs. - Rhythm
Frame gpui - A container that fits fluid-width media — images, video, embeds, any content whose height follows its width instead of the rhythm — into a whole number of rhythm rows, so everything after it stays on the grid at any width.
- Rhythm
Grid gpui - The vertical rhythm grid in gpui units.
- Rhythm
IcfAnchor gpui - A measured ideographic character-face anchor bound to the exact
RhythmFontit was measured from. - Rhythm
Line Metrics - Vertical metrics of one shaped line on the rhythm grid.
- Rhythm
Overlay gpui - A
draw-rhythmsdebug overlay: every other grid row in one color. Place it as the last child of the container it should cover; it fills that container and ignores mouse events. An ordinary gpui container already uses relative positioning by default, so no extra.relative()call is needed, and this element does not alter the container’s position style.
Enums§
- IcfMeasurement
Error gpui - Why an ideographic character-face measurement could not produce an anchor.
- Rhythm
Fit gpui - How a
RhythmFramereconciles its content’s natural height with whole rhythm rows.
Traits§
- Rhythm
Styled gpui - Extension methods for applying rhythm fonts through gpui’s fluent style API.
Functions§
- rhythm_
frame gpui - Create a
RhythmFramefor content with awidth / heightratio ofratio; add the content with.child(). - rhythm_
overlay gpui - Create a
RhythmOverlaypainting every other grid row incolor— the rhythm-sassdraw-rhythms()mixin. AddRhythmOverlay::phasefor a renderer that scrolls by painting at an offset. - snap
- Round
valueto the nearest multiple ofstep(e.g.1.0 / scale_factorto snap a spacing to whole device pixels). The core functions never round, so baseline-anchored results stay exact; snap only final applied values.