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}