Give a length with no share in it its own type again

`UiScalar` was `Len` without the `leftover` weight, which is the separation
canonical `main` already had as `Len` beside `LayoutLen` and this branch
collapsed. It is needed back for the queued clamp: a cap may not contain a
share, because a cap has to read the report a rule otherwise makes moot, and
a share puts the container's division into the same equation -- two
self-consistent assignments, which is the multiple-fixed-point failure
generated seed 13 punished for orthogonal sizing. `min(report, cap)` is not
a `LayoutLen` either: it is a sum of parts, and the smaller of two of them
is not one.

So `UiScalar` is `Len`, what was `Len` is `LayoutLen`, and the two say in
their docs which is which: a `Len` is pixels plus a fraction of a box -- a
position being the length from the box's start, which is why a span is two
of them -- and a `LayoutLen` is a `Len` plus a claim only a container
dividing its room can answer. `From<Len> for LayoutLen` is the one-way step
between them.

Names only; the shader's `UiScalar` is renamed with them. Checked: fmt,
clippy, 105 tests, and `tabs`, `minimal`, `view`, `text` and `random`
byte-identical at 1920x1200.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
iris-aiandClaude Opus 5 committed 2026-09-16 13:40:15 -04:00
1 parent 4f5e27cba9
commit a8898aaa54
27 files changed
+218 -202

No files matched your search

+11 -11
View File
@@ -12,10 +12,10 @@ impl Widget for Span {
let axis = self.dir.axis;
// A length for every child before their final boxes are chosen: from
// a hint where one exists, and from drawing otherwise.
let mut cursor = UiScalar::rel_min();
let mut cursor = Len::rel_min();
let mut lens = Vec::with_capacity(self.children.len());
for child in &self.children {
let mut span = UiSpan::new(cursor, UiScalar::rel_max());
let mut span = UiSpan::new(cursor, Len::rel_max());
if self.dir.sign == Sign::Neg {
span.flip();
}
@@ -33,9 +33,9 @@ impl Widget for Span {
.gap
.mul_int(self.children.len().saturating_sub(1) as i32);
let total = lens.iter().fold(
Len {
LayoutLen {
px: gaps,
..Len::ZERO
..LayoutLen::ZERO
},
|sum, len| sum + *len,
);
@@ -89,11 +89,11 @@ impl Widget for Span {
// from the last child: the share of the room is rounded, and taking
// each from the one before it would carry every rounding along the
// row.
let mut fixed = UiScalar::rel_min();
let mut fixed = Len::rel_min();
let mut taken = Weight::ZERO;
let room = UiScalar::rel_max() - UiScalar::from_parts(total.rel, total.px);
let mut start = UiScalar::rel_min();
let mut ortho = Len::ZERO;
let room = Len::rel_max() - Len::from_parts(total.rel, total.px);
let mut start = Len::rel_min();
let mut ortho = LayoutLen::ZERO;
for (child, len) in self.children.iter().zip(&lens) {
// A child asking for nothing but a part of what is left over,
// when nothing is, is not drawn at all. One that also asked for
@@ -125,7 +125,7 @@ impl Widget for Span {
// A scalable child therefore makes Children scalable too;
// only fixed children are compared with one another.
if used.rel != Rel::ZERO || used.leftover != Weight::ZERO {
ortho = Len::LEFTOVER;
ortho = LayoutLen::LEFTOVER;
} else if ortho.leftover == Weight::ZERO {
ortho.px = ortho.px.max(used.px);
}
@@ -144,7 +144,7 @@ impl Widget for Span {
let along = total;
let ortho = match shrinks {
true => ortho,
false => Len::rel(1.0),
false => LayoutLen::rel(1.0),
};
Size::from_axis(axis, along, ortho)
}
@@ -153,7 +153,7 @@ impl Widget for Span {
/// Where a row has reached: everything fixed before this point, which is a
/// sum and exact, plus the share of the room the weights so far are worth,
/// which is one rounding wherever it is asked for.
fn shared(fixed: UiScalar, taken: Weight, weight: Weight, room: UiScalar) -> UiScalar {
fn shared(fixed: Len, taken: Weight, weight: Weight, room: Len) -> Len {
if taken == Weight::ZERO {
return fixed;
}