mirror of
https://github.com/typst/typst
synced 2025-06-28 00:03:17 +08:00
Horizon alignment
This commit is contained in:
parent
02f114d072
commit
d3f6040ced
@ -3,27 +3,26 @@ use super::*;
|
||||
/// Where to align something along an axis.
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
pub enum Align {
|
||||
/// Align at the left side of the axis.
|
||||
/// Align at the left side.
|
||||
Left,
|
||||
/// Align at the top side of the axis.
|
||||
Top,
|
||||
/// Align in the middle of the axis.
|
||||
/// Align in the horizontal middle.
|
||||
Center,
|
||||
/// Align at the right side of the axis.
|
||||
/// Align at the right side.
|
||||
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,
|
||||
}
|
||||
|
||||
impl Align {
|
||||
/// The axis this alignment belongs to if it is specific.
|
||||
pub const fn axis(self) -> Option<SpecAxis> {
|
||||
/// The axis this alignment belongs to.
|
||||
pub const fn axis(self) -> SpecAxis {
|
||||
match self {
|
||||
Self::Left => Some(SpecAxis::Horizontal),
|
||||
Self::Top => Some(SpecAxis::Vertical),
|
||||
Self::Center => None,
|
||||
Self::Right => Some(SpecAxis::Horizontal),
|
||||
Self::Bottom => Some(SpecAxis::Vertical),
|
||||
Self::Left | Self::Center | Self::Right => SpecAxis::Horizontal,
|
||||
Self::Top | Self::Horizon | Self::Bottom => SpecAxis::Vertical,
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,9 +30,10 @@ impl Align {
|
||||
pub const fn inv(self) -> Self {
|
||||
match self {
|
||||
Self::Left => Self::Right,
|
||||
Self::Top => Self::Bottom,
|
||||
Self::Center => Self::Center,
|
||||
Self::Right => Self::Left,
|
||||
Self::Top => Self::Bottom,
|
||||
Self::Horizon => Self::Horizon,
|
||||
Self::Bottom => Self::Top,
|
||||
}
|
||||
}
|
||||
@ -42,8 +42,8 @@ impl Align {
|
||||
pub fn resolve(self, range: Range<Length>) -> Length {
|
||||
match self {
|
||||
Self::Left | Self::Top => range.start,
|
||||
Self::Center | Self::Horizon => (range.start + range.end) / 2.0,
|
||||
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 {
|
||||
f.pad(match self {
|
||||
Self::Left => "left",
|
||||
Self::Top => "top",
|
||||
Self::Center => "center",
|
||||
Self::Right => "right",
|
||||
Self::Top => "top",
|
||||
Self::Horizon => "horizon",
|
||||
Self::Bottom => "bottom",
|
||||
})
|
||||
}
|
||||
|
@ -14,6 +14,14 @@ pub enum 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.
|
||||
pub const fn start(self) -> Side {
|
||||
match self {
|
||||
@ -34,11 +42,13 @@ impl Dir {
|
||||
}
|
||||
}
|
||||
|
||||
/// The specific axis this direction belongs to.
|
||||
pub const fn axis(self) -> SpecAxis {
|
||||
/// The inverse direction.
|
||||
pub const fn inv(self) -> Self {
|
||||
match self {
|
||||
Self::LTR | Self::RTL => SpecAxis::Horizontal,
|
||||
Self::TTB | Self::BTT => SpecAxis::Vertical,
|
||||
Self::LTR => Self::RTL,
|
||||
Self::RTL => Self::LTR,
|
||||
Self::TTB => Self::BTT,
|
||||
Self::BTT => Self::TTB,
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,24 +61,6 @@ impl Dir {
|
||||
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 {
|
||||
|
@ -20,8 +20,8 @@ pub(super) fn parse_aligns(args: &mut Args) -> TypResult<Spec<Option<Align>>> {
|
||||
let mut y = args.named("vertical")?;
|
||||
for Spanned { v, span } in args.all::<Spanned<Align>>() {
|
||||
match v.axis() {
|
||||
None | Some(SpecAxis::Horizontal) if x.is_none() => x = Some(v),
|
||||
None | Some(SpecAxis::Vertical) if y.is_none() => y = Some(v),
|
||||
SpecAxis::Horizontal if x.is_none() => x = Some(v),
|
||||
SpecAxis::Vertical if y.is_none() => y = Some(v),
|
||||
_ => bail!(span, "unexpected argument"),
|
||||
}
|
||||
}
|
||||
|
@ -121,9 +121,10 @@ pub fn new() -> Scope {
|
||||
std.def_const("ttb", Dir::TTB);
|
||||
std.def_const("btt", Dir::BTT);
|
||||
std.def_const("left", Align::Left);
|
||||
std.def_const("top", Align::Top);
|
||||
std.def_const("center", Align::Center);
|
||||
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("serif", FontFamily::Serif);
|
||||
std.def_const("sans-serif", FontFamily::SansSerif);
|
||||
|
@ -33,7 +33,7 @@ pub fn par(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
|
||||
|
||||
let mut align = None;
|
||||
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);
|
||||
} else {
|
||||
bail!(span, "must be horizontal");
|
||||
|
@ -10,12 +10,12 @@
|
||||
|
||||
Auto-sized circle. \
|
||||
#circle(fill: rgb("eb5278"), thickness: 2pt,
|
||||
align(center, center)[But, soft!]
|
||||
align(center, horizon)[But, soft!]
|
||||
)
|
||||
|
||||
Center-aligned rect in auto-sized circle.
|
||||
#circle(fill: forest, stroke: conifer,
|
||||
align(center, center,
|
||||
align(center, horizon,
|
||||
rect(fill: conifer, pad(5pt)[But, soft!])
|
||||
)
|
||||
)
|
||||
@ -37,7 +37,7 @@ Expanded by height.
|
||||
|
||||
---
|
||||
// Test relative sizing.
|
||||
#let centered(body) = align(center, center, body)
|
||||
#let centered(body) = align(center, horizon, body)
|
||||
#font(fill: white)
|
||||
#rect(width: 100pt, height: 50pt, fill: rgb("aaa"), centered[
|
||||
#circle(radius: 10pt, fill: eastern, centered[A]) // D=20pt
|
||||
|
@ -9,7 +9,7 @@ Rect in ellipse in fixed rect. \
|
||||
#rect(width: 3cm, height: 2cm, fill: rgb("2a631a"),
|
||||
ellipse(fill: forest,
|
||||
rect(fill: conifer,
|
||||
align(center, center)[
|
||||
align(center, horizon)[
|
||||
Stuff inside an ellipse!
|
||||
]
|
||||
)
|
||||
|
@ -16,7 +16,7 @@
|
||||
rect(fill: forest, thickness: 2pt),
|
||||
rect(fill: forest, stroke: conifer, thickness: 2pt),
|
||||
) {
|
||||
(align(vertical: center)[{i + 1}.], rect, [])
|
||||
(align(horizon)[{i + 1}.], rect, [])
|
||||
}
|
||||
|
||||
#grid(
|
||||
|
@ -7,7 +7,7 @@
|
||||
align(center, square(size: 20pt, 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(center, rect(fill: conifer, height: 10pt)),
|
||||
rect(fill: forest, height: 10pt),
|
||||
|
Loading…
x
Reference in New Issue
Block a user