summaryrefslogtreecommitdiff
path: root/src/layout
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2020-07-29 18:09:51 +0200
committerLaurenz <laurmaedje@gmail.com>2020-07-29 18:09:51 +0200
commitbbcdeb128cce04cd95714b7bc7af5a23a7e38bd2 (patch)
treee0a1620d335982669cd7671cbd71df46d100e9ea /src/layout
parentf34ba3dcda182d9b9c14cc94fdb48810bf18bef0 (diff)
Move, rename and switch some things (boring) 🚚
- Problems -> Diagnostics - Position -> Pos - offset_spans -> Offset trait - Size -> Length (and some more size types renamed) - Paper into its own module - scope::Parser -> parsing::CallParser - Create `Decorations` alias - Remove lots of double newlines - Switch from f32 to f64
Diffstat (limited to 'src/layout')
-rw-r--r--src/layout/actions.rs23
-rw-r--r--src/layout/line.rs25
-rw-r--r--src/layout/mod.rs25
-rw-r--r--src/layout/model.rs9
-rw-r--r--src/layout/stack.rs51
-rw-r--r--src/layout/text.rs17
6 files changed, 72 insertions, 78 deletions
diff --git a/src/layout/actions.rs b/src/layout/actions.rs
index 8b50edfa..317cff25 100644
--- a/src/layout/actions.rs
+++ b/src/layout/actions.rs
@@ -4,23 +4,22 @@ use std::fmt::{self, Debug, Formatter};
use serde::ser::{Serialize, Serializer, SerializeTuple};
use toddle::query::FontIndex;
-use crate::size::{Size, Size2D};
+use crate::length::{Length, Size};
use super::Layout;
use self::LayoutAction::*;
-
/// A layouting action, which is the basic building block layouts are composed
/// of.
#[derive(Clone, PartialEq)]
pub enum LayoutAction {
/// Move to an absolute position.
- MoveAbsolute(Size2D),
+ MoveAbsolute(Size),
/// Set the font given the index from the font loader and font size.
- SetFont(FontIndex, Size),
+ SetFont(FontIndex, Length),
/// Write text at the current position.
WriteText(String),
/// Visualize a box for debugging purposes.
- DebugBox(Size2D),
+ DebugBox(Size),
}
impl Serialize for LayoutAction {
@@ -81,11 +80,11 @@ impl Debug for LayoutAction {
/// position.
#[derive(Debug, Clone, PartialEq)]
pub struct LayoutActions {
- origin: Size2D,
+ origin: Size,
actions: Vec<LayoutAction>,
- active_font: (FontIndex, Size),
- next_pos: Option<Size2D>,
- next_font: Option<(FontIndex, Size)>,
+ active_font: (FontIndex, Length),
+ next_pos: Option<Size>,
+ next_font: Option<(FontIndex, Length)>,
}
impl LayoutActions {
@@ -93,8 +92,8 @@ impl LayoutActions {
pub fn new() -> LayoutActions {
LayoutActions {
actions: vec![],
- origin: Size2D::ZERO,
- active_font: (FontIndex::MAX, Size::ZERO),
+ origin: Size::ZERO,
+ active_font: (FontIndex::MAX, Length::ZERO),
next_pos: None,
next_font: None,
}
@@ -126,7 +125,7 @@ impl LayoutActions {
/// Add a layout at a position. All move actions inside the layout are
/// translated by the position.
- pub fn add_layout(&mut self, position: Size2D, layout: Layout) {
+ pub fn add_layout(&mut self, position: Size, layout: Layout) {
self.flush_position();
self.origin = position;
diff --git a/src/layout/line.rs b/src/layout/line.rs
index 18ace29f..1bb36204 100644
--- a/src/layout/line.rs
+++ b/src/layout/line.rs
@@ -11,7 +11,6 @@
use super::stack::{StackLayouter, StackContext};
use super::*;
-
/// Performs the line layouting.
#[derive(Debug)]
pub struct LineLayouter {
@@ -40,7 +39,7 @@ pub struct LineContext {
/// extent of the layout.
pub debug: bool,
/// The line spacing.
- pub line_spacing: Size,
+ pub line_spacing: Length,
}
/// A line run is a sequence of boxes with the same alignment that are arranged
@@ -49,10 +48,10 @@ pub struct LineContext {
#[derive(Debug)]
struct LineRun {
/// The so-far accumulated layouts in the line.
- layouts: Vec<(Size, Layout)>,
- /// The width (primary size) and maximal height (secondary size) of the
+ layouts: Vec<(Length, Layout)>,
+ /// The width (primary length) and maximal height (secondary length) of the
/// line.
- size: Size2D,
+ size: Size,
/// The alignment of all layouts in the line.
///
/// When a new run is created the alignment is yet to be determined. Once a
@@ -61,7 +60,7 @@ struct LineRun {
alignment: Option<LayoutAlignment>,
/// If another line run with different alignment already took up some space
/// of the line, this run has less space and how much is stored here.
- usable: Option<Size>,
+ usable: Option<Length>,
/// A possibly cached soft spacing or spacing state.
last_spacing: LastSpacing,
}
@@ -156,7 +155,7 @@ impl LineLayouter {
///
/// This specifies how much more fits before a line break needs to be
/// issued.
- fn usable(&self) -> Size2D {
+ fn usable(&self) -> Size {
// The base is the usable space per stack layouter.
let mut usable = self.stack.usable().generalized(self.ctx.axes);
@@ -171,7 +170,7 @@ impl LineLayouter {
}
/// Add spacing along the primary axis to the line.
- pub fn add_primary_spacing(&mut self, mut spacing: Size, kind: SpacingKind) {
+ pub fn add_primary_spacing(&mut self, mut spacing: Length, kind: SpacingKind) {
match kind {
// A hard space is simply an empty box.
SpacingKind::Hard => {
@@ -197,7 +196,7 @@ impl LineLayouter {
}
/// Finish the line and add secondary spacing to the underlying stack.
- pub fn add_secondary_spacing(&mut self, spacing: Size, kind: SpacingKind) {
+ pub fn add_secondary_spacing(&mut self, spacing: Length, kind: SpacingKind) {
self.finish_line_if_not_empty();
self.stack.add_spacing(spacing, kind)
}
@@ -219,7 +218,7 @@ impl LineLayouter {
}
/// Update the line spacing.
- pub fn set_line_spacing(&mut self, line_spacing: Size) {
+ pub fn set_line_spacing(&mut self, line_spacing: Length) {
self.ctx.line_spacing = line_spacing;
}
@@ -235,7 +234,7 @@ impl LineLayouter {
/// Whether the currently set line is empty.
pub fn line_is_empty(&self) -> bool {
- self.run.size == Size2D::ZERO && self.run.layouts.is_empty()
+ self.run.size == Size::ZERO && self.run.layouts.is_empty()
}
/// Finish the last line and compute the final list of boxes.
@@ -265,7 +264,7 @@ impl LineLayouter {
- layout.dimensions.primary(self.ctx.axes),
};
- let pos = Size2D::with_x(x);
+ let pos = Size::with_x(x);
actions.add_layout(pos, layout);
}
@@ -293,7 +292,7 @@ impl LineRun {
fn new() -> LineRun {
LineRun {
layouts: vec![],
- size: Size2D::ZERO,
+ size: Size::ZERO,
alignment: None,
usable: None,
last_spacing: LastSpacing::Hard,
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 01d402db..4863d554 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -5,7 +5,7 @@ use smallvec::SmallVec;
use serde::Serialize;
use toddle::query::FontIndex;
-use crate::size::{Size, Size2D, SizeBox};
+use crate::length::{Length, Size, Margins};
use self::prelude::*;
pub mod line;
@@ -27,7 +27,6 @@ pub mod prelude {
pub use super::Alignment::{self, *};
}
-
/// A collection of layouts.
pub type MultiLayout = Vec<Layout>;
@@ -35,7 +34,7 @@ pub type MultiLayout = Vec<Layout>;
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct Layout {
/// The size of the box.
- pub dimensions: Size2D,
+ pub dimensions: Size,
/// How to align this layout in a parent container.
#[serde(skip)]
pub alignment: LayoutAlignment,
@@ -66,9 +65,9 @@ pub type LayoutSpaces = SmallVec<[LayoutSpace; 2]>;
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct LayoutSpace {
/// The maximum size of the box to layout in.
- pub dimensions: Size2D,
+ pub dimensions: Size,
/// Padding that should be respected on each side.
- pub padding: SizeBox,
+ pub padding: Margins,
/// Whether to expand the dimensions of the resulting layout to the full
/// dimensions of this space or to shrink them to fit the content.
pub expansion: LayoutExpansion,
@@ -77,12 +76,12 @@ pub struct LayoutSpace {
impl LayoutSpace {
/// The offset from the origin to the start of content, that is,
/// `(padding.left, padding.top)`.
- pub fn start(&self) -> Size2D {
- Size2D::new(self.padding.left, self.padding.top)
+ pub fn start(&self) -> Size {
+ Size::new(self.padding.left, self.padding.top)
}
/// The actually usable area (dimensions minus padding).
- pub fn usable(&self) -> Size2D {
+ pub fn usable(&self) -> Size {
self.dimensions.unpadded(self.padding)
}
@@ -90,7 +89,7 @@ impl LayoutSpace {
pub fn usable_space(&self) -> LayoutSpace {
LayoutSpace {
dimensions: self.usable(),
- padding: SizeBox::ZERO,
+ padding: Margins::ZERO,
expansion: LayoutExpansion::new(false, false),
}
}
@@ -369,17 +368,17 @@ enum LastSpacing {
/// The last item was hard spacing.
Hard,
/// The last item was soft spacing with the given width and level.
- Soft(Size, u32),
+ Soft(Length, u32),
/// The last item was not spacing.
None,
}
impl LastSpacing {
- /// The size of the soft space if this is a soft space or zero otherwise.
- fn soft_or_zero(self) -> Size {
+ /// The length of the soft space if this is a soft space or zero otherwise.
+ fn soft_or_zero(self) -> Length {
match self {
LastSpacing::Soft(space, _) => space,
- _ => Size::ZERO,
+ _ => Length::ZERO,
}
}
}
diff --git a/src/layout/model.rs b/src/layout/model.rs
index 91d21037..a15598d2 100644
--- a/src/layout/model.rs
+++ b/src/layout/model.rs
@@ -10,14 +10,13 @@ use toddle::query::FontStyle;
use crate::{Pass, Feedback};
use crate::GlobalFontLoader;
use crate::style::{LayoutStyle, PageStyle, TextStyle};
-use crate::size::{Size, Size2D};
+use crate::length::{Length, Size};
use crate::syntax::{Model, SyntaxModel, Node, Decoration};
use crate::syntax::span::{Span, Spanned};
use super::line::{LineLayouter, LineContext};
use super::text::{layout_text, TextContext};
use super::*;
-
/// Performs the model layouting.
#[derive(Debug)]
pub struct ModelLayouter<'a> {
@@ -36,7 +35,7 @@ pub struct LayoutContext<'a> {
/// The style for pages and text.
pub style: &'a LayoutStyle,
/// The base unpadded dimensions of this container (for relative sizing).
- pub base: Size2D,
+ pub base: Size,
/// The spaces to layout in.
pub spaces: LayoutSpaces,
/// Whether to have repeated spaces or to use only the first and only once.
@@ -76,7 +75,7 @@ pub enum Command<'a> {
/// Add spacing of given [kind](super::SpacingKind) along the primary or
/// secondary axis. The spacing kind defines how the spacing interacts with
/// surrounding spacing.
- AddSpacing(Size, SpacingKind, GenericAxis),
+ AddSpacing(Length, SpacingKind, GenericAxis),
/// Start a new line.
BreakLine,
@@ -159,7 +158,7 @@ impl<'a> ModelLayouter<'a> {
for Spanned { v: node, span } in &model.nodes {
let decorate = |this: &mut ModelLayouter, deco| {
- this.feedback.decos.push(Spanned::new(deco, *span));
+ this.feedback.decorations.push(Spanned::new(deco, *span));
};
match node {
diff --git a/src/layout/stack.rs b/src/layout/stack.rs
index 891815e9..20d99fa6 100644
--- a/src/layout/stack.rs
+++ b/src/layout/stack.rs
@@ -22,10 +22,9 @@
//! sentence in the second box.
use smallvec::smallvec;
-use crate::size::ValueBox;
+use crate::length::Value4;
use super::*;
-
/// Performs the stack layouting.
#[derive(Debug)]
pub struct StackLayouter {
@@ -66,14 +65,14 @@ struct Space {
/// The so-far accumulated layouts.
layouts: Vec<(LayoutAxes, Layout)>,
/// The specialized size of this space.
- size: Size2D,
+ size: Size,
/// The specialized remaining space.
- usable: Size2D,
+ usable: Size,
/// The specialized extra-needed dimensions to affect the size at all.
- extra: Size2D,
+ extra: Size,
/// The rulers of a space dictate which alignments for new boxes are still
/// allowed and which require a new space to be started.
- rulers: ValueBox<Alignment>,
+ rulers: Value4<Alignment>,
/// The last added spacing if the last added thing was spacing.
last_spacing: LastSpacing,
}
@@ -129,13 +128,13 @@ impl StackLayouter {
}
/// Add secondary spacing to the stack.
- pub fn add_spacing(&mut self, mut spacing: Size, kind: SpacingKind) {
+ pub fn add_spacing(&mut self, mut spacing: Length, kind: SpacingKind) {
match kind {
// A hard space is simply an empty box.
SpacingKind::Hard => {
// Reduce the spacing such that it definitely fits.
spacing.min_eq(self.space.usable.secondary(self.ctx.axes));
- let dimensions = Size2D::with_y(spacing);
+ let dimensions = Size::with_y(spacing);
self.update_metrics(dimensions);
self.space.layouts.push((self.ctx.axes, Layout {
@@ -165,17 +164,17 @@ impl StackLayouter {
/// Update the size metrics to reflect that a layout or spacing with the
/// given generalized dimensions has been added.
- fn update_metrics(&mut self, dimensions: Size2D) {
+ fn update_metrics(&mut self, dimensions: Size) {
let axes = self.ctx.axes;
let mut size = self.space.size.generalized(axes);
let mut extra = self.space.extra.generalized(axes);
- size.x += (dimensions.x - extra.x).max(Size::ZERO);
- size.y += (dimensions.y - extra.y).max(Size::ZERO);
+ size.x += (dimensions.x - extra.x).max(Length::ZERO);
+ size.y += (dimensions.y - extra.y).max(Length::ZERO);
extra.x.max_eq(dimensions.x);
- extra.y = (extra.y - dimensions.y).max(Size::ZERO);
+ extra.y = (extra.y - dimensions.y).max(Length::ZERO);
self.space.size = size.specialized(axes);
self.space.extra = extra.specialized(axes);
@@ -233,7 +232,7 @@ impl StackLayouter {
/// Move to the first space that can fit the given dimensions or do nothing
/// if no space is capable of that.
- pub fn skip_to_fitting_space(&mut self, dimensions: Size2D) {
+ pub fn skip_to_fitting_space(&mut self, dimensions: Size) {
let start = self.next_space();
for (index, space) in self.ctx.spaces[start..].iter().enumerate() {
if space.usable().fits(dimensions) {
@@ -251,7 +250,7 @@ impl StackLayouter {
let mut spaces = smallvec![LayoutSpace {
dimensions,
- padding: SizeBox::ZERO,
+ padding: Margins::ZERO,
expansion: LayoutExpansion::new(false, false),
}];
@@ -263,15 +262,15 @@ impl StackLayouter {
}
/// The remaining usable size.
- pub fn usable(&self) -> Size2D {
+ pub fn usable(&self) -> Size {
self.space.usable
- - Size2D::with_y(self.space.last_spacing.soft_or_zero())
+ - Size::with_y(self.space.last_spacing.soft_or_zero())
.specialized(self.ctx.axes)
}
/// Whether the current layout space (not subspace) is empty.
pub fn space_is_empty(&self) -> bool {
- self.space.size == Size2D::ZERO && self.space.layouts.is_empty()
+ self.space.size == Size::ZERO && self.space.layouts.is_empty()
}
/// Whether the current layout space is the last is the followup list.
@@ -310,7 +309,7 @@ impl StackLayouter {
let start = space.start();
let mut bounds = vec![];
- let mut bound = SizeBox {
+ let mut bound = Margins {
left: start.x,
top: start.y,
right: start.x + self.space.size.x,
@@ -337,7 +336,7 @@ impl StackLayouter {
// The `x` field stores the maximal primary extent in one axis-aligned
// run, while the `y` fields stores the accumulated secondary extent.
- let mut extent = Size2D::ZERO;
+ let mut extent = Size::ZERO;
let mut rotation = Vertical;
for (bound, entry) in bounds.iter_mut().zip(&self.space.layouts).rev() {
@@ -349,7 +348,7 @@ impl StackLayouter {
// is reset for this new axis-aligned run.
if rotation != axes.secondary.axis() {
extent.y = extent.x;
- extent.x = Size::ZERO;
+ extent.x = Length::ZERO;
rotation = axes.secondary.axis();
}
@@ -383,11 +382,11 @@ impl StackLayouter {
// The space in which this layout is aligned is given by the
// distances between the borders of it's bounding box.
let usable =
- Size2D::new(bound.right - bound.left, bound.bottom - bound.top)
+ Size::new(bound.right - bound.left, bound.bottom - bound.top)
.generalized(axes);
let local = usable.anchor(alignment, axes) - size.anchor(alignment, axes);
- let pos = Size2D::new(bound.left, bound.top) + local.specialized(axes);
+ let pos = Size::new(bound.left, bound.top) + local.specialized(axes);
actions.add_layout(pos, layout);
}
@@ -417,15 +416,15 @@ impl StackLayouter {
}
impl Space {
- fn new(index: usize, hard: bool, usable: Size2D) -> Space {
+ fn new(index: usize, hard: bool, usable: Size) -> Space {
Space {
index,
hard,
layouts: vec![],
- size: Size2D::ZERO,
+ size: Size::ZERO,
usable,
- extra: Size2D::ZERO,
- rulers: ValueBox::with_all(Origin),
+ extra: Size::ZERO,
+ rulers: Value4::with_all(Origin),
last_spacing: LastSpacing::Hard,
}
}
diff --git a/src/layout/text.rs b/src/layout/text.rs
index 286ccc68..cbe40214 100644
--- a/src/layout/text.rs
+++ b/src/layout/text.rs
@@ -8,11 +8,10 @@ use toddle::query::{FontQuery, FontIndex};
use toddle::tables::{CharMap, Header, HorizontalMetrics};
use crate::GlobalFontLoader;
-use crate::size::{Size, Size2D};
+use crate::length::{Length, Size};
use crate::style::TextStyle;
use super::*;
-
/// Performs the text layouting.
#[derive(Debug)]
struct TextLayouter<'a> {
@@ -21,7 +20,7 @@ struct TextLayouter<'a> {
actions: LayoutActions,
buffer: String,
active_font: FontIndex,
- width: Size,
+ width: Length,
}
/// The context for text layouting.
@@ -54,7 +53,7 @@ impl<'a> TextLayouter<'a> {
actions: LayoutActions::new(),
buffer: String::new(),
active_font: FontIndex::MAX,
- width: Size::ZERO,
+ width: Length::ZERO,
}
}
@@ -77,7 +76,7 @@ impl<'a> TextLayouter<'a> {
}
Layout {
- dimensions: Size2D::new(self.width, self.ctx.style.font_size()),
+ dimensions: Size::new(self.width, self.ctx.style.font_size()),
alignment: self.ctx.alignment,
actions: self.actions.into_vec(),
}
@@ -110,7 +109,7 @@ impl<'a> TextLayouter<'a> {
/// Select the best font for a character and return its index along with
/// the width of the char in the font.
- async fn select_font(&mut self, c: char) -> Option<(FontIndex, Size)> {
+ async fn select_font(&mut self, c: char) -> Option<(FontIndex, Length)> {
let mut loader = self.ctx.loader.borrow_mut();
let mut variant = self.ctx.style.variant;
@@ -127,8 +126,8 @@ impl<'a> TextLayouter<'a> {
if let Some((font, index)) = loader.get(query).await {
// Determine the width of the char.
let header = font.read_table::<Header>().ok()?;
- let font_unit_ratio = 1.0 / (header.units_per_em as f32);
- let font_unit_to_size = |x| Size::pt(font_unit_ratio * x);
+ let font_unit_ratio = 1.0 / (header.units_per_em as f64);
+ let font_unit_to_size = |x| Length::pt(font_unit_ratio * x);
let glyph = font
.read_table::<CharMap>()
@@ -139,7 +138,7 @@ impl<'a> TextLayouter<'a> {
.read_table::<HorizontalMetrics>()
.ok()?
.get(glyph)?
- .advance_width as f32;
+ .advance_width as f64;
let char_width = font_unit_to_size(glyph_width)
* self.ctx.style.font_size().to_pt();