cranpose_render_common/
geometry.rs1use 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}