geo_svg/
viewbox.rs

1#[derive(Default, Debug, Clone, Copy, PartialEq)]
2pub struct ViewBox {
3    pub min_x: Option<f32>,
4    pub min_y: Option<f32>,
5    pub max_x: Option<f32>,
6    pub max_y: Option<f32>,
7}
8
9impl ViewBox {
10    pub fn new(min_x: f32, min_y: f32, max_x: f32, max_y: f32) -> Self {
11        Self {
12            min_x: Some(min_x),
13            min_y: Some(min_y),
14            max_x: Some(max_x),
15            max_y: Some(max_y),
16        }
17    }
18
19    pub fn add(&self, other: &Self) -> Self {
20        Self {
21            min_x: Self::min_option(self.min_x, other.min_x),
22            min_y: Self::min_option(self.min_y, other.min_y),
23            max_x: Self::max_option(self.max_x, other.max_x),
24            max_y: Self::max_option(self.max_y, other.max_y),
25        }
26    }
27
28    pub fn min_x(&self) -> f32 {
29        self.min_x.unwrap_or_default()
30    }
31
32    pub fn min_y(&self) -> f32 {
33        self.min_y.unwrap_or_default()
34    }
35
36    pub fn max_x(&self) -> f32 {
37        self.max_x.unwrap_or_default()
38    }
39
40    pub fn max_y(&self) -> f32 {
41        self.max_y.unwrap_or_default()
42    }
43
44    pub fn width(&self) -> f32 {
45        (self.min_x() - self.max_x()).abs()
46    }
47
48    pub fn height(&self) -> f32 {
49        (self.min_y() - self.max_y()).abs()
50    }
51
52    fn min_option(a: Option<f32>, b: Option<f32>) -> Option<f32> {
53        match (a, b) {
54            (Some(a), Some(b)) => Some(a.min(b)),
55            (Some(a), None) => Some(a),
56            (None, Some(b)) => Some(b),
57            (None, None) => None,
58        }
59    }
60
61    fn max_option(a: Option<f32>, b: Option<f32>) -> Option<f32> {
62        match (a, b) {
63            (Some(a), Some(b)) => Some(a.max(b)),
64            (Some(a), None) => Some(a),
65            (None, Some(b)) => Some(b),
66            (None, None) => None,
67        }
68    }
69
70    pub fn with_margin(mut self, margin: f32) -> Self {
71        self.min_x = self.min_x.map(|x| x - margin);
72        self.min_y = self.min_y.map(|y| y - margin);
73        self.max_x = self.max_x.map(|x| x + margin);
74        self.max_y = self.max_y.map(|y| y + margin);
75        self
76    }
77}