mirror of
https://github.com/typst/typst
synced 2025-05-13 20:46:23 +08:00
Division for lengths
This commit is contained in:
parent
ba5622b7b9
commit
75472fee1a
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
use std::cmp::Ordering;
|
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::diag::StrResult;
|
||||||
use crate::geom::{Numeric, Spec, SpecAxis};
|
use crate::geom::{Numeric, Relative, Spec, SpecAxis};
|
||||||
use crate::model;
|
use crate::model;
|
||||||
use Value::*;
|
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), Int(b)) => Length(a / b as f64),
|
||||||
(Length(a), Float(b)) => Length(a / b),
|
(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), Int(b)) => Angle(a / b as f64),
|
||||||
(Angle(a), Float(b)) => Angle(a / b),
|
(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), Int(b)) => Ratio(a / b as f64),
|
||||||
(Ratio(a), Float(b)) => Ratio(a / b),
|
(Ratio(a), Float(b)) => Ratio(a / b),
|
||||||
(Ratio(a), Ratio(b)) => Float(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), Int(b)) => Relative(a / b as f64),
|
||||||
(Relative(a), Float(b)) => Relative(a / b),
|
(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), Int(b)) => Fraction(a / b as f64),
|
||||||
(Fraction(a), Float(b)) => Fraction(a / b),
|
(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.
|
/// Compute the logical "not" of a value.
|
||||||
pub fn not(value: Value) -> StrResult<Value> {
|
pub fn not(value: Value) -> StrResult<Value> {
|
||||||
match value {
|
match value {
|
||||||
|
@ -38,6 +38,26 @@
|
|||||||
// Error: 03-10 cannot add integer and string
|
// Error: 03-10 cannot add integer and string
|
||||||
{(1 + "2", 40% - 1)}
|
{(1 + "2", 40% - 1)}
|
||||||
|
|
||||||
|
---
|
||||||
|
// Error: 14-22 cannot add integer and string
|
||||||
|
{ let x = 1; x += "2" }
|
||||||
|
|
||||||
|
---
|
||||||
|
// Error: 3-12 cannot divide ratio by length
|
||||||
|
{ 10% / 5pt }
|
||||||
|
|
||||||
|
---
|
||||||
|
// Error: 3-12 cannot divide these two lengths
|
||||||
|
{ 1em / 5pt }
|
||||||
|
|
||||||
|
---
|
||||||
|
// Error: 3-19 cannot divide relative length by ratio
|
||||||
|
{ (10% + 1pt) / 5% }
|
||||||
|
|
||||||
|
---
|
||||||
|
// Error: 3-28 cannot divide these two relative lengths
|
||||||
|
{ (10% + 1pt) / (20% + 1pt) }
|
||||||
|
|
||||||
---
|
---
|
||||||
// Error: 12-19 cannot subtract integer from ratio
|
// Error: 12-19 cannot subtract integer from ratio
|
||||||
{(1234567, 40% - 1)}
|
{(1234567, 40% - 1)}
|
||||||
@ -64,10 +84,6 @@
|
|||||||
{x * "abcdefgh"}
|
{x * "abcdefgh"}
|
||||||
}
|
}
|
||||||
|
|
||||||
---
|
|
||||||
// Error: 14-22 cannot add integer and string
|
|
||||||
{ let x = 1; x += "2" }
|
|
||||||
|
|
||||||
---
|
---
|
||||||
// Error: 3-6 cannot mutate a temporary value
|
// Error: 3-6 cannot mutate a temporary value
|
||||||
{ (x) = "" }
|
{ (x) = "" }
|
||||||
|
@ -48,7 +48,15 @@
|
|||||||
#test({ let x; x = 1 + 4*5 >= 21 and { x = "a"; x + "b" == "ab" }; x }, true)
|
#test({ let x; x = 1 + 4*5 >= 21 and { x = "a"; x + "b" == "ab" }; x }, true)
|
||||||
|
|
||||||
// Mathematical identities.
|
// Mathematical identities.
|
||||||
#let nums = (1, 3.14, 12pt, 45deg, 90%, 13% + 10pt)
|
#let nums = (
|
||||||
|
1, 3.14,
|
||||||
|
12pt, 3em, 12pt + 3em,
|
||||||
|
45deg,
|
||||||
|
90%,
|
||||||
|
13% + 10pt, 5% + 1em + 3pt,
|
||||||
|
2.3fr,
|
||||||
|
)
|
||||||
|
|
||||||
#for v in nums {
|
#for v in nums {
|
||||||
// Test plus and minus.
|
// Test plus and minus.
|
||||||
test(v + v - v, v)
|
test(v + v - v, v)
|
||||||
@ -63,18 +71,16 @@
|
|||||||
test(v + v, 2.0 * v)
|
test(v + v, 2.0 * v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lengths cannot be divided by themselves.
|
if "relative" not in type(v) and ("pt" not in repr(v) or "em" not in repr(v)) {
|
||||||
if "length" not in type(v) {
|
|
||||||
test(v / v, 1.0)
|
test(v / v, 1.0)
|
||||||
test(v / v == 1, true)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure length, ratio and relative length
|
// Make sure length, ratio and relative length
|
||||||
// - can all be added to / subtracted from each other,
|
// - can all be added to / subtracted from each other,
|
||||||
// - multiplied with integers and floats,
|
// - multiplied with integers and floats,
|
||||||
// - divided by floats.
|
// - divided by integers and floats.
|
||||||
#let dims = (10pt, 30%, 50% + 3cm)
|
#let dims = (10pt, 1em, 10pt + 1em, 30%, 50% + 3cm, 40% + 2em + 1cm)
|
||||||
#for a in dims {
|
#for a in dims {
|
||||||
for b in dims {
|
for b in dims {
|
||||||
test(type(a + b), type(a - b))
|
test(type(a + b), type(a - b))
|
||||||
@ -87,6 +93,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test division of different numeric types with zero components.
|
||||||
|
#for a in (0pt, 0em, 0%) {
|
||||||
|
for b in (10pt, 10em, 10%) {
|
||||||
|
test((2 * b) / b, 2)
|
||||||
|
test((a + b * 2) / b, 2)
|
||||||
|
test(b / (b * 2 + a), 0.5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
---
|
---
|
||||||
// Test boolean operators.
|
// Test boolean operators.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user