1use gpui::Pixels;
 2
 3/// Calculates the child’s content-corner radius for a single nested level.
 4///
 5/// child_content_radius = max(0, parent_radius - parent_border - parent_padding + self_border)
 6///
 7/// - parent_radius: outer corner radius of the parent element
 8/// - parent_border: border width of the parent element
 9/// - parent_padding: padding of the parent element
10/// - self_border: border width of this child element (for content inset)
11pub fn inner_corner_radius(
12    parent_radius: Pixels,
13    parent_border: Pixels,
14    parent_padding: Pixels,
15    self_border: Pixels,
16) -> Pixels {
17    (parent_radius - parent_border - parent_padding + self_border).max(Pixels::ZERO)
18}
19
20/// Solver for arbitrarily deep nested corner radii.
21///
22/// Each nested level’s outer border-box radius is:
23///   R₀ = max(0, root_radius - root_border - root_padding)
24///   Rᵢ = max(0, Rᵢ₋₁ - childᵢ₋₁_border - childᵢ₋₁_padding) for i > 0
25pub struct CornerSolver {
26    root_radius: Pixels,
27    root_border: Pixels,
28    root_padding: Pixels,
29    children: Vec<(Pixels, Pixels)>, // (border, padding)
30}
31
32impl CornerSolver {
33    pub const fn new(root_radius: Pixels, root_border: Pixels, root_padding: Pixels) -> Self {
34        Self {
35            root_radius,
36            root_border,
37            root_padding,
38            children: Vec::new(),
39        }
40    }
41
42    pub fn add_child(mut self, border: Pixels, padding: Pixels) -> Self {
43        self.children.push((border, padding));
44        self
45    }
46
47    pub fn corner_radius(&self, level: usize) -> Pixels {
48        if level == 0 {
49            return (self.root_radius - self.root_border - self.root_padding).max(Pixels::ZERO);
50        }
51        if level >= self.children.len() {
52            return Pixels::ZERO;
53        }
54        let mut r = (self.root_radius - self.root_border - self.root_padding).max(Pixels::ZERO);
55        for i in 0..level {
56            let (b, p) = self.children[i];
57            r = (r - b - p).max(Pixels::ZERO);
58        }
59        r
60    }
61}