buffer_graphics_lib/text/
pos.rs

1use crate::text::PixelFont;
2use graphics_shapes::coord::Coord;
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
8pub enum TextPos {
9    Px(isize, isize),
10    /// See [PixelFont::get_max_characters] for maximum x and y
11    ColRow(usize, usize),
12}
13
14impl TextPos {
15    pub fn to_coord(&self, font: PixelFont) -> (isize, isize) {
16        match self {
17            TextPos::Px(x, y) => (*x, *y),
18            TextPos::ColRow(col, row) => (
19                (col * (font.char_width())) as isize,
20                (row * (font.line_height())) as isize,
21            ),
22        }
23    }
24
25    pub fn px<P: Into<Coord>>(coord: P) -> TextPos {
26        let coord = coord.into();
27        TextPos::Px(coord.x, coord.y)
28    }
29}
30
31pub trait CoordIntoTextPos {
32    fn textpos(self) -> TextPos;
33}
34
35impl CoordIntoTextPos for Coord {
36    fn textpos(self) -> TextPos {
37        TextPos::px(self)
38    }
39}
40
41pub trait NewTextPos<T> {
42    /// Creates a new TextPos::ColRow
43    fn cr(xy: (T, T)) -> TextPos;
44    /// Creates a new TextPos::Px
45    fn px(xy: (T, T)) -> TextPos;
46}
47
48macro_rules! impl_to_px {
49    ($num_type: ty) => {
50        impl NewTextPos<$num_type> for TextPos {
51            /// Calls abs() on x and y
52            fn cr((x, y): ($num_type, $num_type)) -> Self {
53                TextPos::ColRow((x as isize).unsigned_abs(), (y as isize).unsigned_abs())
54            }
55
56            fn px((x, y): ($num_type, $num_type)) -> Self {
57                TextPos::Px(x as isize, y as isize)
58            }
59        }
60    };
61}
62
63impl_to_px!(isize);
64impl_to_px!(i8);
65impl_to_px!(i16);
66impl_to_px!(i32);
67impl_to_px!(i64);
68impl_to_px!(i128);
69impl_to_px!(usize);
70impl_to_px!(u8);
71impl_to_px!(u16);
72impl_to_px!(u32);
73impl_to_px!(u64);
74impl_to_px!(u128);
75impl_to_px!(f32);
76impl_to_px!(f64);
77
78#[cfg(test)]
79mod test {
80    use crate::text::pos::{CoordIntoTextPos, TextPos};
81    use graphics_shapes::coord::Coord;
82
83    #[test]
84    fn coord_textpos() {
85        let coord = Coord::new(0, 0);
86        let test = coord.textpos();
87        assert_eq!(test, TextPos::Px(0, 0))
88    }
89}