summaryrefslogtreecommitdiff
path: root/src/layout
diff options
context:
space:
mode:
Diffstat (limited to 'src/layout')
-rw-r--r--src/layout/flex.rs18
-rw-r--r--src/layout/mod.rs47
-rw-r--r--src/layout/stack.rs (renamed from src/layout/stacked.rs)2
-rw-r--r--src/layout/text.rs2
-rw-r--r--src/layout/tree.rs36
5 files changed, 29 insertions, 76 deletions
diff --git a/src/layout/flex.rs b/src/layout/flex.rs
index 053954a4..53f6dfdf 100644
--- a/src/layout/flex.rs
+++ b/src/layout/flex.rs
@@ -126,20 +126,8 @@ impl FlexLayouter {
}
}
- pub fn remaining(&self) -> LayoutResult<(LayoutSpaces, Option<LayoutSpaces>)> {
- if self.run_is_empty() {
- Ok((self.stack.remaining(), None))
- } else {
- let mut future = self.clone();
- let remaining_run = future.finish_run()?;
-
- let stack_spaces = future.stack.remaining();
- let mut flex_spaces = stack_spaces.clone();
- flex_spaces[0].dimensions.x = remaining_run.x;
- flex_spaces[0].dimensions.y += remaining_run.y;
-
- Ok((flex_spaces, Some(stack_spaces)))
- }
+ pub fn remaining(&self) -> LayoutSpaces {
+ self.stack.remaining()
}
pub fn run_is_empty(&self) -> bool {
@@ -242,7 +230,7 @@ impl FlexLayouter {
while size.x > self.line.usable {
if self.stack.space_is_last() {
- Err(LayoutError::NotEnoughSpace("failed to add box to flex run"))?;
+ lerr!("box does not fit into line");
}
self.stack.finish_space(true);
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 2e643295..cd4986d9 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -15,14 +15,14 @@ use crate::syntax::{FuncCall, Node, SyntaxTree};
mod actions;
mod tree;
mod flex;
-mod stacked;
+mod stack;
mod text;
/// Different kinds of layouters (fully re-exported).
pub mod layouters {
pub use super::tree::layout_tree;
pub use super::flex::{FlexLayouter, FlexContext};
- pub use super::stacked::{StackLayouter, StackContext};
+ pub use super::stack::{StackLayouter, StackContext};
pub use super::text::{layout_text, TextContext};
}
@@ -130,23 +130,17 @@ pub struct LayoutContext<'a, 'p> {
/// The font loader to retrieve fonts from when typesetting text
/// using [`layout_text`].
pub loader: &'a SharedFontLoader<'p>,
-
/// Whether this layouting process handles the top-level pages.
pub top_level: bool,
-
/// The style to set text with. This includes sizes and font classes
/// which determine which font from the loaders selection is used.
pub text_style: &'a TextStyle,
-
/// The current size and margins of the top-level pages.
pub page_style: PageStyle,
-
/// The spaces to layout in.
pub spaces: LayoutSpaces,
-
/// The axes to flow on.
pub axes: LayoutAxes,
-
/// Whether layouts should expand to the full dimensions of the space
/// they lie on or whether should tightly fit the content.
pub expand: bool,
@@ -160,7 +154,6 @@ pub type LayoutSpaces = SmallVec<[LayoutSpace; 2]>;
pub struct LayoutSpace {
/// The maximum size of the box to layout in.
pub dimensions: Size2D,
-
/// Padding that should be respected on each side.
pub padding: SizeBox,
}
@@ -331,35 +324,21 @@ impl SpaceState {
}
/// The error type for layouting.
-pub enum LayoutError {
- /// An action is unallowed in the active context.
- Unallowed(&'static str),
- /// A specifier or operation is invalid for the given axis.
- UnalignedAxis(&'static str),
- /// There is not enough space to add an item.
- NotEnoughSpace(&'static str),
- /// There was no suitable font for the given character.
- NoSuitableFont(char),
- /// An error occured while gathering font data.
- Font(FontError),
-}
+pub struct LayoutError(String);
/// The result type for layouting.
pub type LayoutResult<T> = Result<T, LayoutError>;
+impl LayoutError {
+ /// Create a new layout error with a message.
+ pub fn new<S: Into<String>>(message: S) -> LayoutError {
+ LayoutError(message.into())
+ }
+}
+
error_type! {
err: LayoutError,
- show: f => match err {
- LayoutError::Unallowed(desc) => write!(f, "unallowed: {}", desc),
- LayoutError::UnalignedAxis(desc) => write!(f, "unaligned axis: {}", desc),
- LayoutError::NotEnoughSpace(desc) => write!(f, "not enough space: {}", desc),
- LayoutError::NoSuitableFont(c) => write!(f, "no suitable font for '{}'", c),
- LayoutError::Font(err) => write!(f, "font error: {}", err),
- },
- source: match err {
- LayoutError::Font(err) => Some(err),
- _ => None,
- },
- from: (std::io::Error, LayoutError::Font(FontError::Io(err))),
- from: (FontError, LayoutError::Font(err)),
+ show: f => f.write_str(&err.0),
+ from: (std::io::Error, LayoutError::new(err.to_string())),
+ from: (FontError, LayoutError::new(err.to_string())),
}
diff --git a/src/layout/stacked.rs b/src/layout/stack.rs
index 2e128a5f..f46c3da0 100644
--- a/src/layout/stacked.rs
+++ b/src/layout/stack.rs
@@ -95,7 +95,7 @@ impl StackLayouter {
while !self.sub.usable.fits(new_dimensions) {
if self.space_is_last() && self.space_is_empty() {
- Err(LayoutError::NotEnoughSpace("failed to add box to stack"))?;
+ lerr!("box does not fit into stack");
}
self.finish_space(true);
diff --git a/src/layout/text.rs b/src/layout/text.rs
index fc7cd385..66ff75fd 100644
--- a/src/layout/text.rs
+++ b/src/layout/text.rs
@@ -114,6 +114,6 @@ impl<'a, 'p> TextLayouter<'a, 'p> {
self.classes.pop();
}
- Err(LayoutError::NoSuitableFont(c))
+ lerr!("no suitable font for character `{}`", c);
}
}
diff --git a/src/layout/tree.rs b/src/layout/tree.rs
index f5ae2435..56fb120c 100644
--- a/src/layout/tree.rs
+++ b/src/layout/tree.rs
@@ -66,34 +66,20 @@ impl<'a, 'p> TreeLayouter<'a, 'p> {
}
fn layout_func(&mut self, func: &FuncCall) -> LayoutResult<()> {
- let (first, second) = self.flex.remaining()?;
+ let spaces = self.flex.remaining();
let mut axes = self.ctx.axes.expanding(false);
axes.secondary.alignment = Alignment::Origin;
- let ctx = |spaces| {
- LayoutContext {
- loader: self.ctx.loader,
- top_level: false,
- text_style: &self.style,
- page_style: self.ctx.page_style,
- spaces,
- axes,
- expand: false,
- }
- };
-
- let commands = match func.body.val.layout(ctx(first)) {
- Ok(c) => c,
- Err(e) => {
- match (e, second) {
- (LayoutError::NotEnoughSpace(_), Some(space)) => {
- func.body.val.layout(ctx(space))?
- }
- (e, _) => Err(e)?,
- }
- }
- };
+ let commands = func.body.val.layout(LayoutContext {
+ loader: self.ctx.loader,
+ top_level: false,
+ text_style: &self.style,
+ page_style: self.ctx.page_style,
+ spaces,
+ axes,
+ expand: false,
+ })?;
for command in commands {
self.execute(command)?;
@@ -123,7 +109,7 @@ impl<'a, 'p> TreeLayouter<'a, 'p> {
Command::SetTextStyle(style) => self.style = style,
Command::SetPageStyle(style) => {
if !self.ctx.top_level {
- Err(LayoutError::Unallowed("can only set page style from top level"))?;
+ lerr!("page style cannot only be altered in the top-level context");
}
self.ctx.page_style = style;