Skip to main content

hpx_browser/layout/
resolve.rs

1use crate::css_values::types::length::*;
2
3pub struct ResolveContext {
4    pub font_size: f32,
5    pub root_font_size: f32,
6    pub viewport_w: f32,
7    pub viewport_h: f32,
8}
9
10impl Default for ResolveContext {
11    fn default() -> Self {
12        Self {
13            font_size: 16.0,
14            root_font_size: 16.0,
15            viewport_w: 1920.0,
16            viewport_h: 1080.0,
17        }
18    }
19}
20
21pub fn resolve_length(length: &Length, ctx: &ResolveContext) -> f32 {
22    match length {
23        Length::Px(v) => *v as f32,
24        Length::Em(v) => *v as f32 * ctx.font_size,
25        Length::Rem(v) => *v as f32 * ctx.root_font_size,
26        Length::Vw(v) => *v as f32 * ctx.viewport_w / 100.0,
27        Length::Vh(v) => *v as f32 * ctx.viewport_h / 100.0,
28        Length::Vmin(v) => *v as f32 * ctx.viewport_w.min(ctx.viewport_h) / 100.0,
29        Length::Vmax(v) => *v as f32 * ctx.viewport_w.max(ctx.viewport_h) / 100.0,
30        Length::Cm(v) => *v as f32 * 96.0 / 2.54,
31        Length::Mm(v) => *v as f32 * 96.0 / 25.4,
32        Length::In(v) => *v as f32 * 96.0,
33        Length::Pt(v) => *v as f32 * 4.0 / 3.0,
34        Length::Pc(v) => *v as f32 * 16.0,
35        Length::Ch(v) => *v as f32 * ctx.font_size * 0.5,
36        Length::Ex(v) => *v as f32 * ctx.font_size * 0.5,
37        Length::Zero => 0.0,
38    }
39}
40
41pub fn resolve_length_percentage(
42    lp: &LengthPercentage,
43    ctx: &ResolveContext,
44    reference_size: f32,
45) -> f32 {
46    match lp {
47        LengthPercentage::Length(l) => resolve_length(l, ctx),
48        LengthPercentage::Percentage(p) => *p as f32 / 100.0 * reference_size,
49    }
50}
51
52pub fn resolve_length_percentage_auto(
53    lpa: &LengthPercentageAuto,
54    ctx: &ResolveContext,
55    reference_size: f32,
56) -> Option<f32> {
57    match lpa {
58        LengthPercentageAuto::Length(l) => Some(resolve_length(l, ctx)),
59        LengthPercentageAuto::Percentage(p) => Some(*p as f32 / 100.0 * reference_size),
60        LengthPercentageAuto::Auto => None,
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    fn ctx() -> ResolveContext {
69        ResolveContext::default()
70    }
71
72    #[test]
73    fn resolve_px() {
74        assert_eq!(resolve_length(&Length::Px(100.0), &ctx()), 100.0);
75    }
76
77    #[test]
78    fn resolve_em() {
79        let mut c = ctx();
80        c.font_size = 20.0;
81        assert_eq!(resolve_length(&Length::Em(2.0), &c), 40.0);
82    }
83
84    #[test]
85    fn resolve_rem() {
86        let mut c = ctx();
87        c.root_font_size = 18.0;
88        assert_eq!(resolve_length(&Length::Rem(1.5), &c), 27.0);
89    }
90
91    #[test]
92    fn resolve_vw() {
93        assert_eq!(resolve_length(&Length::Vw(50.0), &ctx()), 960.0);
94    }
95
96    #[test]
97    fn resolve_percentage() {
98        let lp = LengthPercentage::Percentage(50.0);
99        assert_eq!(resolve_length_percentage(&lp, &ctx(), 200.0), 100.0);
100    }
101
102    #[test]
103    fn resolve_auto() {
104        let lpa = LengthPercentageAuto::Auto;
105        assert_eq!(resolve_length_percentage_auto(&lpa, &ctx(), 200.0), None);
106    }
107
108    #[test]
109    fn resolve_zero() {
110        assert_eq!(resolve_length(&Length::Zero, &ctx()), 0.0);
111    }
112}