summaryrefslogtreecommitdiff
path: root/src/layout
diff options
context:
space:
mode:
Diffstat (limited to 'src/layout')
-rw-r--r--src/layout/actions.rs6
-rw-r--r--src/layout/line.rs1
-rw-r--r--src/layout/mod.rs125
-rw-r--r--src/layout/model.rs82
-rw-r--r--src/layout/text.rs28
5 files changed, 131 insertions, 111 deletions
diff --git a/src/layout/actions.rs b/src/layout/actions.rs
index 1bf5d684..710d92b4 100644
--- a/src/layout/actions.rs
+++ b/src/layout/actions.rs
@@ -1,10 +1,12 @@
//! Drawing and cofiguration actions composing layouts.
+use std::io::{self, Write};
use std::fmt::{self, Display, Formatter};
use toddle::query::FontIndex;
-use super::*;
-use LayoutAction::*;
+use crate::size::{Size, Size2D};
+use super::{Layout, Serialize};
+use self::LayoutAction::*;
/// A layouting action.
diff --git a/src/layout/line.rs b/src/layout/line.rs
index f7777ae0..5e0839b1 100644
--- a/src/layout/line.rs
+++ b/src/layout/line.rs
@@ -1,3 +1,4 @@
+use super::stack::{StackLayouter, StackContext};
use super::*;
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 209874a1..f8074524 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -3,40 +3,26 @@
use std::io::{self, Write};
use std::fmt::{self, Display, Formatter};
use smallvec::SmallVec;
-use toddle::query::{SharedFontLoader, FontIndex};
+use toddle::query::FontIndex;
-use crate::error::Errors;
-use crate::syntax::{SyntaxModel, SpanVec};
use crate::size::{Size, Size2D, SizeBox};
-use crate::style::LayoutStyle;
+use self::{GenericAxis::*, SpecificAxis::*, Direction::*, Alignment::*};
-mod actions;
-mod model;
-mod line;
-mod stack;
-mod text;
+pub mod line;
+pub mod stack;
+pub mod text;
-/// Common types for layouting.
-pub mod prelude {
- pub use super::*;
- pub use GenericAxis::*;
- pub use SpecificAxis::*;
- pub use Direction::*;
- pub use Alignment::*;
-}
+pub_use_mod!(actions);
+pub_use_mod!(model);
-/// Different kinds of layouters (fully re-exported).
-pub mod layouters {
- pub use super::model::ModelLayouter;
- pub use super::line::{LineLayouter, LineContext};
- pub use super::stack::{StackLayouter, StackContext};
- pub use super::text::{layout_text, TextContext};
+pub mod prelude {
+ pub use super::{LayoutSpace, LayoutExpansion, LayoutAxes, LayoutAlignment};
+ pub use super::GenericAxis::{self, *};
+ pub use super::SpecificAxis::{self, *};
+ pub use super::Direction::{self, *};
+ pub use super::Alignment::{self, *};
}
-pub use self::actions::{LayoutAction, LayoutActions};
-pub use self::layouters::*;
-pub use self::prelude::*;
-
/// A collection of layouts.
pub type MultiLayout = Vec<Layout>;
@@ -67,49 +53,32 @@ impl Layout {
}
}
-/// The general context for layouting.
-#[derive(Debug, Clone)]
-pub struct LayoutContext<'a, 'p> {
- /// The font loader to retrieve fonts from when typesetting text
- /// using [`layout_text`].
- pub loader: &'a SharedFontLoader<'p>,
- /// The style for pages and text.
- pub style: &'a LayoutStyle,
- /// The base unpadded dimensions of this container (for relative sizing).
- pub base: Size2D,
- /// The spaces to layout in.
- pub spaces: LayoutSpaces,
- /// Whether to have repeated spaces or to use only the first and only once.
- pub repeat: bool,
- /// The initial axes along which content is laid out.
- pub axes: LayoutAxes,
- /// The alignment of the finished layout.
- pub alignment: LayoutAlignment,
- /// Whether the layout that is to be created will be nested in a parent
- /// container.
- pub nested: bool,
- /// Whether to debug render a box around the layout.
- pub debug: bool,
-}
-
-pub struct Layouted<T> {
- pub output: T,
- pub errors: Errors,
+/// Layout components that can be serialized.
+pub trait Serialize {
+ /// Serialize the data structure into an output writable.
+ fn serialize<W: Write>(&self, f: &mut W) -> io::Result<()>;
}
-impl<T> Layouted<T> {
- pub fn map<F, U>(self, f: F) -> Layouted<U> where F: FnOnce(T) -> U {
- Layouted {
- output: f(self.output),
- errors: self.errors,
+impl Serialize for Layout {
+ fn serialize<W: Write>(&self, f: &mut W) -> io::Result<()> {
+ writeln!(f, "{:.4} {:.4}", self.dimensions.x.to_pt(), self.dimensions.y.to_pt())?;
+ writeln!(f, "{}", self.actions.len())?;
+ for action in &self.actions {
+ action.serialize(f)?;
+ writeln!(f)?;
}
+ Ok(())
}
}
-pub async fn layout(model: &SyntaxModel, ctx: LayoutContext<'_, '_>) -> Layouted<MultiLayout> {
- let mut layouter = ModelLayouter::new(ctx);
- layouter.layout_syntax_model(model).await;
- layouter.finish()
+impl Serialize for MultiLayout {
+ fn serialize<W: Write>(&self, f: &mut W) -> io::Result<()> {
+ writeln!(f, "{}", self.len())?;
+ for layout in self {
+ layout.serialize(f)?;
+ }
+ Ok(())
+ }
}
/// A possibly stack-allocated vector of layout spaces.
@@ -405,31 +374,3 @@ impl LastSpacing {
}
}
}
-
-/// Layout components that can be serialized.
-pub trait Serialize {
- /// Serialize the data structure into an output writable.
- fn serialize<W: Write>(&self, f: &mut W) -> io::Result<()>;
-}
-
-impl Serialize for Layout {
- fn serialize<W: Write>(&self, f: &mut W) -> io::Result<()> {
- writeln!(f, "{:.4} {:.4}", self.dimensions.x.to_pt(), self.dimensions.y.to_pt())?;
- writeln!(f, "{}", self.actions.len())?;
- for action in &self.actions {
- action.serialize(f)?;
- writeln!(f)?;
- }
- Ok(())
- }
-}
-
-impl Serialize for MultiLayout {
- fn serialize<W: Write>(&self, f: &mut W) -> io::Result<()> {
- writeln!(f, "{}", self.len())?;
- for layout in self {
- layout.serialize(f)?;
- }
- Ok(())
- }
-}
diff --git a/src/layout/model.rs b/src/layout/model.rs
index 13d38083..2e61b453 100644
--- a/src/layout/model.rs
+++ b/src/layout/model.rs
@@ -1,9 +1,15 @@
+use std::future::Future;
+use std::pin::Pin;
use smallvec::smallvec;
+use toddle::query::SharedFontLoader;
use crate::error::Errors;
-use crate::func::Command;
-use crate::syntax::{Model, DynFuture, SyntaxModel, Node};
-use crate::syntax::{SpanVec, Spanned, Span, offset_spans};
+use crate::style::{LayoutStyle, PageStyle, TextStyle};
+use crate::size::{Size, Size2D};
+use crate::syntax::{Model, SyntaxModel, Node};
+use crate::syntax::span::{Spanned, Span, offset_spans};
+use super::line::{LineLayouter, LineContext};
+use super::text::{layout_text, TextContext};
use super::*;
@@ -15,6 +21,76 @@ pub struct ModelLayouter<'a, 'p> {
errors: Errors,
}
+/// The general context for layouting.
+#[derive(Debug, Clone)]
+pub struct LayoutContext<'a, 'p> {
+ /// The font loader to retrieve fonts from when typesetting text
+ /// using [`layout_text`].
+ pub loader: &'a SharedFontLoader<'p>,
+ /// The style for pages and text.
+ pub style: &'a LayoutStyle,
+ /// The base unpadded dimensions of this container (for relative sizing).
+ pub base: Size2D,
+ /// The spaces to layout in.
+ pub spaces: LayoutSpaces,
+ /// Whether to have repeated spaces or to use only the first and only once.
+ pub repeat: bool,
+ /// The initial axes along which content is laid out.
+ pub axes: LayoutAxes,
+ /// The alignment of the finished layout.
+ pub alignment: LayoutAlignment,
+ /// Whether the layout that is to be created will be nested in a parent
+ /// container.
+ pub nested: bool,
+ /// Whether to debug render a box around the layout.
+ pub debug: bool,
+}
+
+pub struct Layouted<T> {
+ pub output: T,
+ pub errors: Errors,
+}
+
+impl<T> Layouted<T> {
+ pub fn map<F, U>(self, f: F) -> Layouted<U> where F: FnOnce(T) -> U {
+ Layouted {
+ output: f(self.output),
+ errors: self.errors,
+ }
+ }
+}
+
+/// A sequence of layouting commands.
+pub type Commands<'a> = Vec<Command<'a>>;
+
+/// Layouting commands from functions to the typesetting engine.
+#[derive(Debug)]
+pub enum Command<'a> {
+ LayoutSyntaxModel(&'a SyntaxModel),
+
+ Add(Layout),
+ AddMultiple(MultiLayout),
+ AddSpacing(Size, SpacingKind, GenericAxis),
+
+ FinishLine,
+ FinishSpace,
+ BreakParagraph,
+ BreakPage,
+
+ SetTextStyle(TextStyle),
+ SetPageStyle(PageStyle),
+ SetAlignment(LayoutAlignment),
+ SetAxes(LayoutAxes),
+}
+
+pub async fn layout(model: &SyntaxModel, ctx: LayoutContext<'_, '_>) -> Layouted<MultiLayout> {
+ let mut layouter = ModelLayouter::new(ctx);
+ layouter.layout_syntax_model(model).await;
+ layouter.finish()
+}
+
+pub type DynFuture<'a, T> = Pin<Box<dyn Future<Output=T> + 'a>>;
+
impl<'a, 'p> ModelLayouter<'a, 'p> {
/// Create a new syntax tree layouter.
pub fn new(ctx: LayoutContext<'a, 'p>) -> ModelLayouter<'a, 'p> {
diff --git a/src/layout/text.rs b/src/layout/text.rs
index 16ae93da..eb598e2f 100644
--- a/src/layout/text.rs
+++ b/src/layout/text.rs
@@ -6,12 +6,14 @@ use crate::style::TextStyle;
use super::*;
-/// Layouts text into a box.
-///
-/// There is no complex layout involved. The text is simply laid out left-
-/// to-right using the correct font for each character.
-pub async fn layout_text(text: &str, ctx: TextContext<'_, '_>) -> Layout {
- TextLayouter::new(text, ctx).layout().await
+/// Layouts text into boxes.
+struct TextLayouter<'a, 'p> {
+ ctx: TextContext<'a, 'p>,
+ text: &'a str,
+ actions: LayoutActions,
+ buffer: String,
+ active_font: FontIndex,
+ width: Size,
}
/// The context for text layouting.
@@ -25,14 +27,12 @@ pub struct TextContext<'a, 'p> {
pub alignment: LayoutAlignment,
}
-/// Layouts text into boxes.
-struct TextLayouter<'a, 'p> {
- ctx: TextContext<'a, 'p>,
- text: &'a str,
- actions: LayoutActions,
- buffer: String,
- active_font: FontIndex,
- width: Size,
+/// Layouts text into a box.
+///
+/// There is no complex layout involved. The text is simply laid out left-
+/// to-right using the correct font for each character.
+pub async fn layout_text(text: &str, ctx: TextContext<'_, '_>) -> Layout {
+ TextLayouter::new(text, ctx).layout().await
}
impl<'a, 'p> TextLayouter<'a, 'p> {