Files
TEF6686_ESP32/lib/TFT_eSPI/TFT_eSPI.h

544 lines
25 KiB
C++

#pragma once
#define TFT_ESPI_VERSION "2.5.43"
#include <Arduino.h>
#include <Print.h>
#include <SPI.h>
#include <User_Setup_Select.h>
#include <pgmspace.h>
#define PROCESSOR_ID 0x32
#define SPI_PORT VSPI
#include "soc/spi_reg.h"
#include "driver/spi_master.h"
#include "hal/gpio_ll.h"
#define SET_BUS_WRITE_MODE *_spi_user = SPI_USR_MOSI
#define SET_BUS_READ_MODE *_spi_user = SPI_USR_MOSI | SPI_USR_MISO | SPI_DOUTDIN
#define SPI_BUSY_CHECK while (*_spi_cmd&SPI_USR)
#define FS_NO_GLOBALS
#include <FS.h>
#include "SPIFFS.h" // ESP32 only
#define DC_C GPIO.out_w1tc = (1 << TFT_DC)//;GPIO.out_w1tc = (1 << TFT_DC)
#define DC_D GPIO.out_w1ts = (1 << TFT_DC)//;GPIO.out_w1ts = (1 << TFT_DC)
#define CS_L GPIO.out_w1tc = (1 << TFT_CS); GPIO.out_w1tc = (1 << TFT_CS)
#define CS_H GPIO.out_w1ts = (1 << TFT_CS)//;GPIO.out_w1ts = (1 << TFT_CS)
#define WR_L
#define WR_H
#ifndef TFT_MISO
#define TFT_MISO -1
#endif
#ifndef TFT_MOSI
#define TFT_MOSI 23
#endif
#ifndef TFT_SCLK
#define TFT_SCLK 18
#endif
#define TFT_WRITE_BITS(D, B) *_spi_mosi_dlen = B-1; \
*_spi_w = D; \
*_spi_cmd = SPI_USR; \
while (*_spi_cmd & SPI_USR);
// Write 8 bits
#define tft_Write_8(C) TFT_WRITE_BITS(C, 8)
// Write 16 bits with corrected endianness for 16-bit colours
#define tft_Write_16(C) TFT_WRITE_BITS((C)<<8 | (C)>>8, 16)
// Future option for transfer without wait
#define tft_Write_16N(C) *_spi_mosi_dlen = 16-1; \
*_spi_w = ((C)<<8 | (C)>>8); \
*_spi_cmd = SPI_USR;
// Write 16 bits
#define tft_Write_16S(C) TFT_WRITE_BITS(C, 16)
// Write 32 bits
#define tft_Write_32(C) TFT_WRITE_BITS(C, 32)
// Write two address coordinates
#define tft_Write_32C(C,D) TFT_WRITE_BITS((uint16_t)((D)<<8 | (D)>>8)<<16 | (uint16_t)((C)<<8 | (C)>>8), 32)
// Write same value twice
#define tft_Write_32D(C) TFT_WRITE_BITS((uint16_t)((C)<<8 | (C)>>8)<<16 | (uint16_t)((C)<<8 | (C)>>8), 32)
////////////////////////////////////////////////////////////////////////////////////////
// Macros to read from display using SPI or software SPI
////////////////////////////////////////////////////////////////////////////////////////
#if !defined (TFT_PARALLEL_8_BIT)
#define tft_Read_8() spi.transfer(0)
#endif
#define DAT8TO32(P) ( (uint32_t)P[0]<<8 | P[1] | P[2]<<24 | P[3]<<16 )
#ifndef TFT_SPI_MODE
#define TFT_SPI_MODE SPI_MODE0
#endif
//These enumerate the text plotting alignment (reference datum point)
#define TL_DATUM 0 // Top left (default)
#define TC_DATUM 1 // Top centre
#define TR_DATUM 2 // Top right
#define ML_DATUM 3 // Middle left
#define CL_DATUM 3 // Centre left, same as above
#define MC_DATUM 4 // Middle centre
#define CC_DATUM 4 // Centre centre, same as above
#define MR_DATUM 5 // Middle right
#define CR_DATUM 5 // Centre right, same as above
#define BL_DATUM 6 // Bottom left
#define BC_DATUM 7 // Bottom centre
#define BR_DATUM 8 // Bottom right
#define L_BASELINE 9 // Left character baseline (Line the 'A' character would sit on)
#define C_BASELINE 10 // Centre character baseline
#define R_BASELINE 11 // Right character baseline
/***************************************************************************************
** Section 6: Colour enumeration
***************************************************************************************/
// Default color definitions
#define TFT_BLACK 0x0000 /* 0, 0, 0 */
#define TFT_NAVY 0x000F /* 0, 0, 128 */
#define TFT_DARKGREEN 0x03E0 /* 0, 128, 0 */
#define TFT_DARKCYAN 0x03EF /* 0, 128, 128 */
#define TFT_MAROON 0x7800 /* 128, 0, 0 */
#define TFT_PURPLE 0x780F /* 128, 0, 128 */
#define TFT_OLIVE 0x7BE0 /* 128, 128, 0 */
#define TFT_LIGHTGREY 0xD69A /* 211, 211, 211 */
#define TFT_DARKGREY 0x7BEF /* 128, 128, 128 */
#define TFT_BLUE 0x001F /* 0, 0, 255 */
#define TFT_GREEN 0x07E0 /* 0, 255, 0 */
#define TFT_CYAN 0x07FF /* 0, 255, 255 */
#define TFT_RED 0xF800 /* 255, 0, 0 */
#define TFT_MAGENTA 0xF81F /* 255, 0, 255 */
#define TFT_YELLOW 0xFFE0 /* 255, 255, 0 */
#define TFT_WHITE 0xFFFF /* 255, 255, 255 */
#define TFT_ORANGE 0xFDA0 /* 255, 180, 0 */
#define TFT_GREENYELLOW 0xB7E0 /* 180, 255, 0 */
#define TFT_PINK 0xFE19 /* 255, 192, 203 */ //Lighter pink, was 0xFC9F
#define TFT_BROWN 0x9A60 /* 150, 75, 0 */
#define TFT_GOLD 0xFEA0 /* 255, 215, 0 */
#define TFT_SILVER 0xC618 /* 192, 192, 192 */
#define TFT_SKYBLUE 0x867D /* 135, 206, 235 */
#define TFT_VIOLET 0x915C /* 180, 46, 226 */
// Next is a special 16-bit colour value that encodes to 8 bits
// and will then decode back to the same 16-bit value.
// Convenient for 8-bit and 16-bit transparent sprites.
#define TFT_TRANSPARENT 0x0120 // This is actually a dark green
// Default palette for 4-bit colour sprites
static const uint16_t default_4bit_palette[] PROGMEM = {
TFT_BLACK, // 0 ^
TFT_BROWN, // 1 |
TFT_RED, // 2 |
TFT_ORANGE, // 3 |
TFT_YELLOW, // 4 Colours 0-9 follow the resistor colour code!
TFT_GREEN, // 5 |
TFT_BLUE, // 6 |
TFT_PURPLE, // 7 |
TFT_DARKGREY, // 8 |
TFT_WHITE, // 9 v
TFT_CYAN, // 10 Blue+green mix
TFT_MAGENTA, // 11 Blue+red mix
TFT_MAROON, // 12 Darker red colour
TFT_DARKGREEN,// 13 Darker green colour
TFT_NAVY, // 14 Darker blue colour
TFT_PINK // 15
};
typedef uint16_t (*getColorCallback)(uint16_t x, uint16_t y);
class TFT_eSPI { friend class TFT_eSprite;
public:
void setSPISpeed(uint8_t speed_Mhz);
TFT_eSPI(int16_t _W = TFT_WIDTH, int16_t _H = TFT_HEIGHT);
void init();
virtual void drawPixel(int32_t x, int32_t y, uint32_t color),
drawLine(int32_t xs, int32_t ys, int32_t xe, int32_t ye, uint32_t color),
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);
virtual int16_t drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font),
drawChar(uint16_t uniCode, int32_t x, int32_t y),
height(),
width();
virtual uint16_t readPixel(int32_t x, int32_t y);
virtual void setWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye);
virtual void pushColor(uint16_t color);
virtual void begin_nin_write();
virtual void end_nin_write();
void setRotation(uint8_t r);
void invertDisplay(bool i);
void setAddrWindow(int32_t xs, int32_t ys, int32_t w, int32_t h);
void setViewport(int32_t x, int32_t y, int32_t w, int32_t h, bool vpDatum = true);
bool checkViewport(int32_t x, int32_t y, int32_t w, int32_t h);
void resetViewport();
bool clipAddrWindow(int32_t* x, int32_t* y, int32_t* w, int32_t* h);
bool clipWindow(int32_t* xs, int32_t* ys, int32_t* xe, int32_t* ye);
void pushColor(uint16_t color, uint32_t len);
void pushColors(uint16_t *data, uint32_t len, bool swap = true);
void pushBlock(uint16_t color, uint32_t len);
void pushPixels(const void * data_in, uint32_t len);
void fillScreen(uint32_t color),
drawRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color),
drawRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t radius, uint32_t color),
fillRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t radius, uint32_t color);
void drawCircleHelper(int32_t x, int32_t y, int32_t r, uint8_t cornername, uint32_t color),
fillCircle(int32_t x, int32_t y, int32_t r, uint32_t color),
fillCircleHelper(int32_t x, int32_t y, int32_t r, uint8_t cornername, int32_t delta, uint32_t color),
drawEllipse(int16_t x, int16_t y, int32_t rx, int32_t ry, uint16_t color),
fillEllipse(int16_t x, int16_t y, int32_t rx, int32_t ry, uint16_t color),
fillTriangle(int32_t x1,int32_t y1, int32_t x2,int32_t y2, int32_t x3,int32_t y3, uint32_t color);
uint16_t drawPixel(int32_t x, int32_t y, uint32_t color, uint8_t alpha, uint32_t bg_color = 0x00FFFFFF);
void drawArc(int32_t x, int32_t y, int32_t r, int32_t ir, uint32_t startAngle, uint32_t endAngle, uint32_t fg_color, uint32_t bg_color, bool smoothArc = true);
void drawSmoothCircle(int32_t x, int32_t y, int32_t r, uint32_t fg_color, uint32_t bg_color);
void fillSmoothCircle(int32_t x, int32_t y, int32_t r, uint32_t color, uint32_t bg_color = 0x00FFFFFF);
void drawSmoothRoundRect(int32_t x, int32_t y, int32_t r, int32_t ir, int32_t w, int32_t h, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF, uint8_t quadrants = 0xF);
void fillSmoothRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t radius, uint32_t color, uint32_t bg_color = 0x00FFFFFF);
void drawSpot(float ax, float ay, float r, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF);
void drawWedgeLine(float ax, float ay, float bx, float by, float aw, float bw, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF);
void setSwapBytes(bool swap);
bool getSwapBytes();
void drawBitmap( int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t fgcolor),
drawBitmap( int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t fgcolor, uint16_t bgcolor),
drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t fgcolor),
drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t fgcolor, uint16_t bgcolor),
setBitmapColor(uint16_t fgcolor, uint16_t bgcolor);
void setPivot(int16_t x, int16_t y);
void pushRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data);
void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data);
void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data, uint16_t transparent);
void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *data, uint16_t transparent);
void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *data);
void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *data, bool bpp8 = true, uint16_t *cmap = nullptr);
void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *data, uint8_t transparent, bool bpp8 = true, uint16_t *cmap = nullptr);
void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint8_t *data, bool bpp8, uint16_t *cmap = nullptr);
void readRectRGB(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *data);
// Text rendering - value returned is the pixel width of the rendered text
int16_t drawNumber(long intNumber, int32_t x, int32_t y, uint8_t font), // Draw integer using specified font number
drawNumber(long intNumber, int32_t x, int32_t y), // Draw integer using current font
// Decimal is the number of decimal places to render
// Use with setTextDatum() to position values on TFT, and setTextPadding() to blank old displayed values
drawFloat(float floatNumber, uint8_t decimal, int32_t x, int32_t y, uint8_t font), // Draw float using specified font number
drawFloat(float floatNumber, uint8_t decimal, int32_t x, int32_t y), // Draw float using current font
// Handle char arrays
// Use with setTextDatum() to position string on TFT, and setTextPadding() to blank old displayed strings
drawString(const char *string, int32_t x, int32_t y, uint8_t font), // Draw string using specified font number
drawString(const char *string, int32_t x, int32_t y), // Draw string using current font
drawString(const String& string, int32_t x, int32_t y, uint8_t font),// Draw string using specified font number
drawString(const String& string, int32_t x, int32_t y); // Draw string using current font
// Text rendering and font handling support functions
void setCursor(int16_t x, int16_t y), // Set cursor for tft.print()
setCursor(int16_t x, int16_t y, uint8_t font); // Set cursor and font number for tft.print()
void setTextColor(uint16_t color), // Set character (glyph) color only (background not over-written)
setTextColor(uint16_t fgcolor, uint16_t bgcolor, bool bgfill = false), // Set character (glyph) foreground and background colour, optional background fill for smooth fonts
setTextSize(uint8_t size); // Set character size multiplier (this increases pixel size)
void setTextWrap(bool wrapX, bool wrapY = false); // Turn on/off wrapping of text in TFT width and/or height
void setTextDatum(uint8_t datum); // Set text datum position (default is top left), see Section 5 above
void setTextPadding(uint16_t x_width); // Set text padding (background blanking) width in pixels
void setTextFont(uint8_t font); // Set the font number to use in future
int16_t textWidth(const char *string, uint8_t font), // Returns pixel width of string in specified font
textWidth(const char *string), // Returns pixel width of string in current font
textWidth(const String& string, uint8_t font), // As above for String types
textWidth(const String& string),
fontHeight(uint8_t font), // Returns pixel height of specified font
fontHeight(); // Returns pixel height of current font
// Used by library and Smooth font class to extract Unicode point codes from a UTF8 encoded string
uint16_t decodeUTF8(uint8_t *buf, uint16_t *index, uint16_t remaining),
decodeUTF8(uint8_t c);
// Used by Smooth font class to fetch a pixel colour for the anti-aliasing
void setCallback(getColorCallback getCol);
void spiwrite(uint8_t); // legacy support only
void writecommand(uint8_t c); // Send an 8-bit command, function resets DC/RS high ready for data
void writedata(uint8_t d); // Send data with DC/RS set high
void commandList(const uint8_t *addr); // Send a initialisation sequence to TFT stored in FLASH
uint8_t readcommand8( uint8_t cmd_function, uint8_t index = 0); // read 8 bits from TFT
uint16_t readcommand16(uint8_t cmd_function, uint8_t index = 0); // read 16 bits from TFT
uint32_t readcommand32(uint8_t cmd_function, uint8_t index = 0); // read 32 bits from TFT
// Colour conversion
// Convert 8-bit red, green and blue to 16 bits
uint16_t color565(uint8_t red, uint8_t green, uint8_t blue);
// Alpha blend 2 colours, see generic "alphaBlend_Test" example
// alpha = 0 = 100% background colour
// alpha = 255 = 100% foreground colour
uint16_t alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc);
// 16-bit colour alphaBlend with alpha dither (dither reduces colour banding)
uint16_t alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc, uint8_t dither);
// 24-bit colour alphaBlend with optional alpha dither
uint32_t alphaBlend24(uint8_t alpha, uint32_t fgc, uint32_t bgc, uint8_t dither = 0);
bool initDMA(bool ctrl_cs = false); // Initialise the DMA engine and attach to SPI bus - typically used in setup()
// Push a block of pixels into a window set up using setAddrWindow()
void pushPixelsDMA(uint16_t* image, uint32_t len);
// Check if the DMA is complete - use while(tft.dmaBusy); for a blocking wait
bool dmaBusy(); // returns true if DMA is still in progress
void dmaWait(); // wait until DMA is complete
bool DMA_Enabled = false; // Flag for DMA enabled state
uint8_t spiBusyCheck = 0; // Number of ESP32 transfer buffers to check
// Bare metal functions
void startWrite(); // Begin SPI transaction
void writeColor(uint16_t color, uint32_t len); // Deprecated, use pushBlock()
void endWrite(); // End SPI transaction
// Global variables
static SPIClass& getSPIinstance(); // Get SPI class handle
uint32_t textcolor, textbgcolor; // Text foreground and background colours
uint32_t bitmap_fg, bitmap_bg; // Bitmap foreground (bit=1) and background (bit=0) colours
uint8_t textfont, // Current selected font number
textsize, // Current font size multiplier
textdatum, // Text reference datum
rotation; // Display rotation (0-3)
uint8_t decoderState = 0; // UTF8 decoder state - not for user access
uint16_t decoderBuffer; // Unicode code-point buffer - not for user access
void loadFont(const uint8_t array[], uint8_t font);
void unloadFont(uint8_t font);
bool getUnicodeIndex(uint16_t unicode, uint16_t *index, uint16_t font);
virtual void drawGlyph(uint16_t code, uint16_t font);
typedef struct
{
const uint8_t* gArray; //array start pointer
uint16_t gCount; // Total number of characters
uint16_t yAdvance; // Line advance
uint16_t spaceWidth; // Width of a space character
int16_t ascent; // Height of top of 'd' above baseline, other characters may be taller
int16_t descent; // Offset to bottom of 'p', other characters may have a larger descent
uint16_t maxAscent; // Maximum ascent found in font
uint16_t maxDescent; // Maximum descent found in font
} fontMetrics;
fontMetrics gFonts[7] = {
{ nullptr, 0, 0, 0, 0, 0, 0, 0 },
{ nullptr, 0, 0, 0, 0, 0, 0, 0 },
{ nullptr, 0, 0, 0, 0, 0, 0, 0 },
{ nullptr, 0, 0, 0, 0, 0, 0, 0 },
{ nullptr, 0, 0, 0, 0, 0, 0, 0 },
{ nullptr, 0, 0, 0, 0, 0, 0, 0 },
{ nullptr, 0, 0, 0, 0, 0, 0, 0 }
};
// These are for the metrics for each individual glyph (so we don't need to seek this in file and waste time)
uint16_t* gUnicode[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL}; //UTF-16 code, the codes are searched so do not need to be sequential
uint8_t* gHeight[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL}; //cheight
uint8_t* gWidth[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL}; //cwidth
uint8_t* gxAdvance[7] = {NULL, NULL, NULL, NULL, NULL, NULL}; //setWidth
int16_t* gdY[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL}; //topExtent
int8_t* gdX[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL}; //leftExtent
uint32_t* gBitmap[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL}; //file pointer to greyscale bitmap
uint8_t getTouchRaw(uint16_t *x, uint16_t *y);
uint16_t getTouchRawZ();
void convertRawXY(uint16_t *x, uint16_t *y);
uint8_t getTouch(uint16_t *x, uint16_t *y, uint16_t threshold = 600);
void calibrateTouch(uint16_t *data, uint32_t color_fg, uint32_t color_bg, uint8_t size);
void setTouch(uint16_t *data);
//--------------------------------------- private ------------------------------------//
private:
inline void begin_tft_write() __attribute__((always_inline));
inline void end_tft_write() __attribute__((always_inline));
inline void begin_tft_read() __attribute__((always_inline));
inline void end_tft_read() __attribute__((always_inline));
void initBus();
void pushSwapBytePixels(const void* data_in, uint32_t len);
void readAddrWindow(int32_t xs, int32_t ys, int32_t w, int32_t h);
uint8_t readByte();
void busDir(uint32_t mask, uint8_t mode);
void gpioMode(uint8_t gpio, uint8_t mode);
uint8_t sqrt_fraction(uint32_t num);
float wedgeLineDistance(float pax, float pay, float bax, float bay, float dr);
getColorCallback getColor = nullptr; // Smooth font callback function pointer
bool locked, inTransaction, lockTransaction; // SPI transaction and mutex lock flags
void loadMetrics(uint8_t font); // Function of Fear, which is Unhandled Exception, writing to 0x000000000
uint32_t readInt32();
uint8_t* fontPtr = nullptr;
//-------------------------------------- protected ----------------------------------//
protected:
uint8_t spi_write_speed;
//int32_t win_xe, win_ye; // Window end coords - not needed
int32_t _init_width, _init_height; // Display w/h as input, used by setRotation()
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
int16_t _xPivot; // TFT x pivot point coordinate for rotated Sprites
int16_t _yPivot; // TFT x pivot point coordinate for rotated Sprites
// Viewport variables
int32_t _vpX, _vpY, _vpW, _vpH; // Note: x start, y start, x end + 1, y end + 1
int32_t _xDatum;
int32_t _yDatum;
int32_t _xWidth;
int32_t _yHeight;
bool _vpDatum;
bool _vpOoB;
int32_t cursor_x, cursor_y, padX;
int32_t bg_cursor_x;
int32_t last_cursor_x;
bool isDigits;
bool textwrapX, textwrapY;
bool _swapBytes;
bool _booted;
uint32_t _lastColor;
bool _fillbg;
private:
inline void begin_touch_read_write() __attribute__((always_inline));
inline void end_touch_read_write() __attribute__((always_inline));
uint8_t validTouch(uint16_t *x, uint16_t *y, uint16_t threshold = 600);
uint16_t touchCalibration_x0 = 300, touchCalibration_x1 = 3600, touchCalibration_y0 = 300, touchCalibration_y1 = 3600;
uint8_t touchCalibration_rotate = 1, touchCalibration_invert_x = 2, touchCalibration_invert_y = 0;
uint32_t _pressTime;
};
class TFT_eSprite : public TFT_eSPI {
public:
explicit TFT_eSprite(TFT_eSPI *tft);
~TFT_eSprite();
void* createSprite(int16_t width, int16_t height, uint8_t frames = 1);
void* getPointer();
bool created();
void deleteSprite();
void* setColorDepth(int8_t b);
int8_t getColorDepth();
void createPalette(uint16_t *palette = nullptr, uint8_t colors = 16);
void createPalette(const uint16_t *palette = nullptr, uint8_t colors = 16);
void setPaletteColor(uint8_t index, uint16_t color);
uint16_t getPaletteColor(uint8_t index);
void setBitmapColor(uint16_t fg, uint16_t bg);
void drawPixel(int32_t x, int32_t y, uint32_t color);
void fillSprite(uint32_t color),
setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1),
pushColor(uint16_t color),
pushColor(uint16_t color, uint32_t len),
writeColor(uint16_t color),
drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t color),
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);
uint16_t readPixel(int32_t x0, int32_t y0);
uint16_t readPixelValue(int32_t x, int32_t y);
void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, uint16_t *data, uint8_t sbpp = 0);
void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, const uint16_t *data);
void pushSprite(int32_t x, int32_t y);
void pushSprite(int32_t x, int32_t y, uint16_t transparent);
bool pushSprite(int32_t tx, int32_t ty, int32_t sx, int32_t sy, int32_t sw, int32_t sh);
bool pushToSprite(TFT_eSprite *dspr, int32_t x, int32_t y);
bool pushToSprite(TFT_eSprite *dspr, int32_t x, int32_t y, uint16_t transparent);
int16_t drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font),
drawChar(uint16_t uniCode, int32_t x, int32_t y);
int16_t width(),
height();
void drawGlyph(uint16_t code, uint16_t font);
private:
TFT_eSPI *_tft;
void* callocSprite(int16_t width, int16_t height, uint8_t frames = 1);
protected:
uint8_t _bpp; // bits per pixel (1, 4, 8 or 16)
uint16_t *_img; // pointer to 16-bit sprite
uint8_t *_img8; // pointer to 1 and 8-bit sprite frame 1 or frame 2
uint8_t *_img4; // pointer to 4-bit sprite (uses color map)
uint8_t *_img8_1; // pointer to frame 1
uint8_t *_img8_2; // pointer to frame 2
uint16_t *_colorMap; // color map pointer: 16 entries, used with 4-bit color map.
int32_t _sinra; // Sine of rotation angle in fixed point
int32_t _cosra; // Cosine of rotation angle in fixed point
bool _created;
int32_t _xs, _ys, _xe, _ye, _xptr, _yptr;
int32_t _sx, _sy;
uint32_t _sw, _sh;
uint32_t _scolor;
int32_t _iwidth, _iheight; // Sprite memory image bit width and height (swapped during rotations)
int32_t _dwidth, _dheight; // Real sprite width and height (for <8bpp Sprites)
int32_t _bitwidth; // Sprite image bit width for drawPixel (for <8bpp Sprites, not swapped)
};
template <typename T> static inline void transpose(T& a, T& b) { T t = a; a = b; b = t; }
template <typename A, typename F, typename B> static inline uint16_t fastBlend(A alpha, F fgc, B bgc)
{
// Split out and blend 5-bit red and blue channels
uint32_t rxb = bgc & 0xF81F;
rxb += ((fgc & 0xF81F) - rxb) * (alpha >> 2) >> 6;
// Split out and blend 6-bit green channel
uint32_t xgx = bgc & 0x07E0;
xgx += ((fgc & 0x07E0) - xgx) * alpha >> 8;
// Recombine channels
return (rxb & 0xF81F) | (xgx & 0x07E0);
}