diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-04-08 15:08:26 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-04-08 15:45:14 +0200 |
| commit | 712c00ecb72b67da2c0788e5d3eb4dcc6366b2a7 (patch) | |
| tree | f5d7ef4341a4728c980d020cc173fa6bb70feaff /src/eval/raw.rs | |
| parent | 977ac77e6a3298be2644a8231e93acbef9f7f396 (diff) | |
Em units
Diffstat (limited to 'src/eval/raw.rs')
| -rw-r--r-- | src/eval/raw.rs | 133 |
1 files changed, 131 insertions, 2 deletions
diff --git a/src/eval/raw.rs b/src/eval/raw.rs index 337638f9..622a0562 100644 --- a/src/eval/raw.rs +++ b/src/eval/raw.rs @@ -1,8 +1,9 @@ use std::fmt::{self, Debug, Formatter}; +use std::ops::{Add, Div, Mul, Neg}; use super::{Resolve, StyleChain}; -use crate::geom::{Align, SpecAxis}; -use crate::library::text::ParNode; +use crate::geom::{Align, Em, Length, Numeric, Relative, SpecAxis}; +use crate::library::text::{ParNode, TextNode}; /// The unresolved alignment representation. #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] @@ -47,3 +48,131 @@ impl Debug for RawAlign { } } } + +/// The unresolved length representation. +/// +/// Currently supports absolute and em units, but support could quite easily be +/// extended to other units that can be resolved through a style chain. +/// Probably, it would be a good idea to then move to an enum representation +/// that has a small footprint and allocates for the rare case that units are +/// mixed. +#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] +pub struct RawLength { + /// The absolute part. + pub length: Length, + /// The font-relative part. + pub em: Em, +} + +impl RawLength { + /// The zero length. + pub const fn zero() -> Self { + Self { length: Length::zero(), em: Em::zero() } + } +} + +impl Debug for RawLength { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match (self.length.is_zero(), self.em.is_zero()) { + (false, false) => write!(f, "{:?} + {:?}", self.length, self.em), + (true, false) => self.em.fmt(f), + (_, true) => self.length.fmt(f), + } + } +} + +impl Resolve for Em { + type Output = Length; + + fn resolve(self, styles: StyleChain) -> Self::Output { + if self.is_zero() { + Length::zero() + } else { + self.at(styles.get(TextNode::SIZE)) + } + } +} + +impl Resolve for RawLength { + type Output = Length; + + fn resolve(self, styles: StyleChain) -> Self::Output { + self.length + self.em.resolve(styles) + } +} + +impl From<Length> for RawLength { + fn from(length: Length) -> Self { + Self { length, em: Em::zero() } + } +} + +impl From<Em> for RawLength { + fn from(em: Em) -> Self { + Self { length: Length::zero(), em } + } +} + +impl From<Length> for Relative<RawLength> { + fn from(length: Length) -> Self { + Relative::from(RawLength::from(length)) + } +} + +impl Numeric for RawLength { + fn zero() -> Self { + Self::zero() + } + + fn is_finite(self) -> bool { + self.length.is_finite() && self.em.is_finite() + } +} + +impl Neg for RawLength { + type Output = Self; + + fn neg(self) -> Self::Output { + Self { length: -self.length, em: -self.em } + } +} + +impl Add for RawLength { + type Output = Self; + + fn add(self, rhs: Self) -> Self::Output { + Self { + length: self.length + rhs.length, + em: self.em + rhs.em, + } + } +} + +sub_impl!(RawLength - RawLength -> RawLength); + +impl Mul<f64> for RawLength { + type Output = Self; + + fn mul(self, rhs: f64) -> Self::Output { + Self { + length: self.length * rhs, + em: self.em * rhs, + } + } +} + +impl Div<f64> for RawLength { + type Output = Self; + + fn div(self, rhs: f64) -> Self::Output { + Self { + length: self.length / rhs, + em: self.em / rhs, + } + } +} + +assign_impl!(RawLength += RawLength); +assign_impl!(RawLength -= RawLength); +assign_impl!(RawLength *= f64); +assign_impl!(RawLength /= f64); |
