Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ SSD1306 monochrome OLED display.
### Fixed
- Fix TerminalMode::write_str() to write all chars ([#228](https://github.com/rust-embedded-community/ssd1306/issues/228))

### Added
- Implement `embedded_graphics::draw_target::DrawTarget::fill_contiguous` to more improve performance when filling
contiguous regions.

## [0.10.0] - 2025-03-22
### Changed
- Added `DisplaySize64x32` to the prelude
Expand Down
51 changes: 49 additions & 2 deletions src/mode/buffered_graphics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,9 @@ where
#[cfg(feature = "graphics")]
use embedded_graphics_core::{
draw_target::DrawTarget,
geometry::Size,
geometry::{Dimensions, OriginDimensions},
geometry::{AnchorX, AnchorY, Dimensions, OriginDimensions, Size},
pixelcolor::BinaryColor,
primitives::Rectangle,
Pixel,
};

Expand Down Expand Up @@ -276,6 +276,53 @@ where
.for_each(|Pixel(pos, color)| {
self.set_pixel(pos.x as u32, pos.y as u32, color.is_on());
});
Ok(())
}

fn fill_contiguous<I>(&mut self, area: &Rectangle, pixels: I) -> Result<(), Self::Error>
where
I: IntoIterator<Item = Self::Color>,
{
let area = area.intersection(&self.bounding_box());
let mut pixels = pixels.into_iter();

// Keep track of max and min values
self.mode.min_x = self.mode.min_x.min(area.anchor_x(AnchorX::Left) as u8);
self.mode.max_x = self.mode.max_x.max(area.anchor_x(AnchorX::Right) as u8);
self.mode.min_y = self.mode.min_y.min(area.anchor_y(AnchorY::Top) as u8);
self.mode.max_y = self.mode.max_y.max(area.anchor_y(AnchorY::Bottom) as u8);

let buffer = self.mode.buffer.as_mut();
match self.rotation {
DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => {
for y in area.rows() {
for x in area.columns() {
let Some(color) = pixels.next() else {
return Ok(());
};
let value = color.is_on() as u8;
let idx = ((y as usize) / 8 * SIZE::WIDTH as usize) + (x as usize);
let bit = y % 8;
let byte = &mut buffer[idx];
*byte = *byte & !(1 << bit) | (value << bit);
}
}
}
DisplayRotation::Rotate90 | DisplayRotation::Rotate270 => {
for y in area.rows() {
for x in area.columns() {
let Some(color) = pixels.next() else {
return Ok(());
};
let value = color.is_on() as u8;
let idx = ((x as usize) / 8 * SIZE::WIDTH as usize) + (y as usize);
let bit = x % 8;
let byte = &mut buffer[idx];
*byte = *byte & !(1 << bit) | (value << bit);
}
}
}
};

Ok(())
}
Expand Down