summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-11-18 12:50:28 +0100
committerLaurenz <laurmaedje@gmail.com>2021-11-18 12:50:28 +0100
commit5a59bb48216352d04f78c9a9392ca7cef280d7b2 (patch)
tree463ec7ef40078df17ea79e018caa3e8943bffc94
parentb2e6a297893348a871fba8997017a9fc98d5674b (diff)
Page fill
-rw-r--r--src/eval/template.rs9
-rw-r--r--src/library/page.rs26
-rw-r--r--src/library/shape.rs1
-rw-r--r--src/style/mod.rs3
-rw-r--r--tests/ref/layout/page.pngbin6907 -> 5829 bytes
-rw-r--r--tests/typ/layout/page.typ22
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, &regions).into_iter().map(|c| c.item).collect()
+
+ // Layout the child.
+ let mut frames: Vec<_> =
+ self.child.layout(ctx, &regions).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
index 75ad00d1..dae3d488 100644
--- a/tests/ref/layout/page.png
+++ b/tests/ref/layout/page.png
Binary files differ
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