diff options
| author | Laurenz <laurmaedje@gmail.com> | 2023-02-12 16:40:00 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2023-02-12 16:40:00 +0100 |
| commit | 697ae1f925f1be80b34c1da697ba8db7327a6b61 (patch) | |
| tree | 21193e849497de236e5034a2ff01a94067c6cfec /library/src/layout/mod.rs | |
| parent | ebbee6274cafa6865a0d9123b78cae305c3c12aa (diff) | |
Extract regions into separate module
Diffstat (limited to 'library/src/layout/mod.rs')
| -rw-r--r-- | library/src/layout/mod.rs | 123 |
1 files changed, 2 insertions, 121 deletions
diff --git a/library/src/layout/mod.rs b/library/src/layout/mod.rs index 6c01759c..f603ef6c 100644 --- a/library/src/layout/mod.rs +++ b/library/src/layout/mod.rs @@ -14,6 +14,7 @@ mod pad; mod page; mod par; mod place; +mod regions; mod repeat; mod spacing; mod stack; @@ -34,6 +35,7 @@ pub use self::pad::*; pub use self::page::*; pub use self::par::*; pub use self::place::*; +pub use self::regions::*; pub use self::repeat::*; pub use self::spacing::*; pub use self::stack::*; @@ -45,7 +47,6 @@ use std::mem; use typed_arena::Arena; use typst::diag::SourceResult; -use typst::geom::*; use typst::model::{ applicable, capability, realize, Content, Node, SequenceNode, Style, StyleChain, StyleVecBuilder, StyledNode, @@ -147,126 +148,6 @@ impl Layout for Content { #[capability] pub trait Inline: Layout {} -/// A sequence of regions to layout into. -#[derive(Copy, Clone, Hash)] -pub struct Regions<'a> { - /// The (remaining) size of the first region. - pub first: Size, - /// The base size for relative sizing. - pub base: Size, - /// The height of followup regions. The width is the same for all regions. - pub backlog: &'a [Abs], - /// The height of the final region that is repeated once the backlog is - /// drained. The width is the same for all regions. - pub last: Option<Abs>, - /// Whether nodes should expand to fill the regions instead of shrinking to - /// fit the content. - pub expand: Axes<bool>, -} - -impl<'a> Regions<'a> { - /// Create a new region sequence with exactly one region. - pub fn one(size: Size, base: Size, expand: Axes<bool>) -> Self { - Self { - first: size, - base, - backlog: &[], - last: None, - expand, - } - } - - /// Create a new sequence of same-size regions that repeats indefinitely. - pub fn repeat(size: Size, base: Size, expand: Axes<bool>) -> Self { - Self { - first: size, - base, - backlog: &[], - last: Some(size.y), - expand, - } - } - - /// Create new regions where all sizes are mapped with `f`. - /// - /// Note that since all regions must have the same width, the width returned - /// by `f` is ignored for the backlog and the final region. - pub fn map<'v, F>(&self, backlog: &'v mut Vec<Abs>, mut f: F) -> Regions<'v> - where - F: FnMut(Size) -> Size, - { - let x = self.first.x; - backlog.clear(); - backlog.extend(self.backlog.iter().map(|&y| f(Size::new(x, y)).y)); - Regions { - first: f(self.first), - base: f(self.base), - backlog, - last: self.last.map(|y| f(Size::new(x, y)).y), - expand: self.expand, - } - } - - /// Whether the first region is full and a region break is called for. - pub fn is_full(&self) -> bool { - Abs::zero().fits(self.first.y) && !self.in_last() - } - - /// Whether the first region is the last usable region. - /// - /// If this is true, calling `next()` will have no effect. - pub fn in_last(&self) -> bool { - self.backlog.is_empty() && self.last.map_or(true, |height| self.first.y == height) - } - - /// Advance to the next region if there is any. - pub fn next(&mut self) { - if let Some(height) = self - .backlog - .split_first() - .map(|(first, tail)| { - self.backlog = tail; - *first - }) - .or(self.last) - { - self.first.y = height; - self.base.y = height; - } - } - - /// An iterator that returns the sizes of the first and all following - /// regions, equivalently to what would be produced by calling - /// [`next()`](Self::next) repeatedly until all regions are exhausted. - /// This iterator may be infinite. - pub fn iter(&self) -> impl Iterator<Item = Size> + '_ { - let first = std::iter::once(self.first); - let backlog = self.backlog.iter(); - let last = self.last.iter().cycle(); - first.chain(backlog.chain(last).map(|&h| Size::new(self.first.x, h))) - } -} - -impl Debug for Regions<'_> { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - f.write_str("Regions ")?; - let mut list = f.debug_list(); - let mut prev = self.first.y; - list.entry(&self.first); - for &height in self.backlog { - list.entry(&Size::new(self.first.x, height)); - prev = height; - } - if let Some(last) = self.last { - if last != prev { - list.entry(&Size::new(self.first.x, last)); - } - list.entry(&(..)); - } - list.finish() - } -} - /// Realize into a node that is capable of root-level layout. fn realize_root<'a>( vt: &mut Vt, |
