summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/geom.rs101
-rw-r--r--src/layout/line.rs14
-rw-r--r--src/layout/mod.rs2
-rw-r--r--src/layout/primitive.rs106
4 files changed, 118 insertions, 105 deletions
diff --git a/src/geom.rs b/src/geom.rs
index 0089aa4a..d69797b0 100644
--- a/src/geom.rs
+++ b/src/geom.rs
@@ -6,18 +6,60 @@ pub use kurbo::*;
use std::fmt::{self, Debug, Formatter};
use std::ops::*;
-use crate::layout::primitive::{Dir, Gen2, GenAlign, Side, SpecAxis};
+use crate::layout::primitive::{Dir, Gen2, GenAlign, Get, Side, SpecAxis};
+
+macro_rules! impl_get_2d {
+ ($t:ty, $x:ident, $y:ident) => {
+ impl Get<SpecAxis> for $t {
+ type Component = f64;
+
+ fn get(self, axis: SpecAxis) -> f64 {
+ match axis {
+ SpecAxis::Horizontal => self.$x,
+ SpecAxis::Vertical => self.$y,
+ }
+ }
+
+ fn get_mut(&mut self, axis: SpecAxis) -> &mut f64 {
+ match axis {
+ SpecAxis::Horizontal => &mut self.$x,
+ SpecAxis::Vertical => &mut self.$y,
+ }
+ }
+ }
+ };
+}
+
+impl_get_2d!(Point, x, y);
+impl_get_2d!(Vec2, x, y);
+impl_get_2d!(Size, width, height);
+
+impl Get<Side> for Rect {
+ type Component = f64;
+
+ fn get(self, side: Side) -> f64 {
+ match side {
+ Side::Left => self.x0,
+ Side::Top => self.y0,
+ Side::Right => self.x1,
+ Side::Bottom => self.y1,
+ }
+ }
+
+ fn get_mut(&mut self, side: Side) -> &mut f64 {
+ match side {
+ Side::Left => &mut self.x0,
+ Side::Top => &mut self.y0,
+ Side::Right => &mut self.x1,
+ Side::Bottom => &mut self.y1,
+ }
+ }
+}
/// Additional methods for [sizes].
///
/// [sizes]: ../../kurbo/struct.Size.html
pub trait SizeExt {
- /// Return the component for the specified axis.
- fn get(self, axis: SpecAxis) -> f64;
-
- /// Borrow the component for the specified axis mutably.
- fn get_mut(&mut self, axis: SpecAxis) -> &mut f64;
-
/// Returns the generalized version of a `Size` based on the current
/// directions.
///
@@ -43,20 +85,6 @@ pub trait SizeExt {
}
impl SizeExt for Size {
- fn get(self, axis: SpecAxis) -> f64 {
- match axis {
- SpecAxis::Horizontal => self.width,
- SpecAxis::Vertical => self.height,
- }
- }
-
- fn get_mut(&mut self, axis: SpecAxis) -> &mut f64 {
- match axis {
- SpecAxis::Horizontal => &mut self.width,
- SpecAxis::Vertical => &mut self.height,
- }
- }
-
fn generalized(self, dirs: Gen2<Dir>) -> Self {
match dirs.main.axis() {
SpecAxis::Horizontal => Self::new(self.height, self.width),
@@ -90,37 +118,6 @@ impl SizeExt for Size {
}
}
-/// Additional methods for [rectangles].
-///
-/// [rectangles]: ../../kurbo/struct.Rect.html
-pub trait RectExt {
- /// Return the value for the given side.
- fn get(self, side: Side) -> f64;
-
- /// Borrow the value for the given side mutably.
- fn get_mut(&mut self, side: Side) -> &mut f64;
-}
-
-impl RectExt for Rect {
- fn get(self, side: Side) -> f64 {
- match side {
- Side::Left => self.x0,
- Side::Top => self.y0,
- Side::Right => self.x1,
- Side::Bottom => self.y1,
- }
- }
-
- fn get_mut(&mut self, side: Side) -> &mut f64 {
- match side {
- Side::Left => &mut self.x0,
- Side::Top => &mut self.y0,
- Side::Right => &mut self.x1,
- Side::Bottom => &mut self.y1,
- }
- }
-}
-
/// A function that depends linearly on one value.
///
/// This represents a function `f(x) = rel * x + abs`.
diff --git a/src/layout/line.rs b/src/layout/line.rs
index acf143c0..c1b5920f 100644
--- a/src/layout/line.rs
+++ b/src/layout/line.rs
@@ -198,19 +198,17 @@ impl LineLayouter {
pub fn finish_line(&mut self) {
let mut layout = BoxLayout::new(self.run.size.specialized(self.ctx.dirs));
let aligns = self.run.aligns.unwrap_or_default();
+ let cross = self.ctx.dirs.cross;
let layouts = std::mem::take(&mut self.run.layouts);
for (offset, child) in layouts {
- let x = match self.ctx.dirs.cross.is_positive() {
- true => offset,
- false => {
- self.run.size.width
- - offset
- - child.size.get(self.ctx.dirs.cross.axis())
- }
+ let mut pos = Point::ZERO;
+ *pos.get_mut(cross.axis()) = if cross.is_positive() {
+ offset
+ } else {
+ self.run.size.width - offset - child.size.get(cross.axis())
};
- let pos = Point::new(x, 0.0);
layout.push_layout(pos, child);
}
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index f9372e50..912ca010 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -14,7 +14,7 @@ pub use tree::*;
use crate::diag::Diag;
use crate::eval::{PageState, State, TextState};
use crate::font::SharedFontLoader;
-use crate::geom::{Insets, Point, Rect, RectExt, Size, SizeExt};
+use crate::geom::{Insets, Point, Rect, Size, SizeExt};
use crate::shaping::Shaped;
use crate::syntax::{Deco, Spanned, SynTree};
use crate::{Feedback, Pass};
diff --git a/src/layout/primitive.rs b/src/layout/primitive.rs
index 9070c972..549c1f29 100644
--- a/src/layout/primitive.rs
+++ b/src/layout/primitive.rs
@@ -2,6 +2,50 @@
use std::fmt::{self, Display, Formatter};
+/// Generic access to a structure's components.
+pub trait Get<Index> {
+ /// The structure's component type.
+ type Component;
+
+ /// Return the component for the specified index.
+ fn get(self, index: Index) -> Self::Component;
+
+ /// Borrow the component for the specified index mutably.
+ fn get_mut(&mut self, index: Index) -> &mut Self::Component;
+}
+
+/// Convert a type into its generic representation.
+///
+/// The generic representation deals with main and cross axes while the specific
+/// representation deals with horizontal and vertical axes.
+///
+/// See also [`ToSpec`] for the inverse conversion.
+///
+/// [`ToSpec`]: trait.ToSpec.html
+pub trait ToGen {
+ /// The generic version of this type.
+ type Output;
+
+ /// The generic version of this type based on the current directions.
+ fn to_gen(self, dirs: Gen2<Dir>) -> Self::Output;
+}
+
+/// Convert a type into its specific representation.
+///
+/// The specific representation deals with horizontal and vertical axes while
+/// the generic representation deals with main and cross axes.
+///
+/// See also [`ToGen`] for the inverse conversion.
+///
+/// [`ToGen`]: trait.ToGen.html
+pub trait ToSpec {
+ /// The specific version of this type.
+ type Output;
+
+ /// The specific version of this type based on the current directions.
+ fn to_spec(self, dirs: Gen2<Dir>) -> Self::Output;
+}
+
/// The four directions into which content can be laid out.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Dir {
@@ -81,38 +125,6 @@ impl Display for Dir {
}
}
-/// Convert a type into its generic representation.
-///
-/// The generic representation deals with main and cross axes while the specific
-/// representation deals with horizontal and vertical axes.
-///
-/// See also [`ToSpec`] for the inverse conversion.
-///
-/// [`ToSpec`]: trait.ToSpec.html
-pub trait ToGen {
- /// The generic version of this type.
- type Output;
-
- /// The generic version of this type based on the current directions.
- fn to_gen(self, dirs: Gen2<Dir>) -> Self::Output;
-}
-
-/// Convert a type into its specific representation.
-///
-/// The specific representation deals with horizontal and vertical axes while
-/// the generic representation deals with main and cross axes.
-///
-/// See also [`ToGen`] for the inverse conversion.
-///
-/// [`ToGen`]: trait.ToGen.html
-pub trait ToSpec {
- /// The specific version of this type.
- type Output;
-
- /// The specific version of this type based on the current directions.
- fn to_spec(self, dirs: Gen2<Dir>) -> Self::Output;
-}
-
/// A generic container with two components for the two generic axes.
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
pub struct Gen2<T> {
@@ -127,17 +139,19 @@ impl<T> Gen2<T> {
pub fn new(main: T, cross: T) -> Self {
Self { main, cross }
}
+}
+
+impl<T> Get<GenAxis> for Gen2<T> {
+ type Component = T;
- /// Return the component for the specified generic axis.
- pub fn get(self, axis: GenAxis) -> T {
+ fn get(self, axis: GenAxis) -> T {
match axis {
GenAxis::Main => self.main,
GenAxis::Cross => self.cross,
}
}
- /// Borrow the component for the specified generic axis mutably.
- pub fn get_mut(&mut self, axis: GenAxis) -> &mut T {
+ fn get_mut(&mut self, axis: GenAxis) -> &mut T {
match axis {
GenAxis::Main => &mut self.main,
GenAxis::Cross => &mut self.cross,
@@ -170,17 +184,19 @@ impl<T> Spec2<T> {
pub fn new(horizontal: T, vertical: T) -> Self {
Self { horizontal, vertical }
}
+}
+
+impl<T> Get<SpecAxis> for Spec2<T> {
+ type Component = T;
- /// Return the component for the given specific axis.
- pub fn get(self, axis: SpecAxis) -> T {
+ fn get(self, axis: SpecAxis) -> T {
match axis {
SpecAxis::Horizontal => self.horizontal,
SpecAxis::Vertical => self.vertical,
}
}
- /// Borrow the component for the given specific axis mutably.
- pub fn get_mut(&mut self, axis: SpecAxis) -> &mut T {
+ fn get_mut(&mut self, axis: SpecAxis) -> &mut T {
match axis {
SpecAxis::Horizontal => &mut self.horizontal,
SpecAxis::Vertical => &mut self.vertical,
@@ -416,9 +432,12 @@ impl<T> Sides<T> {
bottom: value,
}
}
+}
+
+impl<T> Get<Side> for Sides<T> {
+ type Component = T;
- /// Return the component for the given side.
- pub fn get(self, side: Side) -> T {
+ fn get(self, side: Side) -> T {
match side {
Side::Left => self.left,
Side::Top => self.top,
@@ -427,8 +446,7 @@ impl<T> Sides<T> {
}
}
- /// Borrow the component for the given side mutably.
- pub fn get_mut(&mut self, side: Side) -> &mut T {
+ fn get_mut(&mut self, side: Side) -> &mut T {
match side {
Side::Left => &mut self.left,
Side::Top => &mut self.top,