From 3aeb150c95f9ae55ded7233b86108be18c3028db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20d=27Herbais=20de=20Thun?= Date: Wed, 3 Jan 2024 10:43:08 +0100 Subject: [PATCH] Added `to-absolute` method to length. (#3117) Co-authored-by: Laurenz --- crates/typst/src/layout/length.rs | 34 ++++++++++++++++++++++++++++++- tests/typ/compiler/methods.typ | 17 ++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/crates/typst/src/layout/length.rs b/crates/typst/src/layout/length.rs index 587085d32..26b9320bf 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 f3ec44347..262f14972 100644 --- a/tests/typ/compiler/methods.typ +++ b/tests/typ/compiler/methods.typ @@ -81,6 +81,23 @@ #test(5em.abs.cm(), 0.0) #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