mirror of
https://github.com/Bodmer/TFT_eSPI.git
synced 2024-09-21 10:27:11 +00:00
Complete viewport update
This commit is contained in:
parent
ee91f723e7
commit
505ca81a70
@ -359,9 +359,13 @@ bool TFT_eSPI::getUnicodeIndex(uint16_t unicode, uint16_t *index)
|
||||
// Expects file to be open
|
||||
void TFT_eSPI::drawGlyph(uint16_t code)
|
||||
{
|
||||
uint16_t fg = textcolor;
|
||||
uint16_t bg = textbgcolor;
|
||||
|
||||
if (code < 0x21)
|
||||
{
|
||||
if (code == 0x20) {
|
||||
//if (fg!=bg) fillRect(cursor_x, cursor_y, gFont.spaceWidth, gFont.yAdvance, bg);
|
||||
cursor_x += gFont.spaceWidth;
|
||||
return;
|
||||
}
|
||||
@ -377,18 +381,15 @@ void TFT_eSPI::drawGlyph(uint16_t code)
|
||||
uint16_t gNum = 0;
|
||||
bool found = getUnicodeIndex(code, &gNum);
|
||||
|
||||
uint16_t fg = textcolor;
|
||||
uint16_t bg = textbgcolor;
|
||||
|
||||
if (found)
|
||||
{
|
||||
|
||||
if (textwrapX && (cursor_x + gWidth[gNum] + gdX[gNum] > _width))
|
||||
if (textwrapX && (cursor_x + gWidth[gNum] + gdX[gNum] > width()))
|
||||
{
|
||||
cursor_y += gFont.yAdvance;
|
||||
cursor_x = 0;
|
||||
}
|
||||
if (textwrapY && ((cursor_y + gFont.yAdvance) >= _height)) cursor_y = 0;
|
||||
if (textwrapY && ((cursor_y + gFont.yAdvance) >= height())) cursor_y = 0;
|
||||
if (cursor_x == 0) cursor_x -= gdX[gNum];
|
||||
|
||||
uint8_t* pbuffer = nullptr;
|
||||
@ -402,15 +403,17 @@ void TFT_eSPI::drawGlyph(uint16_t code)
|
||||
}
|
||||
#endif
|
||||
|
||||
int16_t xs = 0;
|
||||
uint32_t dl = 0;
|
||||
uint8_t pixel;
|
||||
|
||||
int16_t cy = cursor_y + gFont.maxAscent - gdY[gNum];
|
||||
int16_t cx = cursor_x + gdX[gNum];
|
||||
|
||||
int16_t xs = cx;
|
||||
uint32_t dl = 0;
|
||||
uint8_t pixel;
|
||||
|
||||
startWrite(); // Avoid slow ESP32 transaction overhead for every pixel
|
||||
|
||||
//if (fg!=bg) fillRect(cursor_x, cursor_y, gxAdvance[gNum], gFont.yAdvance, bg);
|
||||
|
||||
for (int y = 0; y < gHeight[gNum]; y++)
|
||||
{
|
||||
#ifdef FONT_FS_AVAILABLE
|
||||
|
413
TFT_eSPI.cpp
413
TFT_eSPI.cpp
@ -26,6 +26,26 @@
|
||||
#include "Processors/TFT_eSPI_Generic.c"
|
||||
#endif
|
||||
|
||||
// Clipping macro for pushImage
|
||||
#define PI_CLIP \
|
||||
if (_vpOoB) return; \
|
||||
x+= _xDatum; \
|
||||
y+= _yDatum; \
|
||||
\
|
||||
if ((x >= _vpW) || (y >= _vpH)) return; \
|
||||
\
|
||||
int32_t dx = 0; \
|
||||
int32_t dy = 0; \
|
||||
int32_t dw = w; \
|
||||
int32_t dh = h; \
|
||||
\
|
||||
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; } \
|
||||
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; } \
|
||||
\
|
||||
if ((x + dw) > _vpW ) dw = _vpW - x; \
|
||||
if ((y + dh) > _vpH ) dh = _vpH - y; \
|
||||
\
|
||||
if (dw < 1 || dh < 1) return;
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: begin_tft_write (was called spi_begin)
|
||||
@ -91,50 +111,63 @@ inline void TFT_eSPI::begin_tft_read(void){
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::setViewport(int32_t x, int32_t y, int32_t w, int32_t h, bool vpDatum)
|
||||
{
|
||||
// Set to whole screen in case of error
|
||||
_xDatum = 0;
|
||||
_yDatum = 0;
|
||||
_vpX = 0;
|
||||
_vpY = 0;
|
||||
_vpW = _width;
|
||||
_vpH = _height;
|
||||
// Viewport
|
||||
_xDatum = x; // Datum x position in screen coordinates
|
||||
_yDatum = y; // Datum y position in screen coordinates
|
||||
_xWidth = w; // Viewport width
|
||||
_yHeight = h; // Viewport height
|
||||
|
||||
_vpDatum = false;
|
||||
// Clipped viewport
|
||||
_vpX = 0; // Viewport top left corner x coordinate
|
||||
_vpY = 0; // Viewport top left corner y coordinate
|
||||
_vpW = _width; // Equivalent of TFT width (Nb: viewport right edge coord + 1)
|
||||
_vpH = _height; // Equivalent of TFT height (Nb: viewport bottom edge coord + 1)
|
||||
|
||||
_vpDatum = false; // Datum is at top left corner of screen (true = top left of viewport)
|
||||
_vpOoB = false; // Out of Bounds flag (true is all of viewport is off screen)
|
||||
|
||||
// Check if out of bounds
|
||||
if ((x >= _width) || (y >= _height)) return;
|
||||
// Clip viewport to screen area
|
||||
if (x<0) { w += x; x = 0; }
|
||||
if (y<0) { h += y; y = 0; }
|
||||
if ((x + w) > _width ) { w = _width - x; }
|
||||
if ((y + h) > _height) { h = _height - y; }
|
||||
|
||||
// Clip
|
||||
if (x < 0) { x = 0; }
|
||||
if (y < 0) { y = 0; }
|
||||
//Serial.print(" x=");Serial.print( x);Serial.print(", y=");Serial.print( y);
|
||||
//Serial.print(", w=");Serial.print(w);Serial.print(", h=");Serial.println(h);
|
||||
|
||||
if ((x + w) > _width ) w = _width - x;
|
||||
if ((y + h) > _height) h = _height - y;
|
||||
|
||||
// Check if out of bounds
|
||||
if (w < 1 || h < 1) return;
|
||||
|
||||
if (vpDatum)
|
||||
{
|
||||
_xDatum = x;
|
||||
_yDatum = y;
|
||||
_vpX = 0;
|
||||
_vpY = 0;
|
||||
_vpW = w;
|
||||
_vpH = h;
|
||||
}
|
||||
else
|
||||
// Check if viewport is entirely out of bounds
|
||||
if (w < 1 || h < 1)
|
||||
{
|
||||
// Set default values and Out of Bounds flag in case of error
|
||||
_xDatum = 0;
|
||||
_yDatum = 0;
|
||||
_vpX = x;
|
||||
_vpY = y;
|
||||
_vpW = x + w;
|
||||
_vpH = y + h;
|
||||
_xWidth = _width;
|
||||
_yHeight = _height;
|
||||
_vpOoB = true; // Set Out of Bounds flag to inhibit all drawing
|
||||
return;
|
||||
}
|
||||
|
||||
if (!vpDatum)
|
||||
{
|
||||
_xDatum = 0; // Reset to top left of screen if not useing a viewport datum
|
||||
_yDatum = 0;
|
||||
_xWidth = _width;
|
||||
_yHeight = _height;
|
||||
}
|
||||
|
||||
// Store the on screen viewport metrics and datum position
|
||||
_vpX = x;
|
||||
_vpY = y;
|
||||
_vpW = x + w;
|
||||
_vpH = y + h;
|
||||
_vpDatum = vpDatum;
|
||||
|
||||
//Serial.print(" _xDatum=");Serial.print( _xDatum);Serial.print(", _yDatum=");Serial.print( _yDatum);
|
||||
//Serial.print(", _xWidth=");Serial.print(_xWidth);Serial.print(", _yHeight=");Serial.println(_yHeight);
|
||||
|
||||
//Serial.print(" _vpX=");Serial.print( _vpX);Serial.print(", _vpY=");Serial.print( _vpY);
|
||||
//Serial.print(", _vpW=");Serial.print(_vpW);Serial.print(", _vpH=");Serial.println(_vpH);
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
@ -143,15 +176,18 @@ void TFT_eSPI::setViewport(int32_t x, int32_t y, int32_t w, int32_t h, bool vpDa
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::resetViewport(void)
|
||||
{
|
||||
// Set to whole screen
|
||||
// Reset viewport to the whole screen
|
||||
_xDatum = 0;
|
||||
_yDatum = 0;
|
||||
_vpX = 0;
|
||||
_vpY = 0;
|
||||
_vpW = _width;
|
||||
_vpH = _height;
|
||||
_xWidth = _width;
|
||||
_yHeight = _height;
|
||||
|
||||
_vpDatum = false;
|
||||
_vpOoB = false;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
@ -198,10 +234,10 @@ void TFT_eSPI::frameViewport(uint16_t color, int32_t w)
|
||||
int32_t _hTemp = _vpH; _vpH = _height;
|
||||
bool _dTemp = _vpDatum; _vpDatum = false;
|
||||
|
||||
fillRect(_xDatum + _xTemp - w, _yDatum + _yTemp - w, _wTemp - _xTemp + w + w, w, color);
|
||||
fillRect(_xDatum + _xTemp - w, _yDatum + _yTemp, w, _hTemp -_yTemp, color);
|
||||
fillRect(_xDatum + _wTemp, _yDatum + _yTemp, w, _hTemp - _yTemp, color);
|
||||
fillRect(_xDatum + _xTemp - w, _yDatum + _hTemp, _wTemp - _xTemp + w + w, w, color);
|
||||
fillRect(_xTemp - _xDatum, _yTemp - w - _yDatum, _wTemp - _xTemp + w + w, w, color);
|
||||
fillRect(_xTemp - w - _xDatum, _yTemp - _yDatum, w, _hTemp - _yTemp, color);
|
||||
fillRect(_wTemp - _xDatum, _yTemp - _yDatum, w, _hTemp - _yTemp, color);
|
||||
fillRect(_xTemp - w - _xDatum, _hTemp - _yDatum, _wTemp - _xTemp + w + w, w, color);
|
||||
|
||||
_vpX = _xTemp;
|
||||
_vpY = _yTemp;
|
||||
@ -308,13 +344,8 @@ TFT_eSPI::TFT_eSPI(int16_t w, int16_t h)
|
||||
_init_width = _width = w; // Set by specific xxxxx_Defines.h file or by users sketch
|
||||
_init_height = _height = h; // Set by specific xxxxx_Defines.h file or by users sketch
|
||||
|
||||
// Set display clip window to whole screen
|
||||
_xDatum = 0;
|
||||
_yDatum = 0;
|
||||
_vpX = 0;
|
||||
_vpY = 0;
|
||||
_vpW = _width;
|
||||
_vpH = _height;
|
||||
// Reset the viewport to the whole screen
|
||||
resetViewport();
|
||||
|
||||
rotation = 0;
|
||||
cursor_y = cursor_x = 0;
|
||||
@ -626,17 +657,8 @@ void TFT_eSPI::setRotation(uint8_t m)
|
||||
addr_row = 0xFFFF;
|
||||
addr_col = 0xFFFF;
|
||||
|
||||
if (!_vpDatum)
|
||||
{
|
||||
// Reset viewport to whole screen
|
||||
_xDatum = 0;
|
||||
_yDatum = 0;
|
||||
_vpX = 0;
|
||||
_vpY = 0;
|
||||
_vpW = _width;
|
||||
_vpH = _height;
|
||||
}
|
||||
|
||||
// Reset the viewport to the whole screen
|
||||
resetViewport();
|
||||
}
|
||||
|
||||
|
||||
@ -804,6 +826,19 @@ uint32_t TFT_eSPI::readcommand32(uint8_t cmd_function, uint8_t index)
|
||||
***************************************************************************************/
|
||||
uint16_t TFT_eSPI::readPixel(int32_t x0, int32_t y0)
|
||||
{
|
||||
if (_vpOoB) return 0;
|
||||
|
||||
x0+= _xDatum;
|
||||
y0+= _yDatum;
|
||||
|
||||
// Range checking
|
||||
if ((x0 < _vpX) || (y0 < _vpY) ||(x0 >= _vpW) || (y0 >= _vpH)) return 0;
|
||||
|
||||
#ifdef CGRAM_OFFSET
|
||||
x0+=colstart;
|
||||
y0+=rowstart;
|
||||
#endif
|
||||
|
||||
#if defined(TFT_PARALLEL_8_BIT)
|
||||
|
||||
CS_L;
|
||||
@ -813,13 +848,15 @@ uint16_t TFT_eSPI::readPixel(int32_t x0, int32_t y0)
|
||||
// Set masked pins D0- D7 to input
|
||||
busDir(dir_mask, INPUT);
|
||||
|
||||
#if !defined (SSD1963_DRIVER)
|
||||
// Dummy read to throw away don't care value
|
||||
readByte();
|
||||
#endif
|
||||
|
||||
// Fetch the 16 bit BRG pixel
|
||||
//uint16_t rgb = (readByte() << 8) | readByte();
|
||||
|
||||
#if defined (ILI9341_DRIVER) | defined (ILI9488_DRIVER) // Read 3 bytes
|
||||
#if defined (ILI9341_DRIVER) | defined (ILI9488_DRIVER) | defined (SSD1963_DRIVER)// Read 3 bytes
|
||||
|
||||
// Read window pixel 24 bit RGB values and fill in LS bits
|
||||
uint16_t rgb = ((readByte() & 0xF8) << 8) | ((readByte() & 0xFC) << 3) | (readByte() >> 3);
|
||||
@ -924,7 +961,21 @@ void TFT_eSPI::setCallback(getColorCallback getCol)
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::readRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data)
|
||||
{
|
||||
if ((x > _width) || (y > _height) || (w == 0) || (h == 0)) return;
|
||||
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;
|
||||
|
||||
#if defined(TFT_PARALLEL_8_BIT)
|
||||
|
||||
@ -935,13 +986,13 @@ void TFT_eSPI::readRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *da
|
||||
// Set masked pins D0- D7 to input
|
||||
busDir(dir_mask, INPUT);
|
||||
|
||||
// Dummy read to throw away don't care value
|
||||
readByte();
|
||||
|
||||
// Total pixel count
|
||||
uint32_t len = w * h;
|
||||
|
||||
#if defined (ILI9341_DRIVER) | defined (ILI9488_DRIVER) // Read 3 bytes
|
||||
// Dummy read to throw away don't care value
|
||||
readByte();
|
||||
|
||||
// Fetch the 24 bit RGB value
|
||||
while (len--) {
|
||||
// Assemble the RGB 16 bit colour
|
||||
@ -950,7 +1001,23 @@ void TFT_eSPI::readRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *da
|
||||
// Swapped byte order for compatibility with pushRect()
|
||||
*data++ = (rgb<<8) | (rgb>>8);
|
||||
}
|
||||
|
||||
#elif defined (SSD1963_DRIVER)
|
||||
// Fetch the 18 bit BRG pixels
|
||||
while (len--) {
|
||||
uint16_t bgr = ((readByte() & 0xF8) >> 3);; // CS_L adds a small delay
|
||||
bgr |= ((readByte() & 0xFC) << 3);
|
||||
bgr |= (readByte() << 8);
|
||||
// Swap Red and Blue (could check MADCTL setting to see if this is needed)
|
||||
uint16_t rgb = (bgr>>11) | (bgr<<11) | (bgr & 0x7E0);
|
||||
// Swapped byte order for compatibility with pushRect()
|
||||
*data++ = (rgb<<8) | (rgb>>8);
|
||||
}
|
||||
|
||||
#else // ILI9481 reads as 16 bits
|
||||
// Dummy read to throw away don't care value
|
||||
readByte();
|
||||
|
||||
// Fetch the 16 bit BRG pixels
|
||||
while (len--) {
|
||||
#ifdef ILI9486_DRIVER
|
||||
@ -1049,21 +1116,7 @@ void TFT_eSPI::pushRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *da
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data)
|
||||
{
|
||||
|
||||
if ((x >= _vpW) || (y >= _vpH)) return;
|
||||
|
||||
int32_t dx = 0;
|
||||
int32_t dy = 0;
|
||||
int32_t dw = w;
|
||||
int32_t dh = h;
|
||||
|
||||
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; }
|
||||
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; }
|
||||
|
||||
if ((x + dw) > _vpW ) dw = _vpW - x;
|
||||
if ((y + dh) > _vpH ) dh = _vpH - y;
|
||||
|
||||
if (dw < 1 || dh < 1) return;
|
||||
PI_CLIP;
|
||||
|
||||
begin_tft_write();
|
||||
inTransaction = true;
|
||||
@ -1093,21 +1146,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *d
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data, uint16_t transp)
|
||||
{
|
||||
|
||||
if ((x >= _vpW) || (y >= _vpH)) return;
|
||||
|
||||
int32_t dx = 0;
|
||||
int32_t dy = 0;
|
||||
int32_t dw = w;
|
||||
int32_t dh = h;
|
||||
|
||||
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; }
|
||||
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; }
|
||||
|
||||
if ((x + dw) > _vpW ) dw = _vpW - x;
|
||||
if ((y + dh) > _vpH ) dh = _vpH - y;
|
||||
|
||||
if (dw < 1 || dh < 1) return;
|
||||
PI_CLIP;
|
||||
|
||||
begin_tft_write();
|
||||
inTransaction = true;
|
||||
@ -1167,20 +1206,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *d
|
||||
void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *data)
|
||||
{
|
||||
// Requires 32 bit aligned access, so use PROGMEM 16 bit word functions
|
||||
if ((x >= _vpW) || (y >= _vpH)) return;
|
||||
|
||||
int32_t dx = 0;
|
||||
int32_t dy = 0;
|
||||
int32_t dw = w;
|
||||
int32_t dh = h;
|
||||
|
||||
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; }
|
||||
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; }
|
||||
|
||||
if ((x + dw) > _vpW ) dw = _vpW - x;
|
||||
if ((y + dh) > _vpH ) dh = _vpH - y;
|
||||
|
||||
if (dw < 1 || dh < 1) return;
|
||||
PI_CLIP;
|
||||
|
||||
begin_tft_write();
|
||||
inTransaction = true;
|
||||
@ -1203,7 +1229,6 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint1
|
||||
end_tft_write();
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: pushImage - for FLASH (PROGMEM) stored images
|
||||
** Description: plot 16 bit image with 1 colour being transparent
|
||||
@ -1211,20 +1236,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint1
|
||||
void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *data, uint16_t transp)
|
||||
{
|
||||
// Requires 32 bit aligned access, so use PROGMEM 16 bit word functions
|
||||
if ((x >= _vpW) || (y >= _vpH)) return;
|
||||
|
||||
int32_t dx = 0;
|
||||
int32_t dy = 0;
|
||||
int32_t dw = w;
|
||||
int32_t dh = h;
|
||||
|
||||
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; }
|
||||
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; }
|
||||
|
||||
if ((x + dw) > _vpW ) dw = _vpW - x;
|
||||
if ((y + dh) > _vpH ) dh = _vpH - y;
|
||||
|
||||
if (dw < 1 || dh < 1) return;
|
||||
PI_CLIP;
|
||||
|
||||
begin_tft_write();
|
||||
inTransaction = true;
|
||||
@ -1280,21 +1292,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint1
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *data, bool bpp8, uint16_t *cmap)
|
||||
{
|
||||
|
||||
if ((x >= _vpW) || (y >= _vpH)) return;
|
||||
|
||||
int32_t dx = 0;
|
||||
int32_t dy = 0;
|
||||
int32_t dw = w;
|
||||
int32_t dh = h;
|
||||
|
||||
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; }
|
||||
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; }
|
||||
|
||||
if ((x + dw) > _vpW ) dw = _vpW - x;
|
||||
if ((y + dh) > _vpH ) dh = _vpH - y;
|
||||
|
||||
if (dw < 1 || dh < 1) return;
|
||||
PI_CLIP;
|
||||
|
||||
begin_tft_write();
|
||||
inTransaction = true;
|
||||
@ -1437,20 +1435,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *data, uint8_t transp, bool bpp8, uint16_t *cmap)
|
||||
{
|
||||
if ((x >= _vpW) || (y >= _vpH)) return;
|
||||
|
||||
int32_t dx = 0;
|
||||
int32_t dy = 0;
|
||||
int32_t dw = w;
|
||||
int32_t dh = h;
|
||||
|
||||
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; }
|
||||
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; }
|
||||
|
||||
if ((x + dw) > _vpW ) dw = _vpW - x;
|
||||
if ((y + dh) > _vpH ) dh = _vpH - y;
|
||||
|
||||
if (dw < 1 || dh < 1) return;
|
||||
PI_CLIP;
|
||||
|
||||
begin_tft_write();
|
||||
inTransaction = true;
|
||||
@ -2476,8 +2461,7 @@ uint8_t TFT_eSPI::getTextDatum(void)
|
||||
// Return the size of the display (per current rotation)
|
||||
int16_t TFT_eSPI::width(void)
|
||||
{
|
||||
if (_vpDatum) return _vpW - _vpX;
|
||||
else return _width;
|
||||
return _xWidth;
|
||||
}
|
||||
|
||||
|
||||
@ -2487,8 +2471,7 @@ int16_t TFT_eSPI::width(void)
|
||||
***************************************************************************************/
|
||||
int16_t TFT_eSPI::height(void)
|
||||
{
|
||||
if (_vpDatum) return _vpH - _vpY;
|
||||
else return _height;
|
||||
return _yHeight;
|
||||
}
|
||||
|
||||
|
||||
@ -2628,28 +2611,34 @@ int16_t TFT_eSPI::fontHeight(void)
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32_t bg, uint8_t size)
|
||||
{
|
||||
if ((x >= _vpW) || // Clip right
|
||||
(y >= _vpH) || // Clip bottom
|
||||
((x + 6 * size - 1) < _vpX) || // Clip left
|
||||
((y + 8 * size - 1) < _vpY)) // Clip top
|
||||
return;
|
||||
if (_vpOoB) return;
|
||||
|
||||
int32_t xd = x + _xDatum;
|
||||
int32_t yd = y + _yDatum;
|
||||
|
||||
if (c < 32) return;
|
||||
#ifdef LOAD_GLCD
|
||||
//>>>>>>>>>>>>>>>>>>
|
||||
#ifdef LOAD_GFXFF
|
||||
#ifdef LOAD_GFXFF
|
||||
if(!gfxFont) { // 'Classic' built-in font
|
||||
#endif
|
||||
#endif
|
||||
//>>>>>>>>>>>>>>>>>>
|
||||
|
||||
bool fillbg = (bg != color);
|
||||
if ((xd >= _vpW) || // Clip right
|
||||
( yd >= _vpH) || // Clip bottom
|
||||
((xd + 6 * size - 1) < _vpX) || // Clip left
|
||||
((yd + 8 * size - 1) < _vpY)) // Clip top
|
||||
return;
|
||||
|
||||
if ((size==1) && fillbg && x >= _vpX && (x + 6 * size - 1) < _vpW) {
|
||||
bool fillbg = (bg != color);
|
||||
bool clip = xd < _vpX || xd + 6 * textsize >= _vpW || yd < _vpY || yd + 8 * textsize >= _vpH;
|
||||
|
||||
if ((size==1) && fillbg && !clip) {
|
||||
uint8_t column[6];
|
||||
uint8_t mask = 0x1;
|
||||
begin_tft_write();
|
||||
|
||||
setWindow(x, y, x+5, y+8);
|
||||
setWindow(xd, yd, xd+5, yd+8);
|
||||
|
||||
for (int8_t i = 0; i < 5; i++ ) column[i] = pgm_read_byte(font + (c * 5) + i);
|
||||
column[5] = 0;
|
||||
@ -2668,6 +2657,7 @@ void TFT_eSPI::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32
|
||||
else {
|
||||
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
|
||||
inTransaction = true;
|
||||
|
||||
for (int8_t i = 0; i < 6; i++ ) {
|
||||
uint8_t line;
|
||||
if (i == 5)
|
||||
@ -2694,9 +2684,9 @@ void TFT_eSPI::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32
|
||||
}
|
||||
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
#ifdef LOAD_GFXFF
|
||||
#ifdef LOAD_GFXFF
|
||||
} else { // Custom font
|
||||
#endif
|
||||
#endif
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
#endif // LOAD_GLCD
|
||||
|
||||
@ -2789,14 +2779,6 @@ void TFT_eSPI::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
|
||||
{
|
||||
//begin_tft_write(); // Must be called before setWindow
|
||||
|
||||
if( _vpDatum)
|
||||
{
|
||||
x0+= _xDatum;
|
||||
x1+= _xDatum;
|
||||
y0+= _yDatum;
|
||||
y1+= _yDatum;
|
||||
}
|
||||
|
||||
#if defined (SSD1963_DRIVER)
|
||||
if ((rotation & 0x1) == 0) { swap_coord(x0, y0); swap_coord(x1, y1); }
|
||||
#endif
|
||||
@ -2870,15 +2852,14 @@ void TFT_eSPI::readAddrWindow(int32_t xs, int32_t ys, int32_t w, int32_t h)
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color)
|
||||
{
|
||||
if (_vpOoB) return;
|
||||
|
||||
x+= _xDatum;
|
||||
y+= _yDatum;
|
||||
|
||||
// Range checking
|
||||
if ((x < _vpX) || (y < _vpY) ||(x >= _vpW) || (y >= _vpH)) return;
|
||||
|
||||
if( _vpDatum)
|
||||
{
|
||||
x+= _xDatum;
|
||||
y+= _yDatum;
|
||||
}
|
||||
|
||||
#ifdef CGRAM_OFFSET
|
||||
x+=colstart;
|
||||
y+=rowstart;
|
||||
@ -3077,6 +3058,11 @@ void TFT_eSPI::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color)
|
||||
{
|
||||
if (_vpOoB) return;
|
||||
|
||||
x+= _xDatum;
|
||||
y+= _yDatum;
|
||||
|
||||
// Clipping
|
||||
if ((x < _vpX) || (x >= _vpW) || (y >= _vpH)) return;
|
||||
|
||||
@ -3102,6 +3088,11 @@ void TFT_eSPI::drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color)
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color)
|
||||
{
|
||||
if (_vpOoB) return;
|
||||
|
||||
x+= _xDatum;
|
||||
y+= _yDatum;
|
||||
|
||||
// Clipping
|
||||
if ((y < _vpY) || (x >= _vpW) || (y >= _vpH)) return;
|
||||
|
||||
@ -3127,6 +3118,11 @@ void TFT_eSPI::drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color)
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color)
|
||||
{
|
||||
if (_vpOoB) return;
|
||||
|
||||
x+= _xDatum;
|
||||
y+= _yDatum;
|
||||
|
||||
// Clipping
|
||||
if ((x >= _vpW) || (y >= _vpH)) return;
|
||||
|
||||
@ -3138,6 +3134,15 @@ void TFT_eSPI::fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t col
|
||||
|
||||
if ((w < 1) || (h < 1)) return;
|
||||
|
||||
//Serial.print(" _xDatum=");Serial.print( _xDatum);Serial.print(", _yDatum=");Serial.print( _yDatum);
|
||||
//Serial.print(", _xWidth=");Serial.print(_xWidth);Serial.print(", _yHeight=");Serial.println(_yHeight);
|
||||
|
||||
//Serial.print(" _vpX=");Serial.print( _vpX);Serial.print(", _vpY=");Serial.print( _vpY);
|
||||
//Serial.print(", _vpW=");Serial.print(_vpW);Serial.print(", _vpH=");Serial.println(_vpH);
|
||||
|
||||
//Serial.print(" x=");Serial.print( y);Serial.print(", y=");Serial.print( y);
|
||||
//Serial.print(", w=");Serial.print(w);Serial.print(", h=");Serial.println(h);
|
||||
|
||||
begin_tft_write();
|
||||
|
||||
setWindow(x, y, x + w - 1, y + h - 1);
|
||||
@ -3581,7 +3586,7 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y)
|
||||
// Any UTF-8 decoding must be done before calling drawChar()
|
||||
int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
|
||||
{
|
||||
if (!uniCode) return 0;
|
||||
if (_vpOoB || !uniCode) return 0;
|
||||
|
||||
if (font==1) {
|
||||
#ifdef LOAD_GLCD
|
||||
@ -3645,19 +3650,23 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (x + width * textsize < (int16_t)_vpX || x >= _vpW) return width * textsize ;
|
||||
int32_t xd = x + _xDatum;
|
||||
int32_t yd = y + _yDatum;
|
||||
|
||||
if ((xd + width * textsize < _vpX || xd >= _vpW) && (yd + height * textsize < _vpY || yd >= _vpH)) return width * textsize ;
|
||||
|
||||
int32_t w = width;
|
||||
int32_t pX = 0;
|
||||
int32_t pY = y;
|
||||
uint8_t line = 0;
|
||||
bool clip = xd < _vpX || xd + width * textsize >= _vpW || yd < _vpY || yd + height * textsize >= _vpH;
|
||||
|
||||
#ifdef LOAD_FONT2 // chop out code if we do not need it
|
||||
if (font == 2) {
|
||||
w = w + 6; // Should be + 7 but we need to compensate for width increment
|
||||
w = w / 8;
|
||||
|
||||
if (textcolor == textbgcolor || textsize != 1 || x < _vpX || x + width * textsize >= _vpW) {
|
||||
if (textcolor == textbgcolor || textsize != 1 || clip) {
|
||||
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
|
||||
inTransaction = true;
|
||||
|
||||
@ -3698,9 +3707,10 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
|
||||
end_tft_write();
|
||||
}
|
||||
else { // Faster drawing of characters and background using block write
|
||||
|
||||
begin_tft_write();
|
||||
|
||||
setWindow(x, y, x + width - 1, y + height - 1);
|
||||
setWindow(xd, yd, xd + width - 1, yd + height - 1);
|
||||
|
||||
uint8_t mask;
|
||||
for (int32_t i = 0; i < height; i++) {
|
||||
@ -3734,7 +3744,8 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
|
||||
inTransaction = true;
|
||||
|
||||
w *= height; // Now w is total number of pixels in the character
|
||||
if (textcolor == textbgcolor && x >= _vpX && x + width * textsize <= _vpW) {
|
||||
if (textcolor == textbgcolor && !clip) {
|
||||
|
||||
int32_t px = 0, py = pY; // To hold character block start and end column and row values
|
||||
int32_t pc = 0; // Pixel count
|
||||
uint8_t np = textsize * textsize; // Number of pixels in a drawn pixel
|
||||
@ -3750,12 +3761,12 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
|
||||
line &= 0x7F;
|
||||
line++;
|
||||
if (ts) {
|
||||
px = x + textsize * (pc % width); // Keep these px and py calculations outside the loop as they are slow
|
||||
py = y + textsize * (pc / width);
|
||||
px = xd + textsize * (pc % width); // Keep these px and py calculations outside the loop as they are slow
|
||||
py = yd + textsize * (pc / width);
|
||||
}
|
||||
else {
|
||||
px = x + pc % width; // Keep these px and py calculations outside the loop as they are slow
|
||||
py = y + pc / width;
|
||||
px = xd + pc % width; // Keep these px and py calculations outside the loop as they are slow
|
||||
py = yd + pc / width;
|
||||
}
|
||||
while (line--) { // In this case the while(line--) is faster
|
||||
pc++; // This is faster than putting pc+=line before while()?
|
||||
@ -3768,8 +3779,8 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
|
||||
else {tft_Write_16(textcolor);}
|
||||
px += textsize;
|
||||
|
||||
if (px >= (x + width * textsize)) {
|
||||
px = x;
|
||||
if (px >= (xd + width * textsize)) {
|
||||
px = xd;
|
||||
py += textsize;
|
||||
}
|
||||
}
|
||||
@ -3781,11 +3792,11 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Text colour != background and textsize = 1 and character is within screen area
|
||||
// Text colour != background and textsize = 1 and character is within viewport area
|
||||
// so use faster drawing of characters and background using block write
|
||||
if (textsize == 1 && x >= _vpX && x + width <= _vpW)
|
||||
if (textcolor != textbgcolor && textsize == 1 && !clip)
|
||||
{
|
||||
setWindow(x, y, x + width - 1, y + height - 1);
|
||||
setWindow(xd, yd, xd + width - 1, yd + height - 1);
|
||||
|
||||
// Maximum font size is equivalent to 180x180 pixels in area
|
||||
while (w > 0) {
|
||||
@ -3969,11 +3980,6 @@ int16_t TFT_eSPI::drawString(const char *string, int32_t poX, int32_t poY, uint8
|
||||
padding += 2;
|
||||
break;
|
||||
}
|
||||
/* // Check coordinates are OK, adjust if not
|
||||
if (poX < 0) poX = 0;
|
||||
if (poX+cwidth > width()) poX = width() - cwidth;
|
||||
if (poY < 0) poY = 0;
|
||||
if (poY+cheight-baseline> height()) poY = height() - cheight; //*/
|
||||
}
|
||||
|
||||
|
||||
@ -4010,7 +4016,16 @@ int16_t TFT_eSPI::drawString(const char *string, int32_t poX, int32_t poY, uint8
|
||||
#ifdef SMOOTH_FONT
|
||||
if(fontLoaded) {
|
||||
if (textcolor!=textbgcolor) fillRect(poX, poY, cwidth, cheight, textbgcolor);
|
||||
|
||||
/*
|
||||
// The above only works for a single text line, not if the text is going to wrap...
|
||||
// So need to use code like this in a while loop to fix it:
|
||||
if (textwrapX && (cursor_x + width * textsize > this->width())) {
|
||||
cursor_y += height;
|
||||
cursor_x = 0;
|
||||
}
|
||||
if (textwrapY && (cursor_y >= (int32_t)this->height())) cursor_y = 0;
|
||||
cursor_x += drawChar(uniCode, cursor_x, cursor_y, textfont);
|
||||
*/
|
||||
setCursor(poX, poY);
|
||||
|
||||
while (n < len) {
|
||||
|
@ -16,7 +16,7 @@
|
||||
#ifndef _TFT_eSPIH_
|
||||
#define _TFT_eSPIH_
|
||||
|
||||
#define TFT_ESPI_VERSION "2.3.0"
|
||||
#define TFT_ESPI_VERSION "2.3.1"
|
||||
|
||||
/***************************************************************************************
|
||||
** Section 1: Load required header files
|
||||
@ -736,10 +736,13 @@ class TFT_eSPI : public Print {
|
||||
int32_t addr_row, addr_col; // Window position - used to minimise window commands
|
||||
|
||||
// Viewport variables
|
||||
int32_t _vpX, _vpY, _vpW, _vpH;
|
||||
int32_t _vpX, _vpY, _vpW, _vpH; // Note: x start, y start, x end + 1, y end + 1
|
||||
int32_t _xDatum;
|
||||
int32_t _yDatum;
|
||||
int32_t _xWidth;
|
||||
int32_t _yHeight;
|
||||
bool _vpDatum;
|
||||
bool _vpOoB;
|
||||
|
||||
uint32_t fontsloaded; // Bit field of fonts loaded
|
||||
|
||||
|
@ -45,12 +45,11 @@ void loop() {
|
||||
|
||||
tft.setTextColor(TFT_RED, TFT_BLACK);
|
||||
tft.drawFloat(drawTime / 2890.0, 3, 0, 80, 4);
|
||||
if (drawTime < 100) tft.drawString("Font 1 not loaded!", 0, 108, 2);
|
||||
|
||||
|
||||
delay(4000);
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
drawTime = millis();
|
||||
drawTime = millis();
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
tft.drawNumber(i, 0, 0, 2);
|
||||
@ -60,12 +59,11 @@ void loop() {
|
||||
|
||||
tft.setTextColor(TFT_RED, TFT_BLACK);
|
||||
tft.drawFloat(drawTime / 2890.0, 3, 0, 80, 4);
|
||||
if (drawTime < 200) tft.drawString("Font 2 not loaded!", 0, 108, 2);
|
||||
|
||||
|
||||
delay(4000);
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
drawTime = millis();
|
||||
drawTime = millis();
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
tft.drawNumber(i, 0, 0, 4);
|
||||
@ -75,12 +73,11 @@ void loop() {
|
||||
|
||||
tft.setTextColor(TFT_RED, TFT_BLACK);
|
||||
tft.drawFloat(drawTime / 2890.0, 3, 0, 80, 4);
|
||||
if (drawTime < 200) tft.drawString("Font 4 not loaded!", 0, 108, 2);
|
||||
|
||||
|
||||
delay(4000);
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
drawTime = millis();
|
||||
drawTime = millis();
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
yield(); tft.drawNumber(i, 0, 0, 6);
|
||||
@ -90,12 +87,11 @@ void loop() {
|
||||
|
||||
tft.setTextColor(TFT_RED, TFT_BLACK);
|
||||
tft.drawFloat(drawTime / 2890.0, 3, 0, 80, 4);
|
||||
if (drawTime < 200) tft.drawString("Font 6 not loaded!", 0, 108, 2);
|
||||
|
||||
|
||||
delay(4000);
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
drawTime = millis();
|
||||
drawTime = millis();
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
yield(); tft.drawNumber(i, 0, 0, 7);
|
||||
@ -105,12 +101,11 @@ void loop() {
|
||||
|
||||
tft.setTextColor(TFT_RED, TFT_BLACK);
|
||||
tft.drawFloat(drawTime / 2890.0, 3, 0, 80, 4);
|
||||
if (drawTime < 200) tft.drawString("Font 7 not loaded!", 0, 108, 2);
|
||||
|
||||
|
||||
delay(4000);
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
drawTime = millis();
|
||||
drawTime = millis();
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
yield(); tft.drawNumber(i, 0, 0, 8);
|
||||
@ -120,8 +115,7 @@ void loop() {
|
||||
|
||||
tft.setTextColor(TFT_RED, TFT_BLACK);
|
||||
tft.drawFloat(drawTime / 190.0, 3, 0, 80, 4);
|
||||
if (drawTime < 200) tft.drawString("Font 8 not loaded!", 0, 108, 2);
|
||||
|
||||
|
||||
delay(4000);
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ void setup() {
|
||||
spr.setTextColor(TFT_WHITE, bg_color);
|
||||
spr.setTextDatum(MC_DATUM);
|
||||
spr.setTextPadding(spr_width);
|
||||
spr.drawNumber(0, spr_width/2, 0);
|
||||
spr.drawNumber(0, spr_width/2, spr.fontHeight()/2);
|
||||
spr.pushSprite(DIAL_CENTRE_X - spr_width / 2, DIAL_CENTRE_Y - spr.fontHeight() / 2);
|
||||
|
||||
// Plot the label text
|
||||
@ -203,7 +203,7 @@ void plotNeedle(int16_t angle, uint16_t ms_delay)
|
||||
}
|
||||
|
||||
// Update the number at the centre of the dial
|
||||
spr.drawNumber(old_angle+120, spr_width/2, 0);
|
||||
spr.drawNumber(old_angle+120, spr_width/2, spr.fontHeight()/2);
|
||||
spr.pushSprite(120 - spr_width / 2, 120 - spr.fontHeight() / 2);
|
||||
|
||||
// Slow needle down slightly as it approaches the new position
|
||||
|
@ -132,7 +132,7 @@ void loop() {
|
||||
for (int16_t angle = 30; angle <= 360; angle += 30)
|
||||
{
|
||||
spr.fillSprite(TFT_BLACK); // Clear the Sprite
|
||||
spr.drawNumber(num, 20, 15, 4); // Plot number, in Sprite at 15,15 and with font 4
|
||||
spr.drawNumber(num, 20, 15, 4); // Plot number, in Sprite at 20,15 and with font 4
|
||||
spr.pushRotated(angle, TFT_BLACK); // Plot rotated Sprite, black being transparent
|
||||
num++;
|
||||
}
|
||||
@ -143,7 +143,7 @@ void loop() {
|
||||
for (int16_t angle = -90; angle < 270; angle += 30)
|
||||
{
|
||||
spr.fillSprite(TFT_BLACK); // Clear the Sprite
|
||||
spr.drawNumber(angle+90, 15, 15, 4); // Plot number, in Sprite at 15,15 and with font 4
|
||||
spr.drawNumber(angle+90, 20, 15, 4); // Plot number, in Sprite at 20,15 and with font 4
|
||||
spr.pushRotated(angle, TFT_BLACK); // Plot rotated Sprite, black being transparent
|
||||
num++;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "TFT_eSPI",
|
||||
"version": "2.3.0",
|
||||
"version": "2.3.1",
|
||||
"keywords": "Arduino, tft, ePaper, display, STM32, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9486, ST7789, RM68140",
|
||||
"description": "A TFT and ePaper SPI graphics library with optimisation for ESP8266, ESP32 and STM32",
|
||||
"repository":
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=TFT_eSPI
|
||||
version=2.3.0
|
||||
version=2.3.1
|
||||
author=Bodmer
|
||||
maintainer=Bodmer
|
||||
sentence=TFT graphics library for Arduino processors with performance optimisation for STM32, ESP8266 and ESP32
|
||||
|
Loading…
Reference in New Issue
Block a user