Fix square and circle width & height

This commit is contained in:
Laurenz 2021-11-29 16:13:53 +01:00
parent 67705e2038
commit e4e4c1876f
3 changed files with 71 additions and 19 deletions

View File

@ -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
}
}

BIN
tests/ref/layout/aspect.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -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%)