summaryrefslogtreecommitdiff
path: root/crates/typst-library/src/layout/dir.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2024-10-27 19:04:55 +0100
committerGitHub <noreply@github.com>2024-10-27 18:04:55 +0000
commitbe7cfc85d08c545abfac08098b7b33b4bd71f37e (patch)
treef4137fa2aaa57babae1f7603a9b2ed7e688f43d8 /crates/typst-library/src/layout/dir.rs
parentb8034a343831e8609aec2ec81eb7eeda57aa5d81 (diff)
Split out four new crates (#5302)
Diffstat (limited to 'crates/typst-library/src/layout/dir.rs')
-rw-r--r--crates/typst-library/src/layout/dir.rs132
1 files changed, 132 insertions, 0 deletions
diff --git a/crates/typst-library/src/layout/dir.rs b/crates/typst-library/src/layout/dir.rs
new file mode 100644
index 00000000..9a2e7710
--- /dev/null
+++ b/crates/typst-library/src/layout/dir.rs
@@ -0,0 +1,132 @@
+use ecow::EcoString;
+
+use crate::foundations::{func, scope, ty, Repr};
+use crate::layout::{Axis, Side};
+
+/// The four directions into which content can be laid out.
+///
+/// Possible values are:
+/// - `{ltr}`: Left to right.
+/// - `{rtl}`: Right to left.
+/// - `{ttb}`: Top to bottom.
+/// - `{btt}`: Bottom to top.
+///
+/// These values are available globally and
+/// also in the direction type's scope, so you can write either of the following
+/// two:
+/// ```example
+/// #stack(dir: rtl)[A][B][C]
+/// #stack(dir: direction.rtl)[A][B][C]
+/// ```
+#[ty(scope, name = "direction")]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub enum Dir {
+ /// Left to right.
+ LTR,
+ /// Right to left.
+ RTL,
+ /// Top to bottom.
+ TTB,
+ /// Bottom to top.
+ BTT,
+}
+
+impl Dir {
+ /// Whether this direction points into the positive coordinate direction.
+ ///
+ /// The positive directions are left-to-right and top-to-bottom.
+ pub const fn is_positive(self) -> bool {
+ match self {
+ Self::LTR | Self::TTB => true,
+ Self::RTL | Self::BTT => false,
+ }
+ }
+}
+
+#[scope]
+impl Dir {
+ pub const LTR: Self = Self::LTR;
+ pub const RTL: Self = Self::RTL;
+ pub const TTB: Self = Self::TTB;
+ pub const BTT: Self = Self::BTT;
+
+ /// The axis this direction belongs to, either `{"horizontal"}` or
+ /// `{"vertical"}`.
+ ///
+ /// ```example
+ /// #ltr.axis() \
+ /// #ttb.axis()
+ /// ```
+ #[func]
+ pub const fn axis(self) -> Axis {
+ match self {
+ Self::LTR | Self::RTL => Axis::X,
+ Self::TTB | Self::BTT => Axis::Y,
+ }
+ }
+
+ /// The start point of this direction, as an alignment.
+ ///
+ /// ```example
+ /// #ltr.start() \
+ /// #rtl.start() \
+ /// #ttb.start() \
+ /// #btt.start()
+ /// ```
+ #[func]
+ pub const fn start(self) -> Side {
+ match self {
+ Self::LTR => Side::Left,
+ Self::RTL => Side::Right,
+ Self::TTB => Side::Top,
+ Self::BTT => Side::Bottom,
+ }
+ }
+
+ /// The end point of this direction, as an alignment.
+ ///
+ /// ```example
+ /// #ltr.end() \
+ /// #rtl.end() \
+ /// #ttb.end() \
+ /// #btt.end()
+ /// ```
+ #[func]
+ pub const fn end(self) -> Side {
+ match self {
+ Self::LTR => Side::Right,
+ Self::RTL => Side::Left,
+ Self::TTB => Side::Bottom,
+ Self::BTT => Side::Top,
+ }
+ }
+
+ /// The inverse direction.
+ ///
+ /// ```example
+ /// #ltr.inv() \
+ /// #rtl.inv() \
+ /// #ttb.inv() \
+ /// #btt.inv()
+ /// ```
+ #[func(title = "Inverse")]
+ pub const fn inv(self) -> Dir {
+ match self {
+ Self::LTR => Self::RTL,
+ Self::RTL => Self::LTR,
+ Self::TTB => Self::BTT,
+ Self::BTT => Self::TTB,
+ }
+ }
+}
+
+impl Repr for Dir {
+ fn repr(&self) -> EcoString {
+ match self {
+ Self::LTR => "ltr".into(),
+ Self::RTL => "rtl".into(),
+ Self::TTB => "ttb".into(),
+ Self::BTT => "btt".into(),
+ }
+ }
+}