summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library/shape.rs40
-rw-r--r--tests/ref/layout/aspect.pngbin0 -> 3618 bytes
-rw-r--r--tests/typ/layout/aspect.typ50
3 files changed, 71 insertions, 19 deletions
diff --git a/src/library/shape.rs b/src/library/shape.rs
index 2f2f9686..61c0d6e3 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 00000000..62f17ba4
--- /dev/null
+++ b/tests/ref/layout/aspect.png
Binary files differ
diff --git a/tests/typ/layout/aspect.typ b/tests/typ/layout/aspect.typ
new file mode 100644
index 00000000..c0db17e0
--- /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%)