summaryrefslogtreecommitdiff
path: root/library/src/layout/spacing.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-11-03 11:44:53 +0100
committerLaurenz <laurmaedje@gmail.com>2022-11-03 13:35:39 +0100
commit37a7afddfaffd44cb9bc013c9506599267e08983 (patch)
tree20e7d62d3c5418baff01a21d0406b91bf3096214 /library/src/layout/spacing.rs
parent56342bd972a13ffe21beaf2b87ab7eb1597704b4 (diff)
Split crates
Diffstat (limited to 'library/src/layout/spacing.rs')
-rw-r--r--library/src/layout/spacing.rs100
1 files changed, 100 insertions, 0 deletions
diff --git a/library/src/layout/spacing.rs b/library/src/layout/spacing.rs
new file mode 100644
index 00000000..67fff5db
--- /dev/null
+++ b/library/src/layout/spacing.rs
@@ -0,0 +1,100 @@
+use std::cmp::Ordering;
+
+use crate::prelude::*;
+use crate::text::ParNode;
+
+/// Horizontal spacing.
+#[derive(Debug, Clone, Hash)]
+pub struct HNode {
+ pub amount: Spacing,
+ pub weak: bool,
+}
+
+#[node]
+impl HNode {
+ fn construct(_: &mut Vm, args: &mut Args) -> SourceResult<Content> {
+ let amount = args.expect("spacing")?;
+ let weak = args.named("weak")?.unwrap_or(false);
+ Ok(Self { amount, weak }.pack())
+ }
+}
+
+/// Vertical spacing.
+#[derive(Debug, Clone, Hash)]
+pub struct VNode {
+ pub amount: Spacing,
+ pub weak: bool,
+ pub generated: bool,
+}
+
+#[node]
+impl VNode {
+ fn construct(_: &mut Vm, args: &mut Args) -> SourceResult<Content> {
+ let amount = args.expect("spacing")?;
+ let weak = args.named("weak")?.unwrap_or(false);
+ Ok(Self { amount, weak, generated: false }.pack())
+ }
+}
+
+/// Kinds of spacing.
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub enum Spacing {
+ /// Spacing specified in absolute terms and relative to the parent's size.
+ Relative(Rel<Length>),
+ /// Spacing specified as a fraction of the remaining free space in the
+ /// parent.
+ Fractional(Fr),
+}
+
+impl Spacing {
+ /// Whether this is fractional spacing.
+ pub fn is_fractional(self) -> bool {
+ matches!(self, Self::Fractional(_))
+ }
+}
+
+impl From<Abs> for Spacing {
+ fn from(abs: Abs) -> Self {
+ Self::Relative(abs.into())
+ }
+}
+
+impl PartialOrd for Spacing {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ match (self, other) {
+ (Self::Relative(a), Self::Relative(b)) => a.partial_cmp(b),
+ (Self::Fractional(a), Self::Fractional(b)) => a.partial_cmp(b),
+ _ => None,
+ }
+ }
+}
+
+castable! {
+ Spacing,
+ Expected: "relative length or fraction",
+ Value::Length(v) => Self::Relative(v.into()),
+ Value::Ratio(v) => Self::Relative(v.into()),
+ Value::Relative(v) => Self::Relative(v),
+ Value::Fraction(v) => Self::Fractional(v),
+}
+
+/// Spacing around and between blocks, relative to paragraph spacing.
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub struct BlockSpacing(Rel<Length>);
+
+castable!(BlockSpacing: Rel<Length>);
+
+impl Resolve for BlockSpacing {
+ type Output = Abs;
+
+ fn resolve(self, styles: StyleChain) -> Self::Output {
+ let whole = styles.get(ParNode::SPACING);
+ self.0.resolve(styles).relative_to(whole)
+ }
+}
+
+impl From<Ratio> for BlockSpacing {
+ fn from(ratio: Ratio) -> Self {
+ Self(ratio.into())
+ }
+}