gioser

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 497HTML 254C 19JavaScript 81329 Sutichaykuna

⎇ 0.2.x src/compute/leaf.rs Rust · 86 siq'ikuna · 3.7 KB Ñawpa willay Pi imata llamkarqan ch'uya

Release/0.2.2 (#281) df9799325 · Nico Burns ·

1//! Computes size using styles and measure functions
2
3use crate::geometry::Size;
4use crate::layout::{AvailableSpace, RunMode, SizingMode};
5use crate::math::MaybeMath;
6use crate::node::Node;
7use crate::resolve::{MaybeResolve, ResolveOrDefault};
8use crate::tree::LayoutTree;
9
10#[cfg(feature = "debug")]
11use crate::debug::NODE_LOGGER;
12
13/// Compute the size of a leaf node (node with no children)
14pub(crate) fn compute(
15    tree: &mut impl LayoutTree,
16    node: Node,
17    known_dimensions: Size<Option<f32>>,
18    available_space: Size<AvailableSpace>,
19    _run_mode: RunMode,
20    sizing_mode: SizingMode,
21) -> Size<f32> {
22    let style = tree.style(node);
23
24    // Resolve node's preferred/min/max sizes (width/heights) against the available space (percentages resolve to pixel values)
25    // For ContentSize mode, we pretend that the node has no size styles as these should be ignored.
26    let (node_size, node_min_size, node_max_size) = match sizing_mode {
27        SizingMode::ContentSize => {
28            let node_size = known_dimensions;
29            let node_min_size = Size::NONE;
30            let node_max_size = Size::NONE;
31            (node_size, node_min_size, node_max_size)
32        }
33        SizingMode::InherentSize => {
34            let style_size = style.size.maybe_resolve(available_space.as_options());
35            let node_size = known_dimensions.or(style_size);
36            let node_min_size = style.min_size.maybe_resolve(available_space.as_options());
37            let node_max_size = style.max_size.maybe_resolve(available_space.as_options());
38            (node_size, node_min_size, node_max_size)
39        }
40    };
41
42    #[cfg(feature = "debug")]
43    NODE_LOGGER.log("LEAF");
44    #[cfg(feature = "debug")]
45    NODE_LOGGER.labelled_debug_log("node_size", node_size);
46    #[cfg(feature = "debug")]
47    NODE_LOGGER.labelled_debug_log("min_size ", node_min_size);
48    #[cfg(feature = "debug")]
49    NODE_LOGGER.labelled_debug_log("max_size ", node_max_size);
50
51    // Return early if both width and height are known
52    if let Size { width: Some(width), height: Some(height) } = node_size {
53        return Size { width, height }.maybe_clamp(node_min_size, node_max_size);
54    };
55
56    if tree.needs_measure(node) {
57        // Compute available space
58        let available_space = Size {
59            width: available_space.width.maybe_set(node_size.width),
60            height: available_space.height.maybe_set(node_size.height),
61        };
62
63        // Measure node
64        let measured_size = tree.measure_node(node, known_dimensions, available_space);
65
66        return node_size.unwrap_or(measured_size).maybe_clamp(node_min_size, node_max_size);
67    }
68
69    // Note: both horizontal and vertical percentage padding/borders are resolved against the container's inline size (i.e. width).
70    // This is not a bug, but is how CSS is specified (see: https://developer.mozilla.org/en-US/docs/Web/CSS/padding#values)
71    let padding = style.padding.resolve_or_default(available_space.width.into_option());
72    let border = style.border.resolve_or_default(available_space.width.into_option());
73
74    Size {
75        width: node_size
76            .width
77            // .unwrap_or(0.0) + padding.horizontal_axis_sum() + border.horizontal_axis_sum(), // content-box
78            .unwrap_or(0.0 + padding.horizontal_axis_sum() + border.horizontal_axis_sum()) // border-box
79            .maybe_clamp(node_min_size.width, node_max_size.width),
80        height: node_size
81            .height
82            // .unwrap_or(0.0) + padding.vertical_axis_sum() + border.vertical_axis_sum(), // content-box
83            .unwrap_or(0.0 + padding.vertical_axis_sum() + border.vertical_axis_sum()) // border-box
84            .maybe_clamp(node_min_size.height, node_max_size.height),
85    }
86}