diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-05-04 22:14:51 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-05-04 22:14:51 +0200 |
| commit | 75472fee1a2377f56551fc856cf7511bd55091f0 (patch) | |
| tree | 72b221fd2bd3ddd2dceb6b443d480fcae9298932 /src | |
| parent | ba5622b7b90b23e61942a9f4e6460bf9ea0b4bc8 (diff) | |
Division for lengths
Diffstat (limited to 'src')
| -rw-r--r-- | src/eval/ops.rs | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/src/eval/ops.rs b/src/eval/ops.rs index 56bfdf2e..57390a65 100644 --- a/src/eval/ops.rs +++ b/src/eval/ops.rs @@ -2,9 +2,9 @@ use std::cmp::Ordering; -use super::{Dynamic, RawAlign, RawStroke, Smart, StrExt, Value}; +use super::{Dynamic, RawAlign, RawLength, RawStroke, Smart, StrExt, Value}; use crate::diag::StrResult; -use crate::geom::{Numeric, Spec, SpecAxis}; +use crate::geom::{Numeric, Relative, Spec, SpecAxis}; use crate::model; use Value::*; @@ -204,6 +204,8 @@ pub fn div(lhs: Value, rhs: Value) -> StrResult<Value> { (Length(a), Int(b)) => Length(a / b as f64), (Length(a), Float(b)) => Length(a / b), + (Length(a), Length(b)) => Float(div_length(a, b)?), + (Length(a), Relative(b)) if b.rel.is_zero() => Float(div_length(a, b.abs)?), (Angle(a), Int(b)) => Angle(a / b as f64), (Angle(a), Float(b)) => Angle(a / b), @@ -212,9 +214,13 @@ pub fn div(lhs: Value, rhs: Value) -> StrResult<Value> { (Ratio(a), Int(b)) => Ratio(a / b as f64), (Ratio(a), Float(b)) => Ratio(a / b), (Ratio(a), Ratio(b)) => Float(a / b), + (Ratio(a), Relative(b)) if b.abs.is_zero() => Float(a / b.rel), (Relative(a), Int(b)) => Relative(a / b as f64), (Relative(a), Float(b)) => Relative(a / b), + (Relative(a), Length(b)) if a.rel.is_zero() => Float(div_length(a.abs, b)?), + (Relative(a), Ratio(b)) if a.abs.is_zero() => Float(a.rel / b), + (Relative(a), Relative(b)) => Float(div_relative(a, b)?), (Fraction(a), Int(b)) => Fraction(a / b as f64), (Fraction(a), Float(b)) => Fraction(a / b), @@ -224,6 +230,28 @@ pub fn div(lhs: Value, rhs: Value) -> StrResult<Value> { }) } +/// Try to divide two lengths. +fn div_length(a: RawLength, b: RawLength) -> StrResult<f64> { + if a.length.is_zero() && b.length.is_zero() { + Ok(a.em / b.em) + } else if a.em.is_zero() && b.em.is_zero() { + Ok(a.length / b.length) + } else { + return Err("cannot divide these two lengths".into()); + } +} + +/// Try to divide two relative lengths. +fn div_relative(a: Relative<RawLength>, b: Relative<RawLength>) -> StrResult<f64> { + if a.rel.is_zero() && b.rel.is_zero() { + div_length(a.abs, b.abs) + } else if a.abs.is_zero() && b.abs.is_zero() { + Ok(a.rel / b.rel) + } else { + return Err("cannot divide these two relative lengths".into()); + } +} + /// Compute the logical "not" of a value. pub fn not(value: Value) -> StrResult<Value> { match value { |
