Skip to main content

cranpose_render_common/
geometry.rs

1use cranpose_ui_graphics::Rect;
2
3pub const BLUR_EXTENT_MULTIPLIER: f32 = 3.0;
4
5pub fn union_rect(lhs: Option<Rect>, rhs: Rect) -> Option<Rect> {
6    if rhs.width <= 0.0 || rhs.height <= 0.0 {
7        return lhs;
8    }
9
10    Some(match lhs {
11        Some(current) => current.union(rhs),
12        None => rhs,
13    })
14}
15
16pub fn blur_extent_margin(blur_radius: f32) -> f32 {
17    (blur_radius.max(0.0) * BLUR_EXTENT_MULTIPLIER).max(1.0)
18}
19
20pub fn expand_blurred_rect(mut rect: Rect, blur_radius: f32, clip: Option<Rect>) -> Option<Rect> {
21    let blur_margin = blur_extent_margin(blur_radius);
22    rect.x -= blur_margin;
23    rect.y -= blur_margin;
24    rect.width += blur_margin * 2.0;
25    rect.height += blur_margin * 2.0;
26    if let Some(clip) = clip {
27        rect = rect.intersect(clip)?;
28    }
29    Some(rect)
30}
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35
36    #[test]
37    fn union_rect_ignores_empty_rhs() {
38        let lhs = Some(Rect {
39            x: 1.0,
40            y: 2.0,
41            width: 3.0,
42            height: 4.0,
43        });
44        let rhs = Rect {
45            x: 5.0,
46            y: 6.0,
47            width: 0.0,
48            height: 7.0,
49        };
50
51        assert_eq!(union_rect(lhs, rhs), lhs);
52    }
53
54    #[test]
55    fn union_rect_merges_extents() {
56        let lhs = Some(Rect {
57            x: 8.0,
58            y: 4.0,
59            width: 3.0,
60            height: 5.0,
61        });
62        let rhs = Rect {
63            x: 2.0,
64            y: 7.0,
65            width: 12.0,
66            height: 4.0,
67        };
68
69        assert_eq!(
70            union_rect(lhs, rhs),
71            Some(Rect {
72                x: 2.0,
73                y: 4.0,
74                width: 12.0,
75                height: 7.0,
76            })
77        );
78    }
79
80    #[test]
81    fn blur_extent_margin_has_minimum_one_pixel() {
82        assert_eq!(blur_extent_margin(0.0), 1.0);
83        assert_eq!(blur_extent_margin(-5.0), 1.0);
84        assert_eq!(blur_extent_margin(2.0), 6.0);
85    }
86
87    #[test]
88    fn expand_blurred_rect_applies_margin_and_clip() {
89        let expanded = expand_blurred_rect(
90            Rect {
91                x: 10.0,
92                y: 20.0,
93                width: 30.0,
94                height: 40.0,
95            },
96            2.0,
97            Some(Rect {
98                x: 8.0,
99                y: 18.0,
100                width: 20.0,
101                height: 20.0,
102            }),
103        );
104
105        assert_eq!(
106            expanded,
107            Some(Rect {
108                x: 8.0,
109                y: 18.0,
110                width: 20.0,
111                height: 20.0,
112            })
113        );
114    }
115}