summaryrefslogtreecommitdiff
path: root/src/layout
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-12-20 14:18:29 +0100
committerLaurenz <laurmaedje@gmail.com>2021-12-21 00:20:24 +0100
commit11565a40b315212474f52eb576a9fd92b11f1132 (patch)
treec6b7afb35103065bc92b407094ca905bb75cfc73 /src/layout
parent958f74f77707340f34ee36d09492bdb74523aa2a (diff)
Set Rules Episode IX: The Rise of Testing
Diffstat (limited to 'src/layout')
-rw-r--r--src/layout/mod.rs100
1 files changed, 57 insertions, 43 deletions
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index cf714f88..bc28e893 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -20,13 +20,52 @@ use crate::font::FontStore;
use crate::frame::Frame;
use crate::geom::{Align, Linear, Point, Sides, Size, Spec, Transform};
use crate::image::ImageStore;
-use crate::library::{AlignNode, DocumentNode, PadNode, SizedNode, TransformNode};
+use crate::library::{AlignNode, PadNode, PageNode, SizedNode, TransformNode};
use crate::Context;
-/// Layout a document node into a collection of frames.
-pub fn layout(ctx: &mut Context, node: &DocumentNode) -> Vec<Rc<Frame>> {
- let mut ctx = LayoutContext::new(ctx);
- node.layout(&mut ctx)
+/// The root layout node, a document consisting of top-level page runs.
+#[derive(Hash)]
+pub struct RootNode(pub Vec<PageNode>);
+
+impl RootNode {
+ /// Layout the document into a sequence of frames, one per page.
+ pub fn layout(&self, ctx: &mut Context) -> Vec<Rc<Frame>> {
+ let mut ctx = LayoutContext::new(ctx);
+ self.0.iter().flat_map(|node| node.layout(&mut ctx)).collect()
+ }
+}
+
+impl Debug for RootNode {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ f.write_str("Root ")?;
+ f.debug_list().entries(&self.0).finish()
+ }
+}
+
+/// A node that can be layouted into a sequence of regions.
+///
+/// Layout return one frame per used region alongside constraints that define
+/// whether the result is reusable in other regions.
+pub trait Layout {
+ /// Layout the node into the given regions, producing constrained frames.
+ fn layout(
+ &self,
+ ctx: &mut LayoutContext,
+ regions: &Regions,
+ ) -> Vec<Constrained<Rc<Frame>>>;
+
+ /// Convert to a packed node.
+ fn pack(self) -> PackedNode
+ where
+ Self: Debug + Hash + Sized + 'static,
+ {
+ PackedNode {
+ #[cfg(feature = "layout-cache")]
+ hash: self.hash64(),
+ node: Rc::new(self),
+ styles: Styles::new(),
+ }
+ }
}
/// The context for layouting.
@@ -39,6 +78,7 @@ pub struct LayoutContext<'a> {
#[cfg(feature = "layout-cache")]
pub layouts: &'a mut LayoutCache,
/// The inherited style properties.
+ // TODO(style): This probably shouldn't be here.
pub styles: Styles,
/// How deeply nested the current layout tree position is.
#[cfg(feature = "layout-cache")]
@@ -60,29 +100,22 @@ impl<'a> LayoutContext<'a> {
}
}
-/// A node that can be layouted into a sequence of regions.
+/// A layout node that produces an empty frame.
///
-/// Layout return one frame per used region alongside constraints that define
-/// whether the result is reusable in other regions.
-pub trait Layout {
- /// Layout the node into the given regions, producing constrained frames.
+/// The packed version of this is returned by [`PackedNode::default`].
+#[derive(Debug, Hash)]
+pub struct EmptyNode;
+
+impl Layout for EmptyNode {
fn layout(
&self,
- ctx: &mut LayoutContext,
+ _: &mut LayoutContext,
regions: &Regions,
- ) -> Vec<Constrained<Rc<Frame>>>;
-
- /// Convert to a packed node.
- fn pack(self) -> PackedNode
- where
- Self: Debug + Hash + Sized + 'static,
- {
- PackedNode {
- #[cfg(feature = "layout-cache")]
- hash: self.hash64(),
- node: Rc::new(self),
- styles: Styles::new(),
- }
+ ) -> Vec<Constrained<Rc<Frame>>> {
+ let size = regions.expand.select(regions.current, Size::zero());
+ let mut cts = Constraints::new(regions.expand);
+ cts.exact = regions.current.filter(regions.expand);
+ vec![Frame::new(size).constrain(cts)]
}
}
@@ -288,22 +321,3 @@ where
state.finish()
}
}
-
-/// A layout node that produces an empty frame.
-///
-/// The packed version of this is returned by [`PackedNode::default`].
-#[derive(Debug, Hash)]
-pub struct EmptyNode;
-
-impl Layout for EmptyNode {
- fn layout(
- &self,
- _: &mut LayoutContext,
- regions: &Regions,
- ) -> Vec<Constrained<Rc<Frame>>> {
- let size = regions.expand.select(regions.current, Size::zero());
- let mut cts = Constraints::new(regions.expand);
- cts.exact = regions.current.filter(regions.expand);
- vec![Frame::new(size).constrain(cts)]
- }
-}