diff --git a/src/library/shape.rs b/src/library/shape.rs index 2f2f9686d..61c0d6e32 100644 --- a/src/library/shape.rs +++ b/src/library/shape.rs @@ -119,10 +119,16 @@ impl Layout for ShapeNode { // Relayout with full expansion into square region to make sure // the result is really a square or circle. if self.kind.is_quadratic() { - let size = frames[0].item.size; - let desired = size.x.max(size.y); - let limit = regions.current.x.min(regions.current.y); - pod.current = Size::splat(desired.min(limit)); + let length = if regions.expand.x || regions.expand.y { + let target = regions.expand.select(regions.current, Size::zero()); + target.x.max(target.y) + } else { + let size = frames[0].item.size; + let desired = size.x.max(size.y); + desired.min(regions.current.x).min(regions.current.y) + }; + + pod.current = Size::splat(length); pod.expand = Spec::splat(true); frames = child.layout(ctx, &pod); frames[0].cts = Constraints::tight(regions); @@ -130,27 +136,27 @@ impl Layout for ShapeNode { } else { // The default size that a shape takes on if it has no child and // enough space. - let mut default = Size::splat(Length::pt(30.0)); - if !self.kind.is_quadratic() { - default.x *= 1.5; - } - let mut size = - regions.expand.select(regions.current, default).min(regions.current); + Size::new(Length::pt(45.0), Length::pt(30.0)).min(regions.current); - // Make sure the result is really a square or circle. if self.kind.is_quadratic() { - size.x = size.x.min(size.y); - size.y = size.x; + let length = if regions.expand.x || regions.expand.y { + let target = regions.expand.select(regions.current, Size::zero()); + target.x.max(target.y) + } else { + size.x.min(size.y) + }; + size = Size::splat(length); + } else { + size = regions.expand.select(regions.current, size); } frames = vec![Frame::new(size).constrain(Constraints::tight(regions))]; } - let frame = Rc::make_mut(&mut frames.last_mut().unwrap().item); - // Add fill and/or stroke. if self.fill.is_some() || self.stroke.is_some() { + let frame = Rc::make_mut(&mut frames[0].item); let geometry = match self.kind { ShapeKind::Square | ShapeKind::Rect => Geometry::Rect(frame.size), ShapeKind::Circle | ShapeKind::Ellipse => Geometry::Ellipse(frame.size), @@ -165,10 +171,6 @@ impl Layout for ShapeNode { frame.prepend(Point::zero(), Element::Shape(shape)); } - // Ensure frame size matches regions size if expansion is on. - let target = regions.expand.select(regions.current, frame.size); - frame.resize(target, Align::LEFT_TOP); - frames } } diff --git a/tests/ref/layout/aspect.png b/tests/ref/layout/aspect.png new file mode 100644 index 000000000..62f17ba4f Binary files /dev/null and b/tests/ref/layout/aspect.png differ diff --git a/tests/typ/layout/aspect.typ b/tests/typ/layout/aspect.typ new file mode 100644 index 000000000..c0db17e09 --- /dev/null +++ b/tests/typ/layout/aspect.typ @@ -0,0 +1,50 @@ +// Test that squares and circles respect their 1-1 aspect ratio. + +--- +// Test relative width and height and size that is smaller +// than default size. +#page(width: 120pt, height: 70pt) +#square(width: 50%, align(bottom)[A]) +#square(height: 50%) +#box(stack(square(size: 10pt), 5pt, square(size: 10pt, [B]))) + +--- +// Test alignment in automatically sized square and circle. +#font(8pt) +#grid( + columns: 2, + gutter: 10pt, + square(padding: 4pt)[ + Hey there, #align(center + bottom, rotate(180deg, [you!])) + ], + circle(align(center + horizon, [Hey.])), +) + +--- +// Test that maximum wins if both width and height are given. +#square(width: 10pt, height: 20pt) +#circle(width: 20%, height: 10pt) + +--- +// Test square that is limited by region size. +#page(width: 20pt, height: 10pt, margins: 0pt) +#stack(dir: ltr, square(fill: forest), square(fill: conifer)) + +--- +// Test different ways of sizing. +#page(width: 120pt, height: 40pt) +#circle(radius: 5pt) +#circle(width: 10%) +#circle(height: 50%) + +--- +// Test square that is overflowing due to its aspect ratio. +#page(width: 40pt, height: 20pt, margins: 5pt) +#square(width: 100%) +#square(width: 100%)[Hello] + +--- +// Size cannot be relative because we wouldn't know +// relative to which axis. +// Error: 15-18 expected length, found relative +#square(size: 50%)