use sequoia_core::{Edges, Rect, Size};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum ShrinkAxis {
Both,
Horizontal,
Vertical,
}
pub fn shrink_by_padding(size: Size, padding: Edges) -> Size {
Size::new(
(size.width - padding.horizontal_sum()).max(0.0),
(size.height - padding.vertical_sum()).max(0.0),
)
}
pub fn shrink_by_margin(size: Size, margin: Edges) -> Size {
Size::new(
(size.width - margin.horizontal_sum()).max(0.0),
(size.height - margin.vertical_sum()).max(0.0),
)
}
pub fn inset_rect(rect: Rect, padding: Edges) -> Rect {
Rect::from_xywh(
rect.left() + padding.left,
rect.top() + padding.top,
(rect.size.width - padding.horizontal_sum()).max(0.0),
(rect.size.height - padding.vertical_sum()).max(0.0),
)
}
pub fn apply_aspect_ratio(
w: f32,
h: f32,
w_auto: bool,
h_auto: bool,
ratio: Option<f32>,
) -> (f32, f32) {
let Some(r) = ratio else { return (w, h) };
if !r.is_finite() || r <= 0.0 {
return (w, h);
}
match (w_auto, h_auto) {
(true, false) => ((h * r).max(0.0), h),
(false, true) => (w, if r != 0.0 { (w / r).max(0.0) } else { h }),
(true, true) => {
if w <= 0.0 && h > 0.0 {
((h * r).max(0.0), h)
} else if h <= 0.0 && w > 0.0 {
(w, (w / r).max(0.0))
} else {
(w, h)
}
}
(false, false) => (w, h),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn padding_shrinks_content_box() {
let s = shrink_by_padding(Size::new(100.0, 60.0), Edges::xy(10.0, 5.0));
assert_eq!(s, Size::new(80.0, 50.0));
let s = shrink_by_padding(Size::new(5.0, 5.0), Edges::all(10.0));
assert_eq!(s, Size::ZERO);
}
#[test]
fn aspect_derives_auto_axis() {
assert_eq!(
apply_aspect_ratio(0.0, 50.0, true, false, Some(2.0)),
(100.0, 50.0)
);
assert_eq!(
apply_aspect_ratio(100.0, 0.0, false, true, Some(2.0)),
(100.0, 50.0)
);
assert_eq!(
apply_aspect_ratio(100.0, 50.0, false, false, Some(2.0)),
(100.0, 50.0)
);
assert_eq!(
apply_aspect_ratio(10.0, 10.0, true, true, Some(2.0)),
(10.0, 10.0)
);
}
}