rhythm-gpui 0.2.0

Print-inspired vertical rhythm for gpui: baseline offsets computed from real font metrics
Documentation
//! Vertical rhythm typography for [gpui](https://www.gpui.rs), ported from
//! [rhythm-sass](https://github.com/p233/rhythm-sass).
//!
//! gpui's `WrappedLine` paint path follows the model in [`math`](crate::Rhythm):
//! 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`
//!   (with `RhythmFontSpec` cache keys), measured `RhythmIcfAnchor`s,
//!   `RhythmDropCap`, the `RhythmStyled` extension trait, the `rhythm_frame`
//!   media container (with the `RhythmFit` pad/crop mode), and the configurable
//!   `rhythm_overlay` / `RhythmOverlay` debug grid.
//! - Disable default features to build only the dependency-free rhythm math
//!   ([`Rhythm`], [`FontRhythm`], [`RhythmLineMetrics`], [`RhythmBlockMetrics`],
//!   [`DropCapRhythm`], [`snap`]), usable from any renderer that centers
//!   `ascent + descent` inside the line height:
//!
//!   ```toml
//!   rhythm-gpui = { version = "0.2", default-features = false }
//!   ```
//!
//! # Example
//!
//! ```no_run
//! # #[cfg(feature = "gpui")]
//! use gpui::{div, font, px, prelude::*};
//! # #[cfg(feature = "gpui")]
//! use rhythm_gpui::{RhythmGrid, RhythmStyled};
//!
//! # #[cfg(feature = "gpui")]
//! 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(&para, 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
//! `WrappedLine`s 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 small `Copy`
//!   values. 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 `TextSystem` access 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 resolve` tracks warm font resolution (gpui's request
//!   cache hit plus metric reads). There is deliberately no ns-level CI
//!   threshold: pure `f32` math 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.

#![cfg_attr(docsrs, feature(doc_cfg))]
#![warn(missing_docs)]

mod math;
mod metrics;

pub use math::{snap, DropCapRhythm, FontRhythm, Rhythm};
pub use metrics::{RhythmBlockMetrics, RhythmLineMetrics};

#[cfg(feature = "gpui")]
mod frame;
#[cfg(feature = "gpui")]
mod integration;

#[cfg(feature = "gpui")]
#[cfg_attr(docsrs, doc(cfg(feature = "gpui")))]
pub use frame::{rhythm_frame, RhythmFit, RhythmFrame};
#[cfg(feature = "gpui")]
#[cfg_attr(docsrs, doc(cfg(feature = "gpui")))]
pub use integration::{
    rhythm_overlay, IcfMeasurementError, RhythmDropCap, RhythmFont, RhythmFontSpec, RhythmGrid,
    RhythmIcfAnchor, RhythmOverlay, RhythmStyled,
};