embedded_graphics_simulator/lib.rs
1//! 
2//!
3//! The simulator can be used to test and debug
4//! [embedded-graphics](https://crates.io/crates/embedded-graphics) code, or produce examples and
5//! interactive demos to show off embedded graphics features.
6//!
7//! # [Examples](https://github.com/embedded-graphics/examples)
8//!
9//! More simulator examples can be found in the [examples repository](https://github.com/embedded-graphics/examples).
10//!
11//! ## Simulate a 128x64 SSD1306 OLED
12//!
13//! ```rust,no_run
14//! use embedded_graphics::{
15//! pixelcolor::BinaryColor,
16//! prelude::*,
17//! primitives::{Circle, Line, Rectangle, PrimitiveStyle},
18//! mono_font::{ascii::FONT_6X9, MonoTextStyle},
19//! text::Text,
20//! };
21//! use embedded_graphics_simulator::{BinaryColorTheme, SimulatorDisplay, Window, OutputSettingsBuilder};
22//!
23//! fn main() -> Result<(), core::convert::Infallible> {
24//! let mut display = SimulatorDisplay::<BinaryColor>::new(Size::new(128, 64));
25//!
26//! let line_style = PrimitiveStyle::with_stroke(BinaryColor::On, 1);
27//! let text_style = MonoTextStyle::new(&FONT_6X9, BinaryColor::On);
28//!
29//! Circle::new(Point::new(72, 8), 48)
30//! .into_styled(line_style)
31//! .draw(&mut display)?;
32//!
33//! Line::new(Point::new(48, 16), Point::new(8, 16))
34//! .into_styled(line_style)
35//! .draw(&mut display)?;
36//!
37//! Line::new(Point::new(48, 16), Point::new(64, 32))
38//! .into_styled(line_style)
39//! .draw(&mut display)?;
40//!
41//! Rectangle::new(Point::new(79, 15), Size::new(34, 34))
42//! .into_styled(line_style)
43//! .draw(&mut display)?;
44//!
45//! Text::new("Hello World!", Point::new(5, 5), text_style).draw(&mut display)?;
46//!
47//! let output_settings = OutputSettingsBuilder::new()
48//! .theme(BinaryColorTheme::OledBlue)
49//! .build();
50//! Window::new("Hello World", &output_settings).show_static(&display);
51//!
52//! Ok(())
53//! }
54//! ```
55//!
56//! # Setup
57//!
58//! The simulator uses SDL2 and its development libraries which must be installed to build and run
59//! it.
60//!
61//! ## Linux (`apt`)
62//!
63//! ```bash
64//! sudo apt install libsdl2-dev
65//! ```
66//!
67//! ## macOS (`brew`)
68//!
69//! ```bash
70//! brew install sdl2
71//! ```
72//!
73//! Users on Apple silicon or with custom installation directories will need to
74//! set `LIBRARY_PATH` for the linker to find the installed SDL2 package:
75//!
76//! ```bash
77//! export LIBRARY_PATH="$LIBRARY_PATH:$(brew --prefix)/lib"
78//! ```
79//! More information can be found in the
80//! [SDL2 documentation](https://github.com/Rust-SDL2/rust-sdl2#homebrew).
81//!
82//! ## Windows
83//!
84//! The Windows install process is a bit more involved, but it _does_ work. See [the Rust-SDL2
85//! crate's README](https://github.com/Rust-SDL2/rust-sdl2) for instructions. There are multiple
86//! ways to get it working, but probably the simplest method is copying the binaries as shown
87//! [here](https://github.com/Rust-SDL2/rust-sdl2#windows-msvc).
88//!
89//! # Creating screenshots
90//!
91//! Screenshots of programs, that use [`Window`] to display a simulated display, can be created by
92//! setting the `EG_SIMULATOR_DUMP` or `EG_SIMULATOR_DUMP_RAW` environment variable:
93//!
94//! ```bash
95//! EG_SIMULATOR_DUMP=screenshot.png cargo run
96//! ```
97//!
98//! By setting the variable the display passed to the first [`Window::update`] call gets exported as
99//! a PNG file to the specified path. After the file is exported the process is terminated.
100//!
101//! The difference between `EG_SIMULATOR_DUMP` and `EG_SIMULATOR_DUMP_RAW` is that the first method
102//! applies the output settings before exporting the PNG file and the later dumps the unaltered
103//! display content.
104//!
105//! # Exporting images
106//!
107//! If a program doesn't require to display a window and only needs to export one or more images, a
108//! [`SimulatorDisplay`] can also be converted to an [`image`] crate
109//! [`ImageBuffer`] by using the [`to_rgb_output_image`] or [`to_grayscale_output_image`] methods.
110//! The resulting buffer can then be used to save the display content to any format supported by
111//! [`image`].
112//!
113//! # Using the simulator in CI
114//!
115//! The simulator supports two environment variables to check if the display content matches a
116//! reference PNG file: `EG_SIMULATOR_CHECK` and `EG_SIMULATOR_CHECK_RAW`. If the display content
117//! of the first [`Window::update`] call doesn't match the reference image the process exits with a
118//! non zero exit exit code. Otherwise the process will exit with a zero exit code.
119//!
120//! ```bash
121//! EG_SIMULATOR_CHECK=screenshot.png cargo run || echo "Display doesn't match PNG file"
122//! ```
123//!
124//! `EG_SIMULATOR_CHECK` assumes that the reference image was created using the same
125//! `OutputSetting`s, while `EG_SIMULATOR_CHECK_RAW` assumes an unstyled reference image.
126//!
127//! # Usage without SDL2
128//!
129//! When the simulator is used in headless/CI environments that don't require showing a window, SDL2
130//! support can be disabled. This removes the requirement of SDL2 being installed on the target machine,
131//! but still allows the simulator to be used to generate images.
132//!
133//! The `with-sdl` feature is enabled by default and can be disabled by adding `default-features = false` to the dependency:
134//!
135//! ```toml
136//! [dependencies.embedded-graphics-simulator]
137//! version = "0.2.0"
138//! default-features = false
139//! ```
140//!
141//! See the [Choosing
142//! Features](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#choosing-features)
143//! Cargo manifest documentation for more details.
144//!
145//! [`ImageBuffer`]: image::ImageBuffer
146//! [`to_rgb_output_image`]: SimulatorDisplay::to_rgb_output_image
147//! [`to_grayscale_output_image`]: SimulatorDisplay::to_grayscale_output_image
148
149#![deny(
150 missing_docs,
151 rustdoc::broken_intra_doc_links,
152 rustdoc::private_intra_doc_links
153)]
154
155mod display;
156mod output_image;
157mod output_settings;
158mod theme;
159mod window;
160
161#[cfg(feature = "with-sdl")]
162pub use window::SimulatorEvent;
163
164/// Re-exported types from sdl2 crate.
165///
166/// The types in this module are used in the [`SimulatorEvent`] enum and are re-exported from the
167/// `sdl2` crate to make it possible to use them without adding a dependency to `sdl2`.
168#[cfg(feature = "with-sdl")]
169pub mod sdl2 {
170 pub use sdl2::{
171 keyboard::{Keycode, Mod},
172 mouse::{MouseButton, MouseWheelDirection},
173 };
174}
175
176pub use crate::{
177 display::SimulatorDisplay,
178 output_image::OutputImage,
179 output_settings::{OutputSettings, OutputSettingsBuilder},
180 theme::BinaryColorTheme,
181 window::Window,
182};