embedded_graphics_simulator/
output_settings.rs

1use crate::theme::BinaryColorTheme;
2use embedded_graphics::prelude::*;
3
4/// Output settings.
5#[derive(Debug, PartialEq, Eq, Clone, Copy)]
6pub struct OutputSettings {
7    /// Pixel scale.
8    pub scale: u32,
9    /// Spacing between pixels.
10    pub pixel_spacing: u32,
11    /// Binary color theme.
12    pub theme: BinaryColorTheme,
13}
14
15#[cfg(feature = "with-sdl")]
16impl OutputSettings {
17    /// Translates a output coordinate to the corresponding display coordinate.
18    pub(crate) const fn output_to_display(&self, output_point: Point) -> Point {
19        let pitch = self.pixel_pitch() as i32;
20        Point::new(output_point.x / pitch, output_point.y / pitch)
21    }
22
23    pub(crate) const fn pixel_pitch(&self) -> u32 {
24        self.scale + self.pixel_spacing
25    }
26}
27
28impl Default for OutputSettings {
29    fn default() -> Self {
30        OutputSettingsBuilder::new().build()
31    }
32}
33
34/// Output settings builder.
35#[derive(Default)]
36pub struct OutputSettingsBuilder {
37    scale: Option<u32>,
38    pixel_spacing: Option<u32>,
39    theme: BinaryColorTheme,
40}
41
42impl OutputSettingsBuilder {
43    /// Creates new output settings builder.
44    pub fn new() -> Self {
45        Self::default()
46    }
47
48    /// Sets the pixel scale.
49    ///
50    /// A scale of `2` or higher is useful for viewing the simulator on high DPI displays.
51    ///
52    /// # Panics
53    ///
54    /// Panics if the scale is set to `0`.
55    pub fn scale(mut self, scale: u32) -> Self {
56        assert!(scale > 0, "scale must be > 0");
57
58        self.scale = Some(scale);
59
60        self
61    }
62
63    /// Sets the binary color theme.
64    ///
65    /// The binary color theme defines the mapping between the two display colors
66    /// and the output. The variants provided by the [`BinaryColorTheme`] enum
67    /// simulate the color scheme of commonly used display types.
68    ///
69    /// Most binary color displays are relatively small individual pixels
70    /// are hard to recognize on higher resolution screens. Because of this
71    /// some scaling is automatically applied to the output when a theme is
72    /// set and no scaling was specified explicitly.
73    ///
74    /// Note that a theme should only be set when an monochrome display is used.
75    /// Setting a theme when using a color display will cause an corrupted output.
76    ///
77    pub fn theme(mut self, theme: BinaryColorTheme) -> Self {
78        self.theme = theme;
79
80        self.scale.get_or_insert(3);
81        self.pixel_spacing.get_or_insert(1);
82
83        self
84    }
85
86    /// Sets the gap between pixels.
87    ///
88    /// Most lower resolution displays have visible gaps between individual pixels.
89    /// This effect can be simulated by setting the pixel spacing to a value greater
90    /// than `0`.
91    pub fn pixel_spacing(mut self, pixel_spacing: u32) -> Self {
92        self.pixel_spacing = Some(pixel_spacing);
93
94        self
95    }
96
97    /// Builds the output settings.
98    pub fn build(self) -> OutputSettings {
99        OutputSettings {
100            scale: self.scale.unwrap_or(1),
101            pixel_spacing: self.pixel_spacing.unwrap_or(0),
102            theme: self.theme,
103        }
104    }
105}