6102e0d4d9ef04a982c93a6437a991320ed3ebc4
Iris asked for this 2026-09-06 (IRIS_TODO.md, "a third length kind beside relative and pixels ... a unit resolved against the display's density at layout time"): before this, a Len was abs (physical pixels) or rel/rest (a fraction of the parent), and the only way to make a design size look the same physical size on a denser display was a single global multiply applied after layout -- which the previous commit found is also what made text blurry. Len gains a `dp` field, resolved against a `density: f32` (physical pixels per dp) now carried on UiRenderState/Painter (`UiRenderState::set_density`/`density()`, `Painter::density()`) and threaded through every `apply_rest`/`to_uivec2` call site. `len_fns::dp` / `Len::dp` construct one, exactly parallel to the existing `abs`/`rel`/ `rest`. A bare number is unaffected (still `abs`, physical pixels) -- `dp` is opt-in. Text: `TextBuffer::shape` now takes `density` and multiplies `font_size`/`line_height` (and any span override) by it before handing them to parley, so the size that reaches the shaper and the rasteriser (`TextData::place`) is the display's real physical size -- the atlas holds a bitmap at the resolution it is actually shown at, instead of a low-resolution one stretched afterward. `GlyphKey.size` already keys on the resolved `font_size`, so a cache entry is naturally per physical size with no further change. `TextData` also carries its own `density` copy for `TextEditCtx::layout` (cursor movement/hit-testing), which shapes text from an input callback with no `Painter` to read it from. `Span::gap` and `Padding`'s four sides move from bare `f32` to `Len`, so `.gap(dp(4))`/`.pad(dp(10))` work the same way any other size does; a bare number still means physical pixels, unchanged. Migrated transcript-ui's non-text sizes (row gap/padding, composer padding) and one example to the new unit, per IRIS_TODO.md's "done when" list. Android's own density (`DisplayMetrics.density`) is wired to both copies in `new_peer`; the winit backend has no per-monitor density wired up yet and stays at the default (1.0). docs/IRIS.md, docs/LAYOUT.md and IRIS_TODO.md updated next. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Languages
Rust
53%
Kotlin
44.4%
Shell
2.6%