summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/eval/ops.rs6
-rw-r--r--src/layout/par.rs6
-rw-r--r--src/layout/stack.rs12
-rw-r--r--src/library/layout.rs24
-rw-r--r--tests/ref/layout/stack.pngbin325 -> 318 bytes
-rw-r--r--tests/typ/layout/stack.typ34
6 files changed, 57 insertions, 25 deletions
diff --git a/src/eval/ops.rs b/src/eval/ops.rs
index c7a45614..8756e8c6 100644
--- a/src/eval/ops.rs
+++ b/src/eval/ops.rs
@@ -181,13 +181,13 @@ pub fn div(lhs: Value, rhs: Value) -> StrResult<Value> {
(Relative(a), Float(b)) => Relative(a / b),
(Relative(a), Relative(b)) => Float(a / b),
+ (Linear(a), Int(b)) => Linear(a / b as f64),
+ (Linear(a), Float(b)) => Linear(a / b),
+
(Fractional(a), Int(b)) => Fractional(a / b as f64),
(Fractional(a), Float(b)) => Fractional(a / b),
(Fractional(a), Fractional(b)) => Float(a / b),
- (Linear(a), Int(b)) => Linear(a / b as f64),
- (Linear(a), Float(b)) => Linear(a / b),
-
(a, b) => mismatch!("cannot divide {} by {}", a, b),
})
}
diff --git a/src/layout/par.rs b/src/layout/par.rs
index 847612b9..beb7a1d6 100644
--- a/src/layout/par.rs
+++ b/src/layout/par.rs
@@ -96,9 +96,9 @@ impl From<ParNode> for LayoutNode {
impl Debug for ParChild {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
- ParChild::Spacing(v) => write!(f, "Spacing({:?})", v),
- ParChild::Text(text, ..) => write!(f, "Text({:?})", text),
- ParChild::Any(node, ..) => f.debug_tuple("Any").field(node).finish(),
+ Self::Spacing(v) => write!(f, "Spacing({:?})", v),
+ Self::Text(text, ..) => write!(f, "Text({:?})", text),
+ Self::Any(node, ..) => node.fmt(f),
}
}
}
diff --git a/src/layout/stack.rs b/src/layout/stack.rs
index 4b148ad8..e3416e6b 100644
--- a/src/layout/stack.rs
+++ b/src/layout/stack.rs
@@ -1,3 +1,5 @@
+use std::fmt::{self, Debug, Formatter};
+
use super::*;
/// A node that stacks its children.
@@ -14,7 +16,6 @@ pub struct StackNode {
}
/// A child of a stack node.
-#[derive(Debug)]
#[cfg_attr(feature = "layout-cache", derive(Hash))]
pub enum StackChild {
/// Spacing between other nodes.
@@ -39,6 +40,15 @@ impl From<StackNode> for LayoutNode {
}
}
+impl Debug for StackChild {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ match self {
+ Self::Spacing(v) => write!(f, "Spacing({:?})", v),
+ Self::Any(node, _) => node.fmt(f),
+ }
+ }
+}
+
/// Performs stack layout.
struct StackLayouter<'a> {
/// The stack node to layout.
diff --git a/src/library/layout.rs b/src/library/layout.rs
index 8f645869..e958f3a3 100644
--- a/src/library/layout.rs
+++ b/src/library/layout.rs
@@ -192,11 +192,6 @@ pub fn stack(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let children: Vec<Template> = args.all().collect();
Ok(Value::Template(Template::from_block(move |state| {
- let children = children
- .iter()
- .map(|child| StackChild::Any(child.to_stack(state).into(), state.aligns))
- .collect();
-
let mut dirs = Gen::new(None, dir).unwrap_or(state.dirs);
// If the directions become aligned, fix up the inline direction since
@@ -205,6 +200,19 @@ pub fn stack(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
dirs.inline = state.dirs.block;
}
+ // Use the current alignments for all children, but take care to apply
+ // them to the correct axes (by swapping them if the stack axes are
+ // different from the state axes).
+ let mut aligns = state.aligns;
+ if dirs.block.axis() == state.dirs.inline.axis() {
+ aligns = Gen::new(aligns.block, aligns.inline);
+ }
+
+ let children = children
+ .iter()
+ .map(|child| StackChild::Any(child.to_stack(state).into(), aligns))
+ .collect();
+
StackNode { dirs, children }
})))
}
@@ -233,9 +241,6 @@ pub fn grid(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
);
Ok(Value::Template(Template::from_block(move |state| {
- let children =
- children.iter().map(|child| child.to_stack(&state).into()).collect();
-
// If the directions become aligned, try to fix up the direction which
// is not user-defined.
let mut dirs = Gen::new(column_dir, row_dir).unwrap_or(state.dirs);
@@ -253,6 +258,9 @@ pub fn grid(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
};
}
+ let children =
+ children.iter().map(|child| child.to_stack(&state).into()).collect();
+
GridNode {
dirs,
tracks: tracks.clone(),
diff --git a/tests/ref/layout/stack.png b/tests/ref/layout/stack.png
index 2f190c4d..bc0eb48b 100644
--- a/tests/ref/layout/stack.png
+++ b/tests/ref/layout/stack.png
Binary files differ
diff --git a/tests/typ/layout/stack.typ b/tests/typ/layout/stack.typ
index 729d85fc..384f574f 100644
--- a/tests/typ/layout/stack.typ
+++ b/tests/typ/layout/stack.typ
@@ -1,18 +1,32 @@
// Test stack layouts.
---
-#let rect(width, fill) = rect(width: width, height: 1cm, fill: fill)
-#stack(
- rect(2cm, rgb("2a631a")),
- rect(3cm, forest),
- rect(1cm, conifer),
+// Test stacks with different directions.
+#let widths = (
+ 30pt, 20pt, 40pt, 15pt,
+ 30pt, 50%, 20pt, 100%,
)
+#let shaded = {
+ let v = 0
+ let next() = { v += 0.1; rgb(v, v, v) }
+ w => rect(width: w, height: 10pt, fill: next())
+}
+
+#let items = for w in widths { (shaded(w),) }
+
+#align(right)
+#page(width: 50pt, margins: 0pt)
+#stack(dir: btt, ..items)
+#pagebreak()
+
+// Currently stack works like flexbox apparently.
+#stack(dir: ltr, ..items)
+
---
// Test overflowing stack.
-
-#let rect(width, fill) = rect(width: 1cm, height: 0.4cm, fill: fill)
-#box(height: 0.5cm, stack(
- rect(3cm, forest),
- rect(1cm, conifer),
+#page(width: 50pt, height: 30pt, margins: 0pt)
+#box(stack(
+ rect(width: 40pt, height: 20pt, fill: conifer),
+ rect(width: 30pt, height: 13pt, fill: forest),
))