mirror of
https://github.com/Bodmer/TFT_eSPI.git
synced 2025-08-09 23:54:43 +02:00
Add viewport feature
2 new example sketches added for viewport demonstration
This commit is contained in:
@@ -843,9 +843,9 @@ bool TFT_eSprite::pushSprite(int32_t tx, int32_t ty, int32_t sx, int32_t sy, int
|
||||
_tft->pushImage(tx, ty, sw, sh, _img4 + (_iwidth>>1) * _ys, false, _colorMap );
|
||||
else // Render line by line
|
||||
{
|
||||
uint32_t ds = _xs&1; // Odd x start pixel
|
||||
int32_t ds = _xs&1; // Odd x start pixel
|
||||
|
||||
uint32_t de = 0; // Odd x end pixel
|
||||
int32_t de = 0; // Odd x end pixel
|
||||
if ((sw > ds) && (_xe&1)) de = 1;
|
||||
|
||||
uint32_t dm = 0; // Midsection pixel count
|
||||
@@ -877,7 +877,7 @@ bool TFT_eSprite::pushSprite(int32_t tx, int32_t ty, int32_t sx, int32_t sy, int
|
||||
_tft->setWindow(tx, ty, tx+sw-1, ty+sh-1);
|
||||
while (sh--)
|
||||
{
|
||||
for (uint32_t dx = _xs; dx < _xs + sw; dx++) _tft->pushColor(readPixel(dx, _ys));
|
||||
for (int32_t dx = _xs; dx < _xs + sw; dx++) _tft->pushColor(readPixel(dx, _ys));
|
||||
ty++;
|
||||
_ys++;
|
||||
}
|
||||
|
292
TFT_eSPI.cpp
292
TFT_eSPI.cpp
@@ -85,6 +85,132 @@ inline void TFT_eSPI::begin_tft_read(void){
|
||||
SET_BUS_READ_MODE;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: setViewport
|
||||
** Description: Set the clipping region for the TFT screen
|
||||
***************************************************************************************/
|
||||
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;
|
||||
|
||||
_vpDatum = false;
|
||||
|
||||
|
||||
// Check if out of bounds
|
||||
if ((x >= _width) || (y >= _height)) return;
|
||||
|
||||
// Clip
|
||||
if (x < 0) { x = 0; }
|
||||
if (y < 0) { y = 0; }
|
||||
|
||||
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
|
||||
{
|
||||
_xDatum = 0;
|
||||
_yDatum = 0;
|
||||
_vpX = x;
|
||||
_vpY = y;
|
||||
_vpW = x + w;
|
||||
_vpH = y + h;
|
||||
}
|
||||
|
||||
_vpDatum = vpDatum;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: resetViewport
|
||||
** Description: Reset viewport to whle TFT screen, datum at 0,0
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::resetViewport(void)
|
||||
{
|
||||
// Set to whole screen
|
||||
_xDatum = 0;
|
||||
_yDatum = 0;
|
||||
_vpX = 0;
|
||||
_vpY = 0;
|
||||
_vpW = _width;
|
||||
_vpH = _height;
|
||||
|
||||
_vpDatum = false;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: getViewportWidth
|
||||
** Description: Get width of the viewport
|
||||
***************************************************************************************/
|
||||
int32_t TFT_eSPI::getViewportWidth(void)
|
||||
{
|
||||
return _vpW - _vpX;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: getViewportHeight
|
||||
** Description: Get height of the viewport
|
||||
***************************************************************************************/
|
||||
int32_t TFT_eSPI::getViewportHeight(void)
|
||||
{
|
||||
return _vpH - _vpY;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: frameViewport
|
||||
** Description: Draw a frame inside or outside the viewport of width w
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::frameViewport(uint16_t color, int32_t w)
|
||||
{
|
||||
// If w is positive the frame is drawn inside the viewport
|
||||
// a large positive width will clear the screen inside the viewport
|
||||
if (w>0)
|
||||
{
|
||||
fillRect(_vpX, _vpY, _vpW - _vpX, w, color);
|
||||
fillRect(_vpX, _vpY + w, w, _vpH - _vpY - w - w, color);
|
||||
fillRect(_vpW - w, _vpY + w, w, _vpH - _vpY - w - w, color);
|
||||
fillRect(_vpX, _vpH - w, _vpW - _vpX, w, color);
|
||||
}
|
||||
else
|
||||
// If w is negative the frame is drawn outside the viewport
|
||||
// a large negative width will clear the screen outside the viewport
|
||||
{
|
||||
w = -w;
|
||||
int32_t _xTemp = _vpX; _vpX = 0;
|
||||
int32_t _yTemp = _vpY; _vpY = 0;
|
||||
int32_t _wTemp = _vpW; _vpW = _width;
|
||||
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);
|
||||
|
||||
_vpX = _xTemp;
|
||||
_vpY = _yTemp;
|
||||
_vpW = _wTemp;
|
||||
_vpH = _hTemp;
|
||||
_vpDatum = _dTemp;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: end_tft_read (was called spi_end_read)
|
||||
** Description: End transaction for reads and deselect TFT
|
||||
@@ -181,6 +307,15 @@ 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;
|
||||
|
||||
rotation = 0;
|
||||
cursor_y = cursor_x = 0;
|
||||
textfont = 1;
|
||||
@@ -490,6 +625,18 @@ 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -903,18 +1050,18 @@ 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 >= _width) || (y >= _height)) return;
|
||||
if ((x >= _vpW) || (y >= _vpH)) return;
|
||||
|
||||
int32_t dx = 0;
|
||||
int32_t dy = 0;
|
||||
int32_t dw = w;
|
||||
int32_t dh = h;
|
||||
|
||||
if (x < 0) { dw += x; dx = -x; x = 0; }
|
||||
if (y < 0) { dh += y; dy = -y; y = 0; }
|
||||
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; }
|
||||
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; }
|
||||
|
||||
if ((x + dw) > _width ) dw = _width - x;
|
||||
if ((y + dh) > _height) dh = _height - y;
|
||||
if ((x + dw) > _vpW ) dw = _vpW - x;
|
||||
if ((y + dh) > _vpH ) dh = _vpH - y;
|
||||
|
||||
if (dw < 1 || dh < 1) return;
|
||||
|
||||
@@ -947,18 +1094,18 @@ 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 >= _width) || (y >= _height)) return;
|
||||
if ((x >= _vpW) || (y >= _vpH)) return;
|
||||
|
||||
int32_t dx = 0;
|
||||
int32_t dy = 0;
|
||||
int32_t dw = w;
|
||||
int32_t dh = h;
|
||||
|
||||
if (x < 0) { dw += x; dx = -x; x = 0; }
|
||||
if (y < 0) { dh += y; dy = -y; y = 0; }
|
||||
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; }
|
||||
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; }
|
||||
|
||||
if ((x + dw) > _width ) dw = _width - x;
|
||||
if ((y + dh) > _height) dh = _height - y;
|
||||
if ((x + dw) > _vpW ) dw = _vpW - x;
|
||||
if ((y + dh) > _vpH ) dh = _vpH - y;
|
||||
|
||||
if (dw < 1 || dh < 1) return;
|
||||
|
||||
@@ -1020,18 +1167,18 @@ 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 >= _width) || (y >= _height)) return;
|
||||
if ((x >= _vpW) || (y >= _vpH)) return;
|
||||
|
||||
int32_t dx = 0;
|
||||
int32_t dy = 0;
|
||||
int32_t dw = w;
|
||||
int32_t dh = h;
|
||||
|
||||
if (x < 0) { dw += x; dx = -x; x = 0; }
|
||||
if (y < 0) { dh += y; dy = -y; y = 0; }
|
||||
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; }
|
||||
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; }
|
||||
|
||||
if ((x + dw) > _width ) dw = _width - x;
|
||||
if ((y + dh) > _height) dh = _height - y;
|
||||
if ((x + dw) > _vpW ) dw = _vpW - x;
|
||||
if ((y + dh) > _vpH ) dh = _vpH - y;
|
||||
|
||||
if (dw < 1 || dh < 1) return;
|
||||
|
||||
@@ -1064,18 +1211,18 @@ 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 >= _width) || (y >= (int32_t)_height)) return;
|
||||
if ((x >= _vpW) || (y >= _vpH)) return;
|
||||
|
||||
int32_t dx = 0;
|
||||
int32_t dy = 0;
|
||||
int32_t dw = w;
|
||||
int32_t dh = h;
|
||||
|
||||
if (x < 0) { dw += x; dx = -x; x = 0; }
|
||||
if (y < 0) { dh += y; dy = -y; y = 0; }
|
||||
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; }
|
||||
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; }
|
||||
|
||||
if ((x + dw) > _width ) dw = _width - x;
|
||||
if ((y + dh) > _height) dh = _height - y;
|
||||
if ((x + dw) > _vpW ) dw = _vpW - x;
|
||||
if ((y + dh) > _vpH ) dh = _vpH - y;
|
||||
|
||||
if (dw < 1 || dh < 1) return;
|
||||
|
||||
@@ -1134,18 +1281,18 @@ 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 >= _width) || (y >= (int32_t)_height)) return;
|
||||
if ((x >= _vpW) || (y >= _vpH)) return;
|
||||
|
||||
int32_t dx = 0;
|
||||
int32_t dy = 0;
|
||||
int32_t dw = w;
|
||||
int32_t dh = h;
|
||||
|
||||
if (x < 0) { dw += x; dx = -x; x = 0; }
|
||||
if (y < 0) { dh += y; dy = -y; y = 0; }
|
||||
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; }
|
||||
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; }
|
||||
|
||||
if ((x + dw) > _width ) dw = _width - x;
|
||||
if ((y + dh) > _height) dh = _height - y;
|
||||
if ((x + dw) > _vpW ) dw = _vpW - x;
|
||||
if ((y + dh) > _vpH ) dh = _vpH - y;
|
||||
|
||||
if (dw < 1 || dh < 1) return;
|
||||
|
||||
@@ -1290,18 +1437,18 @@ 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 >= _width) || (y >= _height)) return;
|
||||
if ((x >= _vpW) || (y >= _vpH)) return;
|
||||
|
||||
int32_t dx = 0;
|
||||
int32_t dy = 0;
|
||||
int32_t dw = w;
|
||||
int32_t dh = h;
|
||||
|
||||
if (x < 0) { dw += x; dx = -x; x = 0; }
|
||||
if (y < 0) { dh += y; dy = -y; y = 0; }
|
||||
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; }
|
||||
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; }
|
||||
|
||||
if ((x + dw) > _width ) dw = _width - x;
|
||||
if ((y + dh) > _height) dh = _height - y;
|
||||
if ((x + dw) > _vpW ) dw = _vpW - x;
|
||||
if ((y + dh) > _vpH ) dh = _vpH - y;
|
||||
|
||||
if (dw < 1 || dh < 1) return;
|
||||
|
||||
@@ -2329,7 +2476,8 @@ uint8_t TFT_eSPI::getTextDatum(void)
|
||||
// Return the size of the display (per current rotation)
|
||||
int16_t TFT_eSPI::width(void)
|
||||
{
|
||||
return _width;
|
||||
if (_vpDatum) return _vpW - _vpX;
|
||||
else return _width;
|
||||
}
|
||||
|
||||
|
||||
@@ -2339,7 +2487,8 @@ int16_t TFT_eSPI::width(void)
|
||||
***************************************************************************************/
|
||||
int16_t TFT_eSPI::height(void)
|
||||
{
|
||||
return _height;
|
||||
if (_vpDatum) return _vpH - _vpY;
|
||||
else return _height;
|
||||
}
|
||||
|
||||
|
||||
@@ -2479,10 +2628,10 @@ 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 >= _width) || // Clip right
|
||||
(y >= _height) || // Clip bottom
|
||||
((x + 6 * size - 1) < 0) || // Clip left
|
||||
((y + 8 * size - 1) < 0)) // Clip top
|
||||
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 (c < 32) return;
|
||||
@@ -2495,7 +2644,7 @@ void TFT_eSPI::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32
|
||||
|
||||
bool fillbg = (bg != color);
|
||||
|
||||
if ((size==1) && fillbg) {
|
||||
if ((size==1) && fillbg && x >= _vpX && (x + 6 * size - 1) < _vpW) {
|
||||
uint8_t column[6];
|
||||
uint8_t mask = 0x1;
|
||||
begin_tft_write();
|
||||
@@ -2526,13 +2675,13 @@ void TFT_eSPI::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32
|
||||
else
|
||||
line = pgm_read_byte(font + (c * 5) + i);
|
||||
|
||||
if (size == 1) { // default size
|
||||
if (size == 1 && !fillbg) { // default size
|
||||
for (int8_t j = 0; j < 8; j++) {
|
||||
if (line & 0x1) drawPixel(x + i, y + j, color);
|
||||
line >>= 1;
|
||||
}
|
||||
}
|
||||
else { // big size
|
||||
else { // big size or clipped
|
||||
for (int8_t j = 0; j < 8; j++) {
|
||||
if (line & 0x1) fillRect(x + (i * size), y + (j * size), size, size, color);
|
||||
else if (fillbg) fillRect(x + i * size, y + j * size, size, size, bg);
|
||||
@@ -2640,6 +2789,14 @@ 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
|
||||
@@ -2714,7 +2871,13 @@ 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)
|
||||
{
|
||||
// Range checking
|
||||
if ((x < 0) || (y < 0) ||(x >= _width) || (y >= _height)) return;
|
||||
if ((x < _vpX) || (y < _vpY) ||(x >= _vpW) || (y >= _vpH)) return;
|
||||
|
||||
if( _vpDatum)
|
||||
{
|
||||
x+= _xDatum;
|
||||
y+= _yDatum;
|
||||
}
|
||||
|
||||
#ifdef CGRAM_OFFSET
|
||||
x+=colstart;
|
||||
@@ -2915,11 +3078,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)
|
||||
{
|
||||
// Clipping
|
||||
if ((x < 0) || (x >= _width) || (y >= _height)) return;
|
||||
if ((x < _vpX) || (x >= _vpW) || (y >= _vpH)) return;
|
||||
|
||||
if (y < 0) { h += y; y = 0; }
|
||||
if (y < _vpY) { h += y - _vpY; y = _vpY; }
|
||||
|
||||
if ((y + h) > _height) h = _height - y;
|
||||
if ((y + h) > _vpH) h = _vpH - y;
|
||||
|
||||
if (h < 1) return;
|
||||
|
||||
@@ -2940,11 +3103,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)
|
||||
{
|
||||
// Clipping
|
||||
if ((y < 0) || (x >= _width) || (y >= _height)) return;
|
||||
if ((y < _vpY) || (x >= _vpW) || (y >= _vpH)) return;
|
||||
|
||||
if (x < 0) { w += x; x = 0; }
|
||||
if (x < _vpX) { w += x - _vpX; x = _vpX; }
|
||||
|
||||
if ((x + w) > _width) w = _width - x;
|
||||
if ((x + w) > _vpW) w = _vpW - x;
|
||||
|
||||
if (w < 1) return;
|
||||
|
||||
@@ -2965,13 +3128,13 @@ 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)
|
||||
{
|
||||
// Clipping
|
||||
if ((x >= _width) || (y >= _height)) return;
|
||||
if ((x >= _vpW) || (y >= _vpH)) return;
|
||||
|
||||
if (x < 0) { w += x; x = 0; }
|
||||
if (y < 0) { h += y; y = 0; }
|
||||
if (x < _vpX) { w += x - _vpX; x = _vpX; }
|
||||
if (y < _vpY) { h += y - _vpY; y = _vpY; }
|
||||
|
||||
if ((x + w) > _width) w = _width - x;
|
||||
if ((y + h) > _height) h = _height - y;
|
||||
if ((x + w) > _vpW) w = _vpW - x;
|
||||
if ((y + h) > _vpH) h = _vpH - y;
|
||||
|
||||
if ((w < 1) || (h < 1)) return;
|
||||
|
||||
@@ -3359,11 +3522,11 @@ size_t TFT_eSPI::write(uint8_t utf8)
|
||||
cursor_x = 0;
|
||||
}
|
||||
else {
|
||||
if (textwrapX && (cursor_x + width * textsize > _width)) {
|
||||
if (textwrapX && (cursor_x + width * textsize > this->width())) {
|
||||
cursor_y += height;
|
||||
cursor_x = 0;
|
||||
}
|
||||
if (textwrapY && (cursor_y >= (int32_t)_height)) cursor_y = 0;
|
||||
if (textwrapY && (cursor_y >= (int32_t)this->height())) cursor_y = 0;
|
||||
cursor_x += drawChar(uniCode, cursor_x, cursor_y, textfont);
|
||||
}
|
||||
|
||||
@@ -3386,13 +3549,13 @@ size_t TFT_eSPI::write(uint8_t utf8)
|
||||
h = pgm_read_byte(&glyph->height);
|
||||
if((w > 0) && (h > 0)) { // Is there an associated bitmap?
|
||||
int16_t xo = (int8_t)pgm_read_byte(&glyph->xOffset);
|
||||
if(textwrapX && ((cursor_x + textsize * (xo + w)) > _width)) {
|
||||
if(textwrapX && ((cursor_x + textsize * (xo + w)) > this->width())) {
|
||||
// Drawing character would go off right edge; wrap to new line
|
||||
cursor_x = 0;
|
||||
cursor_y += (int16_t)textsize *
|
||||
(uint8_t)pgm_read_byte(&gfxFont->yAdvance);
|
||||
}
|
||||
if (textwrapY && (cursor_y >= (int32_t)_height)) cursor_y = 0;
|
||||
if (textwrapY && (cursor_y >= (int32_t)this->height())) cursor_y = 0;
|
||||
drawChar(cursor_x, cursor_y, uniCode, textcolor, textbgcolor, textsize);
|
||||
}
|
||||
cursor_x += pgm_read_byte(&glyph->xAdvance) * (int16_t)textsize;
|
||||
@@ -3482,6 +3645,8 @@ 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 w = width;
|
||||
int32_t pX = 0;
|
||||
int32_t pY = y;
|
||||
@@ -3491,9 +3656,8 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
|
||||
if (font == 2) {
|
||||
w = w + 6; // Should be + 7 but we need to compensate for width increment
|
||||
w = w / 8;
|
||||
if (x + width * textsize >= (int16_t)_width) return width * textsize ;
|
||||
|
||||
if (textcolor == textbgcolor || textsize != 1) {
|
||||
if (textcolor == textbgcolor || textsize != 1 || x < _vpX || x + width * textsize >= _vpW) {
|
||||
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
|
||||
inTransaction = true;
|
||||
|
||||
@@ -3570,7 +3734,7 @@ 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) {
|
||||
if (textcolor == textbgcolor && x >= _vpX && x + width * textsize <= _vpW) {
|
||||
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
|
||||
@@ -3619,7 +3783,7 @@ 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
|
||||
// so use faster drawing of characters and background using block write
|
||||
if ((textsize == 1) && (x >= 0) && (x + width <= _width) && (y >= 0) && (y + height <= _height))
|
||||
if (textsize == 1 && x >= _vpX && x + width <= _vpW)
|
||||
{
|
||||
setWindow(x, y, x + width - 1, y + height - 1);
|
||||
|
||||
@@ -3644,12 +3808,12 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
|
||||
int32_t pc = 0; // Pixel count
|
||||
int32_t pl = 0; // Pixel line length
|
||||
uint16_t pcol = 0; // Pixel color
|
||||
|
||||
bool pf = true; // Flag for plotting
|
||||
while (pc < w) {
|
||||
line = pgm_read_byte((uint8_t *)flash_address);
|
||||
flash_address++;
|
||||
if (line & 0x80) { pcol = textcolor; line &= 0x7F; }
|
||||
else pcol = textbgcolor;
|
||||
if (line & 0x80) { pcol = textcolor; line &= 0x7F; pf = true;}
|
||||
else { pcol = textbgcolor; if (textcolor == textbgcolor) pf = false;}
|
||||
line++;
|
||||
px = pc % width;
|
||||
tx = x + textsize * px;
|
||||
@@ -3661,7 +3825,7 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
|
||||
while (line--) {
|
||||
pl++;
|
||||
if ((px+pl) >= width) {
|
||||
fillRect(tx, ty, pl * textsize, textsize, pcol);
|
||||
if (pf) fillRect(tx, ty, pl * textsize, textsize, pcol);
|
||||
pl = 0;
|
||||
px = 0;
|
||||
tx = x;
|
||||
@@ -3669,7 +3833,7 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
|
||||
ty += textsize;
|
||||
}
|
||||
}
|
||||
if (pl) fillRect(tx, ty, pl * textsize, textsize, pcol);
|
||||
if (pl && pf) fillRect(tx, ty, pl * textsize, textsize, pcol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
15
TFT_eSPI.h
15
TFT_eSPI.h
@@ -16,7 +16,7 @@
|
||||
#ifndef _TFT_eSPIH_
|
||||
#define _TFT_eSPIH_
|
||||
|
||||
#define TFT_ESPI_VERSION "2.2.23"
|
||||
#define TFT_ESPI_VERSION "2.3.0"
|
||||
|
||||
/***************************************************************************************
|
||||
** Section 1: Load required header files
|
||||
@@ -390,6 +390,13 @@ class TFT_eSPI : public Print {
|
||||
void setAddrWindow(int32_t xs, int32_t ys, int32_t w, int32_t h), // Note: start coordinates + width and height
|
||||
setWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye); // Note: start + end coordinates
|
||||
|
||||
// Viewport commands, see "Viewport_Demo" sketch
|
||||
void setViewport(int32_t x, int32_t y, int32_t w, int32_t h, bool vpDatum = true);
|
||||
int32_t getViewportWidth(void);
|
||||
int32_t getViewportHeight(void);
|
||||
void frameViewport(uint16_t color, int32_t w);
|
||||
void resetViewport(void);
|
||||
|
||||
// Push (aka write pixel) colours to the TFT (use setAddrWindow() first)
|
||||
void pushColor(uint16_t color),
|
||||
pushColor(uint16_t color, uint32_t len), // Deprecated, use pushBlock()
|
||||
@@ -728,6 +735,12 @@ class TFT_eSPI : public Print {
|
||||
int32_t _width, _height; // Display w/h as modified by current rotation
|
||||
int32_t addr_row, addr_col; // Window position - used to minimise window commands
|
||||
|
||||
// Viewport variables
|
||||
int32_t _vpX, _vpY, _vpW, _vpH;
|
||||
int32_t _xDatum;
|
||||
int32_t _yDatum;
|
||||
bool _vpDatum;
|
||||
|
||||
uint32_t fontsloaded; // Bit field of fonts loaded
|
||||
|
||||
uint8_t glyph_ab, // Smooth font glyph delta Y (height) above baseline
|
||||
|
@@ -20,7 +20,10 @@
|
||||
//#define SSD1963_480_DRIVER // 272 x 480 display
|
||||
//#define SSD1963_800_DRIVER // 480 x 800 display
|
||||
//#define SSD1963_800ALT_DRIVER // Alternative 480 x 800 display
|
||||
#define SSD1963_800BD_DRIVER // 480 x 800 displau sourced from https://www.buydisplay.com/7-tft-screen-touch-lcd-display-module-w-ssd1963-controller-board-mcu
|
||||
#define SSD1963_800BD_DRIVER // 480 x 800 display sourced from https://www.buydisplay.com/7-tft-screen-touch-lcd-display-module-w-ssd1963-controller-board-mcu
|
||||
|
||||
//#define TFT_RGB_ORDER TFT_RGB // Colour order Red-Green-Blue
|
||||
#define TFT_RGB_ORDER TFT_BGR // Colour order Blue-Green-Red
|
||||
|
||||
// ##################################################################################
|
||||
//
|
||||
|
@@ -20,7 +20,7 @@ uint8_t __attribute__((always_inline)) rng()
|
||||
zx++;
|
||||
za = (za^zc^zx);
|
||||
zb = (zb+za);
|
||||
zc = (zc+(zb>>1)^za);
|
||||
zc = ((zc+(zb>>1))^za);
|
||||
return zc;
|
||||
}
|
||||
|
||||
|
142
examples/Viewport_Demo/Viewport_Demo.ino
Normal file
142
examples/Viewport_Demo/Viewport_Demo.ino
Normal file
@@ -0,0 +1,142 @@
|
||||
// Viewport Demo
|
||||
|
||||
// See viewport_commands tab
|
||||
|
||||
// This example uses the viewport commands to create a "virtual TFT" within the
|
||||
// normal TFT display area. This allows a sketch written for a smaller screen to
|
||||
// be run in a viewport window. By default, the graphics 0,0 datum is set to the
|
||||
// top left corner of the viewport, but optionally the datum can be kept at the
|
||||
// corner of the TFT.
|
||||
|
||||
// Viewports have a number of potential uses:
|
||||
// - create a "virtual" TFT screen smaller than the actual TFT screen
|
||||
// - render GUI items (menus etc) in a viewport, erase GUI item by redrawing whole screen,
|
||||
// this will be fast because only the viewport will be refreshed (e.g. clearing menu)
|
||||
// - limit screen refresh to a particular area, e.g. changing numbers, icons or graph plotting
|
||||
// - showing a small portion of a larger image or sprite, this allows panning and scrolling
|
||||
|
||||
// A viewport can have the coordinate datum (position 0,0) either at the top left corner of
|
||||
// the viewport or at the normal top left corner of the TFT.
|
||||
// Putting the coordinate datum at the viewport corner means that functions that draw graphics
|
||||
// in a fixed position can be relocated anywhere on the screen. (see plotShapes() below). This
|
||||
// makes it easier to reposition groupd of graphical ojects (for example GUI buttons) that have
|
||||
// fixed relative positions.
|
||||
|
||||
// The viewport position x, and y coordinates and viewport bounds must be constrained by the
|
||||
// user sketch to be within the screen boundaries.
|
||||
|
||||
#include <SPI.h>
|
||||
#include <TFT_eSPI.h>
|
||||
|
||||
TFT_eSPI tft = TFT_eSPI();
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
tft.init();
|
||||
tft.setRotation(1);
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
|
||||
|
||||
/*
|
||||
tft.setViewport(VP_X, VP_Y, VP_W, VP_H); // By default the 0,0 coordinate datum is
|
||||
// moved to top left corner of viewport
|
||||
// Note: tft.width() and tft.height() now return viewport size
|
||||
// Other command options:
|
||||
//tft.setViewport(VP_X, VP_Y, VP_W, VP_H, true); // Explicitly set datum to viewport corner
|
||||
|
||||
//tft.setViewport(VP_X, VP_Y, VP_W, VP_H, false); // Create viewport but datum stays at TFT corner
|
||||
// Note: tft.width() and tft.height() now return TFT size
|
||||
|
||||
w = tft.getViewportWidth(); // Always returns width of viewport
|
||||
h = tft.getViewportHeight(); // Always returns height of viewport
|
||||
|
||||
tft.frameViewport(TFT_GREEN, -2); // Draw a rectangle of width 2 outside (negative width) viewport
|
||||
tft.frameViewport(TFT_RED, 10); // Draw a rectangle of width 10 inside (positive width) viewport
|
||||
|
||||
// tft.resetViewport(); // Command to reset viewport to "normal" full TFT screen
|
||||
// Graphics will not be drawn to the TFT outside a viewport until
|
||||
// this command is used!
|
||||
|
||||
// tft.setRotation(2); // Using setRotation rotates the whole TFT screen it does not just
|
||||
// rotate the viewport (this is a possible future enhancement).
|
||||
// Redraw all graphics after a rotation since some TFT's do not
|
||||
// re-map the TFT graphics RAM to the screen pixels as expected.
|
||||
delay(1000);
|
||||
*/
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Normal Screen
|
||||
drawX();
|
||||
|
||||
delay(2000);
|
||||
|
||||
// Viewport screen
|
||||
tft.setViewport(10, 10, 140, 100);
|
||||
tft.frameViewport(TFT_NAVY, -2);
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
drawX();
|
||||
tft.resetViewport();
|
||||
|
||||
delay(2000);
|
||||
|
||||
//Normal screen
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
drawX();
|
||||
|
||||
delay(2000);
|
||||
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
|
||||
// Viewport as a clipping window (false parameter means coordinate datum stays at TFT top left)
|
||||
tft.setViewport(10, 10, tft.width()/2 - 10, tft.height() - 20, false);
|
||||
//tft.frameViewport(TFT_NAVY, 2); // Add 2 pixel border inside viewport
|
||||
//tft.frameViewport(TFT_NAVY, -2); // Add 2 pixel border outside viewport
|
||||
drawX();
|
||||
|
||||
delay(2000);
|
||||
|
||||
while(1)
|
||||
{
|
||||
tft.resetViewport(); // Reset viewport so width() and height() return TFT size
|
||||
|
||||
uint16_t w = 40;
|
||||
uint16_t h = 40;
|
||||
uint16_t x = random(tft.width() - w);
|
||||
uint16_t y = random(tft.height() - h);
|
||||
|
||||
tft.setViewport(x, y, w, h);
|
||||
|
||||
plotBox();
|
||||
}
|
||||
}
|
||||
|
||||
void drawX(void)
|
||||
{
|
||||
tft.fillScreen(tft.color565(25,25,25)); // Grey
|
||||
|
||||
// Draw circle
|
||||
tft.drawCircle(tft.width()/2, tft.height()/2, tft.width()/4, TFT_RED);
|
||||
|
||||
// Draw diagonal lines
|
||||
tft.drawLine(0 , 0, tft.width()-1, tft.height()-1, TFT_GREEN);
|
||||
tft.drawLine(0 , tft.height()-1, tft.width()-1, 0, TFT_BLUE);
|
||||
|
||||
tft.setTextDatum(MC_DATUM);
|
||||
tft.setTextColor(TFT_WHITE, tft.color565(25,25,25));
|
||||
tft.drawString("Hello World!", tft.width()/2, tft.height()/2, 4); // Font 4
|
||||
}
|
||||
|
||||
void plotBox(void)
|
||||
{
|
||||
// These are always plotted at a fixed position but they can
|
||||
// be plotted into a viewport anywhere on the screen because
|
||||
// a viewport can move the screen datum
|
||||
tft.fillScreen(TFT_BLACK); // When a viewport is set, this just fills the viewport
|
||||
tft.drawRect(0,0, 40,40, TFT_BLUE);
|
||||
tft.setTextDatum(MC_DATUM);
|
||||
tft.setTextColor(TFT_WHITE);
|
||||
tft.drawNumber( random(100), 20, 23, 4);
|
||||
}
|
33
examples/Viewport_Demo/Viewport_commands.ino
Normal file
33
examples/Viewport_Demo/Viewport_commands.ino
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
|
||||
// Create a viewport at TFT screen coordinated X,y of width W and height H
|
||||
tft.setViewport(X, Y, W, H); // By default the 0,0 coordinate datum is moved to top left
|
||||
// corner of viewport
|
||||
// Note: tft.width() and tft.height() now return viewport size!
|
||||
// The above command is identical to:
|
||||
tft.setViewport(VP_X, VP_Y, VP_W, VP_H, true); // true parameter is optional
|
||||
|
||||
// To create a viewport that keeps the coordinate datum at top left of TFT, use false parameter
|
||||
tft.setViewport(VP_X, VP_Y, VP_W, VP_H, false); // Note: tft.width() and tft.height() return TFT size!
|
||||
|
||||
// To get width of viewport
|
||||
uint16_t w = tft.getViewportWidth(); // Always returns width of viewport
|
||||
|
||||
// To get height of viewport
|
||||
uint16_t h = tft.getViewportHeight(); // Always returns height of viewport
|
||||
|
||||
// To draw a rectangular frame outside viewport of width W (when W is negative)
|
||||
tft.frameViewport(TFT_RED, -W); // Note setting the width to a large negative value will clear the screen
|
||||
// outside the viewport
|
||||
|
||||
// To draw a rectangular frame inside viewport of width W (when W is positive)
|
||||
tft.frameViewport(TFT_RED, W); // Note setting the width to a large positive value will clear the screen
|
||||
// inside the viewport
|
||||
|
||||
// To reset the viewport to the normal TFT full screen
|
||||
tft.resetViewport(); // Note: Graphics will NOT be drawn to the TFT outside a viewport until
|
||||
// this command is used! ( The exception is using the frameViewport command
|
||||
// detailed above with a negative width.)
|
||||
|
||||
|
||||
*/
|
381
examples/Viewport_graphicstest/Viewport_graphicstest.ino
Normal file
381
examples/Viewport_graphicstest/Viewport_graphicstest.ino
Normal file
@@ -0,0 +1,381 @@
|
||||
/*
|
||||
This sketch demonstrates the Adafruit graphicstest sketch running in a
|
||||
viewport (aka window) within the TFT screen area. To do this line 37 has
|
||||
been added. Line 38 outlines the viewport.
|
||||
|
||||
This sketch uses the GLCD font (font 1) only.
|
||||
|
||||
Make sure all the display driver and pin comnenctions are correct by
|
||||
editting the User_Setup.h file in the TFT_eSPI library folder.
|
||||
|
||||
#########################################################################
|
||||
###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
|
||||
#########################################################################
|
||||
*/
|
||||
|
||||
|
||||
#include "SPI.h"
|
||||
#include "TFT_eSPI.h"
|
||||
|
||||
TFT_eSPI tft = TFT_eSPI();
|
||||
|
||||
unsigned long total = 0;
|
||||
unsigned long tn = 0;
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
while (!Serial);
|
||||
|
||||
Serial.println(""); Serial.println("");
|
||||
Serial.println("TFT_eSPI library test!");
|
||||
|
||||
tft.init();
|
||||
|
||||
tn = micros();
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
|
||||
// Create a viewport 220 x 300 pixels
|
||||
tft.setViewport(10,10,220,300);
|
||||
tft.frameViewport(TFT_RED, -1); // 1 pixel wide frame around viewport
|
||||
|
||||
yield(); Serial.println(F("Benchmark Time (microseconds)"));
|
||||
|
||||
yield(); Serial.print(F("Screen fill "));
|
||||
yield(); Serial.println(testFillScreen());
|
||||
//total+=testFillScreen();
|
||||
//delay(500);
|
||||
|
||||
yield(); Serial.print(F("Text "));
|
||||
yield(); Serial.println(testText());
|
||||
//total+=testText();
|
||||
//delay(3000);
|
||||
|
||||
yield(); Serial.print(F("Lines "));
|
||||
yield(); Serial.println(testLines(TFT_CYAN));
|
||||
//total+=testLines(TFT_CYAN);
|
||||
//delay(500);
|
||||
|
||||
yield(); Serial.print(F("Horiz/Vert Lines "));
|
||||
yield(); Serial.println(testFastLines(TFT_RED, TFT_BLUE));
|
||||
//total+=testFastLines(TFT_RED, TFT_BLUE);
|
||||
//delay(500);
|
||||
|
||||
yield(); Serial.print(F("Rectangles (outline) "));
|
||||
yield(); Serial.println(testRects(TFT_GREEN));
|
||||
//total+=testRects(TFT_GREEN);
|
||||
//delay(500);
|
||||
|
||||
yield(); Serial.print(F("Rectangles (filled) "));
|
||||
yield(); Serial.println(testFilledRects(TFT_YELLOW, TFT_MAGENTA));
|
||||
//total+=testFilledRects(TFT_YELLOW, TFT_MAGENTA);
|
||||
//delay(500);
|
||||
|
||||
yield(); Serial.print(F("Circles (filled) "));
|
||||
yield(); Serial.println(testFilledCircles(10, TFT_MAGENTA));
|
||||
//total+= testFilledCircles(10, TFT_MAGENTA);
|
||||
|
||||
yield(); Serial.print(F("Circles (outline) "));
|
||||
yield(); Serial.println(testCircles(10, TFT_WHITE));
|
||||
//total+=testCircles(10, TFT_WHITE);
|
||||
//delay(500);
|
||||
|
||||
yield(); Serial.print(F("Triangles (outline) "));
|
||||
yield(); Serial.println(testTriangles());
|
||||
//total+=testTriangles();
|
||||
//delay(500);
|
||||
|
||||
yield(); Serial.print(F("Triangles (filled) "));
|
||||
yield(); Serial.println(testFilledTriangles());
|
||||
//total += testFilledTriangles();
|
||||
//delay(500);
|
||||
|
||||
yield(); Serial.print(F("Rounded rects (outline) "));
|
||||
yield(); Serial.println(testRoundRects());
|
||||
//total+=testRoundRects();
|
||||
//delay(500);
|
||||
|
||||
yield(); Serial.print(F("Rounded rects (filled) "));
|
||||
yield(); Serial.println(testFilledRoundRects());
|
||||
//total+=testFilledRoundRects();
|
||||
//delay(500);
|
||||
|
||||
yield(); Serial.println(F("Done!")); yield();
|
||||
//Serial.print(F("Total = ")); Serial.println(total);
|
||||
|
||||
//yield();Serial.println(millis()-tn);
|
||||
}
|
||||
|
||||
void loop(void) {
|
||||
for (uint8_t rotation = 0; rotation < 4; rotation++) {
|
||||
tft.setRotation(rotation);
|
||||
tft.resetViewport(); // reset viewport to whole screen
|
||||
tft.fillScreen(TFT_BLACK); // so it can be cleared
|
||||
|
||||
// Create a viewport 220 x 300 pixels
|
||||
tft.setViewport(10,10,220,300);
|
||||
tft.frameViewport(TFT_RED, -1); // 1 pixel wide frame around viewport
|
||||
|
||||
testText();
|
||||
delay(2000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned long testFillScreen() {
|
||||
unsigned long start = micros();
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
tft.fillScreen(TFT_RED);
|
||||
tft.fillScreen(TFT_GREEN);
|
||||
tft.fillScreen(TFT_BLUE);
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testText() {
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
unsigned long start = micros();
|
||||
tft.setCursor(0, 0);
|
||||
tft.setTextColor(TFT_WHITE); tft.setTextSize(1);
|
||||
tft.println("Hello World!");
|
||||
tft.setTextColor(TFT_YELLOW); tft.setTextSize(2);
|
||||
tft.println(1234.56);
|
||||
tft.setTextColor(TFT_RED); tft.setTextSize(3);
|
||||
tft.println(0xDEADBEEF, HEX);
|
||||
tft.println();
|
||||
tft.setTextColor(TFT_GREEN);
|
||||
tft.setTextSize(5);
|
||||
tft.println("Groop");
|
||||
tft.setTextSize(2);
|
||||
tft.println("I implore thee,");
|
||||
//tft.setTextColor(TFT_GREEN,TFT_BLACK);
|
||||
tft.setTextSize(1);
|
||||
tft.println("my foonting turlingdromes.");
|
||||
tft.println("And hooptiously drangle me");
|
||||
tft.println("with crinkly bindlewurdles,");
|
||||
tft.println("Or I will rend thee");
|
||||
tft.println("in the gobberwarts");
|
||||
tft.println("with my blurglecruncheon,");
|
||||
tft.println("see if I don't!");
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testLines(uint16_t color) {
|
||||
unsigned long start, t;
|
||||
int x1, y1, x2, y2,
|
||||
w = tft.width(),
|
||||
h = tft.height();
|
||||
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
|
||||
x1 = y1 = 0;
|
||||
y2 = h - 1;
|
||||
start = micros();
|
||||
for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
x2 = w - 1;
|
||||
for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
t = micros() - start; // fillScreen doesn't count against timing
|
||||
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
|
||||
x1 = w - 1;
|
||||
y1 = 0;
|
||||
y2 = h - 1;
|
||||
start = micros();
|
||||
for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
x2 = 0;
|
||||
for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
t += micros() - start;
|
||||
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
|
||||
x1 = 0;
|
||||
y1 = h - 1;
|
||||
y2 = 0;
|
||||
start = micros();
|
||||
for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
x2 = w - 1;
|
||||
for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
t += micros() - start;
|
||||
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
|
||||
x1 = w - 1;
|
||||
y1 = h - 1;
|
||||
y2 = 0;
|
||||
start = micros();
|
||||
for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
x2 = 0;
|
||||
for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testFastLines(uint16_t color1, uint16_t color2) {
|
||||
unsigned long start;
|
||||
int x, y, w = tft.width(), h = tft.height();
|
||||
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
start = micros();
|
||||
for (y = 0; y < h; y += 5) tft.drawFastHLine(0, y, w, color1);
|
||||
for (x = 0; x < w; x += 5) tft.drawFastVLine(x, 0, h, color2);
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testRects(uint16_t color) {
|
||||
unsigned long start;
|
||||
int n, i, i2,
|
||||
cx = tft.width() / 2,
|
||||
cy = tft.height() / 2;
|
||||
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
n = min(tft.width(), tft.height());
|
||||
start = micros();
|
||||
for (i = 2; i < n; i += 6) {
|
||||
i2 = i / 2;
|
||||
tft.drawRect(cx - i2, cy - i2, i, i, color);
|
||||
}
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testFilledRects(uint16_t color1, uint16_t color2) {
|
||||
unsigned long start, t = 0;
|
||||
int n, i, i2,
|
||||
cx = tft.width() / 2 - 1,
|
||||
cy = tft.height() / 2 - 1;
|
||||
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
n = min(tft.width(), tft.height());
|
||||
for (i = n - 1; i > 0; i -= 6) {
|
||||
i2 = i / 2;
|
||||
start = micros();
|
||||
tft.fillRect(cx - i2, cy - i2, i, i, color1);
|
||||
t += micros() - start;
|
||||
// Outlines are not included in timing results
|
||||
tft.drawRect(cx - i2, cy - i2, i, i, color2);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
|
||||
unsigned long start;
|
||||
int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;
|
||||
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
start = micros();
|
||||
for (x = radius; x < w; x += r2) {
|
||||
for (y = radius; y < h; y += r2) {
|
||||
tft.fillCircle(x, y, radius, color);
|
||||
}
|
||||
}
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testCircles(uint8_t radius, uint16_t color) {
|
||||
unsigned long start;
|
||||
int x, y, r2 = radius * 2,
|
||||
w = tft.width() + radius,
|
||||
h = tft.height() + radius;
|
||||
|
||||
// Screen is not cleared for this one -- this is
|
||||
// intentional and does not affect the reported time.
|
||||
start = micros();
|
||||
for (x = 0; x < w; x += r2) {
|
||||
for (y = 0; y < h; y += r2) {
|
||||
tft.drawCircle(x, y, radius, color);
|
||||
}
|
||||
}
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testTriangles() {
|
||||
unsigned long start;
|
||||
int n, i, cx = tft.width() / 2 - 1,
|
||||
cy = tft.height() / 2 - 1;
|
||||
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
n = min(cx, cy);
|
||||
start = micros();
|
||||
for (i = 0; i < n; i += 5) {
|
||||
tft.drawTriangle(
|
||||
cx , cy - i, // peak
|
||||
cx - i, cy + i, // bottom left
|
||||
cx + i, cy + i, // bottom right
|
||||
tft.color565(0, 0, i));
|
||||
}
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testFilledTriangles() {
|
||||
unsigned long start, t = 0;
|
||||
int i, cx = tft.width() / 2 - 1,
|
||||
cy = tft.height() / 2 - 1;
|
||||
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
start = micros();
|
||||
for (i = min(cx, cy); i > 10; i -= 5) {
|
||||
start = micros();
|
||||
tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
|
||||
tft.color565(0, i, i));
|
||||
t += micros() - start;
|
||||
tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
|
||||
tft.color565(i, i, 0));
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
unsigned long testRoundRects() {
|
||||
unsigned long start;
|
||||
int w, i, i2,
|
||||
cx = tft.width() / 2 - 1,
|
||||
cy = tft.height() / 2 - 1;
|
||||
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
w = min(tft.width(), tft.height());
|
||||
start = micros();
|
||||
for (i = 0; i < w; i += 6) {
|
||||
i2 = i / 2;
|
||||
tft.drawRoundRect(cx - i2, cy - i2, i, i, i / 8, tft.color565(i, 0, 0));
|
||||
}
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testFilledRoundRects() {
|
||||
unsigned long start;
|
||||
int i, i2,
|
||||
cx = tft.width() / 2 - 1,
|
||||
cy = tft.height() / 2 - 1;
|
||||
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
start = micros();
|
||||
for (i = min(tft.width(), tft.height()); i > 20; i -= 6) {
|
||||
i2 = i / 2;
|
||||
tft.fillRoundRect(cx - i2, cy - i2, i, i, i / 8, tft.color565(0, i, 0));
|
||||
}
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
/***************************************************
|
||||
Original Adafruit text:
|
||||
|
||||
This is an example sketch for the Adafruit 2.2" SPI display.
|
||||
This library works with the Adafruit 2.2" TFT Breakout w/SD card
|
||||
----> http://www.adafruit.com/products/1480
|
||||
|
||||
Check out the links above for our tutorials and wiring diagrams
|
||||
These displays use SPI to communicate, 4 or 5 pins are required to
|
||||
interface (RST is optional)
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||
MIT license, all text above must be included in any redistribution
|
||||
****************************************************/
|
@@ -17,6 +17,11 @@ getRotation KEYWORD2
|
||||
invertDisplay KEYWORD2
|
||||
setAddrWindow KEYWORD2
|
||||
setWindow KEYWORD2
|
||||
setViewport KEYWORD2
|
||||
resetViewport KEYWORD2
|
||||
getViewportWidth KEYWORD2
|
||||
getViewportHeight KEYWORD2
|
||||
frameViewport KEYWORD2
|
||||
pushColor KEYWORD2
|
||||
pushColors KEYWORD2
|
||||
pushBlock KEYWORD2
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "TFT_eSPI",
|
||||
"version": "2.2.23",
|
||||
"version": "2.3.0",
|
||||
"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.2.23
|
||||
version=2.3.0
|
||||
author=Bodmer
|
||||
maintainer=Bodmer
|
||||
sentence=TFT graphics library for Arduino processors with performance optimisation for STM32, ESP8266 and ESP32
|
||||
|
Reference in New Issue
Block a user