diff options
Diffstat (limited to 'src/layout')
| -rw-r--r-- | src/layout/elements.rs | 15 | ||||
| -rw-r--r-- | src/layout/line.rs | 30 | ||||
| -rw-r--r-- | src/layout/mod.rs | 16 | ||||
| -rw-r--r-- | src/layout/shaping.rs | 11 | ||||
| -rw-r--r-- | src/layout/stack.rs | 55 | ||||
| -rw-r--r-- | src/layout/tree.rs | 17 |
6 files changed, 68 insertions, 76 deletions
diff --git a/src/layout/elements.rs b/src/layout/elements.rs index dd148a24..b5f83bfe 100644 --- a/src/layout/elements.rs +++ b/src/layout/elements.rs @@ -5,11 +5,11 @@ use std::fmt::{self, Debug, Formatter}; use fontdock::FaceId; use ttf_parser::GlyphId; -use crate::geom::Size; +use crate::geom::Point; /// A collection of absolutely positioned layout elements. #[derive(Debug, Default, Clone, PartialEq)] -pub struct LayoutElements(pub Vec<(Size, LayoutElement)>); +pub struct LayoutElements(pub Vec<(Point, LayoutElement)>); impl LayoutElements { /// Create an new empty collection. @@ -18,16 +18,15 @@ impl LayoutElements { } /// Add an element at a position. - pub fn push(&mut self, pos: Size, element: LayoutElement) { + pub fn push(&mut self, pos: Point, element: LayoutElement) { self.0.push((pos, element)); } - /// Add all elements of another collection, offsetting each by the given - /// `offset`. This can be used to place a sublayout at a position in another - /// layout. - pub fn extend_offset(&mut self, offset: Size, more: Self) { + /// Add all elements of another collection, placing them relative to the + /// given position. + pub fn push_elements(&mut self, pos: Point, more: Self) { for (subpos, element) in more.0 { - self.0.push((subpos + offset, element)); + self.0.push((pos + subpos.to_vec2(), element)); } } } diff --git a/src/layout/line.rs b/src/layout/line.rs index d8e97df3..86531f30 100644 --- a/src/layout/line.rs +++ b/src/layout/line.rs @@ -95,14 +95,14 @@ impl LineLayouter { let usable = self.stack.usable().primary(sys); rest_run.usable = Some(match layout.align.primary { GenAlign::Start => unreachable!("start > x"), - GenAlign::Center => usable - 2.0 * self.run.size.x, - GenAlign::End => usable - self.run.size.x, + GenAlign::Center => usable - 2.0 * self.run.size.width, + GenAlign::End => usable - self.run.size.width, }); - rest_run.size.y = self.run.size.y; + rest_run.size.height = self.run.size.height; self.finish_line(); - self.stack.add_spacing(-rest_run.size.y, SpacingKind::Hard); + self.stack.add_spacing(-rest_run.size.height, SpacingKind::Hard); self.run = rest_run; } @@ -126,10 +126,10 @@ impl LineLayouter { } self.run.align = Some(layout.align); - self.run.layouts.push((self.run.size.x, layout)); + self.run.layouts.push((self.run.size.width, layout)); - self.run.size.x += size.x; - self.run.size.y = self.run.size.y.max(size.y); + self.run.size.width += size.width; + self.run.size.height = self.run.size.height.max(size.height); self.run.last_spacing = LastSpacing::None; } @@ -152,10 +152,10 @@ impl LineLayouter { // If there was another run already, override the stack's size. if let Some(primary) = self.run.usable { - usable.x = primary; + usable.width = primary; } - usable.x -= self.run.size.x; + usable.width -= self.run.size.width; usable } @@ -163,8 +163,8 @@ impl LineLayouter { pub fn add_primary_spacing(&mut self, mut spacing: f64, kind: SpacingKind) { match kind { SpacingKind::Hard => { - spacing = spacing.min(self.usable().x); - self.run.size.x += spacing; + spacing = spacing.min(self.usable().width); + self.run.size.width += spacing; self.run.last_spacing = LastSpacing::Hard; } @@ -215,7 +215,7 @@ impl LineLayouter { /// it will fit into this layouter's underlying stack. pub fn remaining(&self) -> LayoutSpaces { let mut spaces = self.stack.remaining(); - *spaces[0].size.secondary_mut(self.ctx.sys) -= self.run.size.y; + *spaces[0].size.secondary_mut(self.ctx.sys) -= self.run.size.height; spaces } @@ -246,11 +246,11 @@ impl LineLayouter { for (offset, layout) in layouts { let x = match self.ctx.sys.primary.is_positive() { true => offset, - false => self.run.size.x - offset - layout.size.primary(self.ctx.sys), + false => self.run.size.width - offset - layout.size.primary(self.ctx.sys), }; - let pos = Size::with_x(x); - elements.extend_offset(pos, layout.elements); + let pos = Point::new(x, 0.0); + elements.push_elements(pos, layout.elements); } self.stack.add(BoxLayout { diff --git a/src/layout/mod.rs b/src/layout/mod.rs index fcaab372..11c03b0b 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -10,9 +10,10 @@ mod tree; pub use primitive::*; pub use tree::layout_tree as layout; +use crate::geom::{Insets, Point, Rect, RectExt, Sides, Size, SizeExt}; + use crate::eval::Scope; use crate::font::SharedFontLoader; -use crate::geom::{Margins, Size}; use crate::style::{LayoutStyle, PageStyle, TextStyle}; use crate::syntax::SynTree; @@ -67,22 +68,21 @@ pub struct LayoutSpace { /// The maximum size of the rectangle to layout into. pub size: Size, /// Padding that should be respected on each side. - pub padding: Margins, + pub insets: Insets, /// Whether to expand the size of the resulting layout to the full size of /// this space or to shrink it to fit the content. pub expansion: LayoutExpansion, } impl LayoutSpace { - /// The offset from the origin to the start of content, i.e. - /// `(padding.left, padding.top)`. - pub fn start(&self) -> Size { - Size::new(self.padding.left, self.padding.top) + /// The position of the padded start in the space. + pub fn start(&self) -> Point { + Point::new(-self.insets.x0, -self.insets.y0) } /// The actually usable area (size minus padding). pub fn usable(&self) -> Size { - self.size.unpadded(self.padding) + self.size + self.insets.size() } /// The inner layout space with size reduced by the padding, zero padding of @@ -90,7 +90,7 @@ impl LayoutSpace { pub fn inner(&self) -> Self { Self { size: self.usable(), - padding: Margins::ZERO, + insets: Insets::ZERO, expansion: LayoutExpansion::new(false, false), } } diff --git a/src/layout/shaping.rs b/src/layout/shaping.rs index 0f42d4bb..4de30a9e 100644 --- a/src/layout/shaping.rs +++ b/src/layout/shaping.rs @@ -11,7 +11,6 @@ use super::elements::{LayoutElement, Shaped}; use super::BoxLayout as Layout; use super::*; use crate::font::FontLoader; -use crate::geom::Size; use crate::style::TextStyle; /// Shape text into a box. @@ -74,7 +73,7 @@ impl<'a> Shaper<'a> { // Flush the last buffered parts of the word. if !self.shaped.text.is_empty() { - let pos = Size::new(self.offset, 0.0); + let pos = Point::new(self.offset, 0.0); self.layout.elements.push(pos, LayoutElement::Text(self.shaped)); } @@ -97,9 +96,9 @@ impl<'a> Shaper<'a> { Shaped::new(FaceId::MAX, self.opts.style.font_size()), ); - let pos = Size::new(self.offset, 0.0); + let pos = Point::new(self.offset, 0.0); self.layout.elements.push(pos, LayoutElement::Text(shaped)); - self.offset = self.layout.size.x; + self.offset = self.layout.size.width; } self.shaped.face = index; @@ -107,9 +106,9 @@ impl<'a> Shaper<'a> { self.shaped.text.push(c); self.shaped.glyphs.push(glyph); - self.shaped.offsets.push(self.layout.size.x - self.offset); + self.shaped.offsets.push(self.layout.size.width - self.offset); - self.layout.size.x += char_width; + self.layout.size.width += char_width; } async fn select_font(&mut self, c: char) -> Option<(FaceId, GlyphId, f64)> { diff --git a/src/layout/stack.rs b/src/layout/stack.rs index 3e63f5e5..a68fbac0 100644 --- a/src/layout/stack.rs +++ b/src/layout/stack.rs @@ -20,7 +20,6 @@ //! sentence in the second box. use super::*; -use crate::geom::Value4; /// Performs the stack layouting. pub struct StackLayouter { @@ -64,7 +63,7 @@ struct Space { /// Dictate which alignments for new boxes are still allowed and which /// require a new space to be started. For example, after an `End`-aligned /// item, no `Start`-aligned one can follow. - rulers: Value4<GenAlign>, + rulers: Sides<GenAlign>, /// The spacing state. This influences how new spacing is handled, e.g. hard /// spacing may override soft spacing. last_spacing: LastSpacing, @@ -127,7 +126,7 @@ impl StackLayouter { SpacingKind::Hard => { // Reduce the spacing such that it definitely fits. spacing = spacing.min(self.space.usable.secondary(self.ctx.sys)); - let size = Size::with_y(spacing); + let size = Size::new(0.0, spacing); self.update_metrics(size); self.space.layouts.push((self.ctx.sys, BoxLayout { @@ -161,15 +160,15 @@ impl StackLayouter { let mut size = self.space.size.generalized(sys); let mut extra = self.space.extra.generalized(sys); - size.x += (added.x - extra.x).max(0.0); - size.y += (added.y - extra.y).max(0.0); + size.width += (added.width - extra.width).max(0.0); + size.height += (added.height - extra.height).max(0.0); - extra.x = extra.x.max(added.x); - extra.y = (extra.y - added.y).max(0.0); + extra.width = extra.width.max(added.width); + extra.height = (extra.height - added.height).max(0.0); self.space.size = size.specialized(sys); self.space.extra = extra.specialized(sys); - *self.space.usable.secondary_mut(sys) -= added.y; + *self.space.usable.secondary_mut(sys) -= added.height; } /// Returns true if a space break is necessary. @@ -239,7 +238,7 @@ impl StackLayouter { let mut spaces = vec![LayoutSpace { size, - padding: Margins::ZERO, + insets: Insets::ZERO, expansion: LayoutExpansion::new(false, false), }]; @@ -253,7 +252,7 @@ impl StackLayouter { /// The remaining usable size. pub fn usable(&self) -> Size { self.space.usable - - Size::with_y(self.space.last_spacing.soft_or_zero()) + - Size::new(0.0, self.space.last_spacing.soft_or_zero()) .specialized(self.ctx.sys) } @@ -286,13 +285,13 @@ impl StackLayouter { let usable = space.usable(); if space.expansion.horizontal { - self.space.size.x = usable.x; + self.space.size.width = usable.width; } if space.expansion.vertical { - self.space.size.y = usable.y; + self.space.size.height = usable.height; } - let size = self.space.size.padded(space.padding); + let size = self.space.size - space.insets.size(); // ------------------------------------------------------------------ // // Step 2: Forward pass. Create a bounding box for each layout in which @@ -302,11 +301,11 @@ impl StackLayouter { let start = space.start(); let mut bounds = vec![]; - let mut bound = Margins { - left: start.x, - top: start.y, - right: start.x + self.space.size.x, - bottom: start.y + self.space.size.y, + let mut bound = Rect { + x0: start.x, + y0: start.y, + x1: start.x + self.space.size.width, + y1: start.y + self.space.size.height, }; for (sys, layout) in &self.space.layouts { @@ -340,8 +339,8 @@ impl StackLayouter { // is thus stored in `extent.y`. The primary extent is reset for // this new axis-aligned run. if rotation != sys.secondary.axis() { - extent.y = extent.x; - extent.x = 0.0; + extent.height = extent.width; + extent.width = 0.0; rotation = sys.secondary.axis(); } @@ -349,12 +348,12 @@ impl StackLayouter { // accumulated secondary extent of all layouts we have seen so far, // which are the layouts after this one since we iterate reversed. *bound.get_mut(sys.secondary, GenAlign::End) -= - sys.secondary.factor() * extent.y; + sys.secondary.factor() * extent.height; // Then, we add this layout's secondary extent to the accumulator. let size = layout.size.generalized(*sys); - extent.x = extent.x.max(size.x); - extent.y += size.y; + extent.width = extent.width.max(size.width); + extent.height += size.height; } // ------------------------------------------------------------------ // @@ -370,13 +369,11 @@ impl StackLayouter { // The space in which this layout is aligned is given by the // distances between the borders of its bounding box. - let usable = Size::new(bound.right - bound.left, bound.bottom - bound.top) - .generalized(sys); - + let usable = bound.size().generalized(sys); let local = usable.anchor(align, sys) - size.anchor(align, sys); - let pos = Size::new(bound.left, bound.top) + local.specialized(sys); + let pos = bound.origin() + local.to_size().specialized(sys).to_vec2(); - elements.extend_offset(pos, layout.elements); + elements.push_elements(pos, layout.elements); } self.layouts.push(BoxLayout { size, align: self.ctx.align, elements }); @@ -406,7 +403,7 @@ impl Space { size: Size::ZERO, usable, extra: Size::ZERO, - rulers: Value4::with_all(GenAlign::Start), + rulers: Sides::uniform(GenAlign::Start), last_spacing: LastSpacing::Hard, } } diff --git a/src/layout/tree.rs b/src/layout/tree.rs index b43ef089..58774215 100644 --- a/src/layout/tree.rs +++ b/src/layout/tree.rs @@ -202,16 +202,13 @@ impl<'a> TreeLayouter<'a> { // The line layouter has no idea of page styles and thus we // need to recompute the layouting space resulting of the // new page style and update it within the layouter. - let margins = style.margins(); - self.ctx.base = style.size.unpadded(margins); - self.layouter.set_spaces( - vec![LayoutSpace { - size: style.size, - padding: margins, - expansion: LayoutExpansion::new(true, true), - }], - true, - ); + let space = LayoutSpace { + size: style.size, + insets: style.insets(), + expansion: LayoutExpansion::new(true, true), + }; + self.ctx.base = space.usable(); + self.layouter.set_spaces(vec![space], true); } else { error!( @self.feedback, span, |
