Say rel base, and give containers back a box to hand over

`frame` named a length, not a rectangle, which was the one word in the
layout vocabulary that lied about its own shape. It is `rel_base`: what a
fraction a widget declares or reports is a fraction of.

Three API changes with it, all for containers that do one simple thing:

- `widget_within(id, region)` returns, taking a box in the widget's own
  coordinates and deriving the child's rel base from it. `Offset` and `Pad`
  are one call each again. `Offset` also stops reading `region_len`, which
  pinned its drawing to a box length it does not care about.
- `place_at` takes the rel base, returns the answer, and asks the child
  where there is no answer to re-express. Which of the two happens is the
  painter's to work out, so `Span`'s second pass is one call and its
  `drawn_across` bookkeeping is gone.
- `Part::All` is a `Part::WHOLE` constant rather than a variant, since it
  was exactly `Of(UiSpan::FULL)` and bought a separate arm in two matches.
  Measured at 0.07% of instructions retired against 0.04% run-to-run noise.

Cold layout is byte-identical to `84dad21` over 400 depth-5 trees.
This commit is contained in:
iris-ai committed 2026-09-19 16:33:49 -04:00
1 parent a904cf4f36
commit aeb60e50f5
16 files changed
+246 -238

No files matched your search

+2 -2
View File
@@ -406,8 +406,8 @@ fn describe_widget(id: WidgetId, h: &Harness) -> String {
fn record(id: WidgetId, h: &Harness) -> String {
let active = &h.render.active[&id];
format!(
"frame {} region {} placement {} size {}",
active.frame, active.region, active.placement, active.size,
"rel_base {} region {} placement {} size {}",
active.rel_base, active.region, active.placement, active.size,
)
}