Skip to main content

hpx_browser/layout/
layout_unit.rs

1const SHIFT: i32 = 6;
2const ONE_PX: i32 = 1 << SHIFT;
3const SCALE_F64: f64 = ONE_PX as f64;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]
6pub struct LayoutUnit(i32);
7
8impl LayoutUnit {
9    pub const ZERO: LayoutUnit = LayoutUnit(0);
10
11    pub fn from_f64_px(v: f64) -> Self {
12        if !v.is_finite() {
13            return LayoutUnit::ZERO;
14        }
15        let scaled = (v * SCALE_F64).round();
16        let clamped = scaled.clamp(i32::MIN as f64, i32::MAX as f64) as i32;
17        LayoutUnit(clamped)
18    }
19
20    pub fn from_taffy_f32(v: f32) -> Self {
21        Self::from_f64_px(v as f64)
22    }
23
24    pub fn to_f64_px(self) -> f64 {
25        (self.0 as f64) / SCALE_F64
26    }
27
28    pub fn raw(self) -> i32 {
29        self.0
30    }
31}
32
33impl std::ops::Add for LayoutUnit {
34    type Output = LayoutUnit;
35    fn add(self, rhs: Self) -> Self::Output {
36        LayoutUnit(self.0.saturating_add(rhs.0))
37    }
38}
39
40impl std::ops::Sub for LayoutUnit {
41    type Output = LayoutUnit;
42    fn sub(self, rhs: Self) -> Self::Output {
43        LayoutUnit(self.0.saturating_sub(rhs.0))
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50
51    #[test]
52    fn quantizes_to_64ths() {
53        let v = LayoutUnit::from_f64_px(1.3);
54        assert_eq!(v.to_f64_px(), 1.296875);
55        assert_eq!(v.raw(), 83);
56    }
57
58    #[test]
59    fn integer_pixels_round_trip() {
60        let v = LayoutUnit::from_f64_px(100.0);
61        assert_eq!(v.to_f64_px(), 100.0);
62    }
63
64    #[test]
65    fn nan_becomes_zero() {
66        let v = LayoutUnit::from_f64_px(f64::NAN);
67        assert_eq!(v.raw(), 0);
68    }
69
70    #[test]
71    fn from_taffy_f32_quantizes() {
72        let v = LayoutUnit::from_taffy_f32(1.3);
73        assert_eq!(v.to_f64_px(), 1.296875);
74    }
75}