diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-11-18 12:50:28 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-11-18 12:50:28 +0100 |
| commit | 5a59bb48216352d04f78c9a9392ca7cef280d7b2 (patch) | |
| tree | 463ec7ef40078df17ea79e018caa3e8943bffc94 | |
| parent | b2e6a297893348a871fba8997017a9fc98d5674b (diff) | |
Page fill
| -rw-r--r-- | src/eval/template.rs | 9 | ||||
| -rw-r--r-- | src/library/page.rs | 26 | ||||
| -rw-r--r-- | src/library/shape.rs | 1 | ||||
| -rw-r--r-- | src/style/mod.rs | 3 | ||||
| -rw-r--r-- | tests/ref/layout/page.png | bin | 6907 -> 5829 bytes | |||
| -rw-r--r-- | tests/typ/layout/page.typ | 22 |
6 files changed, 44 insertions, 17 deletions
diff --git a/src/eval/template.rs b/src/eval/template.rs index 7801dc79..307bff2a 100644 --- a/src/eval/template.rs +++ b/src/eval/template.rs @@ -6,7 +6,7 @@ use std::ops::{Add, AddAssign}; use std::rc::Rc; use crate::diag::StrResult; -use crate::geom::{Align, Dir, GenAxis, Length, Linear, Sides, Size}; +use crate::geom::{Align, Dir, GenAxis, Length, Linear, Paint, Sides, Size}; use crate::layout::{Layout, PackedNode}; use crate::library::{ Decoration, DocumentNode, FlowChild, FlowNode, PageNode, ParChild, ParNode, @@ -384,6 +384,7 @@ impl Builder { struct PageBuilder { size: Size, padding: Sides<Linear>, + fill: Option<Paint>, hard: bool, } @@ -392,15 +393,17 @@ impl PageBuilder { Self { size: style.page.size, padding: style.page.margins(), + fill: style.page.fill, hard, } } fn build(self, child: FlowNode, keep: bool) -> Option<PageNode> { - let Self { size, padding, hard } = self; + let Self { size, padding, fill, hard } = self; (!child.children.is_empty() || (keep && hard)).then(|| PageNode { - size, child: child.pack().padded(padding), + size, + fill, }) } } diff --git a/src/library/page.rs b/src/library/page.rs index a5935002..6642de16 100644 --- a/src/library/page.rs +++ b/src/library/page.rs @@ -18,6 +18,7 @@ pub fn page(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> { let right = args.named("right")?; let bottom = args.named("bottom")?; let flip = args.named("flip")?; + let fill = args.named("fill")?; ctx.template.modify(move |style| { let page = style.page_mut(); @@ -60,6 +61,10 @@ pub fn page(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> { if flip.unwrap_or(false) { std::mem::swap(&mut page.size.w, &mut page.size.h); } + + if let Some(fill) = fill { + page.fill = Some(Paint::Color(fill)); + } }); ctx.template.pagebreak(false); @@ -77,10 +82,12 @@ pub fn pagebreak(_: &mut EvalContext, _: &mut Args) -> TypResult<Value> { /// Layouts its children onto one or multiple pages. #[derive(Debug, Hash)] pub struct PageNode { - /// The size of the page. - pub size: Size, /// The node that produces the actual pages. pub child: PackedNode, + /// The size of the page. + pub size: Size, + /// The background fill. + pub fill: Option<Paint>, } impl PageNode { @@ -90,6 +97,19 @@ impl PageNode { // that axis. let expand = self.size.to_spec().map(Length::is_finite); let regions = Regions::repeat(self.size, self.size, expand); - self.child.layout(ctx, ®ions).into_iter().map(|c| c.item).collect() + + // Layout the child. + let mut frames: Vec<_> = + self.child.layout(ctx, ®ions).into_iter().map(|c| c.item).collect(); + + // Add background fill if requested. + if let Some(fill) = self.fill { + for frame in &mut frames { + let element = Element::Geometry(Geometry::Rect(frame.size), fill); + Rc::make_mut(frame).prepend(Point::zero(), element) + } + } + + frames } } diff --git a/src/library/shape.rs b/src/library/shape.rs index 7c543958..d0df5f48 100644 --- a/src/library/shape.rs +++ b/src/library/shape.rs @@ -131,6 +131,7 @@ impl Layout for ShapeNode { frames = node.layout(ctx, &pod); } + // TODO: What if there are multiple or no frames? // Extract the frame. Rc::take(frames.into_iter().next().unwrap().item) } else { diff --git a/src/style/mod.rs b/src/style/mod.rs index 9cf2de07..4588163b 100644 --- a/src/style/mod.rs +++ b/src/style/mod.rs @@ -71,6 +71,8 @@ pub struct PageStyle { /// The amount of white space on each side of the page. If a side is set to /// `None`, the default for the paper class is used. pub margins: Sides<Option<Linear>>, + /// The background fill of the page. + pub fill: Option<Paint>, } impl PageStyle { @@ -93,6 +95,7 @@ impl Default for PageStyle { class: paper.class(), size: paper.size(), margins: Sides::splat(None), + fill: None, } } } diff --git a/tests/ref/layout/page.png b/tests/ref/layout/page.png Binary files differindex 75ad00d1..dae3d488 100644 --- a/tests/ref/layout/page.png +++ b/tests/ref/layout/page.png diff --git a/tests/typ/layout/page.typ b/tests/typ/layout/page.typ index 1d2fdb62..9bb3097d 100644 --- a/tests/typ/layout/page.typ +++ b/tests/typ/layout/page.typ @@ -2,15 +2,15 @@ --- // Set width and height. -#page(width: 120pt, height: 120pt) +#page(width: 80pt, height: 80pt) [#page(width: 40pt) High] [#page(height: 40pt) Wide] // Set all margins at once. [ - #page(margins: 30pt) - #align(top, left)[TL] - #align(bottom, right)[BR] + #page(margins: 5pt) + #place(top, left)[TL] + #place(bottom, right)[BR] ] // Set individual margins. @@ -26,15 +26,10 @@ // Flipped predefined paper. [#page(paper: "a11", flip: true) Flipped A11] -// Flipped custom page size. -#page(width: 40pt, height: 120pt) -#page(flip: true) -Wide - --- // Test a combination of pages with bodies and normal content. -#page(height: 50pt) +#page(width: 80pt, height: 30pt) [#page() First] [#page() Second] @@ -43,4 +38,9 @@ Wide Fourth [#page(height: 25pt)] Sixth -[#page() Seventh and last] +[#page() Seventh] + +--- +#page(width: 80pt, height: 40pt, fill: eastern) +#font(15pt, "Roboto", fill: white, smallcaps: true) +Typst |
