mirror of
https://github.com/typst/typst
synced 2025-05-13 20:46:23 +08:00
Fix square and circle width & height
This commit is contained in:
parent
67705e2038
commit
e4e4c1876f
@ -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
BIN
tests/ref/layout/aspect.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
50
tests/typ/layout/aspect.typ
Normal file
50
tests/typ/layout/aspect.typ
Normal 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%)
|
Loading…
x
Reference in New Issue
Block a user