summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2023-04-06 12:25:55 +0200
committerLaurenz <laurmaedje@gmail.com>2023-04-06 12:26:39 +0200
commitf9b9be16f96d01ffb0587f65c8c32da9e9e4b3f5 (patch)
tree08395e4627bc669d2c6780f8e4885185d390d86b
parent23a884a67f4afde7541e4c39f22ff275f939a8f5 (diff)
Fix box and block sizing
-rw-r--r--library/src/layout/container.rs14
-rw-r--r--library/src/layout/flow.rs6
-rw-r--r--library/src/layout/mod.rs4
-rw-r--r--library/src/visualize/shape.rs9
-rw-r--r--tests/ref/compiler/construct.pngbin6327 -> 6320 bytes
-rw-r--r--tests/ref/layout/container.pngbin8541 -> 20514 bytes
-rw-r--r--tests/typ/layout/container.typ10
7 files changed, 37 insertions, 6 deletions
diff --git a/library/src/layout/container.rs b/library/src/layout/container.rs
index 166d6c09..ef5fbe5d 100644
--- a/library/src/layout/container.rs
+++ b/library/src/layout/container.rs
@@ -132,6 +132,9 @@ impl Layout for BoxElem {
let pod = Regions::one(size, expand);
let mut frame = body.layout(vt, styles, pod)?.into_frame();
+ // Enforce correct size.
+ *frame.size_mut() = expand.select(size, frame.size());
+
// Apply baseline shift.
let shift = self.baseline(styles).relative_to(frame.height());
if !shift.is_zero() {
@@ -377,10 +380,17 @@ impl Layout for BlockElem {
pod.last = None;
}
- body.layout(vt, styles, pod)?.into_frames()
+ let mut frames = body.layout(vt, styles, pod)?.into_frames();
+ for (frame, &height) in frames.iter_mut().zip(&heights) {
+ *frame.size_mut() =
+ expand.select(Size::new(size.x, height), frame.size());
+ }
+ frames
} else {
let pod = Regions::one(size, expand);
- body.layout(vt, styles, pod)?.into_frames()
+ let mut frames = body.layout(vt, styles, pod)?.into_frames();
+ *frames[0].size_mut() = expand.select(size, frames[0].size());
+ frames
};
// Clip the contents
diff --git a/library/src/layout/flow.rs b/library/src/layout/flow.rs
index cd7b1f60..b45c39c2 100644
--- a/library/src/layout/flow.rs
+++ b/library/src/layout/flow.rs
@@ -1,6 +1,8 @@
use super::{AlignElem, BlockElem, ColbreakElem, ParElem, PlaceElem, Spacing, VElem};
use crate::prelude::*;
-use crate::visualize::{CircleElem, EllipseElem, ImageElem, RectElem, SquareElem};
+use crate::visualize::{
+ CircleElem, EllipseElem, ImageElem, PathElem, PolygonElem, RectElem, SquareElem,
+};
/// Arrange spacing, paragraphs and block-level elements into a flow.
///
@@ -42,6 +44,8 @@ impl Layout for FlowElem {
|| child.is::<EllipseElem>()
|| child.is::<CircleElem>()
|| child.is::<ImageElem>()
+ || child.is::<PolygonElem>()
+ || child.is::<PathElem>()
{
let layoutable = child.with::<dyn Layout>().unwrap();
layouter.layout_single(vt, layoutable, styles)?;
diff --git a/library/src/layout/mod.rs b/library/src/layout/mod.rs
index d12ce158..0fed1a34 100644
--- a/library/src/layout/mod.rs
+++ b/library/src/layout/mod.rs
@@ -57,6 +57,8 @@ use crate::meta::DocumentElem;
use crate::prelude::*;
use crate::shared::BehavedBuilder;
use crate::text::{LinebreakElem, SmartQuoteElem, SpaceElem, TextElem};
+use crate::visualize::PathElem;
+use crate::visualize::PolygonElem;
use crate::visualize::{CircleElem, EllipseElem, ImageElem, RectElem, SquareElem};
/// Root-level layout.
@@ -192,6 +194,8 @@ fn realize_block<'a>(
&& !content.is::<EllipseElem>()
&& !content.is::<CircleElem>()
&& !content.is::<ImageElem>()
+ && !content.is::<PolygonElem>()
+ && !content.is::<PathElem>()
&& !applicable(content, styles)
{
return Ok((content.clone(), styles));
diff --git a/library/src/visualize/shape.rs b/library/src/visualize/shape.rs
index ba7f052f..c899ad6d 100644
--- a/library/src/visualize/shape.rs
+++ b/library/src/visualize/shape.rs
@@ -483,7 +483,7 @@ fn layout(
let mut frame;
if let Some(child) = body {
- let region = resolved.unwrap_or(regions.base());
+ let mut region = resolved.unwrap_or(regions.base());
if kind.is_round() {
inset = inset.map(|side| side + Ratio::new(0.5 - SQRT_2 / 4.0));
}
@@ -498,10 +498,13 @@ fn layout(
// the result is really a square or circle.
if kind.is_quadratic() {
let length = frame.size().max_by_side().min(region.min_by_side());
- let size = Size::splat(length);
- let pod = Regions::one(size, Axes::splat(true));
+ region = Size::splat(length);
+ let pod = Regions::one(region, Axes::splat(true));
frame = child.layout(vt, styles, pod)?.into_frame();
}
+
+ // Enforce correct size.
+ *frame.size_mut() = expand.select(region, frame.size());
} else {
// The default size that a shape takes on if it has no child and
// enough space.
diff --git a/tests/ref/compiler/construct.png b/tests/ref/compiler/construct.png
index eba9aa9f..3dac041f 100644
--- a/tests/ref/compiler/construct.png
+++ b/tests/ref/compiler/construct.png
Binary files differ
diff --git a/tests/ref/layout/container.png b/tests/ref/layout/container.png
index ce298d29..eff06f1a 100644
--- a/tests/ref/layout/container.png
+++ b/tests/ref/layout/container.png
Binary files differ
diff --git a/tests/typ/layout/container.typ b/tests/typ/layout/container.typ
index 0b30c4e1..d9b62f5e 100644
--- a/tests/typ/layout/container.typ
+++ b/tests/typ/layout/container.typ
@@ -10,6 +10,16 @@ Spaced \
Apart
---
+// Test box sizing.
+#box(width: 50pt, height: 50pt, fill: yellow, path(
+ fill: purple,
+ (0pt, 0pt),
+ (30pt, 30pt),
+ (0pt, 30pt),
+ (30pt, 0pt),
+))
+
+---
// Test fr box.
Hello #box(width: 1fr, rect(height: 0.7em, width: 100%)) World