hpx_browser/layout/
layout_unit.rs1const 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}