summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-10-13 18:33:10 +0200
committerLaurenz <laurmaedje@gmail.com>2021-10-23 20:22:47 +0200
commit1e74f7c407e42174b631cb7477f3c88252da7e25 (patch)
tree53c0510b6503c434c9ba470b188d9e737ce1c3cf
parent5f4dde0a6b32c7620b29af30f69591cf3995af9b (diff)
New `ShapeNode`
Replaces `BackgroundNode` and `FixedNode`
-rw-r--r--src/layout/background.rs55
-rw-r--r--src/layout/fixed.rs99
-rw-r--r--src/layout/mod.rs6
-rw-r--r--src/layout/shape.rs141
-rw-r--r--src/layout/tree.rs21
-rw-r--r--src/library/elements.rs108
-rw-r--r--src/library/layout.rs12
-rw-r--r--src/library/mod.rs1
-rw-r--r--tests/ref/elements/circle.pngbin12600 -> 12965 bytes
-rw-r--r--tests/ref/elements/ellipse.pngbin7359 -> 7717 bytes
-rw-r--r--tests/ref/elements/rect.pngbin2542 -> 2866 bytes
-rw-r--r--tests/ref/elements/square.pngbin6124 -> 6983 bytes
-rw-r--r--tests/typ/coma.typ18
-rw-r--r--tests/typ/elements/circle.typ17
-rw-r--r--tests/typ/elements/ellipse.typ4
-rw-r--r--tests/typ/elements/rect.typ24
-rw-r--r--tests/typ/elements/square.typ10
-rw-r--r--tests/typ/layout/grid-1.typ31
18 files changed, 253 insertions, 294 deletions
diff --git a/src/layout/background.rs b/src/layout/background.rs
deleted file mode 100644
index 09282260..00000000
--- a/src/layout/background.rs
+++ /dev/null
@@ -1,55 +0,0 @@
-use super::*;
-
-/// A node that places a rectangular filled background behind its child.
-#[derive(Debug)]
-#[cfg_attr(feature = "layout-cache", derive(Hash))]
-pub struct BackgroundNode {
- /// The kind of shape to use as a background.
- pub shape: BackgroundShape,
- /// Background color / texture.
- pub fill: Paint,
- /// The child node to be filled.
- pub child: LayoutNode,
-}
-
-/// The kind of shape to use as a background.
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum BackgroundShape {
- Rect,
- Ellipse,
-}
-
-impl Layout for BackgroundNode {
- fn layout(
- &self,
- ctx: &mut LayoutContext,
- regions: &Regions,
- ) -> Vec<Constrained<Rc<Frame>>> {
- let mut frames = self.child.layout(ctx, regions);
-
- for Constrained { item: frame, .. } in &mut frames {
- let (point, geometry) = match self.shape {
- BackgroundShape::Rect => (Point::zero(), Geometry::Rect(frame.size)),
- BackgroundShape::Ellipse => {
- (frame.size.to_point() / 2.0, Geometry::Ellipse(frame.size))
- }
- };
-
- // Create a new frame with the background geometry and the child's
- // frame.
- let empty = Frame::new(frame.size, frame.baseline);
- let prev = std::mem::replace(frame, Rc::new(empty));
- let new = Rc::make_mut(frame);
- new.push(point, Element::Geometry(geometry, self.fill));
- new.push_frame(Point::zero(), prev);
- }
-
- frames
- }
-}
-
-impl From<BackgroundNode> for LayoutNode {
- fn from(background: BackgroundNode) -> Self {
- Self::new(background)
- }
-}
diff --git a/src/layout/fixed.rs b/src/layout/fixed.rs
deleted file mode 100644
index f0528643..00000000
--- a/src/layout/fixed.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-use decorum::N64;
-
-use super::*;
-
-/// A node that can fix its child's width and height.
-#[derive(Debug)]
-#[cfg_attr(feature = "layout-cache", derive(Hash))]
-pub struct FixedNode {
- /// The fixed width, if any.
- pub width: Option<Linear>,
- /// The fixed height, if any.
- pub height: Option<Linear>,
- /// The fixed aspect ratio between width and height.
- ///
- /// The resulting frame will satisfy `width = aspect * height`.
- pub aspect: Option<N64>,
- /// The child node whose size to fix.
- pub child: LayoutNode,
-}
-
-impl Layout for FixedNode {
- fn layout(
- &self,
- ctx: &mut LayoutContext,
- regions: &Regions,
- ) -> Vec<Constrained<Rc<Frame>>> {
- // Fill in width or height if aspect ratio and the other is given.
- let aspect = self.aspect.map(N64::into_inner);
- let width = self.width.or(self.height.zip(aspect).map(|(h, a)| a * h));
- let height = self.height.or(self.width.zip(aspect).map(|(w, a)| w / a));
-
- // Resolve the linears based on the current width and height.
- let mut child_size = Size::new(
- width.map_or(regions.current.w, |w| w.resolve(regions.base.w)),
- height.map_or(regions.current.h, |h| h.resolve(regions.base.h)),
- );
-
- // If width or height aren't set for an axis, the base should be
- // inherited from the parent for that axis.
- let child_base = Size::new(
- if width.is_some() { child_size.w } else { regions.base.w },
- if height.is_some() { child_size.h } else { regions.base.h },
- );
-
- // Prepare constraints.
- let mut constraints = Constraints::new(regions.expand);
- constraints.set_base_if_linear(regions.base, Spec::new(width, height));
-
- // If the size for one axis isn't specified, the `current` size along
- // that axis needs to remain the same for the result to be reusable.
- if width.is_none() {
- constraints.exact.x = Some(regions.current.w);
- }
- if height.is_none() {
- constraints.exact.y = Some(regions.current.h);
- }
-
- // Apply the aspect ratio.
- if let Some(aspect) = aspect {
- let width = child_size.w.min(aspect * child_size.h);
- child_size = Size::new(width, width / aspect);
- constraints.exact = regions.current.to_spec().map(Some);
- constraints.min = Spec::splat(None);
- constraints.max = Spec::splat(None);
- }
-
- // If width or height are fixed, the child should fill the available
- // space along that axis.
- let child_expand = Spec::new(width.is_some(), height.is_some());
-
- // Layout the child.
- let mut regions = Regions::one(child_size, child_base, child_expand);
- let mut frames = self.child.layout(ctx, &regions);
-
- // If we have an aspect ratio and the child is content-sized, we need to
- // relayout with expansion.
- if let Some(aspect) = aspect {
- if width.is_none() && height.is_none() {
- let needed = frames[0].item.size.cap(child_size);
- let width = needed.w.max(aspect * needed.h);
- regions.current = Size::new(width, width / aspect);
- regions.expand = Spec::splat(true);
- frames = self.child.layout(ctx, &regions);
- }
- }
-
- // Overwrite the child's constraints with ours.
- assert_eq!(frames.len(), 1);
- frames[0].constraints = constraints;
-
- frames
- }
-}
-
-impl From<FixedNode> for LayoutNode {
- fn from(fixed: FixedNode) -> Self {
- Self::new(fixed)
- }
-}
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 1ca9001d..cd59e3d2 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -1,8 +1,6 @@
//! Layouting.
-mod background;
mod constraints;
-mod fixed;
mod frame;
mod grid;
mod image;
@@ -11,14 +9,13 @@ mod incremental;
mod pad;
mod par;
mod regions;
+mod shape;
mod shaping;
mod stack;
mod tree;
pub use self::image::*;
-pub use background::*;
pub use constraints::*;
-pub use fixed::*;
pub use frame::*;
pub use grid::*;
#[cfg(feature = "layout-cache")]
@@ -26,6 +23,7 @@ pub use incremental::*;
pub use pad::*;
pub use par::*;
pub use regions::*;
+pub use shape::*;
pub use shaping::*;
pub use stack::*;
pub use tree::*;
diff --git a/src/layout/shape.rs b/src/layout/shape.rs
new file mode 100644
index 00000000..aa90707c
--- /dev/null
+++ b/src/layout/shape.rs
@@ -0,0 +1,141 @@
+use std::f64::consts::SQRT_2;
+
+use super::*;
+
+/// Places its child into a sizable and fillable shape.
+#[derive(Debug)]
+#[cfg_attr(feature = "layout-cache", derive(Hash))]
+pub struct ShapeNode {
+ /// Which shape to place the child into.
+ pub shape: ShapeKind,
+ /// The width, if any.
+ pub width: Option<Linear>,
+ /// The height, if any.
+ pub height: Option<Linear>,
+ /// How to fill the shape, if at all.
+ pub fill: Option<Paint>,
+ /// The child node to place into the shape, if any.
+ pub child: Option<LayoutNode>,
+}
+
+/// The type of a shape.
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub enum ShapeKind {
+ /// A rectangle with equal side lengths.
+ Square,
+ /// A quadrilateral with four right angles.
+ Rect,
+ /// An ellipse with coinciding foci.
+ Circle,
+ /// A curve around two focal points.
+ Ellipse,
+}
+
+impl Layout for ShapeNode {
+ fn layout(
+ &self,
+ ctx: &mut LayoutContext,
+ regions: &Regions,
+ ) -> Vec<Constrained<Rc<Frame>>> {
+ // Resolve width and height relative to the region's base.
+ let width = self.width.map(|w| w.resolve(regions.base.w));
+ let height = self.height.map(|h| h.resolve(regions.base.h));
+
+ // Generate constraints.
+ let constraints = {
+ let mut cts = Constraints::new(regions.expand);
+ cts.set_base_if_linear(regions.base, Spec::new(self.width, self.height));
+
+ // Set exact and base constraint if child is automatically sized.
+ if self.width.is_none() {
+ cts.exact.x = Some(regions.current.w);
+ cts.base.x = Some(regions.base.w);
+ }
+
+ // Same here.
+ if self.height.is_none() {
+ cts.exact.y = Some(regions.current.h);
+ cts.base.y = Some(regions.base.h);
+ }
+
+ cts
+ };
+
+ // Layout.
+ let mut frames = if let Some(child) = &self.child {
+ let mut node: &dyn Layout = child;
+
+ let padded;
+ if matches!(self.shape, ShapeKind::Circle | ShapeKind::Ellipse) {
+ // Padding with this ratio ensures that a rectangular child fits
+ // perfectly into a circle / an ellipse.
+ padded = PadNode {
+ padding: Sides::splat(Relative::new(0.5 - SQRT_2 / 4.0).into()),
+ child: child.clone(),
+ };
+ node = &padded;
+ }
+
+ // The "pod" is the region into which the child will be layouted.
+ let mut pod = {
+ let size = Size::new(
+ width.unwrap_or(regions.current.w),
+ height.unwrap_or(regions.current.h),
+ );
+
+ let base = Size::new(
+ if width.is_some() { size.w } else { regions.base.w },
+ if height.is_some() { size.h } else { regions.base.h },
+ );
+
+ let expand = Spec::new(width.is_some(), height.is_some());
+ Regions::one(size, base, expand)
+ };
+
+ // Now, layout the child.
+ let mut frames = node.layout(ctx, &pod);
+
+ if matches!(self.shape, ShapeKind::Square | ShapeKind::Circle) {
+ // Relayout with full expansion into square region to make sure
+ // the result is really a square or circle.
+ let size = frames[0].item.size;
+ pod.current.w = size.w.max(size.h).min(pod.current.w);
+ pod.current.h = pod.current.w;
+ pod.expand = Spec::splat(true);
+ frames = node.layout(ctx, &pod);
+ }
+
+ // Validate and set constraints.
+ assert_eq!(frames.len(), 1);
+ frames[0].constraints = constraints;
+ frames
+ } else {
+ // Resolve shape size.
+ let size = Size::new(width.unwrap_or_default(), height.unwrap_or_default());
+ vec![Frame::new(size, size.h).constrain(constraints)]
+ };
+
+ // Add background shape if desired.
+ if let Some(fill) = self.fill {
+ let frame = Rc::make_mut(&mut frames[0].item);
+ let (pos, geometry) = match self.shape {
+ ShapeKind::Square | ShapeKind::Rect => {
+ (Point::zero(), Geometry::Rect(frame.size))
+ }
+ ShapeKind::Circle | ShapeKind::Ellipse => {
+ (frame.size.to_point() / 2.0, Geometry::Ellipse(frame.size))
+ }
+ };
+
+ frame.prepend(pos, Element::Geometry(geometry, fill));
+ }
+
+ frames
+ }
+}
+
+impl From<ShapeNode> for LayoutNode {
+ fn from(shape: ShapeNode) -> Self {
+ Self::new(shape)
+ }
+}
diff --git a/src/layout/tree.rs b/src/layout/tree.rs
index 38ba6e85..900eb1a9 100644
--- a/src/layout/tree.rs
+++ b/src/layout/tree.rs
@@ -50,8 +50,9 @@ impl PageRun {
}
/// A dynamic layouting node.
+#[derive(Clone)]
pub struct LayoutNode {
- node: Box<dyn Layout>,
+ node: Rc<dyn Layout>,
#[cfg(feature = "layout-cache")]
hash: u64,
}
@@ -63,7 +64,7 @@ impl LayoutNode {
where
T: Layout + 'static,
{
- Self { node: Box::new(node) }
+ Self { node: Rc::new(node) }
}
/// Create a new instance from any node that satisifies the required bounds.
@@ -79,7 +80,7 @@ impl LayoutNode {
state.finish()
};
- Self { node: Box::new(node), hash }
+ Self { node: Rc::new(node), hash }
}
}
@@ -99,10 +100,16 @@ impl Layout for LayoutNode {
ctx.level -= 1;
let entry = FramesEntry::new(frames.clone(), ctx.level);
- debug_assert!(
- entry.check(regions),
- "constraints did not match regions they were created for",
- );
+
+ #[cfg(debug_assertions)]
+ if !entry.check(regions) {
+ eprintln!("regions: {:#?}", regions);
+ eprintln!(
+ "constraints: {:#?}",
+ frames.iter().map(|c| c.constraints).collect::<Vec<_>>()
+ );
+ panic!("constraints did not match regions they were created for");
+ }
ctx.layouts.insert(self.hash, entry);
frames
diff --git a/src/library/elements.rs b/src/library/elements.rs
index 51f8dc98..5d87d65d 100644
--- a/src/library/elements.rs
+++ b/src/library/elements.rs
@@ -1,11 +1,8 @@
-use std::f64::consts::SQRT_2;
use std::io;
-use decorum::N64;
-
use super::*;
use crate::diag::Error;
-use crate::layout::{BackgroundNode, BackgroundShape, FixedNode, ImageNode, PadNode};
+use crate::layout::{ImageNode, ShapeKind, ShapeNode};
/// `image`: An image.
pub fn image(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
@@ -33,52 +30,24 @@ pub fn rect(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let width = args.named("width")?;
let height = args.named("height")?;
let fill = args.named("fill")?;
- let body = args.eat().unwrap_or_default();
- Ok(rect_impl(width, height, None, fill, body))
+ let body = args.eat();
+ Ok(shape_impl(ShapeKind::Rect, width, height, fill, body))
}
/// `square`: A square with optional content.
pub fn square(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let size = args.named::<Length>("size")?.map(Linear::from);
let width = match size {
- Some(size) => Some(size),
None => args.named("width")?,
+ size => size,
};
- let height = match width {
- Some(_) => None,
+ let height = match size {
None => args.named("height")?,
+ size => size,
};
- let aspect = Some(N64::from(1.0));
let fill = args.named("fill")?;
- let body = args.eat().unwrap_or_default();
- Ok(rect_impl(width, height, aspect, fill, body))
-}
-
-fn rect_impl(
- width: Option<Linear>,
- height: Option<Linear>,
- aspect: Option<N64>,
- fill: Option<Color>,
- body: Template,
-) -> Value {
- Value::Template(Template::from_inline(move |style| {
- let mut node = LayoutNode::new(FixedNode {
- width,
- height,
- aspect,
- child: body.to_stack(style).into(),
- });
-
- if let Some(fill) = fill {
- node = LayoutNode::new(BackgroundNode {
- shape: BackgroundShape::Rect,
- fill: Paint::Color(fill),
- child: node,
- });
- }
-
- node
- }))
+ let body = args.eat();
+ Ok(shape_impl(ShapeKind::Square, width, height, fill, body))
}
/// `ellipse`: An ellipse with optional content.
@@ -86,8 +55,8 @@ pub fn ellipse(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let width = args.named("width")?;
let height = args.named("height")?;
let fill = args.named("fill")?;
- let body = args.eat().unwrap_or_default();
- Ok(ellipse_impl(width, height, None, fill, body))
+ let body = args.eat();
+ Ok(shape_impl(ShapeKind::Ellipse, width, height, fill, body))
}
/// `circle`: A circle with optional content.
@@ -97,46 +66,39 @@ pub fn circle(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
None => args.named("width")?,
diameter => diameter,
};
- let height = match width {
+ let height = match diameter {
None => args.named("height")?,
- width => width,
+ diameter => diameter,
};
- let aspect = Some(N64::from(1.0));
let fill = args.named("fill")?;
- let body = args.eat().unwrap_or_default();
- Ok(ellipse_impl(width, height, aspect, fill, body))
+ let body = args.eat();
+ Ok(shape_impl(ShapeKind::Circle, width, height, fill, body))
}
-fn ellipse_impl(
- width: Option<Linear>,
- height: Option<Linear>,
- aspect: Option<N64>,
+fn shape_impl(
+ shape: ShapeKind,
+ mut width: Option<Linear>,
+ mut height: Option<Linear>,
fill: Option<Color>,
- body: Template,
+ body: Option<Template>,
) -> Value {
- Value::Template(Template::from_inline(move |style| {
- // This padding ratio ensures that the rectangular padded region fits
- // perfectly into the ellipse.
- const PAD: f64 = 0.5 - SQRT_2 / 4.0;
-
- let mut node = LayoutNode::new(FixedNode {
- width,
- height,
- aspect,
- child: LayoutNode::new(PadNode {
- padding: Sides::splat(Relative::new(PAD).into()),
- child: body.to_stack(style).into(),
- }),
+ // Set default shape size if there's no body.
+ if body.is_none() {
+ let v = Length::pt(30.0).into();
+ height.get_or_insert(v);
+ width.get_or_insert(match shape {
+ ShapeKind::Square | ShapeKind::Circle => v,
+ ShapeKind::Rect | ShapeKind::Ellipse => 1.5 * v,
});
+ }
- if let Some(fill) = fill {
- node = LayoutNode::new(BackgroundNode {
- shape: BackgroundShape::Ellipse,
- fill: Paint::Color(fill),
- child: node,
- });
- }
-
- node
+ Value::Template(Template::from_inline(move |style| ShapeNode {
+ shape,
+ width,
+ height,
+ fill: Some(Paint::Color(
+ fill.unwrap_or(Color::Rgba(RgbaColor::new(175, 175, 175, 255))),
+ )),
+ child: body.as_ref().map(|template| template.to_stack(style).into()),
}))
}
diff --git a/src/library/layout.rs b/src/library/layout.rs
index efa012b9..b98b08f1 100644
--- a/src/library/layout.rs
+++ b/src/library/layout.rs
@@ -1,5 +1,7 @@
use super::*;
-use crate::layout::{FixedNode, GridNode, PadNode, StackChild, StackNode, TrackSizing};
+use crate::layout::{
+ GridNode, PadNode, ShapeKind, ShapeNode, StackChild, StackNode, TrackSizing,
+};
use crate::style::{Paper, PaperClass};
/// `page`: Configure pages.
@@ -146,13 +148,15 @@ pub fn v(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
pub fn boxed(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let width = args.named("width")?;
let height = args.named("height")?;
+ let fill = args.named("fill")?;
let body: Template = args.eat().unwrap_or_default();
Ok(Value::Template(Template::from_inline(move |style| {
- FixedNode {
+ ShapeNode {
+ shape: ShapeKind::Rect,
width,
height,
- aspect: None,
- child: body.to_stack(style).into(),
+ fill: fill.map(Paint::Color),
+ child: Some(body.to_stack(style).into()),
}
})))
}
diff --git a/src/library/mod.rs b/src/library/mod.rs
index 7c8f4a93..430e260b 100644
--- a/src/library/mod.rs
+++ b/src/library/mod.rs
@@ -20,7 +20,6 @@ use crate::diag::{At, TypResult};
use crate::eval::{Args, Array, EvalContext, Scope, Str, Template, Value};
use crate::font::{FontFamily, FontStretch, FontStyle, FontWeight, VerticalFontMetric};
use crate::geom::*;
-use crate::layout::LayoutNode;
use crate::style::Style;
use crate::syntax::{Span, Spanned};
diff --git a/tests/ref/elements/circle.png b/tests/ref/elements/circle.png
index 65b087ed..41079fda 100644
--- a/tests/ref/elements/circle.png
+++ b/tests/ref/elements/circle.png
Binary files differ
diff --git a/tests/ref/elements/ellipse.png b/tests/ref/elements/ellipse.png
index d429f66e..98e66902 100644
--- a/tests/ref/elements/ellipse.png
+++ b/tests/ref/elements/ellipse.png
Binary files differ
diff --git a/tests/ref/elements/rect.png b/tests/ref/elements/rect.png
index ad4c48e6..b6d40545 100644
--- a/tests/ref/elements/rect.png
+++ b/tests/ref/elements/rect.png
Binary files differ
diff --git a/tests/ref/elements/square.png b/tests/ref/elements/square.png
index a7343a10..a12e1a12 100644
--- a/tests/ref/elements/square.png
+++ b/tests/ref/elements/square.png
Binary files differ
diff --git a/tests/typ/coma.typ b/tests/typ/coma.typ
index 8f47a749..54f80cf6 100644
--- a/tests/typ/coma.typ
+++ b/tests/typ/coma.typ
@@ -10,18 +10,12 @@
#let university = [*Technische Universität {city}*]
#let faculty = [*Fakultät II, Institut for Mathematik*]
-// The `box` function just places content into a rectangular container. When
-// the only argument to a function is a template, the parentheses can be omitted
-// (i.e. `f[a]` is the same as `f([a])`).
-#box[
- // Backslash adds a forced line break.
- #university \
- #faculty \
- Sekretariat MA \
- Dr. Max Mustermann \
- Ola Nordmann, John Doe
-]
-#align(right, box[*WiSe 2019/2020* \ Woche 3])
+// Backslashs add forced line breaks.
+#university #align(right)[*WiSe 2019/2020*] \
+#faculty #align(right)[Woche 3] \
+Sekretariat MA \
+Dr. Max Mustermann \
+Ola Nordmann, John Doe
// Adds vertical spacing.
#v(6mm)
diff --git a/tests/typ/elements/circle.typ b/tests/typ/elements/circle.typ
index c46d37e4..c36f9f94 100644
--- a/tests/typ/elements/circle.typ
+++ b/tests/typ/elements/circle.typ
@@ -1,6 +1,10 @@
// Test the `circle` function.
---
+// Default circle.
+#circle()
+
+---
// Test auto sizing.
Auto-sized circle. \
@@ -29,20 +33,15 @@ Expanded by height.
---
// Test relative sizing.
-#rect(width: 100%, height: 50pt, fill: rgb("aaa"))[
+#rect(width: 100pt, height: 50pt, fill: rgb("aaa"))[
#align(center, center)
#font(fill: white)
- #circle(radius: 10pt, fill: eastern)[A]
- #circle(height: 60%, fill: eastern)[B]
- #circle(width: 20% + 20pt, fill: eastern)[C]
+ #circle(radius: 10pt, fill: eastern)[A] // D=20pt
+ #circle(height: 60%, fill: eastern)[B] // D=30pt
+ #circle(width: 20% + 20pt, fill: eastern)[C] // D=40pt
]
---
// Radius wins over width and height.
// Error: 23-34 unexpected argument
#circle(radius: 10pt, width: 50pt, height: 100pt, fill: eastern)
-
----
-// Width wins over height.
-// Error: 9-21 unexpected argument
-#circle(height: 50pt, width: 20pt, fill: eastern)
diff --git a/tests/typ/elements/ellipse.typ b/tests/typ/elements/ellipse.typ
index 33ba727f..106a8172 100644
--- a/tests/typ/elements/ellipse.typ
+++ b/tests/typ/elements/ellipse.typ
@@ -1,6 +1,10 @@
// Test the `ellipse` function.
---
+// Default ellipse.
+#ellipse()
+
+---
100% rect in 100% ellipse in fixed rect. \
#rect(width: 3cm, height: 2cm, fill: rgb("2a631a"),
ellipse(width: 100%, height: 100%, fill: forest,
diff --git a/tests/typ/elements/rect.typ b/tests/typ/elements/rect.typ
index 4824095a..59dd4ee0 100644
--- a/tests/typ/elements/rect.typ
+++ b/tests/typ/elements/rect.typ
@@ -1,27 +1,25 @@
-// Test shapes.
+// Test the `rect` function.
---
-// Test the `rect` function.
+// Default rectangle.
+#rect()
+---
#page(width: 150pt)
// Fit to text.
#rect(fill: conifer)[Textbox]
// Empty with fixed width and height.
-#rect(width: 3cm, height: 12pt, fill: rgb("CB4CED"))
+#rect(width: 3cm, height: 12pt, fill: rgb("ed8a4c"))
// Fixed width, text height.
-#rect(width: 2cm, fill: rgb("9650D6"), pad(5pt)[Fixed and padded])
+#rect(width: 2cm, fill: rgb("9650d6"), pad(5pt)[Fixed and padded])
// Page width, fixed height.
-#rect(height: 1cm, width: 100%, fill: rgb("734CED"))[Topleft]
-
-// Not visible, but creates a gap between the boxes above and below
-// due to line spacing.
-#rect(width: 1in, fill: rgb("ff0000"))
+#rect(height: 1cm, width: 100%, fill: rgb("734ced"))[Topleft]
-// These are in a row!
-#rect(width: 0.5in, height: 10pt, fill: rgb("D6CD67"))
-#rect(width: 0.5in, height: 10pt, fill: rgb("EDD466"))
-#rect(width: 0.5in, height: 10pt, fill: rgb("E3BE62"))
+// These are inline with text.
+\{#rect(width: 0.5in, height: 7pt, fill: rgb("d6cd67"))
+ #rect(width: 0.5in, height: 7pt, fill: rgb("edd466"))
+ #rect(width: 0.5in, height: 7pt, fill: rgb("e3be62"))\}
diff --git a/tests/typ/elements/square.typ b/tests/typ/elements/square.typ
index 7597cb22..0e9c3c55 100644
--- a/tests/typ/elements/square.typ
+++ b/tests/typ/elements/square.typ
@@ -1,12 +1,18 @@
// Test the `square` function.
---
+// Default square.
+#square()
+#square[hey!]
+
+---
// Test auto-sized square.
#square(fill: eastern)[
#font(fill: white, weight: bold)
#align(center)
#pad(5pt)[Typst]
]
+
---
// Test relative-sized child.
#square(fill: eastern)[
@@ -15,14 +21,14 @@
]
---
-// Test height overflow.
+// Test text overflowing height.
#page(width: 75pt, height: 100pt)
#square(fill: conifer)[
But, soft! what light through yonder window breaks?
]
---
-// Test width overflow.
+// Test required height overflowing page.
#page(width: 100pt, height: 75pt)
#square(fill: conifer)[
But, soft! what light through yonder window breaks?
diff --git a/tests/typ/layout/grid-1.typ b/tests/typ/layout/grid-1.typ
index 3d0412c2..43a3883d 100644
--- a/tests/typ/layout/grid-1.typ
+++ b/tests/typ/layout/grid-1.typ
@@ -1,23 +1,23 @@
// Test grid layouts.
---
-#let rect(width, fill) = rect(width: width, height: 2cm, fill: fill)
+#let cell(width, color) = rect(width: width, height: 2cm, fill: color)
#page(width: 100pt, height: 140pt)
#grid(
columns: (auto, 1fr, 3fr, 0.25cm, 3%, 2mm + 10%),
- rect(0.5cm, rgb("2a631a")),
- rect(100%, forest),
- rect(100%, conifer),
- rect(100%, rgb("ff0000")),
- rect(100%, rgb("00ff00")),
- rect(80%, rgb("00faf0")),
- rect(1cm, rgb("00ff00")),
- rect(0.5cm, rgb("2a631a")),
- rect(100%, forest),
- rect(100%, conifer),
- rect(100%, rgb("ff0000")),
- rect(100%, rgb("00ff00")),
+ cell(0.5cm, rgb("2a631a")),
+ cell(100%, forest),
+ cell(100%, conifer),
+ cell(100%, rgb("ff0000")),
+ cell(100%, rgb("00ff00")),
+ cell(80%, rgb("00faf0")),
+ cell(1cm, rgb("00ff00")),
+ cell(0.5cm, rgb("2a631a")),
+ cell(100%, forest),
+ cell(100%, conifer),
+ cell(100%, rgb("ff0000")),
+ cell(100%, rgb("00ff00")),
)
#grid()
@@ -51,6 +51,7 @@
#grid(
columns: (1fr,),
rows: (1fr, auto, 2fr),
- [], rect(width: 100%)[A bit more to the top], [],
+ [],
+ box(width: 100%)[A bit more to the top],
+ [],
)
-