diff --git a/src/eval/template.rs b/src/eval/template.rs index 0ea312e5d..59fe293aa 100644 --- a/src/eval/template.rs +++ b/src/eval/template.rs @@ -6,7 +6,7 @@ use std::rc::Rc; use super::Str; use crate::diag::StrResult; -use crate::geom::{Align, Dir, Gen, GenAxis, Length, Linear, Sides, Size}; +use crate::geom::{Align, Dir, GenAxis, Length, Linear, Sides, Size}; use crate::layout::{ Decoration, LayoutNode, LayoutTree, PadNode, PageRun, ParChild, ParNode, StackChild, StackNode, @@ -335,8 +335,7 @@ impl Builder { /// Push a block node into the active stack, finishing the active paragraph. fn block(&mut self, node: impl Into) { self.parbreak(); - let aligns = self.style.aligns; - self.stack.push(StackChild::Any(node.into(), aligns)); + self.stack.push(StackChild::Any(node.into(), self.style.aligns.block)); self.parbreak(); } @@ -407,7 +406,7 @@ impl PageBuilder { } struct StackBuilder { - dirs: Gen, + dir: Dir, children: Vec, last: Last, par: ParBuilder, @@ -416,7 +415,7 @@ struct StackBuilder { impl StackBuilder { fn new(style: &Style) -> Self { Self { - dirs: Gen::new(style.dir, Dir::TTB), + dir: Dir::TTB, children: vec![], last: Last::None, par: ParBuilder::new(style), @@ -445,17 +444,17 @@ impl StackBuilder { } fn build(self) -> StackNode { - let Self { dirs, mut children, par, mut last } = self; + let Self { dir, mut children, par, mut last } = self; if let Some(par) = par.build() { children.extend(last.any()); children.push(par); } - StackNode { dirs, children } + StackNode { dir, children } } } struct ParBuilder { - aligns: Gen, + align: Align, dir: Dir, line_spacing: Length, children: Vec, @@ -465,7 +464,7 @@ struct ParBuilder { impl ParBuilder { fn new(style: &Style) -> Self { Self { - aligns: style.aligns, + align: style.aligns.block, dir: style.dir, line_spacing: style.line_spacing(), children: vec![], @@ -508,10 +507,10 @@ impl ParBuilder { } fn build(self) -> Option { - let Self { aligns, dir, line_spacing, children, .. } = self; + let Self { align, dir, line_spacing, children, .. } = self; (!children.is_empty()).then(|| { let node = ParNode { dir, line_spacing, children }; - StackChild::Any(node.into(), aligns) + StackChild::Any(node.into(), align) }) } } diff --git a/src/eval/walk.rs b/src/eval/walk.rs index 903611412..b76300ecc 100644 --- a/src/eval/walk.rs +++ b/src/eval/walk.rs @@ -2,7 +2,7 @@ use std::rc::Rc; use super::{Eval, EvalContext, Str, Template, Value}; use crate::diag::TypResult; -use crate::geom::{Dir, Gen}; +use crate::geom::Align; use crate::layout::{ParChild, ParNode, StackChild, StackNode}; use crate::syntax::*; use crate::util::BoolExt; @@ -117,11 +117,11 @@ fn walk_item(ctx: &mut EvalContext, label: Str, body: Template) { )], }; StackNode { - dirs: Gen::new(Dir::TTB, style.dir), + dir: style.dir, children: vec![ - StackChild::Any(label.into(), Gen::default()), + StackChild::Any(label.into(), Align::Start), StackChild::Spacing((style.text.size / 2.0).into()), - StackChild::Any(body.to_stack(&style).into(), Gen::default()), + StackChild::Any(body.to_stack(&style).into(), Align::Start), ], } }); diff --git a/src/layout/stack.rs b/src/layout/stack.rs index e3416e6bb..765fb7ab0 100644 --- a/src/layout/stack.rs +++ b/src/layout/stack.rs @@ -6,11 +6,8 @@ use super::*; #[derive(Debug)] #[cfg_attr(feature = "layout-cache", derive(Hash))] pub struct StackNode { - /// The inline and block directions of this stack. - /// - /// The children are stacked along the block direction. The inline direction - /// is required for aligning the children. - pub dirs: Gen, + /// The stacking direction. + pub dir: Dir, /// The nodes to be stacked. pub children: Vec, } @@ -21,7 +18,7 @@ pub enum StackChild { /// Spacing between other nodes. Spacing(Linear), /// Any child node and how to align it in the stack. - Any(LayoutNode, Gen), + Any(LayoutNode, Align), } impl Layout for StackNode { @@ -72,7 +69,7 @@ struct StackLayouter<'a> { overflowing: bool, /// Offset, alignment and frame for all children that fit into the current /// region. The exact positions are not known yet. - frames: Vec<(Length, Gen, Rc)>, + frames: Vec<(Length, Align, Rc)>, /// Finished frames for previous regions. finished: Vec>>, } @@ -80,7 +77,7 @@ struct StackLayouter<'a> { impl<'a> StackLayouter<'a> { /// Create a new stack layouter. fn new(stack: &'a StackNode, mut regions: Regions) -> Self { - let block = stack.dirs.block.axis(); + let block = stack.dir.axis(); let full = regions.current; let expand = regions.expand; @@ -107,14 +104,14 @@ impl<'a> StackLayouter<'a> { for child in &self.stack.children { match *child { StackChild::Spacing(amount) => self.space(amount), - StackChild::Any(ref node, aligns) => { + StackChild::Any(ref node, align) => { let nodes = node.layout(ctx, &self.regions); let len = nodes.len(); for (i, frame) in nodes.into_iter().enumerate() { if i + 1 < len { self.constraints.exact = self.full.to_spec().map(Some); } - self.push_frame(frame.item, aligns); + self.push_frame(frame.item, align); } } } @@ -142,11 +139,11 @@ impl<'a> StackLayouter<'a> { /// Push a frame into the current or next fitting region, finishing regions /// if necessary. - fn push_frame(&mut self, frame: Rc, aligns: Gen) { + fn push_frame(&mut self, frame: Rc, align: Align) { let size = frame.size.to_gen(self.block); // Don't allow `Start` after `End` in the same region. - if aligns.block < self.ruler { + if align < self.ruler { self.finish_region(); } @@ -172,10 +169,10 @@ impl<'a> StackLayouter<'a> { let offset = self.used.block; self.used.block += size.block; self.used.inline.set_max(size.inline); - self.ruler = aligns.block; + self.ruler = align; // Remember the frame with offset and alignment. - self.frames.push((offset, aligns, frame)); + self.frames.push((offset, align, frame)); } /// Finish the frame for one region. @@ -211,20 +208,14 @@ impl<'a> StackLayouter<'a> { let mut first = true; // Place all frames. - for (offset, aligns, frame) in self.frames.drain(..) { + for (offset, align, frame) in self.frames.drain(..) { let stack_size = size.to_gen(self.block); let child_size = frame.size.to_gen(self.block); - // Align along the inline axis. - let inline = aligns.inline.resolve( - self.stack.dirs.inline, - Length::zero() .. stack_size.inline - child_size.inline, - ); - // Align along the block axis. - let block = aligns.block.resolve( - self.stack.dirs.block, - if self.stack.dirs.block.is_positive() { + let block = align.resolve( + self.stack.dir, + if self.stack.dir.is_positive() { offset .. stack_size.block - self.used.block + offset } else { let offset_with_self = offset + child_size.block; @@ -233,7 +224,7 @@ impl<'a> StackLayouter<'a> { }, ); - let pos = Gen::new(inline, block).to_point(self.block); + let pos = Gen::new(Length::zero(), block).to_point(self.block); // The baseline of the stack is that of the first frame. if first { diff --git a/src/library/layout.rs b/src/library/layout.rs index c8b22f88c..efa012b9e 100644 --- a/src/library/layout.rs +++ b/src/library/layout.rs @@ -204,27 +204,11 @@ pub fn stack(_: &mut EvalContext, args: &mut Args) -> TypResult { Value::Template(v) => Self::Any(v), } - let dir = args.named("dir")?; + let dir = args.named("dir")?.unwrap_or(Dir::TTB); let spacing = args.named("spacing")?; let list: Vec = args.all().collect(); Ok(Value::Template(Template::from_block(move |style| { - let mut dirs = Gen::new(style.dir, dir.unwrap_or(Dir::TTB)); - - // If the directions become aligned, fix up the inline direction since - // that's the one that is not user-defined. - if dirs.inline.axis() == dirs.block.axis() { - dirs.inline = Dir::TTB; - } - - // 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 style axes). - let mut aligns = style.aligns; - if dirs.inline.axis() != style.dir.axis() { - aligns = Gen::new(aligns.block, aligns.inline); - } - let mut children = vec![]; let mut delayed = None; @@ -241,13 +225,13 @@ pub fn stack(_: &mut EvalContext, args: &mut Args) -> TypResult { } let node = template.to_stack(style).into(); - children.push(StackChild::Any(node, aligns)); + children.push(StackChild::Any(node, style.aligns.block)); delayed = spacing; } } } - StackNode { dirs, children } + StackNode { dir, children } }))) } diff --git a/tests/ref/layout/stack.png b/tests/ref/layout/stack.png index 13438d07c..78f7ed773 100644 Binary files a/tests/ref/layout/stack.png and b/tests/ref/layout/stack.png differ diff --git a/tests/typ/layout/stack.typ b/tests/typ/layout/stack.typ index a6e7e0016..b8d8a09d1 100644 --- a/tests/typ/layout/stack.typ +++ b/tests/typ/layout/stack.typ @@ -20,9 +20,6 @@ #stack(dir: btt, ..items) #pagebreak() -// Currently stack works like flexbox apparently. -#stack(dir: ltr, ..items) - --- // Test spacing. #page(width: 50pt, margins: 0pt)