1
0
mirror of https://github.com/esphome/esphome.git synced 2026-02-08 08:41:59 +00:00

[display] Ensure drivers respect clipping during fill() (#12808)

This commit is contained in:
Stuart Parmenter
2026-01-01 21:34:39 -08:00
committed by GitHub
parent 2841b5fe44
commit 7483bbd6ea
16 changed files with 114 additions and 2 deletions

View File

@@ -76,6 +76,12 @@ class EPaperBase : public Display,
return 0;
}
void fill(Color color) override {
// If clipping is active, fall back to base implementation
if (this->get_clipping().is_set()) {
Display::fill(color);
return;
}
auto pixel_color = color_to_bit(color) ? 0xFF : 0x00;
// We store 8 pixels per byte

View File

@@ -97,6 +97,12 @@ void EPaperSpectraE6::deep_sleep() {
}
void EPaperSpectraE6::fill(Color color) {
// If clipping is active, fall back to base implementation
if (this->get_clipping().is_set()) {
EPaperBase::fill(color);
return;
}
auto pixel_color = color_to_hex(color);
// We store 2 pixels per byte

View File

@@ -131,6 +131,13 @@ float ILI9XXXDisplay::get_setup_priority() const { return setup_priority::HARDWA
void ILI9XXXDisplay::fill(Color color) {
if (!this->check_buffer_())
return;
// If clipping is active, fall back to base implementation
if (this->get_clipping().is_set()) {
Display::fill(color);
return;
}
uint16_t new_color = 0;
this->x_low_ = 0;
this->y_low_ = 0;

View File

@@ -293,6 +293,13 @@ void Inkplate::fill(Color color) {
ESP_LOGV(TAG, "Fill called");
uint32_t start_time = millis();
// If clipping is active, fall back to base implementation
if (this->get_clipping().is_set()) {
Display::fill(color);
ESP_LOGV(TAG, "Fill finished (%ums)", millis() - start_time);
return;
}
if (this->greyscale_) {
uint8_t fill = ((color.red * 2126 / 10000) + (color.green * 7152 / 10000) + (color.blue * 722 / 10000)) >> 5;
memset(this->buffer_, (fill << 4) | fill, this->get_buffer_length_());

View File

@@ -293,6 +293,13 @@ void MIPI_DSI::draw_pixel_at(int x, int y, Color color) {
void MIPI_DSI::fill(Color color) {
if (!this->check_buffer_())
return;
// If clipping is active, fall back to base implementation
if (this->get_clipping().is_set()) {
Display::fill(color);
return;
}
switch (this->color_depth_) {
case display::COLOR_BITNESS_565: {
auto *ptr_16 = reinterpret_cast<uint16_t *>(this->buffer_);

View File

@@ -300,6 +300,13 @@ void MipiRgb::draw_pixel_at(int x, int y, Color color) {
void MipiRgb::fill(Color color) {
if (!this->check_buffer_())
return;
// If clipping is active, fall back to base implementation
if (this->get_clipping().is_set()) {
Display::fill(color);
return;
}
auto *ptr_16 = reinterpret_cast<uint16_t *>(this->buffer_);
uint8_t hi_byte = static_cast<uint8_t>(color.r & 0xF8) | (color.g >> 5);
uint8_t lo_byte = static_cast<uint8_t>((color.g & 0x1C) << 3) | (color.b >> 3);

View File

@@ -569,6 +569,12 @@ class MipiSpiBuffer : public MipiSpi<BUFFERTYPE, BUFFERPIXEL, IS_BIG_ENDIAN, DIS
// Fills the display with a color.
void fill(Color color) override {
// If clipping is active, fall back to base implementation
if (this->get_clipping().is_set()) {
display::Display::fill(color);
return;
}
this->x_low_ = 0;
this->y_low_ = this->start_line_;
this->x_high_ = WIDTH - 1;

View File

@@ -117,6 +117,12 @@ void PCD8544::update() {
}
void PCD8544::fill(Color color) {
// If clipping is active, fall back to base implementation
if (this->get_clipping().is_set()) {
Display::fill(color);
return;
}
uint8_t fill = color.is_on() ? 0xFF : 0x00;
for (uint32_t i = 0; i < this->get_buffer_length_(); i++)
this->buffer_[i] = fill;

View File

@@ -329,6 +329,12 @@ void HOT SSD1306::draw_absolute_pixel_internal(int x, int y, Color color) {
}
}
void SSD1306::fill(Color color) {
// If clipping is active, fall back to base implementation
if (this->get_clipping().is_set()) {
Display::fill(color);
return;
}
uint8_t fill = color.is_on() ? 0xFF : 0x00;
for (uint32_t i = 0; i < this->get_buffer_length_(); i++)
this->buffer_[i] = fill;

View File

@@ -174,6 +174,12 @@ void HOT SSD1322::draw_absolute_pixel_internal(int x, int y, Color color) {
this->buffer_[pos] |= color4;
}
void SSD1322::fill(Color color) {
// If clipping is active, fall back to base implementation
if (this->get_clipping().is_set()) {
Display::fill(color);
return;
}
const uint32_t color4 = display::ColorUtil::color_to_grayscale4(color);
uint8_t fill = (color4 & SSD1322_COLORMASK) | ((color4 & SSD1322_COLORMASK) << SSD1322_COLORSHIFT);
for (uint32_t i = 0; i < this->get_buffer_length_(); i++)

View File

@@ -150,6 +150,12 @@ void HOT SSD1327::draw_absolute_pixel_internal(int x, int y, Color color) {
this->buffer_[pos] |= color4;
}
void SSD1327::fill(Color color) {
// If clipping is active, fall back to base implementation
if (this->get_clipping().is_set()) {
Display::fill(color);
return;
}
const uint32_t color4 = display::ColorUtil::color_to_grayscale4(color);
uint8_t fill = (color4 & SSD1327_COLORMASK) | ((color4 & SSD1327_COLORMASK) << SSD1327_COLORSHIFT);
for (uint32_t i = 0; i < this->get_buffer_length_(); i++)

View File

@@ -128,6 +128,12 @@ void HOT SSD1331::draw_absolute_pixel_internal(int x, int y, Color color) {
this->buffer_[pos] = color565 & 0xff;
}
void SSD1331::fill(Color color) {
// If clipping is active, fall back to base implementation
if (this->get_clipping().is_set()) {
Display::fill(color);
return;
}
const uint32_t color565 = display::ColorUtil::color_to_565(color);
for (uint32_t i = 0; i < this->get_buffer_length_(); i++) {
if (i & 1) {

View File

@@ -160,6 +160,12 @@ void HOT SSD1351::draw_absolute_pixel_internal(int x, int y, Color color) {
this->buffer_[pos] = color565 & 0xff;
}
void SSD1351::fill(Color color) {
// If clipping is active, fall back to base implementation
if (this->get_clipping().is_set()) {
Display::fill(color);
return;
}
const uint32_t color565 = display::ColorUtil::color_to_565(color);
for (uint32_t i = 0; i < this->get_buffer_length_(); i++) {
if (i & 1) {

View File

@@ -131,7 +131,16 @@ void HOT ST7567::draw_absolute_pixel_internal(int x, int y, Color color) {
}
}
void ST7567::fill(Color color) { memset(buffer_, color.is_on() ? 0xFF : 0x00, this->get_buffer_length_()); }
void ST7567::fill(Color color) {
// If clipping is active, fall back to base implementation
if (this->get_clipping().is_set()) {
Display::fill(color);
return;
}
uint8_t fill = color.is_on() ? 0xFF : 0x00;
memset(buffer_, fill, this->get_buffer_length_());
}
void ST7567::init_reset_() {
if (this->reset_pin_ != nullptr) {

View File

@@ -89,7 +89,16 @@ void HOT ST7920::write_display_data() {
}
}
void ST7920::fill(Color color) { memset(this->buffer_, color.is_on() ? 0xFF : 0x00, this->get_buffer_length_()); }
void ST7920::fill(Color color) {
// If clipping is active, fall back to base implementation
if (this->get_clipping().is_set()) {
Display::fill(color);
return;
}
uint8_t fill = color.is_on() ? 0xFF : 0x00;
memset(this->buffer_, fill, this->get_buffer_length_());
}
void ST7920::dump_config() {
LOG_DISPLAY("", "ST7920", this);

View File

@@ -172,6 +172,12 @@ void WaveshareEPaperBase::update() {
this->display();
}
void WaveshareEPaper::fill(Color color) {
// If clipping is active, fall back to base implementation
if (this->get_clipping().is_set()) {
Display::fill(color);
return;
}
// flip logic
const uint8_t fill = color.is_on() ? 0x00 : 0xFF;
for (uint32_t i = 0; i < this->get_buffer_length_(); i++)
@@ -234,6 +240,12 @@ uint8_t WaveshareEPaper7C::color_to_hex(Color color) {
return hex_code;
}
void WaveshareEPaper7C::fill(Color color) {
// If clipping is active, use base class (3-bit packing is complex for partial fills)
if (this->get_clipping().is_set()) {
display::Display::fill(color);
return;
}
uint8_t pixel_color;
if (color.is_on()) {
pixel_color = this->color_to_hex(color);