summaryrefslogtreecommitdiff
path: root/src/layout/mod.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-08-19 15:31:29 +0200
committerLaurenz <laurmaedje@gmail.com>2021-08-19 15:52:15 +0200
commita6f260ca39f70f82617eca87855789413715f47d (patch)
tree08141ae619bd21e0544d21433bce759aebc7ba83 /src/layout/mod.rs
parentfdab7158c91c52a4ace211c804fdd8e9110f56de (diff)
Refactor layouting a bit
Notably: - Handle aspect ratio in fixed node - Inline constraint inflation into pad node
Diffstat (limited to 'src/layout/mod.rs')
-rw-r--r--src/layout/mod.rs113
1 files changed, 10 insertions, 103 deletions
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 9700004d..96bd7e7e 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -10,6 +10,7 @@ mod image;
mod incremental;
mod pad;
mod par;
+mod regions;
mod shaping;
mod stack;
mod tree;
@@ -24,13 +25,11 @@ pub use grid::*;
pub use incremental::*;
pub use pad::*;
pub use par::*;
+pub use regions::*;
pub use shaping::*;
pub use stack::*;
pub use tree::*;
-use std::hash::Hash;
-#[cfg(feature = "layout-cache")]
-use std::hash::Hasher;
use std::rc::Rc;
use crate::font::FontStore;
@@ -45,16 +44,6 @@ pub fn layout(ctx: &mut Context, tree: &LayoutTree) -> Vec<Rc<Frame>> {
tree.layout(&mut ctx)
}
-/// Layout a node.
-pub trait Layout {
- /// Layout the node into the given regions.
- fn layout(
- &self,
- ctx: &mut LayoutContext,
- regions: &Regions,
- ) -> Vec<Constrained<Rc<Frame>>>;
-}
-
/// The context for layouting.
pub struct LayoutContext<'a> {
/// Stores parsed font faces.
@@ -83,94 +72,12 @@ impl<'a> LayoutContext<'a> {
}
}
-/// A sequence of regions to layout into.
-#[derive(Debug, Clone, Eq, PartialEq)]
-pub struct Regions {
- /// The remaining size of the current region.
- pub current: Size,
- /// The base size for relative sizing.
- pub base: Size,
- /// A stack of followup regions.
- ///
- /// Note that this is a stack and not a queue! The size of the next region is
- /// `backlog.last()`.
- pub backlog: Vec<Size>,
- /// The final region that is repeated once the backlog is drained.
- pub last: Option<Size>,
- /// Whether nodes should expand to fill the regions instead of shrinking to
- /// fit the content.
- ///
- /// This property is only handled by nodes that have the ability to control
- /// their own size.
- pub expand: Spec<bool>,
-}
-
-impl Regions {
- /// Create a new region sequence with exactly one region.
- pub fn one(size: Size, expand: Spec<bool>) -> Self {
- Self {
- current: size,
- base: size,
- backlog: vec![],
- last: None,
- expand,
- }
- }
-
- /// Create a new sequence of same-size regions that repeats indefinitely.
- pub fn repeat(size: Size, expand: Spec<bool>) -> Self {
- Self {
- current: size,
- base: size,
- backlog: vec![],
- last: Some(size),
- expand,
- }
- }
-
- /// Create new regions where all sizes are mapped with `f`.
- pub fn map<F>(&self, mut f: F) -> Self
- where
- F: FnMut(Size) -> Size,
- {
- let mut regions = self.clone();
- regions.mutate(|s| *s = f(*s));
- regions
- }
-
- /// Whether `current` is a fully sized (untouched) copy of the last region.
- ///
- /// If this is true, calling `next()` will have no effect.
- pub fn in_full_last(&self) -> bool {
- self.backlog.is_empty() && self.last.map_or(true, |size| self.current == size)
- }
-
- /// An iterator that returns pairs of `(current, base)` that are equivalent
- /// to what would be produced by calling [`next()`](Self::next) repeatedly
- /// until all regions are exhausted.
- pub fn iter(&self) -> impl Iterator<Item = (Size, Size)> + '_ {
- let first = std::iter::once((self.current, self.base));
- let backlog = self.backlog.iter().rev();
- let last = self.last.iter().cycle();
- first.chain(backlog.chain(last).map(|&s| (s, s)))
- }
-
- /// Advance to the next region if there is any.
- pub fn next(&mut self) {
- if let Some(size) = self.backlog.pop().or(self.last) {
- self.current = size;
- self.base = size;
- }
- }
-
- /// Mutate all contained sizes in place.
- pub fn mutate<F>(&mut self, mut f: F)
- where
- F: FnMut(&mut Size),
- {
- f(&mut self.current);
- f(&mut self.base);
- self.last.as_mut().map(|x| f(x));
- self.backlog.iter_mut().for_each(f);
- }
+/// Layout a node.
+pub trait Layout {
+ /// Layout the node into the given regions.
+ fn layout(
+ &self,
+ ctx: &mut LayoutContext,
+ regions: &Regions,
+ ) -> Vec<Constrained<Rc<Frame>>>;
}