mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
Page fill
This commit is contained in:
parent
b2e6a29789
commit
5a59bb4821
@ -6,7 +6,7 @@ use std::ops::{Add, AddAssign};
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use crate::diag::StrResult;
|
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::layout::{Layout, PackedNode};
|
||||||
use crate::library::{
|
use crate::library::{
|
||||||
Decoration, DocumentNode, FlowChild, FlowNode, PageNode, ParChild, ParNode,
|
Decoration, DocumentNode, FlowChild, FlowNode, PageNode, ParChild, ParNode,
|
||||||
@ -384,6 +384,7 @@ impl Builder {
|
|||||||
struct PageBuilder {
|
struct PageBuilder {
|
||||||
size: Size,
|
size: Size,
|
||||||
padding: Sides<Linear>,
|
padding: Sides<Linear>,
|
||||||
|
fill: Option<Paint>,
|
||||||
hard: bool,
|
hard: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,15 +393,17 @@ impl PageBuilder {
|
|||||||
Self {
|
Self {
|
||||||
size: style.page.size,
|
size: style.page.size,
|
||||||
padding: style.page.margins(),
|
padding: style.page.margins(),
|
||||||
|
fill: style.page.fill,
|
||||||
hard,
|
hard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build(self, child: FlowNode, keep: bool) -> Option<PageNode> {
|
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 {
|
(!child.children.is_empty() || (keep && hard)).then(|| PageNode {
|
||||||
size,
|
|
||||||
child: child.pack().padded(padding),
|
child: child.pack().padded(padding),
|
||||||
|
size,
|
||||||
|
fill,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ pub fn page(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
|
|||||||
let right = args.named("right")?;
|
let right = args.named("right")?;
|
||||||
let bottom = args.named("bottom")?;
|
let bottom = args.named("bottom")?;
|
||||||
let flip = args.named("flip")?;
|
let flip = args.named("flip")?;
|
||||||
|
let fill = args.named("fill")?;
|
||||||
|
|
||||||
ctx.template.modify(move |style| {
|
ctx.template.modify(move |style| {
|
||||||
let page = style.page_mut();
|
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) {
|
if flip.unwrap_or(false) {
|
||||||
std::mem::swap(&mut page.size.w, &mut page.size.h);
|
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);
|
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.
|
/// Layouts its children onto one or multiple pages.
|
||||||
#[derive(Debug, Hash)]
|
#[derive(Debug, Hash)]
|
||||||
pub struct PageNode {
|
pub struct PageNode {
|
||||||
/// The size of the page.
|
|
||||||
pub size: Size,
|
|
||||||
/// The node that produces the actual pages.
|
/// The node that produces the actual pages.
|
||||||
pub child: PackedNode,
|
pub child: PackedNode,
|
||||||
|
/// The size of the page.
|
||||||
|
pub size: Size,
|
||||||
|
/// The background fill.
|
||||||
|
pub fill: Option<Paint>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PageNode {
|
impl PageNode {
|
||||||
@ -90,6 +97,19 @@ impl PageNode {
|
|||||||
// that axis.
|
// that axis.
|
||||||
let expand = self.size.to_spec().map(Length::is_finite);
|
let expand = self.size.to_spec().map(Length::is_finite);
|
||||||
let regions = Regions::repeat(self.size, self.size, expand);
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,6 +131,7 @@ impl Layout for ShapeNode {
|
|||||||
frames = node.layout(ctx, &pod);
|
frames = node.layout(ctx, &pod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: What if there are multiple or no frames?
|
||||||
// Extract the frame.
|
// Extract the frame.
|
||||||
Rc::take(frames.into_iter().next().unwrap().item)
|
Rc::take(frames.into_iter().next().unwrap().item)
|
||||||
} else {
|
} else {
|
||||||
|
@ -71,6 +71,8 @@ pub struct PageStyle {
|
|||||||
/// The amount of white space on each side of the page. If a side is set to
|
/// 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.
|
/// `None`, the default for the paper class is used.
|
||||||
pub margins: Sides<Option<Linear>>,
|
pub margins: Sides<Option<Linear>>,
|
||||||
|
/// The background fill of the page.
|
||||||
|
pub fill: Option<Paint>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PageStyle {
|
impl PageStyle {
|
||||||
@ -93,6 +95,7 @@ impl Default for PageStyle {
|
|||||||
class: paper.class(),
|
class: paper.class(),
|
||||||
size: paper.size(),
|
size: paper.size(),
|
||||||
margins: Sides::splat(None),
|
margins: Sides::splat(None),
|
||||||
|
fill: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 5.7 KiB |
@ -2,15 +2,15 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
// Set width and height.
|
// Set width and height.
|
||||||
#page(width: 120pt, height: 120pt)
|
#page(width: 80pt, height: 80pt)
|
||||||
[#page(width: 40pt) High]
|
[#page(width: 40pt) High]
|
||||||
[#page(height: 40pt) Wide]
|
[#page(height: 40pt) Wide]
|
||||||
|
|
||||||
// Set all margins at once.
|
// Set all margins at once.
|
||||||
[
|
[
|
||||||
#page(margins: 30pt)
|
#page(margins: 5pt)
|
||||||
#align(top, left)[TL]
|
#place(top, left)[TL]
|
||||||
#align(bottom, right)[BR]
|
#place(bottom, right)[BR]
|
||||||
]
|
]
|
||||||
|
|
||||||
// Set individual margins.
|
// Set individual margins.
|
||||||
@ -26,15 +26,10 @@
|
|||||||
// Flipped predefined paper.
|
// Flipped predefined paper.
|
||||||
[#page(paper: "a11", flip: true) Flipped A11]
|
[#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.
|
// Test a combination of pages with bodies and normal content.
|
||||||
|
|
||||||
#page(height: 50pt)
|
#page(width: 80pt, height: 30pt)
|
||||||
|
|
||||||
[#page() First]
|
[#page() First]
|
||||||
[#page() Second]
|
[#page() Second]
|
||||||
@ -43,4 +38,9 @@ Wide
|
|||||||
Fourth
|
Fourth
|
||||||
[#page(height: 25pt)]
|
[#page(height: 25pt)]
|
||||||
Sixth
|
Sixth
|
||||||
[#page() Seventh and last]
|
[#page() Seventh]
|
||||||
|
|
||||||
|
---
|
||||||
|
#page(width: 80pt, height: 40pt, fill: eastern)
|
||||||
|
#font(15pt, "Roboto", fill: white, smallcaps: true)
|
||||||
|
Typst
|
||||||
|
Loading…
x
Reference in New Issue
Block a user