Horizon alignment

This commit is contained in:
Laurenz 2021-11-23 11:58:16 +01:00
parent 02f114d072
commit d3f6040ced
9 changed files with 42 additions and 48 deletions

View File

@ -3,27 +3,26 @@ use super::*;
/// Where to align something along an axis. /// Where to align something along an axis.
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Align { pub enum Align {
/// Align at the left side of the axis. /// Align at the left side.
Left, Left,
/// Align at the top side of the axis. /// Align in the horizontal middle.
Top,
/// Align in the middle of the axis.
Center, Center,
/// Align at the right side of the axis. /// Align at the right side.
Right, Right,
/// Align at the bottom side of the axis. /// Align at the top side.
Top,
/// Align in the vertical middle.
Horizon,
/// Align at the bottom side.
Bottom, Bottom,
} }
impl Align { impl Align {
/// The axis this alignment belongs to if it is specific. /// The axis this alignment belongs to.
pub const fn axis(self) -> Option<SpecAxis> { pub const fn axis(self) -> SpecAxis {
match self { match self {
Self::Left => Some(SpecAxis::Horizontal), Self::Left | Self::Center | Self::Right => SpecAxis::Horizontal,
Self::Top => Some(SpecAxis::Vertical), Self::Top | Self::Horizon | Self::Bottom => SpecAxis::Vertical,
Self::Center => None,
Self::Right => Some(SpecAxis::Horizontal),
Self::Bottom => Some(SpecAxis::Vertical),
} }
} }
@ -31,9 +30,10 @@ impl Align {
pub const fn inv(self) -> Self { pub const fn inv(self) -> Self {
match self { match self {
Self::Left => Self::Right, Self::Left => Self::Right,
Self::Top => Self::Bottom,
Self::Center => Self::Center, Self::Center => Self::Center,
Self::Right => Self::Left, Self::Right => Self::Left,
Self::Top => Self::Bottom,
Self::Horizon => Self::Horizon,
Self::Bottom => Self::Top, Self::Bottom => Self::Top,
} }
} }
@ -42,8 +42,8 @@ impl Align {
pub fn resolve(self, range: Range<Length>) -> Length { pub fn resolve(self, range: Range<Length>) -> Length {
match self { match self {
Self::Left | Self::Top => range.start, Self::Left | Self::Top => range.start,
Self::Center | Self::Horizon => (range.start + range.end) / 2.0,
Self::Right | Self::Bottom => range.end, Self::Right | Self::Bottom => range.end,
Self::Center => (range.start + range.end) / 2.0,
} }
} }
} }
@ -63,9 +63,10 @@ impl Debug for Align {
fn fmt(&self, f: &mut Formatter) -> fmt::Result { fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.pad(match self { f.pad(match self {
Self::Left => "left", Self::Left => "left",
Self::Top => "top",
Self::Center => "center", Self::Center => "center",
Self::Right => "right", Self::Right => "right",
Self::Top => "top",
Self::Horizon => "horizon",
Self::Bottom => "bottom", Self::Bottom => "bottom",
}) })
} }

View File

@ -14,6 +14,14 @@ pub enum Dir {
} }
impl Dir { impl Dir {
/// The specific axis this direction belongs to.
pub const fn axis(self) -> SpecAxis {
match self {
Self::LTR | Self::RTL => SpecAxis::Horizontal,
Self::TTB | Self::BTT => SpecAxis::Vertical,
}
}
/// The side this direction starts at. /// The side this direction starts at.
pub const fn start(self) -> Side { pub const fn start(self) -> Side {
match self { match self {
@ -34,11 +42,13 @@ impl Dir {
} }
} }
/// The specific axis this direction belongs to. /// The inverse direction.
pub const fn axis(self) -> SpecAxis { pub const fn inv(self) -> Self {
match self { match self {
Self::LTR | Self::RTL => SpecAxis::Horizontal, Self::LTR => Self::RTL,
Self::TTB | Self::BTT => SpecAxis::Vertical, Self::RTL => Self::LTR,
Self::TTB => Self::BTT,
Self::BTT => Self::TTB,
} }
} }
@ -51,24 +61,6 @@ impl Dir {
Self::RTL | Self::BTT => false, Self::RTL | Self::BTT => false,
} }
} }
/// The factor for this direction.
///
/// - `1.0` if the direction is positive.
/// - `-1.0` if the direction is negative.
pub const fn factor(self) -> f64 {
if self.is_positive() { 1.0 } else { -1.0 }
}
/// The inverse direction.
pub const fn inv(self) -> Self {
match self {
Self::LTR => Self::RTL,
Self::RTL => Self::LTR,
Self::TTB => Self::BTT,
Self::BTT => Self::TTB,
}
}
} }
impl Debug for Dir { impl Debug for Dir {

View File

@ -20,8 +20,8 @@ pub(super) fn parse_aligns(args: &mut Args) -> TypResult<Spec<Option<Align>>> {
let mut y = args.named("vertical")?; let mut y = args.named("vertical")?;
for Spanned { v, span } in args.all::<Spanned<Align>>() { for Spanned { v, span } in args.all::<Spanned<Align>>() {
match v.axis() { match v.axis() {
None | Some(SpecAxis::Horizontal) if x.is_none() => x = Some(v), SpecAxis::Horizontal if x.is_none() => x = Some(v),
None | Some(SpecAxis::Vertical) if y.is_none() => y = Some(v), SpecAxis::Vertical if y.is_none() => y = Some(v),
_ => bail!(span, "unexpected argument"), _ => bail!(span, "unexpected argument"),
} }
} }

View File

@ -121,9 +121,10 @@ pub fn new() -> Scope {
std.def_const("ttb", Dir::TTB); std.def_const("ttb", Dir::TTB);
std.def_const("btt", Dir::BTT); std.def_const("btt", Dir::BTT);
std.def_const("left", Align::Left); std.def_const("left", Align::Left);
std.def_const("top", Align::Top);
std.def_const("center", Align::Center); std.def_const("center", Align::Center);
std.def_const("right", Align::Right); std.def_const("right", Align::Right);
std.def_const("top", Align::Top);
std.def_const("horizon", Align::Horizon);
std.def_const("bottom", Align::Bottom); std.def_const("bottom", Align::Bottom);
std.def_const("serif", FontFamily::Serif); std.def_const("serif", FontFamily::Serif);
std.def_const("sans-serif", FontFamily::SansSerif); std.def_const("sans-serif", FontFamily::SansSerif);

View File

@ -33,7 +33,7 @@ pub fn par(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let mut align = None; let mut align = None;
if let Some(Spanned { v, span }) = args.named::<Spanned<Align>>("align")? { if let Some(Spanned { v, span }) = args.named::<Spanned<Align>>("align")? {
if matches!(v.axis(), None | Some(SpecAxis::Horizontal)) { if v.axis() == SpecAxis::Horizontal {
align = Some(v); align = Some(v);
} else { } else {
bail!(span, "must be horizontal"); bail!(span, "must be horizontal");

View File

@ -10,12 +10,12 @@
Auto-sized circle. \ Auto-sized circle. \
#circle(fill: rgb("eb5278"), thickness: 2pt, #circle(fill: rgb("eb5278"), thickness: 2pt,
align(center, center)[But, soft!] align(center, horizon)[But, soft!]
) )
Center-aligned rect in auto-sized circle. Center-aligned rect in auto-sized circle.
#circle(fill: forest, stroke: conifer, #circle(fill: forest, stroke: conifer,
align(center, center, align(center, horizon,
rect(fill: conifer, pad(5pt)[But, soft!]) rect(fill: conifer, pad(5pt)[But, soft!])
) )
) )
@ -37,7 +37,7 @@ Expanded by height.
--- ---
// Test relative sizing. // Test relative sizing.
#let centered(body) = align(center, center, body) #let centered(body) = align(center, horizon, body)
#font(fill: white) #font(fill: white)
#rect(width: 100pt, height: 50pt, fill: rgb("aaa"), centered[ #rect(width: 100pt, height: 50pt, fill: rgb("aaa"), centered[
#circle(radius: 10pt, fill: eastern, centered[A]) // D=20pt #circle(radius: 10pt, fill: eastern, centered[A]) // D=20pt

View File

@ -9,7 +9,7 @@ Rect in ellipse in fixed rect. \
#rect(width: 3cm, height: 2cm, fill: rgb("2a631a"), #rect(width: 3cm, height: 2cm, fill: rgb("2a631a"),
ellipse(fill: forest, ellipse(fill: forest,
rect(fill: conifer, rect(fill: conifer,
align(center, center)[ align(center, horizon)[
Stuff inside an ellipse! Stuff inside an ellipse!
] ]
) )

View File

@ -16,7 +16,7 @@
rect(fill: forest, thickness: 2pt), rect(fill: forest, thickness: 2pt),
rect(fill: forest, stroke: conifer, thickness: 2pt), rect(fill: forest, stroke: conifer, thickness: 2pt),
) { ) {
(align(vertical: center)[{i + 1}.], rect, []) (align(horizon)[{i + 1}.], rect, [])
} }
#grid( #grid(

View File

@ -7,7 +7,7 @@
align(center, square(size: 20pt, fill: eastern)), align(center, square(size: 20pt, fill: eastern)),
align(right, square(size: 15pt, fill: eastern)), align(right, square(size: 15pt, fill: eastern)),
) )
#align(center, center, rect(fill: eastern, height: 10pt)) #align(center, horizon, rect(fill: eastern, height: 10pt))
#align(bottom, stack( #align(bottom, stack(
align(center, rect(fill: conifer, height: 10pt)), align(center, rect(fill: conifer, height: 10pt)),
rect(fill: forest, height: 10pt), rect(fill: forest, height: 10pt),