From d5e520bb34e53cdc84ad21dbb1063b2a9f22a517 Mon Sep 17 00:00:00 2001 From: James Waples Date: Mon, 7 Jun 2021 23:10:19 +0100 Subject: [PATCH] Upgrade to embedded-graphics 0.7 (#154) * Upgrade to embedded-graphics 0.7 * Changelog entry * Use black and white Rust BMP image The darker colours in the rainbow rust-pride.bmp were being converted to black pixels when going from RGB565 -> BinaryColor, so only half the logo would show up. I've replaced the BMP with a black and white version which is what actually shows on the display. --- CHANGELOG.md | 3 +++ Cargo.toml | 8 ++----- README.md | 3 +-- examples/bmp_i2c.rs | 34 +++++++---------------------- examples/graphics.rs | 9 ++++---- examples/graphics_i2c.rs | 9 ++++---- examples/graphics_i2c_128x32.rs | 9 ++++---- examples/graphics_i2c_72x40.rs | 9 ++++---- examples/image_i2c.rs | 2 +- examples/rotation_i2c.rs | 2 +- examples/rtic_brightness.rs | 21 ++++++++++-------- examples/rtic_dvd.rs | 21 ++++++++++-------- examples/rust-pride.bmp | Bin 8262 -> 0 bytes examples/rust.bmp | Bin 0 -> 8262 bytes examples/text_i2c.rs | 13 ++++++----- src/lib.rs | 19 ++++++++-------- src/mode/buffered_graphics.rs | 37 +++++++++++++++++++++----------- 17 files changed, 97 insertions(+), 102 deletions(-) delete mode 100644 examples/rust-pride.bmp create mode 100644 examples/rust.bmp diff --git a/CHANGELOG.md b/CHANGELOG.md index 317a5566..2c9693d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ ## [Unreleased] - ReleaseDate +### Changed + +- **(breaking)** [#154](https://github.com/jamwaffles/ssd1306/pull/154) Upgrade to `embedded-graphics` 0.7. - **(breaking)** [#150](https://github.com/jamwaffles/ssd1306/pull/150) `BufferedGraphicsMode::set_pixel` now accepts a `bool` instead of a `u8` for the pixel color value. - **(breaking)** [#150](https://github.com/jamwaffles/ssd1306/pull/150) `display_on` is now called `set_display_on`. - **(breaking)** [#150](https://github.com/jamwaffles/ssd1306/pull/150) `TerminalMode::get_position` is now called `position` to conform with Rust API guidelines. diff --git a/Cargo.toml b/Cargo.toml index bc1d73b8..34e03d30 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ generic-array = "0.14.2" [dependencies.embedded-graphics] optional = true -version = "0.6.0" +version = "0.7.0" [dev-dependencies] cortex-m = "0.7.2" @@ -35,12 +35,8 @@ cortex-m-rt = "0.6.12" cortex-m-rtic = "0.5.3" panic-halt = "0.2.0" cast = { version = "0.2.6", default-features = false } - # Used to load BMP images in various examples -[dev-dependencies.tinybmp] -version = "0.2.2" -# Enable embedded-graphics integration -features = [ "graphics" ] +tinybmp = "0.3.0" # Used by the noise_i2c examples [dev-dependencies.rand] diff --git a/README.md b/README.md index 6b9891e8..e6f9ad93 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ fn main() -> ! { .into_buffered_graphics_mode(); display.init().unwrap(); - let raw: ImageRaw = ImageRaw::new(include_bytes!("./rust.raw"), 64, 64); + let raw: ImageRaw = ImageRaw::new(include_bytes!("./rust.raw"), 64); let im = Image::new(&raw, Point::new(32, 0)); @@ -88,7 +88,6 @@ fn main() -> ! { fn HardFault(ef: &ExceptionFrame) -> ! { panic!("{:#?}", ef); } - ``` ## License diff --git a/examples/bmp_i2c.rs b/examples/bmp_i2c.rs index c896273a..f611906d 100644 --- a/examples/bmp_i2c.rs +++ b/examples/bmp_i2c.rs @@ -22,11 +22,7 @@ #![no_main] use cortex_m_rt::{entry, exception, ExceptionFrame}; -use embedded_graphics::{ - image::Image, - pixelcolor::{BinaryColor, Rgb565}, - prelude::*, -}; +use embedded_graphics::{image::Image, pixelcolor::Rgb565, prelude::*}; use panic_halt as _; use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306}; use stm32f1xx_hal::{ @@ -73,29 +69,15 @@ fn main() -> ! { .into_buffered_graphics_mode(); display.init().unwrap(); - let bmp = - Bmp::from_slice(include_bytes!("./rust-pride.bmp")).expect("Failed to load BMP image"); + let bmp = Bmp::from_slice(include_bytes!("./rust.bmp")).expect("Failed to load BMP image"); - // The image is an RGB565 encoded BMP, so specifying the type as `Image` will read + // The image is an RGB565 encoded BMP, so specifying the type as `Image>` will read // the pixels correctly - let im: Image = Image::new(&bmp, Point::new(32, 0)); - - // The display uses `BinaryColor` pixels (on/off only). Here, we `map()` over every pixel - // and naively convert the color to an on/off value. The logic below simply converts any - // color that's not black into an "on" pixel. - im.into_iter() - .map(|Pixel(position, color)| { - Pixel( - position, - if color != Rgb565::BLACK { - BinaryColor::On - } else { - BinaryColor::Off - }, - ) - }) - .draw(&mut display) - .unwrap(); + let im: Image> = Image::new(&bmp, Point::new(32, 0)); + + // We use the `color_converted` method here to automatically convert the RGB565 image data into + // BinaryColor values. + im.draw(&mut display.color_converted()).unwrap(); display.flush().unwrap(); diff --git a/examples/graphics.rs b/examples/graphics.rs index f4cae0e2..0297f88e 100644 --- a/examples/graphics.rs +++ b/examples/graphics.rs @@ -24,8 +24,7 @@ use cortex_m_rt::{entry, exception, ExceptionFrame}; use embedded_graphics::{ pixelcolor::BinaryColor, prelude::*, - primitives::{Circle, Rectangle, Triangle}, - style::PrimitiveStyleBuilder, + primitives::{Circle, PrimitiveStyleBuilder, Rectangle, Triangle}, }; use panic_halt as _; use ssd1306::{prelude::*, Ssd1306}; @@ -91,7 +90,7 @@ fn main() -> ! { // screen outline // default display size is 128x64 if you don't pass a _DisplaySize_ // enum to the _Builder_ struct - Rectangle::new(Point::new(0, 0), Point::new(127, 63)) + Rectangle::new(Point::new(0, 0), Size::new(127, 63)) .into_styled(style) .draw(&mut display) .unwrap(); @@ -107,13 +106,13 @@ fn main() -> ! { .unwrap(); // square - Rectangle::new(Point::new(52, yoffset), Point::new(52 + 16, 16 + yoffset)) + Rectangle::new(Point::new(52, yoffset), Size::new_equal(16)) .into_styled(style) .draw(&mut display) .unwrap(); // circle - Circle::new(Point::new(96, yoffset + 8), 8) + Circle::new(Point::new(88, yoffset), 16) .into_styled(style) .draw(&mut display) .unwrap(); diff --git a/examples/graphics_i2c.rs b/examples/graphics_i2c.rs index 0758f973..a3546d2d 100644 --- a/examples/graphics_i2c.rs +++ b/examples/graphics_i2c.rs @@ -21,8 +21,7 @@ use cortex_m_rt::{entry, exception, ExceptionFrame}; use embedded_graphics::{ pixelcolor::BinaryColor, prelude::*, - primitives::{Circle, Rectangle, Triangle}, - style::PrimitiveStyleBuilder, + primitives::{Circle, PrimitiveStyleBuilder, Rectangle, Triangle}, }; use panic_halt as _; use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306}; @@ -79,7 +78,7 @@ fn main() -> ! { // screen outline // default display size is 128x64 if you don't pass a _DisplaySize_ // enum to the _Builder_ struct - Rectangle::new(Point::new(0, 0), Point::new(127, 63)) + Rectangle::new(Point::new(0, 0), Size::new(127, 63)) .into_styled(style) .draw(&mut display) .unwrap(); @@ -95,13 +94,13 @@ fn main() -> ! { .unwrap(); // square - Rectangle::new(Point::new(52, yoffset), Point::new(52 + 16, 16 + yoffset)) + Rectangle::new(Point::new(52, yoffset), Size::new_equal(16)) .into_styled(style) .draw(&mut display) .unwrap(); // circle - Circle::new(Point::new(96, yoffset + 8), 8) + Circle::new(Point::new(88, yoffset), 16) .into_styled(style) .draw(&mut display) .unwrap(); diff --git a/examples/graphics_i2c_128x32.rs b/examples/graphics_i2c_128x32.rs index 07276f81..7cdf0506 100644 --- a/examples/graphics_i2c_128x32.rs +++ b/examples/graphics_i2c_128x32.rs @@ -21,8 +21,7 @@ use cortex_m_rt::{entry, exception, ExceptionFrame}; use embedded_graphics::{ pixelcolor::BinaryColor, prelude::*, - primitives::{Circle, Rectangle, Triangle}, - style::PrimitiveStyleBuilder, + primitives::{Circle, PrimitiveStyleBuilder, Rectangle, Triangle}, }; use panic_halt as _; use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306}; @@ -79,7 +78,7 @@ fn main() -> ! { // screen outline // default display size is 128x64 if you don't pass a _DisplaySize_ // enum to the _Builder_ struct - Rectangle::new(Point::new(0, 0), Point::new(127, 31)) + Rectangle::new(Point::new(0, 0), Size::new(127, 31)) .into_styled(style) .draw(&mut display) .unwrap(); @@ -95,13 +94,13 @@ fn main() -> ! { .unwrap(); // square - Rectangle::new(Point::new(52, yoffset), Point::new(52 + 16, 16 + yoffset)) + Rectangle::new(Point::new(52, yoffset), Size::new_equal(16)) .into_styled(style) .draw(&mut display) .unwrap(); // circle - Circle::new(Point::new(96, yoffset + 8), 8) + Circle::new(Point::new(88, yoffset), 16) .into_styled(style) .draw(&mut display) .unwrap(); diff --git a/examples/graphics_i2c_72x40.rs b/examples/graphics_i2c_72x40.rs index a4c85437..d5247050 100644 --- a/examples/graphics_i2c_72x40.rs +++ b/examples/graphics_i2c_72x40.rs @@ -21,8 +21,7 @@ use cortex_m_rt::{entry, exception, ExceptionFrame}; use embedded_graphics::{ pixelcolor::BinaryColor, prelude::*, - primitives::{Circle, Rectangle, Triangle}, - style::PrimitiveStyleBuilder, + primitives::{Circle, PrimitiveStyleBuilder, Rectangle, Triangle}, }; use panic_halt as _; use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306}; @@ -81,7 +80,7 @@ fn main() -> ! { // screen outline // default display size is 128x64 if you don't pass a _DisplaySize_ // enum to the _Builder_ struct - Rectangle::new(Point::new(0, 0), Point::new(71, 39)) + Rectangle::with_corners(Point::new(0, 0), Point::new(71, 39)) .into_styled(style) .draw(&mut display) .unwrap(); @@ -101,7 +100,7 @@ fn main() -> ! { let offset = offset + Point::new(spacing, 0); // Draw a square - Rectangle::new(Point::new(0, 0), Point::new(size, size)) + Rectangle::new(Point::new(0, 0), Size::new_equal(size as u32)) .translate(offset) .into_styled(style) .draw(&mut display) @@ -111,7 +110,7 @@ fn main() -> ! { let offset = offset + Point::new(spacing, 0); // Circle - Circle::new(Point::new(size / 2, size / 2), size as u32 / 2) + Circle::new(Point::zero(), size as u32) .translate(offset) .into_styled(style) .draw(&mut display) diff --git a/examples/image_i2c.rs b/examples/image_i2c.rs index 3e008d74..57bd796a 100644 --- a/examples/image_i2c.rs +++ b/examples/image_i2c.rs @@ -74,7 +74,7 @@ fn main() -> ! { .into_buffered_graphics_mode(); display.init().unwrap(); - let raw: ImageRaw = ImageRaw::new(include_bytes!("./rust.raw"), 64, 64); + let raw: ImageRaw = ImageRaw::new(include_bytes!("./rust.raw"), 64); let im = Image::new(&raw, Point::new(32, 0)); diff --git a/examples/rotation_i2c.rs b/examples/rotation_i2c.rs index ecf5863f..e4a72465 100644 --- a/examples/rotation_i2c.rs +++ b/examples/rotation_i2c.rs @@ -80,7 +80,7 @@ fn main() -> ! { let (w, h) = display.dimensions(); - let raw: ImageRaw = ImageRaw::new(include_bytes!("./rust.raw"), 64, 64); + let raw: ImageRaw = ImageRaw::new(include_bytes!("./rust.raw"), 64); let im = Image::new( &raw, diff --git a/examples/rtic_brightness.rs b/examples/rtic_brightness.rs index 2badffb8..7cc43297 100644 --- a/examples/rtic_brightness.rs +++ b/examples/rtic_brightness.rs @@ -6,10 +6,13 @@ #![no_std] #![no_main] -use core::convert::TryFrom; use display_interface_spi::SPIInterfaceNoCS; use embedded_graphics::{ - geometry::Point, image::Image, pixelcolor::BinaryColor, prelude::*, primitives::Rectangle, + geometry::Point, + image::Image, + pixelcolor::{BinaryColor, Rgb565}, + prelude::*, + primitives::{PrimitiveStyle, Rectangle}, }; use panic_halt as _; use rtic::app; @@ -49,7 +52,7 @@ const APP: () = { timer: CountDownTimer, top_left: Point, velocity: Point, - bmp: Bmp<'static>, + bmp: Bmp, brightness: Brightness, } @@ -135,13 +138,11 @@ const APP: () = { .. } = cx.resources; - let bottom_right = *top_left + Point::try_from(bmp.dimensions()).unwrap(); + let bottom_right = *top_left + bmp.bounding_box().size; // Erase previous image position with a filled black rectangle - Rectangle::new(*top_left, bottom_right) - .into_styled(embedded_graphics::primitive_style!( - fill_color = BinaryColor::Off - )) + Rectangle::with_corners(*top_left, bottom_right) + .into_styled(PrimitiveStyle::with_fill(BinaryColor::Off)) .draw(display) .unwrap(); @@ -178,7 +179,9 @@ const APP: () = { *top_left += *velocity; // Draw image at new position - Image::new(bmp, *top_left).draw(display).unwrap(); + Image::new(bmp, *top_left) + .draw(&mut display.color_converted()) + .unwrap(); // Write changes to the display display.flush().unwrap(); diff --git a/examples/rtic_dvd.rs b/examples/rtic_dvd.rs index 06b35646..31bfe854 100644 --- a/examples/rtic_dvd.rs +++ b/examples/rtic_dvd.rs @@ -7,10 +7,13 @@ #![no_std] #![no_main] -use core::convert::TryFrom; use display_interface_spi::SPIInterfaceNoCS; use embedded_graphics::{ - geometry::Point, image::Image, pixelcolor::BinaryColor, prelude::*, primitives::Rectangle, + geometry::Point, + image::Image, + pixelcolor::{BinaryColor, Rgb565}, + prelude::*, + primitives::{PrimitiveStyle, Rectangle}, }; use panic_halt as _; use rtic::app; @@ -50,7 +53,7 @@ const APP: () = { timer: CountDownTimer, top_left: Point, velocity: Point, - bmp: Bmp<'static>, + bmp: Bmp, } #[init] @@ -133,13 +136,11 @@ const APP: () = { .. } = cx.resources; - let bottom_right = *top_left + Point::try_from(bmp.dimensions()).unwrap(); + let bottom_right = *top_left + bmp.bounding_box().size; // Erase previous image position with a filled black rectangle - Rectangle::new(*top_left, bottom_right) - .into_styled(embedded_graphics::primitive_style!( - fill_color = BinaryColor::Off - )) + Rectangle::with_corners(*top_left, bottom_right) + .into_styled(PrimitiveStyle::with_fill(BinaryColor::Off)) .draw(display) .unwrap(); @@ -158,7 +159,9 @@ const APP: () = { *top_left += *velocity; // Draw image at new position - Image::new(bmp, *top_left).draw(display).unwrap(); + Image::new(bmp, *top_left) + .draw(&mut display.color_converted()) + .unwrap(); // Write changes to the display display.flush().unwrap(); diff --git a/examples/rust-pride.bmp b/examples/rust-pride.bmp deleted file mode 100644 index cc0e1ee8a588c14407f02305ea1cc6c2b795efe0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8262 zcmcgxzi(Vc5Z?2Tdx(H^QWWfnaO(=CgAO{MC_)56ri?^kmy~prPMI!$g6Yyy(%rRm zbSb?E6eSXprAUZpV*A*6bMt0qZ+E@xyKtZ0&NuUY^X=KPES>$uHxKqq_j=&Z&;2u5 zJOeW_o1U9JV{YHV2ioq{8si#cEcGkZK|Any|L<$7-Rkd5@%6u>roXdk0dNB{$?0Bp z(`2>!ZVP}6Wa*PVtKF!#-*4-o6K>Lt`tSLutq0x6DKsgqx7+og^uEw{r@hmD&_j1T zzn+D;rTuP;xZ71a@3x5DMWsGnOYcM9hb;g&vgI?CchB$LivavMPi@NixJ^U)Qr!A| zdYHjv-2XhMc42N`N}zM>V3ymGn)J%7(ggb(gK}X){JJW=oK&&@i|v7TVSnAdq=Osz z_-9U{8M(r0f662Dr~7;ksPSF0@>bJ*DVmbZ0o zYy)QYkw(f_JJ+f9QEJ~l^q6!fvx%Q%q0{nSRP_dQ_P+ge@!ak46PFq-yH;y+B{c{sgQtdA7+09ij?mp;1*8U=Af3qC0ce<$oGk%da z_bz%)`#ah9omZE^`mzQS)K9h~cn6qNm}?Jo(>?>)bPK>f?Dfg&;WmS(z<4g1_N08r z+tPQu4LIyiso5bz&i!vjp)fD;*kRtq>giB|=fI>=!{L5eZ&4T-b@912qN$!4J2V^4hFm>6n@I7?_QqG!rnCYIzx81WC;@&{|`?V|7KtF#s-#hl@6Hcvr2*|m3;QrLq``x4!}`+yH3 zvhc*UvT2x=xH3MTT;)MqdDq?*`D*Lq%RDHLT}R!<(Ir=4g$cYIl0%!bx%4ax(lSNmzW~5!s+}T%kmekL^Gf@2c{qlUg zy%?r?X32V*tW$w z{ZspWF> zQP;cU({w!1VOPghX*8|UWH@~p+sF2E_MQ54yD9Y9rip7ia`s$%ZtdDjfXk=mt?o$r zDBsw#+iyAMt@1o~Wc@}b=aue^j~p{?iyW?~>FD6p$&?)J8J>1%h9bBBoI^sIA@I{;#H+rx|FB-t=WC}Oq`w5!1zQmc`DPjKF#tnX`|?MkirQLBvZQFY&?x#Ra6IbQcQ!p%Hv zU@(El307xR>|L7Yd!94v49T^9bSE`>`dzbfFDbh0nv<`Q-IUo^J%KCpC+Vk*{@gh~ z19iIzqt9>8wVe&Rsfu`xj#;ki{$zT-Atz^vLbp1ZkZ;J#S)$ObPA24==jEKDtG&=$ zMz=%ze5Vt6`*TjeM)uogCqL0uuX(ASlXemOCNv$-GIvtF+gJOn6>PPGfA6XNdtLtk DtSsWn literal 0 HcmV?d00001 diff --git a/examples/text_i2c.rs b/examples/text_i2c.rs index 54d77da1..3ac9a3ec 100644 --- a/examples/text_i2c.rs +++ b/examples/text_i2c.rs @@ -20,10 +20,10 @@ use cortex_m_rt::{entry, exception, ExceptionFrame}; use embedded_graphics::{ - fonts::{Font6x8, Text}, + mono_font::{ascii::FONT_6X10, MonoTextStyleBuilder}, pixelcolor::BinaryColor, prelude::*, - style::TextStyleBuilder, + text::{Baseline, Text}, }; use panic_halt as _; use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306}; @@ -70,17 +70,16 @@ fn main() -> ! { .into_buffered_graphics_mode(); display.init().unwrap(); - let text_style = TextStyleBuilder::new(Font6x8) + let text_style = MonoTextStyleBuilder::new() + .font(&FONT_6X10) .text_color(BinaryColor::On) .build(); - Text::new("Hello world!", Point::zero()) - .into_styled(text_style) + Text::with_baseline("Hello world!", Point::zero(), text_style, Baseline::Top) .draw(&mut display) .unwrap(); - Text::new("Hello Rust!", Point::new(0, 16)) - .into_styled(text_style) + Text::with_baseline("Hello Rust!", Point::new(0, 16), text_style, Baseline::Top) .draw(&mut display) .unwrap(); diff --git a/src/lib.rs b/src/lib.rs index 42cab107..c5c89651 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,10 +27,10 @@ //! # use ssd1306::test_helpers::I2cStub; //! # let i2c = I2cStub; //! use embedded_graphics::{ -//! fonts::{Font6x8, Text}, +//! mono_font::{ascii::FONT_6X10, MonoTextStyleBuilder}, //! pixelcolor::BinaryColor, //! prelude::*, -//! style::TextStyleBuilder, +//! text::{Baseline, Text}, //! }; //! use ssd1306::{mode::BufferedGraphicsMode, prelude::*, I2CDisplayInterface, Ssd1306}; //! @@ -42,17 +42,18 @@ //! ).into_buffered_graphics_mode(); //! display.init().unwrap(); //! -//! let text_style = TextStyleBuilder::new(Font6x8) +//! let text_style = MonoTextStyleBuilder::new() +//! .font(&FONT_6X10) //! .text_color(BinaryColor::On) //! .build(); //! -//! Text::new("Hello world!", Point::zero()) -//! .into_styled(text_style) -//! .draw(&mut display); +//! Text::with_baseline("Hello world!", Point::zero(), text_style, Baseline::Top) +//! .draw(&mut display) +//! .unwrap(); //! -//! Text::new("Hello Rust!", Point::new(0, 16)) -//! .into_styled(text_style) -//! .draw(&mut display); +//! Text::with_baseline("Hello Rust!", Point::new(0, 16), text_style, Baseline::Top) +//! .draw(&mut display) +//! .unwrap(); //! //! display.flush().unwrap(); //! ``` diff --git a/src/mode/buffered_graphics.rs b/src/mode/buffered_graphics.rs index 714b869d..e3c749b6 100644 --- a/src/mode/buffered_graphics.rs +++ b/src/mode/buffered_graphics.rs @@ -2,6 +2,7 @@ use crate::{command::AddrMode, rotation::DisplayRotation, size::DisplaySize, Ssd1306}; use display_interface::{DisplayError, WriteOnlyDataCommand}; +use embedded_graphics::prelude::Dimensions; use generic_array::GenericArray; /// Buffered graphics mode. @@ -185,33 +186,45 @@ where } #[cfg(feature = "graphics")] -use embedded_graphics::{drawable, geometry::Size, pixelcolor::BinaryColor, DrawTarget}; +use embedded_graphics::{ + draw_target::DrawTarget, geometry::OriginDimensions, geometry::Size, pixelcolor::BinaryColor, + Pixel, +}; use super::DisplayConfig; #[cfg(feature = "graphics")] -impl DrawTarget for Ssd1306> +impl DrawTarget for Ssd1306> where DI: WriteOnlyDataCommand, SIZE: DisplaySize, { + type Color = BinaryColor; type Error = DisplayError; - fn draw_pixel(&mut self, pixel: drawable::Pixel) -> Result<(), Self::Error> { - let drawable::Pixel(pos, color) = pixel; + fn draw_iter(&mut self, pixels: I) -> Result<(), Self::Error> + where + I: IntoIterator>, + { + let bb = self.bounding_box(); - // Guard against negative values. All positive i32 values from `pos` can be represented in - // the `u32`s that `set_pixel()` accepts... - if pos.x < 0 || pos.y < 0 { - return Ok(()); - } - - // ... which makes the `as` coercions here safe. - self.set_pixel(pos.x as u32, pos.y as u32, color.is_on()); + pixels + .into_iter() + .filter(|Pixel(pos, _color)| bb.contains(*pos)) + .for_each(|Pixel(pos, color)| { + self.set_pixel(pos.x as u32, pos.y as u32, color.is_on()) + }); Ok(()) } +} +#[cfg(feature = "graphics")] +impl OriginDimensions for Ssd1306> +where + DI: WriteOnlyDataCommand, + SIZE: DisplaySize, +{ fn size(&self) -> Size { let (w, h) = self.dimensions();