From 0daee5d5020a0e49c139e73597d6c8ef90500c24 Mon Sep 17 00:00:00 2001 From: Bodmer Date: Sat, 8 Jan 2022 20:01:42 +0000 Subject: [PATCH] Add filled rectangles with gradient --- TFT_eSPI.cpp | 92 +++++++++++++++++++++++++++++++++++++++++----- TFT_eSPI.h | 7 +++- library.json | 2 +- library.properties | 2 +- 4 files changed, 89 insertions(+), 14 deletions(-) diff --git a/TFT_eSPI.cpp b/TFT_eSPI.cpp index 0455fa5..e4a26da 100644 --- a/TFT_eSPI.cpp +++ b/TFT_eSPI.cpp @@ -58,18 +58,14 @@ ** Description: Start SPI transaction for writes and select TFT ***************************************************************************************/ inline void TFT_eSPI::begin_tft_write(void){ -#if defined (SPI_HAS_TRANSACTION) && defined (SUPPORT_TRANSACTIONS) && !defined(TFT_PARALLEL_8_BIT) && !defined(RP2040_PIO_INTERFACE) if (locked) { locked = false; // Flag to show SPI access now unlocked +#if defined (SPI_HAS_TRANSACTION) && defined (SUPPORT_TRANSACTIONS) && !defined(TFT_PARALLEL_8_BIT) && !defined(RP2040_PIO_INTERFACE) spi.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, TFT_SPI_MODE)); +#endif CS_L; SET_BUS_WRITE_MODE; // Some processors (e.g. ESP32) allow recycling the tx buffer when rx is not used } -#else - CS_L; - SET_BUS_WRITE_MODE; -#endif - } /*************************************************************************************** @@ -77,19 +73,17 @@ inline void TFT_eSPI::begin_tft_write(void){ ** Description: End transaction for write and deselect TFT ***************************************************************************************/ inline void TFT_eSPI::end_tft_write(void){ -#if defined (SPI_HAS_TRANSACTION) && defined (SUPPORT_TRANSACTIONS) && !defined(TFT_PARALLEL_8_BIT) && !defined(RP2040_PIO_INTERFACE) if(!inTransaction) { // Flag to stop ending transaction during multiple graphics calls if (!locked) { // Locked when beginTransaction has been called locked = true; // Flag to show SPI access now locked SPI_BUSY_CHECK; // Check send complete and clean out unused rx data CS_H; +#if defined (SPI_HAS_TRANSACTION) && defined (SUPPORT_TRANSACTIONS) && !defined(TFT_PARALLEL_8_BIT) && !defined(RP2040_PIO_INTERFACE) spi.endTransaction(); +#endif } SET_BUS_READ_MODE; // In case SPI has been configured for tx only } -#else - if(!inTransaction) {SPI_BUSY_CHECK; CS_H; SET_BUS_READ_MODE;} -#endif } /*************************************************************************************** @@ -3685,6 +3679,84 @@ void TFT_eSPI::fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t col } +/*************************************************************************************** +** Function name: fillRectVGradient +** Description: draw a filled rectangle with a vertical colour gradient +***************************************************************************************/ +void TFT_eSPI::fillRectVGradient(int16_t x, int16_t y, int16_t w, int16_t h, uint32_t color1, uint32_t color2) +{ + if (_vpOoB) return; + + x+= _xDatum; + y+= _yDatum; + + // Clipping + if ((x >= _vpW) || (y >= _vpH)) return; + + if (x < _vpX) { w += x - _vpX; x = _vpX; } + if (y < _vpY) { h += y - _vpY; y = _vpY; } + + if ((x + w) > _vpW) w = _vpW - x; + if ((y + h) > _vpH) h = _vpH - y; + + if ((w < 1) || (h < 1)) return; + + begin_tft_write(); + + setWindow(x, y, x + w - 1, y + h - 1); + + float delta = -255.0/h; + float alpha = 255.0; + uint32_t color = color1; + + while (h--) { + pushBlock(color, w); + alpha += delta; + color = alphaBlend((uint8_t)alpha, color1, color2); + } + + end_tft_write(); +} + + +/*************************************************************************************** +** Function name: fillRectHGradient +** Description: draw a filled rectangle with a horizontal colour gradient +***************************************************************************************/ +void TFT_eSPI::fillRectHGradient(int16_t x, int16_t y, int16_t w, int16_t h, uint32_t color1, uint32_t color2) +{ + if (_vpOoB) return; + + x+= _xDatum; + y+= _yDatum; + + // Clipping + if ((x >= _vpW) || (y >= _vpH)) return; + + if (x < _vpX) { w += x - _vpX; x = _vpX; } + if (y < _vpY) { h += y - _vpY; y = _vpY; } + + if ((x + w) > _vpW) w = _vpW - x; + if ((y + h) > _vpH) h = _vpH - y; + + if ((w < 1) || (h < 1)) return; + + begin_tft_write(); + + float delta = -255.0/w; + float alpha = 255.0; + uint32_t color = color1; + + while (w--) { + drawFastVLine(x++, y, h, color); + alpha += delta; + color = alphaBlend((uint8_t)alpha, color1, color2); + } + + end_tft_write(); +} + + /*************************************************************************************** ** Function name: color565 ** Description: convert three 8 bit RGB levels to a 16 bit colour value diff --git a/TFT_eSPI.h b/TFT_eSPI.h index c85fef9..a92696a 100644 --- a/TFT_eSPI.h +++ b/TFT_eSPI.h @@ -16,7 +16,7 @@ #ifndef _TFT_eSPIH_ #define _TFT_eSPIH_ -#define TFT_ESPI_VERSION "2.4.24" +#define TFT_ESPI_VERSION "2.4.25" // Bit level feature flags // Bit 0 set: viewport capability @@ -458,6 +458,8 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac drawRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t radius, uint32_t color), fillRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t radius, uint32_t color); + void fillRectVGradient(int16_t x, int16_t y, int16_t w, int16_t h, uint32_t color1, uint32_t color2); + void fillRectHGradient(int16_t x, int16_t y, int16_t w, int16_t h, uint32_t color1, uint32_t color2); void drawCircle(int32_t x, int32_t y, int32_t r, uint32_t color), drawCircleHelper(int32_t x, int32_t y, int32_t r, uint8_t cornername, uint32_t color), @@ -763,6 +765,8 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac getColorCallback getColor = nullptr; // Smooth font callback function pointer + bool locked, inTransaction, lockTransaction; // SPI transaction and mutex lock flags + //-------------------------------------- protected ----------------------------------// protected: @@ -794,7 +798,6 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac bool isDigits; // adjust bounding box for numbers to reduce visual jiggling bool textwrapX, textwrapY; // If set, 'wrap' text at right and optionally bottom edge of display bool _swapBytes; // Swap the byte order for TFT pushImage() - bool locked, inTransaction, lockTransaction; // SPI transaction and mutex lock flags bool _booted; // init() or begin() has already run once diff --git a/library.json b/library.json index b927ccc..8f5b720 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "TFT_eSPI", - "version": "2.4.24", + "version": "2.4.25", "keywords": "Arduino, tft, ePaper, display, Pico, RP2040, STM32, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9481, ILI9486, ILI9488, ST7789, RM68140, SSD1351, SSD1963, ILI9225, HX8357D", "description": "A TFT and ePaper SPI graphics library with optimisation for Raspberry Pi Pico, ESP8266, ESP32 and STM32", "repository": diff --git a/library.properties b/library.properties index b2abf1d..8923a09 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=TFT_eSPI -version=2.4.24 +version=2.4.25 author=Bodmer maintainer=Bodmer sentence=TFT graphics library for Arduino processors with performance optimisation for RP2040, STM32, ESP8266 and ESP32