summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSébastien d'Herbais de Thun <sebastien.d.herbais@gmail.com>2024-01-03 10:43:08 +0100
committerGitHub <noreply@github.com>2024-01-03 09:43:08 +0000
commit3aeb150c95f9ae55ded7233b86108be18c3028db (patch)
tree470ec3212b2ab10e33301068715a6423be39fa85
parent28a5069f959a4276b8280a78c925448f93d7121e (diff)
Added `to-absolute` method to length. (#3117)
Co-authored-by: Laurenz <laurmaedje@gmail.com>
-rw-r--r--crates/typst/src/layout/length.rs34
-rw-r--r--tests/typ/compiler/methods.typ17
2 files changed, 50 insertions, 1 deletions
diff --git a/crates/typst/src/layout/length.rs b/crates/typst/src/layout/length.rs
index 587085d3..26b9320b 100644
--- a/crates/typst/src/layout/length.rs
+++ b/crates/typst/src/layout/length.rs
@@ -5,7 +5,7 @@ use std::ops::{Add, Div, Mul, Neg};
use ecow::{eco_format, EcoString};
use crate::diag::{At, Hint, SourceResult};
-use crate::foundations::{func, scope, ty, Repr, Resolve, StyleChain};
+use crate::foundations::{func, scope, ty, Repr, Resolve, StyleChain, Styles};
use crate::layout::{Abs, Em};
use crate::syntax::Span;
use crate::util::Numeric;
@@ -132,6 +132,38 @@ impl Length {
self.ensure_that_em_is_zero(span, "inches")?;
Ok(self.abs.to_inches())
}
+
+ /// Resolve this length to an absolute length.
+ ///
+ /// ```example
+ /// #set text(size: 12pt)
+ /// #style(styles => [
+ /// #(6pt).to-absolute(styles) \
+ /// #(6pt + 10em).to-absolute(styles) \
+ /// #(10em).to-absolute(styles)
+ /// ])
+ ///
+ /// #set text(size: 6pt)
+ /// #style(styles => [
+ /// #(6pt).to-absolute(styles) \
+ /// #(6pt + 10em).to-absolute(styles) \
+ /// #(10em).to-absolute(styles)
+ /// ])
+ /// ```
+ #[func]
+ pub fn to_absolute(
+ &self,
+ /// The styles to resolve the length with.
+ ///
+ /// Since a length can use font-relative em units, resolving it to an
+ /// absolute length requires knowledge of the font size. This size is
+ /// provided through these styles. You can obtain the styles using
+ /// the [`style`]($style) function.
+ styles: Styles,
+ ) -> Length {
+ let styles = StyleChain::new(&styles);
+ self.resolve(styles).into()
+ }
}
impl Debug for Length {
diff --git a/tests/typ/compiler/methods.typ b/tests/typ/compiler/methods.typ
index f3ec4434..262f1497 100644
--- a/tests/typ/compiler/methods.typ
+++ b/tests/typ/compiler/methods.typ
@@ -82,6 +82,23 @@
#test((5em + 6in).abs.inches(), 6.0)
---
+// Test length `to-absolute` method.
+
+#set text(size: 12pt)
+#style(styles => {
+ test((6pt).to-absolute(styles), 6pt)
+ test((6pt + 10em).to-absolute(styles), 126pt)
+ test((10em).to-absolute(styles), 120pt)
+})
+
+#set text(size: 64pt)
+#style(styles => {
+ test((6pt).to-absolute(styles), 6pt)
+ test((6pt + 10em).to-absolute(styles), 646pt)
+ test((10em).to-absolute(styles), 640pt)
+})
+
+---
// Error: 2-21 cannot convert a length with non-zero em units (`-6pt + 10.5em`) to pt
// Hint: 2-21 use `length.abs.pt()` instead to ignore its em component
#(10.5em - 6pt).pt()