Skip to main content

takumi_css/style/
sizing.rs

1use std::rc::Rc;
2
3use taffy::Size;
4
5use crate::Viewport;
6use crate::style::CalcArena;
7
8/// The sizing context used for length value resolving.
9#[derive(Clone)]
10pub struct SizingContext {
11  /// The viewport for the image renderer.
12  pub viewport: Viewport,
13  /// The nearest query container size (content box) in device pixels.
14  pub container_size: Size<Option<f32>>,
15  /// The font size in pixels.
16  pub font_size: f32,
17  /// Computed `font-size` of the root element in device pixels. `None` before
18  /// the root has been resolved; readers should fall back to `viewport.font_size`.
19  /// https://www.w3.org/TR/css-values-4/#rem
20  pub root_font_size: Option<f32>,
21  /// Pixel basis for the `lh` unit.
22  pub line_height: f32,
23  /// Pixel basis for the `rlh` unit; `None` before root is resolved.
24  pub root_line_height: Option<f32>,
25  /// The calc arena shared by the current layout tree.
26  pub calc_arena: Rc<CalcArena>,
27}
28
29impl SizingContext {
30  /// Test/bench helper. Exposed (not `#[cfg(test)]`) so dependent crates can
31  /// build a context in their own tests.
32  #[doc(hidden)]
33  pub fn new_test(viewport: Viewport) -> Self {
34    // Seed device-pixel metrics so `em`/`lh` conversions don't collapse to zero
35    // or drift at non-1.0 DPR.
36    let font_size = viewport.font_size * viewport.device_pixel_ratio;
37    Self {
38      viewport,
39      container_size: Size::NONE,
40      font_size,
41      root_font_size: None,
42      line_height: font_size,
43      root_line_height: None,
44      calc_arena: Rc::new(CalcArena::default()),
45    }
46  }
47
48  /// Device-pixel basis for the `rem` unit.
49  pub fn rem_basis(&self) -> f32 {
50    self
51      .root_font_size
52      .unwrap_or(self.viewport.font_size * self.viewport.device_pixel_ratio)
53  }
54
55  pub fn root_line_height_basis(&self) -> f32 {
56    self.root_line_height.unwrap_or(self.line_height)
57  }
58
59  pub fn query_container_width(&self) -> f32 {
60    self
61      .container_size
62      .width
63      .unwrap_or(self.viewport.size.width.unwrap_or_default() as f32)
64  }
65
66  pub fn query_container_height(&self) -> f32 {
67    self
68      .container_size
69      .height
70      .unwrap_or(self.viewport.size.height.unwrap_or_default() as f32)
71  }
72}