mirror of
https://github.com/Bodmer/TFT_eSPI.git
synced 2024-09-21 02:17:13 +00:00
Add support for 1 bit per pixel in Sprite class
This is stage one of support for ePaper displays from Waveshare. Examples for 1 bit per pixel Sprites and 2 or 3 colour ePaper displays to follow soon.
This commit is contained in:
parent
1db0c30b81
commit
9276b0162d
@ -74,14 +74,14 @@ void TFT_eSPI::loadFont(String fontName)
|
||||
|
||||
*/
|
||||
|
||||
unloadFont();
|
||||
|
||||
_gFontFilename = "/" + fontName + ".vlw";
|
||||
|
||||
fontFile = SPIFFS.open( _gFontFilename, "r");
|
||||
|
||||
if(!fontFile) return;
|
||||
|
||||
//unloadFont();
|
||||
|
||||
fontFile.seek(0, fs::SeekSet);
|
||||
|
||||
gFont.gCount = (uint16_t)readInt32(); // glyph count in file
|
||||
@ -230,7 +230,8 @@ void TFT_eSPI::unloadFont( void )
|
||||
free(gBitmap);
|
||||
gBitmap = NULL;
|
||||
}
|
||||
fontFile.close();
|
||||
|
||||
if(fontFile) fontFile.close();
|
||||
fontLoaded = false;
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ TFT_eSprite::TFT_eSprite(TFT_eSPI *tft)
|
||||
|
||||
_iwidth = 0; // Initialise width and height to 0 (it does not exist yet)
|
||||
_iheight = 0;
|
||||
_bpp16 = true;
|
||||
_bpp = 16;
|
||||
_iswapBytes = false; // Do not swap pushImage colour bytes by default
|
||||
|
||||
_created = false;
|
||||
@ -33,7 +33,7 @@ TFT_eSprite::TFT_eSprite(TFT_eSPI *tft)
|
||||
_xptr = 0; // pushColor coordinate
|
||||
_yptr = 0;
|
||||
|
||||
_icursor_y = _icursor_x = 0; // Text cursor position
|
||||
this->cursor_y = this->cursor_x = 0; // Text cursor position
|
||||
}
|
||||
|
||||
|
||||
@ -42,22 +42,18 @@ TFT_eSprite::TFT_eSprite(TFT_eSPI *tft)
|
||||
** Description: Create a sprite (bitmap) of defined width and height
|
||||
*************************************************************************************x*/
|
||||
// cast returned value to (uint8_t*) for 8 bit or (uint16_t*) for 16 bit colours
|
||||
void* TFT_eSprite::createSprite(int16_t w, int16_t h)
|
||||
void* TFT_eSprite::createSprite(int16_t w, int16_t h, uint8_t frames)
|
||||
{
|
||||
|
||||
if ( _created )
|
||||
{
|
||||
if ( _bpp16 ) return _img;
|
||||
return _img8;
|
||||
}
|
||||
if ( _created ) return _img8_1;
|
||||
|
||||
if ( w < 1 || h < 1 ) return NULL;
|
||||
|
||||
_iwidth = w;
|
||||
_iheight = h;
|
||||
_iwidth = _dwidth = w;
|
||||
_iheight = _dheight = h;
|
||||
|
||||
_icursor_x = 0;
|
||||
_icursor_y = 0;
|
||||
this->cursor_x = 0;
|
||||
this->cursor_y = 0;
|
||||
|
||||
// Default scroll rectangle and gap fill colour
|
||||
_sx = 0;
|
||||
@ -69,28 +65,76 @@ void* TFT_eSprite::createSprite(int16_t w, int16_t h)
|
||||
// Add one extra "off screen" pixel to point out-of-bounds setWindow() coordinates
|
||||
// this means push/writeColor functions do not need additional bounds checks and
|
||||
// hence will run faster in normal circumstances.
|
||||
if(_bpp16)
|
||||
if (_bpp == 16)
|
||||
{
|
||||
_img = (uint16_t*) calloc(w * h + 1, sizeof(uint16_t));
|
||||
_img8_1 = ( uint8_t*) calloc(w * h + 1, sizeof(uint16_t));
|
||||
_img8_2 = _img8_1;
|
||||
_img = (uint16_t*) _img8_1;
|
||||
|
||||
if (_img)
|
||||
{
|
||||
_created = true;
|
||||
return _img;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
else if (_bpp == 8)
|
||||
{
|
||||
_img8 = ( uint8_t*) calloc(w * h + 1, sizeof(uint8_t));
|
||||
_img8_1 = ( uint8_t*) calloc(w * h + 1, sizeof(uint8_t));
|
||||
|
||||
if (_img8_1)
|
||||
{
|
||||
_img8 = _img8_1;
|
||||
_img8_2 = _img8_1;
|
||||
_created = true;
|
||||
return _img8;
|
||||
}
|
||||
}
|
||||
|
||||
else // Must be 1 bpp
|
||||
{
|
||||
//_dwidth Display width+height in pixels always in rotation 0 orientation
|
||||
//_dheight Not swapped for sprite rotations
|
||||
// Note: for 1bpp _iwidth and _iheight are swapped during Sprite rotations
|
||||
|
||||
w = (w+7) & 0xFFF8; // width should be the multiple of 8 bits to be compatible with epdpaint
|
||||
_iwidth = w; // _iwidth is rounded up to be multiple of 8, so might not be = _dwidth
|
||||
_bitwidth = w;
|
||||
|
||||
if (frames > 2) frames = 2; // Currently restricted to 2 frame buffers
|
||||
if (frames < 1) frames = 1;
|
||||
_img8 = ( uint8_t*) calloc(frames * (w>>3) * h + frames, sizeof(uint8_t)); // extra pixel added
|
||||
|
||||
if (_img8)
|
||||
{
|
||||
_created = true;
|
||||
return _img8;
|
||||
_img8_1 = _img8;
|
||||
_img8_2 = _img8 + ( (w>>3) * h + 1 );
|
||||
return _img8_1;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: frameBuffer
|
||||
** Description: For 1 bpp Sprites, select the frame used for graphics
|
||||
*************************************************************************************x*/
|
||||
// Frames are numbered 1 and 2
|
||||
void* TFT_eSprite::frameBuffer(int8_t f)
|
||||
{
|
||||
if (!_created) return NULL;
|
||||
|
||||
if (_bpp == 16) return _img;
|
||||
|
||||
if (_bpp == 8) return _img8;
|
||||
|
||||
if ( f == 2 ) _img8 = _img8_2;
|
||||
else _img8 = _img8_1;
|
||||
|
||||
return _img8;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: setDepth
|
||||
@ -100,15 +144,12 @@ void* TFT_eSprite::createSprite(int16_t w, int16_t h)
|
||||
void* TFT_eSprite::setColorDepth(int8_t b)
|
||||
{
|
||||
// Can't change an existing sprite's colour depth so delete it
|
||||
if (_created)
|
||||
{
|
||||
if (_bpp16) free(_img);
|
||||
else free(_img8);
|
||||
}
|
||||
if (_created) free(_img8_1);
|
||||
|
||||
// Now define the new colour depth
|
||||
if ( b > 8 ) _bpp16 = true; // Bytes per pixel
|
||||
else _bpp16 = false;
|
||||
if ( b > 8 ) _bpp = 16; // Bytes per pixel
|
||||
else if ( b > 1 ) _bpp = 8;
|
||||
else _bpp = 1;
|
||||
|
||||
// If it existed, re-create the sprite with the new colour depth
|
||||
if (_created)
|
||||
@ -120,6 +161,17 @@ void* TFT_eSprite::setColorDepth(int8_t b)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: setBitmapColor
|
||||
** Description: Set the foreground foreground and background colour
|
||||
***************************************************************************************/
|
||||
void TFT_eSprite::setBitmapColor(uint16_t c, uint16_t b)
|
||||
{
|
||||
if (c == b) b = ~c;
|
||||
_tft->bitmap_fg = c;
|
||||
_tft->bitmap_bg = b;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: deleteSprite
|
||||
@ -129,8 +181,7 @@ void TFT_eSprite::deleteSprite(void)
|
||||
{
|
||||
if (!_created ) return;
|
||||
|
||||
if (_bpp16) free(_img);
|
||||
else free(_img8);
|
||||
free(_img8_1);
|
||||
|
||||
_created = false;
|
||||
}
|
||||
@ -142,11 +193,12 @@ void TFT_eSprite::deleteSprite(void)
|
||||
*************************************************************************************x*/
|
||||
void TFT_eSprite::pushSprite(int32_t x, int32_t y)
|
||||
{
|
||||
if (!_created ) return;
|
||||
if (!_created) return;
|
||||
|
||||
if (_bpp == 16) _tft->pushImage(x, y, _iwidth, _iheight, _img );
|
||||
|
||||
else _tft->pushImage(x, y, _dwidth, _dheight, _img8, (bool)(_bpp == 8));
|
||||
|
||||
if (_bpp16) _tft->pushImage(x, y, _iwidth, _iheight, _img );
|
||||
//if (_bpp16) TFT_eSPI::pushImage(x, y, _iwidth, _iheight, _img );
|
||||
else _tft->pushImage(x, y, _iwidth, _iheight, _img8);
|
||||
}
|
||||
|
||||
|
||||
@ -156,14 +208,15 @@ void TFT_eSprite::pushSprite(int32_t x, int32_t y)
|
||||
*************************************************************************************x*/
|
||||
void TFT_eSprite::pushSprite(int32_t x, int32_t y, uint16_t transp)
|
||||
{
|
||||
if (!_created ) return;
|
||||
if (!_created) return;
|
||||
|
||||
if (_bpp16) _tft->pushImage(x, y, _iwidth, _iheight, _img, transp );
|
||||
else
|
||||
if (_bpp == 16) _tft->pushImage(x, y, _iwidth, _iheight, _img, transp );
|
||||
else if (_bpp == 8)
|
||||
{
|
||||
transp = (uint8_t)((transp & 0xE000)>>8 | (transp & 0x0700)>>6 | (transp & 0x0018)>>3);
|
||||
_tft->pushImage(x, y, _iwidth, _iheight, _img8, (uint8_t)transp);
|
||||
_tft->pushImage(x, y, _dwidth, _dheight, _img8, (uint8_t)transp, (bool)true);
|
||||
}
|
||||
else _tft->pushImage(x, y, _dwidth, _dheight, _img8, 0, (bool)false);
|
||||
}
|
||||
|
||||
|
||||
@ -173,24 +226,48 @@ void TFT_eSprite::pushSprite(int32_t x, int32_t y, uint16_t transp)
|
||||
*************************************************************************************x*/
|
||||
uint16_t TFT_eSprite::readPixel(int32_t x, int32_t y)
|
||||
{
|
||||
if (!_created ) return 0;
|
||||
if ((x < 0) || (x >= _iwidth) || (y < 0) || (y >= _iheight) || !_created) return 0;
|
||||
|
||||
if (_bpp16)
|
||||
if (_bpp == 16)
|
||||
{
|
||||
uint16_t color = _img[x + y * _iwidth];
|
||||
return (color >> 8) | (color << 8);
|
||||
}
|
||||
|
||||
uint16_t color = _img8[x + y * _iwidth];
|
||||
if (color != 0)
|
||||
|
||||
if (_bpp == 8)
|
||||
{
|
||||
uint16_t color = _img8[x + y * _iwidth];
|
||||
if (color != 0)
|
||||
{
|
||||
uint8_t blue[] = {0, 11, 21, 31};
|
||||
color = (color & 0xE0)<<8 | (color & 0xC0)<<5
|
||||
| (color & 0x1C)<<6 | (color & 0x1C)<<3
|
||||
| blue[color & 0x03];
|
||||
color = (color & 0xE0)<<8 | (color & 0xC0)<<5
|
||||
| (color & 0x1C)<<6 | (color & 0x1C)<<3
|
||||
| blue[color & 0x03];
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
return color;
|
||||
if (_rotation == 1)
|
||||
{
|
||||
uint16_t tx = x;
|
||||
x = _dwidth - y - 1;
|
||||
y = tx;
|
||||
}
|
||||
else if (_rotation == 2)
|
||||
{
|
||||
x = _dwidth - x - 1;
|
||||
y = _dheight - y - 1;
|
||||
}
|
||||
else if (_rotation == 3)
|
||||
{
|
||||
uint16_t tx = x;
|
||||
x = y;
|
||||
y = _dheight - tx - 1;
|
||||
}
|
||||
|
||||
uint16_t color = (_img8[(x + y * _bitwidth)>>3] << (x & 0x7)) & 0x80;
|
||||
|
||||
return color >> 7;
|
||||
}
|
||||
|
||||
|
||||
@ -198,11 +275,12 @@ uint16_t TFT_eSprite::readPixel(int32_t x, int32_t y)
|
||||
** Function name: pushImage
|
||||
** Description: push 565 colour image into a defined area of a sprite
|
||||
*************************************************************************************x*/
|
||||
// TODO Need to add more area boundary checks
|
||||
void TFT_eSprite::pushImage(int32_t x, int32_t y, uint32_t w, uint32_t h, uint16_t *data)
|
||||
{
|
||||
if ((x > _iwidth) || (y > _iheight) || (w == 0) || (h == 0) || !_created) return;
|
||||
if ((x >= _iwidth) || (y >= _iheight) || (w == 0) || (h == 0) || !_created) return;
|
||||
|
||||
if (_bpp16)
|
||||
if (_bpp == 16)
|
||||
{
|
||||
for (uint32_t yp = y; yp < y + h; yp++)
|
||||
{
|
||||
@ -214,7 +292,7 @@ void TFT_eSprite::pushImage(int32_t x, int32_t y, uint32_t w, uint32_t h, uint1
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (_bpp == 8)
|
||||
{
|
||||
for (uint32_t yp = y; yp < y + h; yp++)
|
||||
{
|
||||
@ -226,6 +304,7 @@ void TFT_eSprite::pushImage(int32_t x, int32_t y, uint32_t w, uint32_t h, uint1
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO Currently does nothing for 1 bpp
|
||||
}
|
||||
|
||||
|
||||
@ -233,11 +312,12 @@ void TFT_eSprite::pushImage(int32_t x, int32_t y, uint32_t w, uint32_t h, uint1
|
||||
** Function name: pushImage
|
||||
** Description: push 565 colour FLASH (PROGMEM) image into a defined area
|
||||
*************************************************************************************x*/
|
||||
// TODO Need to add more area boundary checks
|
||||
void TFT_eSprite::pushImage(int32_t x, int32_t y, uint32_t w, uint32_t h, const uint16_t *data)
|
||||
{
|
||||
if ((x > _iwidth) || (y > _iheight) || (w == 0) || (h == 0) || !_created) return;
|
||||
if ((x >= _iwidth) || (y >= _iheight) || (w == 0) || (h == 0) || !_created) return;
|
||||
|
||||
if (_bpp16)
|
||||
if (_bpp == 16)
|
||||
{
|
||||
for (uint32_t yp = y; yp < y + h; yp++)
|
||||
{
|
||||
@ -249,7 +329,7 @@ void TFT_eSprite::pushImage(int32_t x, int32_t y, uint32_t w, uint32_t h, const
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (_bpp == 8)
|
||||
{
|
||||
for (uint32_t yp = y; yp < y + h; yp++)
|
||||
{
|
||||
@ -261,6 +341,7 @@ void TFT_eSprite::pushImage(int32_t x, int32_t y, uint32_t w, uint32_t h, const
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO Currently does nothing for 1 bpp
|
||||
}
|
||||
|
||||
|
||||
@ -334,11 +415,13 @@ void TFT_eSprite::pushColor(uint32_t color)
|
||||
if (!_created ) return;
|
||||
|
||||
// Write the colour to RAM in set window
|
||||
if (_bpp16)
|
||||
if (_bpp == 16)
|
||||
_img [_xptr + _yptr * _iwidth] = (uint16_t) (color >> 8) | (color << 8);
|
||||
|
||||
else
|
||||
else if (_bpp == 8)
|
||||
_img8[_xptr + _yptr * _iwidth] = (uint8_t )((color & 0xE000)>>8 | (color & 0x0700)>>6 | (color & 0x0018)>>3);
|
||||
|
||||
else drawPixel(_xptr, _yptr, color);
|
||||
|
||||
// Increment x
|
||||
_xptr++;
|
||||
@ -363,12 +446,14 @@ void TFT_eSprite::pushColor(uint32_t color, uint16_t len)
|
||||
if (!_created ) return;
|
||||
|
||||
uint16_t pixelColor;
|
||||
if (_bpp16)
|
||||
if (_bpp == 16)
|
||||
pixelColor = (uint16_t) (color >> 8) | (color << 8);
|
||||
|
||||
else
|
||||
else if (_bpp == 8)
|
||||
pixelColor = (color & 0xE000)>>8 | (color & 0x0700)>>6 | (color & 0x0018)>>3;
|
||||
|
||||
// else Nothing to do for 1bpp
|
||||
|
||||
while(len--) writeColor(pixelColor);
|
||||
}
|
||||
|
||||
@ -382,10 +467,12 @@ void TFT_eSprite::writeColor(uint16_t color)
|
||||
if (!_created ) return;
|
||||
|
||||
// Write 16 bit RGB 565 encoded colour to RAM
|
||||
if (_bpp16) _img [_xptr + _yptr * _iwidth] = color;
|
||||
if (_bpp == 16) _img [_xptr + _yptr * _iwidth] = color;
|
||||
|
||||
// Write 8 bit RGB 332 encoded colour to RAM
|
||||
else _img8[_xptr + _yptr * _iwidth] = (uint8_t) color;
|
||||
else if (_bpp == 8) _img8[_xptr + _yptr * _iwidth] = (uint8_t) color;
|
||||
|
||||
else drawPixel(_xptr, _yptr, color);
|
||||
|
||||
// Increment x
|
||||
_xptr++;
|
||||
@ -466,7 +553,7 @@ void TFT_eSprite::scroll(int16_t dx, int16_t dy)
|
||||
uint32_t typ = tx + ty * _iwidth;
|
||||
|
||||
// Now move the pixels in RAM
|
||||
if (_bpp16)
|
||||
if (_bpp == 16)
|
||||
{
|
||||
while (h--)
|
||||
{ // move pixel lines (to, from, byte count)
|
||||
@ -475,7 +562,7 @@ void TFT_eSprite::scroll(int16_t dx, int16_t dy)
|
||||
fyp += iw;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (_bpp == 8)
|
||||
{
|
||||
while (h--)
|
||||
{ // move pixel lines (to, from, byte count)
|
||||
@ -484,6 +571,7 @@ void TFT_eSprite::scroll(int16_t dx, int16_t dy)
|
||||
fyp += iw;
|
||||
}
|
||||
}
|
||||
else return; // TODO add scroll for 1 bpp
|
||||
|
||||
// Fill the gap left by the scrolling
|
||||
if (dx > 0) fillRect(_sx, _sy, dx, _sh, _scolor);
|
||||
@ -502,13 +590,18 @@ void TFT_eSprite::fillSprite(uint32_t color)
|
||||
if (!_created ) return;
|
||||
|
||||
// Use memset if possible as it is super fast
|
||||
if(( (uint8_t)color == (uint8_t)(color>>8) ) && _bpp16)
|
||||
if(( (uint8_t)color == (uint8_t)(color>>8) ) && _bpp == 16)
|
||||
memset(_img, (uint8_t)color, _iwidth * _iheight * 2);
|
||||
else if (!_bpp16)
|
||||
else if (_bpp == 8)
|
||||
{
|
||||
color = (color & 0xE000)>>8 | (color & 0x0700)>>6 | (color & 0x0018)>>3;
|
||||
memset(_img8, (uint8_t)color, _iwidth * _iheight);
|
||||
}
|
||||
else if (_bpp == 1)
|
||||
{
|
||||
if(color) memset(_img8, 0xFF, (_iwidth>>3) * _iheight + 1);
|
||||
else memset(_img8, 0x00, (_iwidth>>3) * _iheight + 1);
|
||||
}
|
||||
|
||||
else fillRect(0, 0, _iwidth, _iheight, color);
|
||||
}
|
||||
@ -518,11 +611,12 @@ void TFT_eSprite::fillSprite(uint32_t color)
|
||||
** Function name: setCursor
|
||||
** Description: Set the sprite text cursor x,y position
|
||||
*************************************************************************************x*/
|
||||
void TFT_eSprite::setCursor(int16_t x, int16_t y)
|
||||
{
|
||||
_icursor_x = x;
|
||||
_icursor_y = y;
|
||||
}
|
||||
// Not needed - using TFT_eSPI class function and this->cursor_x/y
|
||||
//void TFT_eSprite::setCursor(int16_t x, int16_t y)
|
||||
//{
|
||||
// this->cursor_x = x;
|
||||
// this->cursor_y = y;
|
||||
//}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
@ -533,7 +627,12 @@ void TFT_eSprite::setCursor(int16_t x, int16_t y)
|
||||
int16_t TFT_eSprite::width(void)
|
||||
{
|
||||
if (!_created ) return 0;
|
||||
return _iwidth;
|
||||
|
||||
if (_bpp > 1) return _iwidth;
|
||||
|
||||
if (_rotation == 1 || _rotation == 3) return _dheight;
|
||||
|
||||
return _dwidth;
|
||||
}
|
||||
|
||||
|
||||
@ -544,7 +643,38 @@ int16_t TFT_eSprite::width(void)
|
||||
int16_t TFT_eSprite::height(void)
|
||||
{
|
||||
if (!_created ) return 0;
|
||||
return _iheight;
|
||||
|
||||
if (_bpp > 1) return _iheight;
|
||||
|
||||
if (_rotation == 1 || _rotation == 3) return _dwidth;
|
||||
|
||||
return _dheight;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: setRotation
|
||||
** Description: Rotate coordinate frame for 1bpp sprite
|
||||
*************************************************************************************x*/
|
||||
// Does nothing for 8 and 16 bpp sprites. TODO allow rotation of these sprites
|
||||
void TFT_eSprite::setRotation(uint8_t rotation)
|
||||
{
|
||||
_rotation = rotation;
|
||||
if (rotation == 0 && _iwidth > _iheight) swap_coord(_iwidth, _iheight);
|
||||
if (rotation == 1 && _iwidth < _iheight) swap_coord(_iwidth, _iheight);
|
||||
if (rotation == 2 && _iwidth > _iheight) swap_coord(_iwidth, _iheight);
|
||||
if (rotation == 3 && _iwidth < _iheight) swap_coord(_iwidth, _iheight);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: getRotation
|
||||
** Description: Get rotation for 1bpp sprite
|
||||
*************************************************************************************x*/
|
||||
|
||||
uint8_t TFT_eSprite::getRotation(void)
|
||||
{
|
||||
return _rotation;
|
||||
}
|
||||
|
||||
|
||||
@ -558,15 +688,38 @@ void TFT_eSprite::drawPixel(uint32_t x, uint32_t y, uint32_t color)
|
||||
// this make bounds checking a bit faster
|
||||
if ((x >= _iwidth) || (y >= _iheight) || !_created) return;
|
||||
|
||||
if (_bpp16)
|
||||
if (_bpp == 16)
|
||||
{
|
||||
color = (color >> 8) | (color << 8);
|
||||
_img[x+y*_iwidth] = (uint16_t) color;
|
||||
}
|
||||
else
|
||||
else if (_bpp == 8)
|
||||
{
|
||||
_img8[x+y*_iwidth] = (uint8_t)((color & 0xE000)>>8 | (color & 0x0700)>>6 | (color & 0x0018)>>3);
|
||||
}
|
||||
else // 1 bpp
|
||||
{
|
||||
if (_rotation == 1)
|
||||
{
|
||||
uint16_t tx = x;
|
||||
x = _dwidth - y - 1;
|
||||
y = tx;
|
||||
}
|
||||
else if (_rotation == 2)
|
||||
{
|
||||
x = _dwidth - x - 1;
|
||||
y = _dheight - y - 1;
|
||||
}
|
||||
else if (_rotation == 3)
|
||||
{
|
||||
uint16_t tx = x;
|
||||
x = y;
|
||||
y = _dheight - tx - 1;
|
||||
}
|
||||
|
||||
if (color) _img8[(x + y * _bitwidth)>>3] |= (0x80 >> (x & 0x7));
|
||||
else _img8[(x + y * _bitwidth)>>3] &= ~(0x80 >> (x & 0x7));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -641,17 +794,25 @@ void TFT_eSprite::drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color)
|
||||
|
||||
if (h < 1) return;
|
||||
|
||||
if (_bpp16)
|
||||
if (_bpp == 16)
|
||||
{
|
||||
color = (color >> 8) | (color << 8);
|
||||
int32_t yp = x + _iwidth * y;
|
||||
while (h--) {_img[yp] = (uint16_t) color; yp += _iwidth;}
|
||||
}
|
||||
else
|
||||
else if (_bpp == 8)
|
||||
{
|
||||
color = (color & 0xE000)>>8 | (color & 0x0700)>>6 | (color & 0x0018)>>3;
|
||||
while (h--) _img8[x + _iwidth * y++] = (uint8_t) color;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (h--)
|
||||
{
|
||||
drawPixel(x, y, color);
|
||||
y++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -670,16 +831,24 @@ void TFT_eSprite::drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color)
|
||||
|
||||
if (w < 1) return;
|
||||
|
||||
if (_bpp16)
|
||||
if (_bpp == 16)
|
||||
{
|
||||
color = (color >> 8) | (color << 8);
|
||||
while (w--) _img[_iwidth * y + x++] = (uint16_t) color;
|
||||
}
|
||||
else
|
||||
else if (_bpp == 8)
|
||||
{
|
||||
color = (color & 0xE000)>>8 | (color & 0x0700)>>6 | (color & 0x0018)>>3;
|
||||
memset(_img8+_iwidth * y + x, (uint8_t)color, w);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (w--)
|
||||
{
|
||||
drawPixel(x, y, color);
|
||||
x++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -700,7 +869,7 @@ void TFT_eSprite::fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t
|
||||
|
||||
int32_t yp = _iwidth * y + x;
|
||||
|
||||
if (_bpp16)
|
||||
if (_bpp == 16)
|
||||
{
|
||||
color = (color >> 8) | (color << 8);
|
||||
uint32_t iw = w;
|
||||
@ -713,15 +882,25 @@ void TFT_eSprite::fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t
|
||||
memcpy( _img+yp, _img+ys, w<<1);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (_bpp == 8)
|
||||
{
|
||||
color = (color & 0xE000)>>8 | (color & 0x0700)>>6 | (color & 0x0018)>>3;
|
||||
while (h--)
|
||||
{
|
||||
memset(_img8 + yp, (uint8_t)color, w);
|
||||
memset(_img8 + yp, (uint8_t)color, w);
|
||||
yp += _iwidth;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (h--)
|
||||
{
|
||||
int32_t ww = w;
|
||||
int32_t xx = x;
|
||||
while (ww--) drawPixel(xx++, y, color);
|
||||
y++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -734,21 +913,23 @@ size_t TFT_eSprite::write(uint8_t utf8)
|
||||
if (utf8 == '\r') return 1;
|
||||
|
||||
#ifdef SMOOTH_FONT
|
||||
if(fontLoaded)
|
||||
if(this->fontLoaded)
|
||||
{
|
||||
uint16_t unicode = decodeUTF8(utf8);
|
||||
if (unicode < 32 && utf8 != '\n') return 0;
|
||||
|
||||
fontFile = SPIFFS.open( _gFontFilename, "r" );
|
||||
//fontFile = SPIFFS.open( _gFontFilename, "r" );
|
||||
//fontFile = SPIFFS.open( this->_gFontFilename, "r" );
|
||||
|
||||
if(!fontFile)
|
||||
{
|
||||
fontLoaded = false;
|
||||
return 0;
|
||||
}
|
||||
//if(!fontFile)
|
||||
//{
|
||||
// fontLoaded = false;
|
||||
// return 0;
|
||||
//}
|
||||
//Serial.print("Decoded Unicode = 0x");Serial.println(unicode,HEX);
|
||||
|
||||
drawGlyph(unicode);
|
||||
fontFile.close();
|
||||
//fontFile.close();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@ -818,18 +999,18 @@ size_t TFT_eSprite::write(uint8_t utf8)
|
||||
|
||||
if (utf8 == '\n')
|
||||
{
|
||||
_icursor_y += height;
|
||||
_icursor_x = 0;
|
||||
this->cursor_y += height;
|
||||
this->cursor_x = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (textwrapX && (_icursor_x + width * textsize > _iwidth))
|
||||
if (textwrapX && (this->cursor_x + width * textsize > _iwidth))
|
||||
{
|
||||
_icursor_y += height;
|
||||
_icursor_x = 0;
|
||||
this->cursor_y += height;
|
||||
this->cursor_x = 0;
|
||||
}
|
||||
if (textwrapY && (_icursor_y >= _iheight)) _icursor_y = 0;
|
||||
_icursor_x += drawChar(uniCode, _icursor_x, _icursor_y, textfont);
|
||||
if (textwrapY && (this->cursor_y >= _iheight)) this->cursor_y = 0;
|
||||
this->cursor_x += drawChar(uniCode, this->cursor_x, this->cursor_y, textfont);
|
||||
}
|
||||
|
||||
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
@ -839,8 +1020,8 @@ size_t TFT_eSprite::write(uint8_t utf8)
|
||||
{
|
||||
|
||||
if(utf8 == '\n') {
|
||||
_icursor_x = 0;
|
||||
_icursor_y += (int16_t)textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
|
||||
this->cursor_x = 0;
|
||||
this->cursor_y += (int16_t)textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
|
||||
} else {
|
||||
if (uniCode > (uint8_t)pgm_read_byte(&gfxFont->last )) return 0;
|
||||
if (uniCode < (uint8_t)pgm_read_byte(&gfxFont->first)) return 0;
|
||||
@ -851,15 +1032,15 @@ size_t TFT_eSprite::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 && ((_icursor_x + textsize * (xo + w)) > _iwidth)) {
|
||||
if(textwrapX && ((this->cursor_x + textsize * (xo + w)) > _iwidth)) {
|
||||
// Drawing character would go off right edge; wrap to new line
|
||||
_icursor_x = 0;
|
||||
_icursor_y += (int16_t)textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
|
||||
this->cursor_x = 0;
|
||||
this->cursor_y += (int16_t)textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
|
||||
}
|
||||
if (textwrapY && (_icursor_y >= _iheight)) _icursor_y = 0;
|
||||
drawChar(_icursor_x, _icursor_y, uniCode, textcolor, textbgcolor, textsize);
|
||||
if (textwrapY && (this->cursor_y >= _iheight)) this->cursor_y = 0;
|
||||
drawChar(this->cursor_x, this->cursor_y, uniCode, textcolor, textbgcolor, textsize);
|
||||
}
|
||||
_icursor_x += pgm_read_byte(&glyph->xAdvance) * (int16_t)textsize;
|
||||
this->cursor_x += pgm_read_byte(&glyph->xAdvance) * (int16_t)textsize;
|
||||
}
|
||||
}
|
||||
#endif // LOAD_GFXFF
|
||||
@ -1151,9 +1332,9 @@ int16_t TFT_eSprite::drawChar(unsigned int uniCode, int x, int y, int font)
|
||||
w *= height; // Now w is total number of pixels in the character
|
||||
|
||||
if (textcolor != textbgcolor) fillRect(x, pY, width * textsize, textsize * height, textbgcolor);
|
||||
int16_t color;
|
||||
if (_bpp16) color = (textcolor >> 8) | (textcolor << 8);
|
||||
else color = ((textcolor & 0xE000)>>8 | (textcolor & 0x0700)>>6 | (textcolor & 0x0018)>>3);
|
||||
int16_t color = textcolor;
|
||||
if (_bpp == 16) color = (textcolor >> 8) | (textcolor << 8);
|
||||
else if (_bpp == 8) color = ((textcolor & 0xE000)>>8 | (textcolor & 0x0700)>>6 | (textcolor & 0x0018)>>3);
|
||||
int px = 0, py = pY; // To hold character block start and end column and row values
|
||||
int pc = 0; // Pixel count
|
||||
uint8_t np = textsize * textsize; // Number of pixels in a drawn pixel
|
||||
@ -1212,17 +1393,17 @@ void TFT_eSprite::drawGlyph(uint16_t code)
|
||||
if (code < 0x21)
|
||||
{
|
||||
if (code == 0x20) {
|
||||
if (_created) _icursor_x += _tft->gFont.spaceWidth;
|
||||
else _tft->cursor_x += _tft->gFont.spaceWidth;
|
||||
if (_created) this->cursor_x += this->gFont.spaceWidth;
|
||||
else this->cursor_x += this->gFont.spaceWidth;
|
||||
return;
|
||||
}
|
||||
|
||||
if (code == '\n') {
|
||||
if (_created)
|
||||
{
|
||||
_icursor_x = 0;
|
||||
_icursor_y += _tft->gFont.yAdvance;
|
||||
if (_icursor_y >= _height) _icursor_y = 0;
|
||||
this->cursor_x = 0;
|
||||
this->cursor_y += this->gFont.yAdvance;
|
||||
if (this->cursor_y >= _height) this->cursor_y = 0;
|
||||
return;
|
||||
}
|
||||
else
|
||||
@ -1236,10 +1417,10 @@ void TFT_eSprite::drawGlyph(uint16_t code)
|
||||
}
|
||||
|
||||
uint16_t gNum = 0;
|
||||
bool found = _tft->getUnicodeIndex(code, &gNum);
|
||||
bool found = this->getUnicodeIndex(code, &gNum);
|
||||
|
||||
uint16_t fg = _tft->textcolor;
|
||||
uint16_t bg = _tft->textbgcolor;
|
||||
uint16_t fg = this->textcolor;
|
||||
uint16_t bg = this->textbgcolor;
|
||||
|
||||
if (found)
|
||||
{
|
||||
@ -1248,59 +1429,59 @@ void TFT_eSprite::drawGlyph(uint16_t code)
|
||||
|
||||
if (newSprite)
|
||||
{
|
||||
createSprite(_tft->gWidth[gNum], _tft->gFont.yAdvance);
|
||||
createSprite(this->gWidth[gNum], this->gFont.yAdvance);
|
||||
if(bg) fillSprite(bg);
|
||||
_icursor_x = -_tft->gdX[gNum];
|
||||
_icursor_y = 0;
|
||||
this->cursor_x = -this->gdX[gNum];
|
||||
this->cursor_y = 0;
|
||||
}
|
||||
|
||||
fontFile.seek(_tft->gBitmap[gNum], fs::SeekSet); // This is slow for a significant position shift!
|
||||
this->fontFile.seek(this->gBitmap[gNum], fs::SeekSet); // This is slow for a significant position shift!
|
||||
|
||||
uint8_t pbuffer[_tft->gWidth[gNum]];
|
||||
uint8_t pbuffer[this->gWidth[gNum]];
|
||||
|
||||
uint16_t xs = 0;
|
||||
uint16_t dl = 0;
|
||||
|
||||
for (int y = 0; y < _tft->gHeight[gNum]; y++)
|
||||
for (int y = 0; y < this->gHeight[gNum]; y++)
|
||||
{
|
||||
fontFile.read(pbuffer, _tft->gWidth[gNum]);
|
||||
for (int x = 0; x < _tft->gWidth[gNum]; x++)
|
||||
this->fontFile.read(pbuffer, this->gWidth[gNum]);
|
||||
for (int x = 0; x < this->gWidth[gNum]; x++)
|
||||
{
|
||||
uint8_t pixel = pbuffer[x];
|
||||
if (pixel)
|
||||
{
|
||||
if (pixel != 0xFF)
|
||||
{
|
||||
if (dl) { drawFastHLine( xs, y + _icursor_y + _tft->gFont.maxAscent - _tft->gdY[gNum], dl, fg); dl = 0; }
|
||||
drawPixel(x + _icursor_x + _tft->gdX[gNum], y + _icursor_y + _tft->gFont.maxAscent - _tft->gdY[gNum], alphaBlend(pixel, fg, bg));
|
||||
if (dl) { drawFastHLine( xs, y + this->cursor_y + this->gFont.maxAscent - this->gdY[gNum], dl, fg); dl = 0; }
|
||||
if (pixel>127) drawPixel(x + this->cursor_x + this->gdX[gNum], y + this->cursor_y + this->gFont.maxAscent - this->gdY[gNum], alphaBlend(pixel, fg, bg));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dl==0) xs = x + _icursor_x + _tft->gdX[gNum];
|
||||
if (dl==0) xs = x + this->cursor_x + this->gdX[gNum];
|
||||
dl++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dl) { drawFastHLine( xs, y + _icursor_y + _tft->gFont.maxAscent - _tft->gdY[gNum], dl, fg); dl = 0; }
|
||||
if (dl) { drawFastHLine( xs, y + this->cursor_y + this->gFont.maxAscent - this->gdY[gNum], dl, fg); dl = 0; }
|
||||
}
|
||||
}
|
||||
if (dl) { drawFastHLine( xs, y + _icursor_y + _tft->gFont.maxAscent - _tft->gdY[gNum], dl, fg); dl = 0; }
|
||||
if (dl) { drawFastHLine( xs, y + this->cursor_y + this->gFont.maxAscent - this->gdY[gNum], dl, fg); dl = 0; }
|
||||
}
|
||||
|
||||
if (newSprite)
|
||||
{
|
||||
pushSprite(_tft->cursor_x + _tft->gdX[gNum], _tft->cursor_y, bg);
|
||||
pushSprite(this->cursor_x + this->gdX[gNum], this->cursor_y, bg);
|
||||
deleteSprite();
|
||||
_tft->cursor_x += _tft->gxAdvance[gNum];
|
||||
this->cursor_x += this->gxAdvance[gNum];
|
||||
}
|
||||
else _icursor_x += _tft->gxAdvance[gNum];
|
||||
else this->cursor_x += this->gxAdvance[gNum];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not a Unicode in font so draw a rectangle and move on cursor
|
||||
drawRect(_icursor_x, _icursor_y + _tft->gFont.maxAscent - _tft->gFont.ascent, _tft->gFont.spaceWidth, _tft->gFont.ascent, fg);
|
||||
_icursor_x += _tft->gFont.spaceWidth + 1;
|
||||
drawRect(this->cursor_x, this->cursor_y + this->gFont.maxAscent - this->gFont.ascent, this->gFont.spaceWidth, this->gFont.ascent, fg);
|
||||
this->cursor_x += this->gFont.spaceWidth + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1311,7 +1492,7 @@ void TFT_eSprite::drawGlyph(uint16_t code)
|
||||
*************************************************************************************x*/
|
||||
void TFT_eSprite::printToSprite(String string)
|
||||
{
|
||||
if(!_tft->fontLoaded) return;
|
||||
if(!this->fontLoaded) return;
|
||||
int16_t len = string.length();
|
||||
char cbuffer[len + 1]; // Add 1 for the null
|
||||
string.toCharArray(cbuffer, len + 1); // Add 1 for the null, otherwise characters get dropped
|
||||
@ -1325,13 +1506,13 @@ void TFT_eSprite::printToSprite(String string)
|
||||
*************************************************************************************x*/
|
||||
void TFT_eSprite::printToSprite(char *cbuffer, int len) //String string)
|
||||
{
|
||||
if(!_tft->fontLoaded) return;
|
||||
if(!this->fontLoaded) return;
|
||||
|
||||
fontFile = SPIFFS.open( _tft->_gFontFilename, "r" );
|
||||
//fontFile = SPIFFS.open( this->_gFontFilename, "r" );
|
||||
|
||||
if(!fontFile)
|
||||
if(!this->fontFile)
|
||||
{
|
||||
_tft->fontLoaded = false;
|
||||
this->fontLoaded = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1346,19 +1527,19 @@ void TFT_eSprite::printToSprite(char *cbuffer, int len) //String string)
|
||||
while (n < len)
|
||||
{
|
||||
uint16_t unicode = decodeUTF8((uint8_t*)cbuffer, &n, len - n);
|
||||
if (_tft->getUnicodeIndex(unicode, &index))
|
||||
if (this->getUnicodeIndex(unicode, &index))
|
||||
{
|
||||
if (n == 0) sWidth -= _tft->gdX[index];
|
||||
if (n == len-1) sWidth += ( _tft->gWidth[index] + _tft->gdX[index]);
|
||||
else sWidth += _tft->gxAdvance[index];
|
||||
if (n == 0) sWidth -= this->gdX[index];
|
||||
if (n == len-1) sWidth += ( this->gWidth[index] + this->gdX[index]);
|
||||
else sWidth += this->gxAdvance[index];
|
||||
}
|
||||
else sWidth += _tft->gFont.spaceWidth + 1;
|
||||
else sWidth += this->gFont.spaceWidth + 1;
|
||||
}
|
||||
|
||||
createSprite(sWidth, _tft->gFont.yAdvance);
|
||||
createSprite(sWidth, this->gFont.yAdvance);
|
||||
uint16_t transparent = TFT_BLACK;
|
||||
|
||||
if (_tft->textbgcolor != TFT_BLACK) fillSprite(_tft->textbgcolor);
|
||||
if (this->textbgcolor != TFT_BLACK) fillSprite(this->textbgcolor);
|
||||
}
|
||||
|
||||
n = 0;
|
||||
@ -1372,12 +1553,12 @@ void TFT_eSprite::printToSprite(char *cbuffer, int len) //String string)
|
||||
}
|
||||
|
||||
if (newSprite)
|
||||
{
|
||||
{ // The sprite had to be created so place at TFT cursor
|
||||
pushSprite(_tft->cursor_x, _tft->cursor_y);
|
||||
deleteSprite();
|
||||
}
|
||||
|
||||
fontFile.close();
|
||||
//fontFile.close();
|
||||
}
|
||||
|
||||
|
||||
@ -1388,22 +1569,22 @@ void TFT_eSprite::printToSprite(char *cbuffer, int len) //String string)
|
||||
int16_t TFT_eSprite::printToSprite(int16_t x, int16_t y, uint16_t index)
|
||||
{
|
||||
bool newSprite = !_created;
|
||||
int16_t sWidth = _tft->gWidth[index];
|
||||
int16_t sWidth = this->gWidth[index];
|
||||
|
||||
if (newSprite)
|
||||
{
|
||||
createSprite(sWidth, _tft->gFont.yAdvance);
|
||||
createSprite(sWidth, this->gFont.yAdvance);
|
||||
uint16_t transparent = TFT_BLACK;
|
||||
if (_tft->textbgcolor != TFT_BLACK) fillSprite(_tft->textbgcolor);
|
||||
if (this->textbgcolor != TFT_BLACK) fillSprite(this->textbgcolor);
|
||||
|
||||
drawGlyph(_tft->gUnicode[index]);
|
||||
drawGlyph(this->gUnicode[index]);
|
||||
|
||||
pushSprite(x + _tft->gdX[index], y, _tft->textbgcolor);
|
||||
pushSprite(x + this->gdX[index], y, this->textbgcolor);
|
||||
deleteSprite();
|
||||
}
|
||||
|
||||
else drawGlyph(_tft->gUnicode[index]);
|
||||
else drawGlyph(this->gUnicode[index]);
|
||||
|
||||
return _tft->gxAdvance[index];
|
||||
return this->gxAdvance[index];
|
||||
}
|
||||
#endif
|
||||
|
@ -14,15 +14,20 @@ class TFT_eSprite : public TFT_eSPI {
|
||||
// Create a sprite of width x height pixels, return a pointer to the RAM area
|
||||
// Sketch can cast returned value to (uint16_t*) for 16 bit depth if needed
|
||||
// RAM required is 1 byte per pixel for 8 bit colour depth, 2 bytes for 16 bit
|
||||
void* createSprite(int16_t width, int16_t height);
|
||||
void* createSprite(int16_t width, int16_t height, uint8_t frames = 1);
|
||||
|
||||
// Delete the sprite to free up the RAM
|
||||
void deleteSprite(void);
|
||||
|
||||
// Select the frame buffer for graphics
|
||||
void* frameBuffer(int8_t f);
|
||||
|
||||
// Set the colour depth to 8 or 16 bits. Can be used to change depth an existing
|
||||
// sprite, but clears it to black, returns a new pointer if sprite is re-created.
|
||||
void* setColorDepth(int8_t b);
|
||||
|
||||
void setBitmapColor(uint16_t c, uint16_t b);
|
||||
|
||||
void drawPixel(uint32_t x, uint32_t y, uint32_t color);
|
||||
|
||||
void drawChar(int32_t x, int32_t y, unsigned char c, uint32_t color, uint32_t bg, uint8_t size),
|
||||
@ -49,10 +54,13 @@ class TFT_eSprite : public TFT_eSPI {
|
||||
drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color),
|
||||
drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color),
|
||||
|
||||
fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color),
|
||||
fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color);
|
||||
|
||||
// Set the sprite text cursor position for print class (does not change the TFT screen cursor)
|
||||
setCursor(int16_t x, int16_t y);
|
||||
//setCursor(int16_t x, int16_t y);
|
||||
|
||||
void setRotation(uint8_t rotation);
|
||||
uint8_t getRotation(void);
|
||||
|
||||
// Read the colour of a pixel at x,y and return value in 565 format
|
||||
uint16_t readPixel(int32_t x0, int32_t y0);
|
||||
@ -92,13 +100,17 @@ class TFT_eSprite : public TFT_eSPI {
|
||||
|
||||
protected:
|
||||
|
||||
uint16_t *_img; // pointer to 16 bit sprite
|
||||
uint8_t *_img8; // pointer to 8 bit sprite
|
||||
bool _created, _bpp16; // created and bits per pixel depth flags
|
||||
uint8_t _bpp;
|
||||
uint16_t *_img; // pointer to 16 bit sprite
|
||||
uint8_t *_img8; // pointer to 8 bit sprite
|
||||
uint8_t *_img8_1; // pointer to frame 1
|
||||
uint8_t *_img8_2; // pointer to frame 2
|
||||
|
||||
bool _created; // created and bits per pixel depth flags
|
||||
bool _gFont = false;
|
||||
|
||||
int32_t _icursor_x, _icursor_y;
|
||||
// int32_t _icursor_x, _icursor_y;
|
||||
uint8_t _rotation = 0;
|
||||
int32_t _xs, _ys, _xe, _ye, _xptr, _yptr; // for setWindow
|
||||
int32_t _sx, _sy; // x,y for scroll zone
|
||||
uint32_t _sw, _sh; // w,h for scroll zone
|
||||
@ -106,6 +118,8 @@ class TFT_eSprite : public TFT_eSPI {
|
||||
|
||||
boolean _iswapBytes; // Swap the byte order for Sprite pushImage()
|
||||
|
||||
int32_t _iwidth, _iheight; // Sprite image width and height
|
||||
int32_t _iwidth, _iheight; // Sprite memory image bit width and height (swapped during rotations)
|
||||
int32_t _dwidth, _dheight; // Real display width and height (for <8bpp Sprites)
|
||||
int32_t _bitwidth; // Sprite image bit width for drawPixel (for <8bpp Sprites, not swapped)
|
||||
|
||||
};
|
||||
|
27
TFT_Drivers/EPD_Defines.h
Normal file
27
TFT_Drivers/EPD_Defines.h
Normal file
@ -0,0 +1,27 @@
|
||||
// Null set for ePaper
|
||||
#define TFT_WIDTH 1000
|
||||
#define TFT_HEIGHT 1000
|
||||
|
||||
#define TFT_INIT_DELAY 0
|
||||
|
||||
#define TFT_NOP 0x00
|
||||
#define TFT_SWRST 0x00
|
||||
|
||||
#define TFT_CASET 0x00
|
||||
#define TFT_PASET 0x00
|
||||
#define TFT_RAMWR 0x00
|
||||
|
||||
#define TFT_RAMRD 0x00
|
||||
#define TFT_IDXRD 0x00
|
||||
|
||||
#define TFT_MADCTL 0x00
|
||||
#define TFT_MAD_MY 0x00
|
||||
#define TFT_MAD_MX 0x00
|
||||
#define TFT_MAD_MV 0x00
|
||||
#define TFT_MAD_ML 0x00
|
||||
#define TFT_MAD_BGR 0x00
|
||||
#define TFT_MAD_MH 0x00
|
||||
#define TFT_MAD_RGB 0x00
|
||||
|
||||
#define TFT_INVOFF 0x00
|
||||
#define TFT_INVON 0x00
|
395
TFT_eSPI.cpp
395
TFT_eSPI.cpp
@ -153,11 +153,11 @@ 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
|
||||
rotation = 0;
|
||||
cursor_y = cursor_x = 0;
|
||||
cursor_y = cursor_x = 0;
|
||||
textfont = 1;
|
||||
textsize = 1;
|
||||
textcolor = 0xFFFF; // White
|
||||
textbgcolor = 0x0000; // Black
|
||||
textcolor = bitmap_fg = 0xFFFF; // White
|
||||
textbgcolor = bitmap_bg = 0x0000; // Black
|
||||
padX = 0; // No padding
|
||||
textwrapX = true; // Wrap text at end of line when using print stream
|
||||
textwrapY = false; // Wrap text at bottom of screen when using print stream
|
||||
@ -998,7 +998,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, uint32_t w, uint32_t h, const uin
|
||||
** Function name: pushImage
|
||||
** Description: plot 8 bit image or sprite using a line buffer
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::pushImage(int32_t x, int32_t y, uint32_t w, uint32_t h, uint8_t *data)
|
||||
void TFT_eSPI::pushImage(int32_t x, int32_t y, uint32_t w, uint32_t h, uint8_t *data, bool bpp8)
|
||||
{
|
||||
if ((x >= (int32_t)_width) || (y >= (int32_t)_height)) return;
|
||||
|
||||
@ -1020,45 +1020,79 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, uint32_t w, uint32_t h, uint8_t *
|
||||
|
||||
setAddrWindow(x, y, x + dw - 1, y + dh - 1); // Sets CS low and sent RAMWR
|
||||
|
||||
data += dx + dy * w;
|
||||
|
||||
// Line buffer makes plotting faster
|
||||
uint16_t lineBuf[dw];
|
||||
|
||||
uint8_t blue[] = {0, 11, 21, 31}; // blue 2 to 5 bit colour lookup table
|
||||
|
||||
_lastColor = -1; // Set to illegal value
|
||||
|
||||
// Used to store last shifted colour
|
||||
uint8_t msbColor = 0;
|
||||
uint8_t lsbColor = 0;
|
||||
|
||||
while (dh--)
|
||||
if (bpp8)
|
||||
{
|
||||
uint32_t len = dw;
|
||||
uint8_t* ptr = data;
|
||||
uint8_t* linePtr = (uint8_t*)lineBuf;
|
||||
uint8_t blue[] = {0, 11, 21, 31}; // blue 2 to 5 bit colour lookup table
|
||||
|
||||
while(len--)
|
||||
_lastColor = -1; // Set to illegal value
|
||||
|
||||
// Used to store last shifted colour
|
||||
uint8_t msbColor = 0;
|
||||
uint8_t lsbColor = 0;
|
||||
|
||||
data += dx + dy * w;
|
||||
while (dh--)
|
||||
{
|
||||
uint32_t color = *ptr++;
|
||||
uint32_t len = dw;
|
||||
uint8_t* ptr = data;
|
||||
uint8_t* linePtr = (uint8_t*)lineBuf;
|
||||
|
||||
// Shifts are slow so check if colour has changed first
|
||||
if (color != _lastColor) {
|
||||
// =====Green===== ===============Red==============
|
||||
msbColor = (color & 0x1C)>>2 | (color & 0xC0)>>3 | (color & 0xE0);
|
||||
// =====Green===== =======Blue======
|
||||
lsbColor = (color & 0x1C)<<3 | blue[color & 0x03];
|
||||
_lastColor = color;
|
||||
while(len--)
|
||||
{
|
||||
uint32_t color = *ptr++;
|
||||
|
||||
// Shifts are slow so check if colour has changed first
|
||||
if (color != _lastColor) {
|
||||
// =====Green===== ===============Red==============
|
||||
msbColor = (color & 0x1C)>>2 | (color & 0xC0)>>3 | (color & 0xE0);
|
||||
// =====Green===== =======Blue======
|
||||
lsbColor = (color & 0x1C)<<3 | blue[color & 0x03];
|
||||
_lastColor = color;
|
||||
}
|
||||
|
||||
*linePtr++ = msbColor;
|
||||
*linePtr++ = lsbColor;
|
||||
}
|
||||
|
||||
*linePtr++ = msbColor;
|
||||
*linePtr++ = lsbColor;
|
||||
pushColors(lineBuf, dw, false);
|
||||
|
||||
data += w;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (dh--)
|
||||
{
|
||||
w = (w+7) & 0xFFF8;
|
||||
|
||||
pushColors(lineBuf, dw, false);
|
||||
int32_t len = dw;
|
||||
uint8_t* ptr = data;
|
||||
uint8_t* linePtr = (uint8_t*)lineBuf;
|
||||
uint8_t bits = 8;
|
||||
while(len>0)
|
||||
{
|
||||
if (len < 8) bits = len;
|
||||
uint32_t xp = dx;
|
||||
for (uint16_t i = 0; i < bits; i++)
|
||||
{
|
||||
uint8_t col = (ptr[(xp + dy * w)>>3] << (xp & 0x7)) & 0x80;
|
||||
if (col) {*linePtr++ = bitmap_fg>>8; *linePtr++ = (uint8_t) bitmap_fg;}
|
||||
else {*linePtr++ = bitmap_bg>>8; *linePtr++ = (uint8_t) bitmap_bg;}
|
||||
//if (col) drawPixel((dw-len)+xp,h-dh,bitmap_fg);
|
||||
//else drawPixel((dw-len)+xp,h-dh,bitmap_bg);
|
||||
xp++;
|
||||
}
|
||||
*ptr++;
|
||||
len -= 8;
|
||||
}
|
||||
|
||||
data += w;
|
||||
pushColors(lineBuf, dw, false);
|
||||
|
||||
dy++;
|
||||
}
|
||||
}
|
||||
|
||||
CS_H;
|
||||
@ -1070,9 +1104,9 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, uint32_t w, uint32_t h, uint8_t *
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: pushImage
|
||||
** Description: plot 8 bit image or sprite with 1 colour being transparent
|
||||
** Description: plot 8 or 1 bit image or sprite with a transparent colour
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::pushImage(int32_t x, int32_t y, uint32_t w, uint32_t h, uint8_t *data, uint8_t transp)
|
||||
void TFT_eSPI::pushImage(int32_t x, int32_t y, uint32_t w, uint32_t h, uint8_t *data, uint8_t transp, bool bpp8)
|
||||
{
|
||||
if ((x >= (int32_t)_width) || (y >= (int32_t)_height)) return;
|
||||
|
||||
@ -1092,70 +1126,121 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, uint32_t w, uint32_t h, uint8_t *
|
||||
spi_begin();
|
||||
inTransaction = true;
|
||||
|
||||
data += dx + dy * w;
|
||||
|
||||
int32_t xe = x + dw - 1, ye = y + dh - 1;
|
||||
|
||||
// Line buffer makes plotting faster
|
||||
uint16_t lineBuf[dw];
|
||||
|
||||
uint8_t blue[] = {0, 11, 21, 31}; // blue 2 to 5 bit colour lookup table
|
||||
|
||||
_lastColor = -1; // Set to illegal value
|
||||
|
||||
// Used to store last shifted colour
|
||||
uint8_t msbColor = 0;
|
||||
uint8_t lsbColor = 0;
|
||||
|
||||
int32_t spx = x, spy = y;
|
||||
|
||||
while (dh--)
|
||||
if (bpp8)
|
||||
{
|
||||
int32_t len = dw;
|
||||
uint8_t* ptr = data;
|
||||
uint8_t* linePtr = (uint8_t*)lineBuf;
|
||||
data += dx + dy * w;
|
||||
|
||||
int32_t px = x;
|
||||
boolean move = true;
|
||||
uint16_t np = 0;
|
||||
uint8_t blue[] = {0, 11, 21, 31}; // blue 2 to 5 bit colour lookup table
|
||||
|
||||
while (len--)
|
||||
_lastColor = -1; // Set to illegal value
|
||||
|
||||
// Used to store last shifted colour
|
||||
uint8_t msbColor = 0;
|
||||
uint8_t lsbColor = 0;
|
||||
|
||||
int32_t spx = x, spy = y;
|
||||
|
||||
while (dh--)
|
||||
{
|
||||
if (transp != *ptr)
|
||||
{
|
||||
if (move) { move = false; setAddrWindow(px, y, xe, ye);}
|
||||
uint8_t color = *ptr;
|
||||
int32_t len = dw;
|
||||
uint8_t* ptr = data;
|
||||
uint8_t* linePtr = (uint8_t*)lineBuf;
|
||||
|
||||
// Shifts are slow so check if colour has changed first
|
||||
if (color != _lastColor) {
|
||||
// =====Green===== ===============Red==============
|
||||
msbColor = (color & 0x1C)>>2 | (color & 0xC0)>>3 | (color & 0xE0);
|
||||
// =====Green===== =======Blue======
|
||||
lsbColor = (color & 0x1C)<<3 | blue[color & 0x03];
|
||||
_lastColor = color;
|
||||
}
|
||||
*linePtr++ = msbColor;
|
||||
*linePtr++ = lsbColor;
|
||||
np++;
|
||||
}
|
||||
else
|
||||
int32_t px = x;
|
||||
boolean move = true;
|
||||
uint16_t np = 0;
|
||||
|
||||
while (len--)
|
||||
{
|
||||
move = true;
|
||||
if (np)
|
||||
if (transp != *ptr)
|
||||
{
|
||||
pushColors(lineBuf, np, false);
|
||||
linePtr = (uint8_t*)lineBuf;
|
||||
np = 0;
|
||||
if (move) { move = false; setAddrWindow(px, y, xe, ye);}
|
||||
uint8_t color = *ptr;
|
||||
|
||||
// Shifts are slow so check if colour has changed first
|
||||
if (color != _lastColor) {
|
||||
// =====Green===== ===============Red==============
|
||||
msbColor = (color & 0x1C)>>2 | (color & 0xC0)>>3 | (color & 0xE0);
|
||||
// =====Green===== =======Blue======
|
||||
lsbColor = (color & 0x1C)<<3 | blue[color & 0x03];
|
||||
_lastColor = color;
|
||||
}
|
||||
*linePtr++ = msbColor;
|
||||
*linePtr++ = lsbColor;
|
||||
np++;
|
||||
}
|
||||
else
|
||||
{
|
||||
move = true;
|
||||
if (np)
|
||||
{
|
||||
pushColors(lineBuf, np, false);
|
||||
linePtr = (uint8_t*)lineBuf;
|
||||
np = 0;
|
||||
}
|
||||
}
|
||||
px++;
|
||||
ptr++;
|
||||
}
|
||||
px++;
|
||||
ptr++;
|
||||
|
||||
if (np) pushColors(lineBuf, np, false);
|
||||
|
||||
y++;
|
||||
data += w;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
w = (w+7) & 0xFFF8;
|
||||
while (dh--)
|
||||
{
|
||||
int32_t px = x;
|
||||
boolean move = true;
|
||||
uint16_t np = 0;
|
||||
int32_t len = dw;
|
||||
uint8_t* ptr = data;
|
||||
uint8_t bits = 8;
|
||||
while(len>0)
|
||||
{
|
||||
if (len < 8) bits = len;
|
||||
uint32_t xp = dx;
|
||||
uint32_t yp = (dy * w)>>3;
|
||||
for (uint16_t i = 0; i < bits; i++)
|
||||
{
|
||||
//uint8_t col = (ptr[(xp + dy * w)>>3] << (xp & 0x7)) & 0x80;
|
||||
if ((ptr[(xp>>3) + yp] << (xp & 0x7)) & 0x80)
|
||||
{
|
||||
if (move)
|
||||
{
|
||||
move = false;
|
||||
setAddrWindow(px, y, xe, ye);
|
||||
}
|
||||
np++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (np)
|
||||
{
|
||||
pushColor(bitmap_fg, np);
|
||||
np = 0;
|
||||
move = true;
|
||||
}
|
||||
}
|
||||
px++;
|
||||
xp++;
|
||||
}
|
||||
*ptr++;
|
||||
len -= 8;
|
||||
}
|
||||
if (np) pushColor(bitmap_fg, np);
|
||||
y++;
|
||||
dy++;
|
||||
}
|
||||
|
||||
if (np) pushColors(lineBuf, np, false);
|
||||
|
||||
y++;
|
||||
data += w;
|
||||
}
|
||||
|
||||
CS_H;
|
||||
@ -1769,6 +1854,18 @@ void TFT_eSPI::setTextColor(uint16_t c, uint16_t b)
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: setBitmapColor
|
||||
** Description: Set the foreground foreground and background colour
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::setBitmapColor(uint16_t c, uint16_t b)
|
||||
{
|
||||
if (c == b) b = ~c;
|
||||
bitmap_fg = c;
|
||||
bitmap_bg = b;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: setTextWrap
|
||||
** Description: Define if text should wrap at end of line
|
||||
@ -2978,7 +3075,7 @@ void TFT_eSPI::pushColors(uint16_t *data, uint32_t len, bool swap)
|
||||
#if defined (ESP32)
|
||||
#ifdef ESP32_PARALLEL
|
||||
if (swap) while ( len-- ) {tft_Write_16(*data); data++;}
|
||||
else while ( len-- ) {transwap16(*data); data++;}
|
||||
else while ( len-- ) {tft_Write_16S(*data); data++;}
|
||||
#else
|
||||
if (swap) SPI.writePixels(data,len<<1);
|
||||
else SPI.writeBytes((uint8_t*)data,len<<1);
|
||||
@ -3013,6 +3110,8 @@ void TFT_eSPI::pushColors(uint16_t *data, uint32_t len, bool swap)
|
||||
}
|
||||
|
||||
len -= 16;
|
||||
|
||||
// ESP8266 wait time here at 40MHz SPI is ~5.45us
|
||||
while(SPI1CMD & SPIBUSY) {}
|
||||
SPI1W0 = color[0];
|
||||
SPI1W1 = color[1];
|
||||
@ -4446,6 +4545,136 @@ void writeBlock(uint16_t color, uint32_t repeat)
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: getSetup
|
||||
** Description: Get the setup details for diagnostic and sketch access
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::getSetup(setup_t &tft_settings)
|
||||
{
|
||||
|
||||
#if defined (ESP8266)
|
||||
tft_settings.esp = 8266;
|
||||
#elif defined (ESP32)
|
||||
tft_settings.esp = 32;
|
||||
#else
|
||||
tft_settings.esp = -1;
|
||||
#endif
|
||||
|
||||
#if defined (SUPPORT_TRANSACTIONS)
|
||||
tft_settings.trans = true;
|
||||
#else
|
||||
tft_settings.trans = false;
|
||||
#endif
|
||||
|
||||
#if defined (ESP32_PARALLEL)
|
||||
tft_settings.serial = false;
|
||||
tft_settings.tft_spi_freq = 0;
|
||||
#else
|
||||
tft_settings.serial = true;
|
||||
tft_settings.tft_spi_freq = SPI_FREQUENCY/100000;
|
||||
#endif
|
||||
|
||||
tft_settings.tft_driver = TFT_DRIVER;
|
||||
tft_settings.tft_width = _init_width;
|
||||
tft_settings.tft_height = _init_height;
|
||||
|
||||
#ifdef CGRAM_OFFSET
|
||||
tft_settings.r0_x_offset = colstart;
|
||||
tft_settings.r0_y_offset = rowstart;
|
||||
tft_settings.r1_x_offset = 0;
|
||||
tft_settings.r1_y_offset = 0;
|
||||
tft_settings.r2_x_offset = 0;
|
||||
tft_settings.r2_y_offset = 0;
|
||||
tft_settings.r3_x_offset = 0;
|
||||
tft_settings.r3_y_offset = 0;
|
||||
#else
|
||||
tft_settings.r0_x_offset = 0;
|
||||
tft_settings.r0_y_offset = 0;
|
||||
tft_settings.r1_x_offset = 0;
|
||||
tft_settings.r1_y_offset = 0;
|
||||
tft_settings.r2_x_offset = 0;
|
||||
tft_settings.r2_y_offset = 0;
|
||||
tft_settings.r3_x_offset = 0;
|
||||
tft_settings.r3_y_offset = 0;
|
||||
#endif
|
||||
|
||||
#if defined (TFT_MOSI)
|
||||
tft_settings.pin_tft_mosi = TFT_MOSI;
|
||||
#else
|
||||
tft_settings.pin_tft_mosi = -1;
|
||||
#endif
|
||||
|
||||
#if defined (TFT_MISO)
|
||||
tft_settings.pin_tft_miso = TFT_MISO;
|
||||
#else
|
||||
tft_settings.pin_tft_miso = -1;
|
||||
#endif
|
||||
|
||||
#if defined (TFT_SCLK)
|
||||
tft_settings.pin_tft_clk = TFT_SCLK;
|
||||
#else
|
||||
tft_settings.pin_tft_clk = -1;
|
||||
#endif
|
||||
|
||||
#if defined (TFT_CS)
|
||||
tft_settings.pin_tft_cs = TFT_CS;
|
||||
#else
|
||||
tft_settings.pin_tft_cs = -1;
|
||||
#endif
|
||||
|
||||
#if defined (TFT_DC)
|
||||
tft_settings.pin_tft_dc = TFT_DC;
|
||||
#else
|
||||
tft_settings.pin_tft_dc = -1;
|
||||
#endif
|
||||
|
||||
#if defined (TFT_RD)
|
||||
tft_settings.pin_tft_rd = TFT_RD;
|
||||
#else
|
||||
tft_settings.pin_tft_rd = -1;
|
||||
#endif
|
||||
|
||||
#if defined (TFT_WR)
|
||||
tft_settings.pin_tft_wr = TFT_WR;
|
||||
#else
|
||||
tft_settings.pin_tft_wr = -1;
|
||||
#endif
|
||||
|
||||
#if defined (TFT_RST)
|
||||
tft_settings.pin_tft_rst = TFT_RST;
|
||||
#else
|
||||
tft_settings.pin_tft_rst = -1;
|
||||
#endif
|
||||
|
||||
#if defined (ESP32_PARALLEL)
|
||||
tft_settings.pin_tft_d0 = TFT_D0;
|
||||
tft_settings.pin_tft_d1 = TFT_D1;
|
||||
tft_settings.pin_tft_d2 = TFT_D2;
|
||||
tft_settings.pin_tft_d3 = TFT_D3;
|
||||
tft_settings.pin_tft_d4 = TFT_D4;
|
||||
tft_settings.pin_tft_d5 = TFT_D5;
|
||||
tft_settings.pin_tft_d6 = TFT_D6;
|
||||
tft_settings.pin_tft_d7 = TFT_D7;
|
||||
#else
|
||||
tft_settings.pin_tft_d0 = -1;
|
||||
tft_settings.pin_tft_d1 = -1;
|
||||
tft_settings.pin_tft_d2 = -1;
|
||||
tft_settings.pin_tft_d3 = -1;
|
||||
tft_settings.pin_tft_d4 = -1;
|
||||
tft_settings.pin_tft_d5 = -1;
|
||||
tft_settings.pin_tft_d6 = -1;
|
||||
tft_settings.pin_tft_d7 = -1;
|
||||
#endif
|
||||
|
||||
#if defined (TOUCH_CS)
|
||||
tft_settings.pin_tch_cs = TOUCH_CS;
|
||||
tft_settings.tch_spi_freq = SPI_TOUCH_FREQUENCY/100000;
|
||||
#else
|
||||
tft_settings.pin_tch_cs = -1;
|
||||
tft_settings.tch_spi_freq = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifdef TOUCH_CS
|
||||
#include "Extensions/Touch.cpp"
|
||||
|
94
TFT_eSPI.h
94
TFT_eSPI.h
@ -155,42 +155,42 @@
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ESP32_PARALLEL
|
||||
|
||||
#if defined (ESP32) && defined (ESP32_PARALLEL)
|
||||
// Mask for the 8 data bits to set pin directions
|
||||
#define dir_mask ((1 << TFT_D0) | (1 << TFT_D1) | (1 << TFT_D2) | (1 << TFT_D3) | (1 << TFT_D4) | (1 << TFT_D5) | (1 << TFT_D6) | (1 << TFT_D7))
|
||||
|
||||
// Data bits and the write line are cleared to 0 in one step
|
||||
#define clr_mask (dir_mask | (1 << TFT_WR))
|
||||
|
||||
// A lookup table is used to set the different bit patterns, this uses 1kByte of RAM
|
||||
#define set_mask(C) xset_mask[C] // 63fps Sprite rendering test 33% faster, graphicstest only 1.8% faster than shifting in real time
|
||||
|
||||
// Real-time shifting alternative to above to save 1KByte RAM, 47 fps Sprite rendering test
|
||||
//#define set_mask(C) ((C&0x80)>>7)<<TFT_D7 | ((C&0x40)>>6)<<TFT_D6 | ((C&0x20)>>5)<<TFT_D5 | ((C&0x10)>>4)<<TFT_D4 | \
|
||||
((C&0x08)>>3)<<TFT_D3 | ((C&0x04)>>2)<<TFT_D2 | ((C&0x02)>>1)<<TFT_D1 | ((C&0x01)>>0)<<TFT_D0
|
||||
|
||||
// Write 8 bits to TFT
|
||||
#define tft_Write_8(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)C); WR_H
|
||||
|
||||
// Write 16 bits to TFT
|
||||
#define tft_Write_16(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)(C >> 8)); WR_H; \
|
||||
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)(C >> 0)); WR_H
|
||||
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)(C >> 0)); WR_H
|
||||
|
||||
// 16 bit transfer with swapped bytes
|
||||
#define transwap16(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 0)); WR_H; \
|
||||
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 8)); WR_H
|
||||
// 16 bit write with swapped bytes
|
||||
#define tft_Write_16S(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 0)); WR_H; \
|
||||
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 8)); WR_H
|
||||
|
||||
// Write 32 bits to TFT
|
||||
#define tft_Write_32(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 24)); WR_H; \
|
||||
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 16)); WR_H; \
|
||||
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 8)); WR_H; \
|
||||
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 0)); WR_H
|
||||
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 16)); WR_H; \
|
||||
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 8)); WR_H; \
|
||||
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 0)); WR_H
|
||||
|
||||
#ifdef TFT_RD
|
||||
#if defined (ESP32)
|
||||
#define RD_L GPIO.out_w1tc = (1 << TFT_RD)
|
||||
//#define RD_L digitalWrite(TFT_WR, LOW)
|
||||
#define RD_H GPIO.out_w1ts = (1 << TFT_RD)
|
||||
//#define RD_H digitalWrite(TFT_WR, HIGH)
|
||||
#else
|
||||
//#define RD_L GPOC=rdpinmask
|
||||
//#define RD_H GPOS=rdpinmask
|
||||
#endif
|
||||
#define RD_L GPIO.out_w1tc = (1 << TFT_RD)
|
||||
//#define RD_L digitalWrite(TFT_WR, LOW)
|
||||
#define RD_H GPIO.out_w1ts = (1 << TFT_RD)
|
||||
//#define RD_H digitalWrite(TFT_WR, HIGH)
|
||||
#endif
|
||||
|
||||
#elif defined (SEND_16_BITS)
|
||||
@ -330,9 +330,55 @@ template <typename T> static inline void
|
||||
swap_coord(T& a, T& b) { T t = a; a = b; b = t; }
|
||||
|
||||
#ifndef min
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
// This structure allows sketches to retrieve the user setup parameters at runtime
|
||||
// by calling getSetup(), zero impact on code size unless used, mainly for diagnostics
|
||||
typedef struct
|
||||
{
|
||||
int16_t esp;
|
||||
uint8_t trans;
|
||||
uint8_t serial;
|
||||
|
||||
uint16_t tft_driver; // Hexadecimal code
|
||||
uint16_t tft_width; // Rotation 0 width and height
|
||||
uint16_t tft_height;
|
||||
|
||||
uint8_t r0_x_offset; // Offsets, not all used yet
|
||||
uint8_t r0_y_offset;
|
||||
uint8_t r1_x_offset;
|
||||
uint8_t r1_y_offset;
|
||||
uint8_t r2_x_offset;
|
||||
uint8_t r2_y_offset;
|
||||
uint8_t r3_x_offset;
|
||||
uint8_t r3_y_offset;
|
||||
|
||||
int8_t pin_tft_mosi;
|
||||
int8_t pin_tft_miso;
|
||||
int8_t pin_tft_clk;
|
||||
int8_t pin_tft_cs;
|
||||
|
||||
int8_t pin_tft_dc;
|
||||
int8_t pin_tft_rd;
|
||||
int8_t pin_tft_wr;
|
||||
int8_t pin_tft_rst;
|
||||
|
||||
int8_t pin_tft_d0;
|
||||
int8_t pin_tft_d1;
|
||||
int8_t pin_tft_d2;
|
||||
int8_t pin_tft_d3;
|
||||
int8_t pin_tft_d4;
|
||||
int8_t pin_tft_d5;
|
||||
int8_t pin_tft_d6;
|
||||
int8_t pin_tft_d7;
|
||||
|
||||
int8_t pin_tch_cs;
|
||||
|
||||
int16_t tft_spi_freq;
|
||||
int16_t tch_spi_freq;
|
||||
} setup_t;
|
||||
|
||||
// This is a structure to conveniently hold information on the default fonts
|
||||
// Stores pointer to font character image address table, width table and height
|
||||
|
||||
@ -444,6 +490,7 @@ class TFT_eSPI : public Print {
|
||||
fillTriangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t color),
|
||||
|
||||
drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color),
|
||||
setBitmapColor(uint16_t c, uint16_t b), // For 1bpp sprites
|
||||
|
||||
setCursor(int16_t x, int16_t y),
|
||||
setCursor(int16_t x, int16_t y, uint8_t font),
|
||||
@ -489,9 +536,9 @@ class TFT_eSPI : public Print {
|
||||
void pushImage(int32_t x0, int32_t y0, uint32_t w, uint32_t h, const uint16_t *data, uint16_t transparent);
|
||||
void pushImage(int32_t x0, int32_t y0, uint32_t w, uint32_t h, const uint16_t *data);
|
||||
|
||||
// These are used by pushSprite for 8 bit colours
|
||||
void pushImage(int32_t x0, int32_t y0, uint32_t w, uint32_t h, uint8_t *data);
|
||||
void pushImage(int32_t x0, int32_t y0, uint32_t w, uint32_t h, uint8_t *data, uint8_t transparent);
|
||||
// These are used by pushSprite for 1 and 8 bit colours
|
||||
void pushImage(int32_t x0, int32_t y0, uint32_t w, uint32_t h, uint8_t *data, bool bpp8 = true);
|
||||
void pushImage(int32_t x0, int32_t y0, uint32_t w, uint32_t h, uint8_t *data, uint8_t transparent, bool bpp8 = true);
|
||||
|
||||
// Swap the byte order for pushImage() - corrects endianness
|
||||
void setSwapBytes(bool swap);
|
||||
@ -543,8 +590,11 @@ class TFT_eSPI : public Print {
|
||||
|
||||
size_t write(uint8_t);
|
||||
|
||||
void getSetup(setup_t& tft_settings); // Sketch provides the instance to populate
|
||||
|
||||
int32_t cursor_x, cursor_y;
|
||||
uint32_t textcolor, textbgcolor;
|
||||
uint32_t bitmap_fg, bitmap_bg;
|
||||
|
||||
|
||||
private:
|
||||
|
Binary file not shown.
@ -40,7 +40,7 @@
|
||||
|
||||
//#include <User_Setups/Setup99.h>
|
||||
|
||||
//#include <User_Setups/SetupX_Template.h> // Setup file template for copying/editting
|
||||
// ePaper #include <User_Setups/SetupX_Template.h> // Setup file template for copying/editting
|
||||
|
||||
|
||||
#endif // USER_SETUP_LOADED
|
||||
@ -58,39 +58,51 @@
|
||||
// Load the right driver definition - do not tinker here !
|
||||
#if defined (ILI9341_DRIVER)
|
||||
#include <TFT_Drivers/ILI9341_Defines.h>
|
||||
#define TFT_DRIVER 0x9341
|
||||
#elif defined (ST7735_DRIVER)
|
||||
#include <TFT_Drivers/ST7735_Defines.h>
|
||||
#define TFT_DRIVER 0x7735
|
||||
#elif defined (ILI9163_DRIVER)
|
||||
#include <TFT_Drivers/ILI9163_Defines.h>
|
||||
#define TFT_DRIVER 0x9163
|
||||
#elif defined (S6D02A1_DRIVER)
|
||||
#include <TFT_Drivers/S6D02A1_Defines.h>
|
||||
#define TFT_DRIVER 0x6D02
|
||||
#elif defined (RPI_ILI9486_DRIVER)
|
||||
#include <TFT_Drivers/RPI_ILI9486_Defines.h>
|
||||
#define TFT_DRIVER 0x9481
|
||||
#elif defined (ILI9481_DRIVER)
|
||||
#include <TFT_Drivers/ILI9481_Defines.h>
|
||||
#define TFT_DRIVER 0x9481
|
||||
#elif defined (ILI9488_DRIVER)
|
||||
#include <TFT_Drivers/ILI9488_Defines.h>
|
||||
#define TFT_DRIVER 0x9488
|
||||
#elif defined (HX8357D_DRIVER)
|
||||
#include "TFT_Drivers/HX8357D_Defines.h"
|
||||
#define TFT_DRIVER 0x8357
|
||||
#elif defined (EPD_DRIVER)
|
||||
#include "TFT_Drivers/EPD_Defines.h"
|
||||
#define TFT_DRIVER 0xE9D
|
||||
#endif
|
||||
|
||||
// These are the pins for all ESP8266 boards
|
||||
#define PIN_D0 16
|
||||
#define PIN_D1 5
|
||||
#define PIN_D2 4
|
||||
#define PIN_D3 0
|
||||
#define PIN_D4 2
|
||||
#define PIN_D5 14
|
||||
#define PIN_D6 12
|
||||
#define PIN_D7 13
|
||||
#define PIN_D8 15
|
||||
#define PIN_D9 3
|
||||
#define PIN_D10 1
|
||||
// Name GPIO Function
|
||||
#define PIN_D0 16 // WAKE
|
||||
#define PIN_D1 5 // User purpose
|
||||
#define PIN_D2 4 // User purpose
|
||||
#define PIN_D3 0 // FLASH mode at boot time
|
||||
#define PIN_D4 2 // TXD1 (Note: low on boot means go to FLASH mode)
|
||||
#define PIN_D5 14 // HSCLK
|
||||
#define PIN_D6 12 // HMISO
|
||||
#define PIN_D7 13 // HMOSI RXD2
|
||||
#define PIN_D8 15 // HCS TXD0
|
||||
#define PIN_D9 3 // RXD0
|
||||
#define PIN_D10 1 // TXD0
|
||||
|
||||
#define PIN_MOSI 8
|
||||
#define PIN_MISO 7
|
||||
#define PIN_SCLK 6
|
||||
#define PIN_HWCS 0
|
||||
#define PIN_MOSI 8 // SD1
|
||||
#define PIN_MISO 7 // SD0
|
||||
#define PIN_SCLK 6 // CLK
|
||||
#define PIN_HWCS 0 // CMD
|
||||
|
||||
#define PIN_D11 9
|
||||
#define PIN_D12 10
|
||||
#define PIN_D11 9 // SD2
|
||||
#define PIN_D12 10 // SD4
|
||||
|
@ -121,6 +121,10 @@
|
||||
//#define TFT_RST 4 // Reset pin (could connect to RST pin)
|
||||
//#define TFT_RST -1 // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST
|
||||
|
||||
//#define TOUCH_CS 22 // Chip select pin (T_CS) of touch screen
|
||||
|
||||
//#define TFT_WR 21 // Write strobe for modified Raspberry Pi TFT only
|
||||
|
||||
// For the M5Stack module use these #define lines
|
||||
//#define TFT_MISO 19
|
||||
//#define TFT_MOSI 23
|
||||
@ -130,9 +134,6 @@
|
||||
//#define TFT_RST 33 // Reset pin (could connect to Arduino RESET pin)
|
||||
//#define TFT_BL 32 // LED back-light
|
||||
|
||||
//#define TOUCH_CS 21 // Chip select pin (T_CS) of touch screen
|
||||
|
||||
//#define TFT_WR 22 // Write strobe for modified Raspberry Pi TFT only
|
||||
|
||||
// ##################################################################################
|
||||
//
|
||||
@ -199,6 +200,7 @@
|
||||
// #define SPI_FREQUENCY 20000000
|
||||
#define SPI_FREQUENCY 27000000 // Actually sets it to 26.67MHz = 80/3
|
||||
// #define SPI_FREQUENCY 40000000 // Maximum to use SPIFFS
|
||||
// #define SPI_FREQUENCY 53400000
|
||||
// #define SPI_FREQUENCY 80000000
|
||||
|
||||
// The XPT2046 requires a lower SPI clock rate of 2.5MHz so we define that here:
|
||||
|
76
User_Setups/ePaper_Template.h
Normal file
76
User_Setups/ePaper_Template.h
Normal file
@ -0,0 +1,76 @@
|
||||
// USER DEFINED SETTINGS
|
||||
// Set driver type, fonts to be loaded, pins used and SPI control method etc
|
||||
//
|
||||
// See the User_Setup_Select.h file if you wish to be able to define multiple
|
||||
// setups and then easily select which setup file is used by the compiler.
|
||||
//
|
||||
// If this file is edited correctly then all the library example sketches should
|
||||
// run without the need to make any more changes for a particular hardware setup!
|
||||
|
||||
// ##################################################################################
|
||||
//
|
||||
// Section 0. Call up the right driver file and any options for it
|
||||
//
|
||||
// ##################################################################################
|
||||
|
||||
// Only define one driver, the other ones must be commented out
|
||||
#define EPD_DRIVER
|
||||
|
||||
|
||||
// ##################################################################################
|
||||
//
|
||||
// Section 1. Define the pins that are used to interface with the display here
|
||||
//
|
||||
// ##################################################################################
|
||||
|
||||
// ePaper pins are not defined here - dummy set
|
||||
|
||||
//#define TFT_CS
|
||||
//#define TFT_DC
|
||||
//#define TFT_RST
|
||||
|
||||
|
||||
// ##################################################################################
|
||||
//
|
||||
// Section 2. Not used
|
||||
//
|
||||
// ##################################################################################
|
||||
|
||||
|
||||
// ##################################################################################
|
||||
//
|
||||
// Section 3. Define the fonts that are to be used here
|
||||
//
|
||||
// ##################################################################################
|
||||
|
||||
// Comment out the #defines below with // to stop that font being loaded
|
||||
// The ESP8366 and ESP32 have plenty of memory so commenting out fonts is not
|
||||
// normally necessary. If all fonts are loaded the extra FLASH space required is
|
||||
// about 17Kbytes. To save FLASH space only enable the fonts you need!
|
||||
|
||||
#define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
|
||||
#define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
|
||||
#define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
|
||||
#define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
|
||||
//#define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:.
|
||||
//#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
|
||||
//#define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
|
||||
#define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
|
||||
|
||||
// Comment out the #define below to stop the SPIFFS filing system and smooth font code being loaded
|
||||
// this will save ~20kbytes of FLASH
|
||||
#define SMOOTH_FONT
|
||||
|
||||
// ##################################################################################
|
||||
//
|
||||
// Section 4. Not used
|
||||
//
|
||||
// ##################################################################################
|
||||
|
||||
|
||||
// ##################################################################################
|
||||
//
|
||||
// Section 5. Not used
|
||||
//
|
||||
// ##################################################################################
|
||||
|
@ -75,7 +75,6 @@ calibrateTouch KEYWORD2
|
||||
setTouch KEYWORD2
|
||||
validTouch KEYWORD2
|
||||
|
||||
|
||||
TFT_eSPI_Button KEYWORD1
|
||||
|
||||
initButton KEYWORD2
|
||||
@ -99,8 +98,14 @@ pushBitmap KEYWORD2
|
||||
pushSprite KEYWORD2
|
||||
setScrollRect KEYWORD2
|
||||
scroll KEYWORD2
|
||||
printToSprite KEYWORD2
|
||||
frameBuffer KEYWORD2
|
||||
setBitmapColor KEYWORD2
|
||||
|
||||
alphaBlend KEYWORD2
|
||||
showFont KEYWORD2
|
||||
loadFont KEYWORD2
|
||||
unloadFont KEYWORD2
|
||||
getUnicodeIndex KEYWORD2
|
||||
decodeUTF8 KEYWORD2
|
||||
drawGlyph KEYWORD2
|
||||
|
@ -14,10 +14,6 @@
|
||||
"name": "Bodmer",
|
||||
"email": "bodmer@anola.net",
|
||||
"maintainer": true
|
||||
},
|
||||
{
|
||||
"name": "Adafruit",
|
||||
"url": "https://www.adafruit.com/"
|
||||
}
|
||||
],
|
||||
"frameworks": "arduino",
|
||||
|
Loading…
Reference in New Issue
Block a user