sequoia_layout/
box_model.rs1use sequoia_core::{Edges, Rect, Size};
4
5#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7#[non_exhaustive]
8pub enum ShrinkAxis {
9 Both,
11 Horizontal,
13 Vertical,
15}
16
17pub fn shrink_by_padding(size: Size, padding: Edges) -> Size {
21 Size::new(
22 (size.width - padding.horizontal_sum()).max(0.0),
23 (size.height - padding.vertical_sum()).max(0.0),
24 )
25}
26
27pub fn shrink_by_margin(size: Size, margin: Edges) -> Size {
31 Size::new(
32 (size.width - margin.horizontal_sum()).max(0.0),
33 (size.height - margin.vertical_sum()).max(0.0),
34 )
35}
36
37pub fn inset_rect(rect: Rect, padding: Edges) -> Rect {
39 Rect::from_xywh(
40 rect.left() + padding.left,
41 rect.top() + padding.top,
42 (rect.size.width - padding.horizontal_sum()).max(0.0),
43 (rect.size.height - padding.vertical_sum()).max(0.0),
44 )
45}
46
47pub fn apply_aspect_ratio(
53 w: f32,
54 h: f32,
55 w_auto: bool,
56 h_auto: bool,
57 ratio: Option<f32>,
58) -> (f32, f32) {
59 let Some(r) = ratio else { return (w, h) };
60 if !r.is_finite() || r <= 0.0 {
61 return (w, h);
62 }
63 match (w_auto, h_auto) {
64 (true, false) => ((h * r).max(0.0), h),
65 (false, true) => (w, if r != 0.0 { (w / r).max(0.0) } else { h }),
66 (true, true) => {
67 if w <= 0.0 && h > 0.0 {
68 ((h * r).max(0.0), h)
69 } else if h <= 0.0 && w > 0.0 {
70 (w, (w / r).max(0.0))
71 } else {
72 (w, h)
73 }
74 }
75 (false, false) => (w, h),
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[test]
84 fn padding_shrinks_content_box() {
85 let s = shrink_by_padding(Size::new(100.0, 60.0), Edges::xy(10.0, 5.0));
86 assert_eq!(s, Size::new(80.0, 50.0));
87 let s = shrink_by_padding(Size::new(5.0, 5.0), Edges::all(10.0));
88 assert_eq!(s, Size::ZERO);
89 }
90
91 #[test]
92 fn aspect_derives_auto_axis() {
93 assert_eq!(
94 apply_aspect_ratio(0.0, 50.0, true, false, Some(2.0)),
95 (100.0, 50.0)
96 );
97 assert_eq!(
98 apply_aspect_ratio(100.0, 0.0, false, true, Some(2.0)),
99 (100.0, 50.0)
100 );
101 assert_eq!(
102 apply_aspect_ratio(100.0, 50.0, false, false, Some(2.0)),
103 (100.0, 50.0)
104 );
105 assert_eq!(
106 apply_aspect_ratio(10.0, 10.0, true, true, Some(2.0)),
107 (10.0, 10.0)
108 );
109 }
110}