twali_screen.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. struct twali_screen {
  2. int x;
  3. int y;
  4. int w;
  5. int h;
  6. TFT_eSPI * tft;
  7. };
  8. void twali_screen_clip(struct twali_screen * s, int32_t * x, int32_t * y) {
  9. int cx = *x + s->x;
  10. int cy = *y + s->y;
  11. if cx > (
  12. }
  13. void twali_screen_draw_pixel(struct twali_screen * s, int32_t x, int32_t y, uint32_t color) {
  14. s->tft->drawPixel(x, y, color);
  15. }
  16. void twali_screen_draw_char(struct twali_screen * s, int32_t x, int32_t y, uint16_t c, uint32_t color, uint32_t bg, uint8_t size) {
  17. s->tft->drawChar(x, y, c, color, bg, size);
  18. }
  19. void twali_screen_draw_line(struct twali_screen * s, int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color) {
  20. s->tft->drawLine(x, y, x+w, y+h, c, color, bg, size);
  21. }
  22. drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32_t bg, uint8_t size),
  23. drawLine(int32_t xs, int32_t ys, int32_t xe, int32_t ye, uint32_t color),
  24. drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color),
  25. drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color),
  26. fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color);
  27. virtual int16_t drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font),
  28. drawChar(uint16_t uniCode, int32_t x, int32_t y),
  29. height(void),
  30. width(void);
  31. void setRotation(uint8_t r); // Set the display image orientation to 0, 1, 2 or 3
  32. uint8_t getRotation(void); // Read the current rotation
  33. void invertDisplay(bool i); // Tell TFT to invert all displayed colours
  34. // The TFT_eSprite class inherits the following functions (not all are useful to Sprite class
  35. void setAddrWindow(int32_t xs, int32_t ys, int32_t w, int32_t h), // Note: start coordinates + width and height
  36. setWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye); // Note: start + end coordinates
  37. // Push (aka write pixel) colours to the TFT (use setAddrWindow() first)
  38. void pushColor(uint16_t color),
  39. pushColor(uint16_t color, uint32_t len), // Deprecated, use pushBlock()
  40. pushColors(uint16_t *data, uint32_t len, bool swap = true), // With byte swap option
  41. pushColors(uint8_t *data, uint32_t len); // Deprecated, use pushPixels()
  42. // Write a solid block of a single colour
  43. void pushBlock(uint16_t color, uint32_t len);
  44. // Write a set of pixels stored in memory, use setSwapBytes(true/false) function to correct endianess
  45. void pushPixels(const void *data_in, uint32_t len);
  46. // Read the colour of a pixel at x,y and return value in 565 format
  47. uint16_t readPixel(int32_t x, int32_t y);
  48. // Support for half duplex (bi-directional SDA) SPI bus where MOSI must be switched to input
  49. #ifdef TFT_SDA_READ
  50. #if defined (TFT_eSPI_ENABLE_8_BIT_READ)
  51. uint8_t tft_Read_8(void); // Read 8 bit value from TFT command register
  52. #endif
  53. void begin_SDA_Read(void); // Begin a read on a half duplex (bi-directional SDA) SPI bus - sets MOSI to input
  54. void end_SDA_Read(void); // Restore MOSI to output
  55. #endif
  56. // Graphics drawing
  57. void fillScreen(uint32_t color),
  58. drawRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color),
  59. drawRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t radius, uint32_t color),
  60. fillRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t radius, uint32_t color);
  61. void drawCircle(int32_t x, int32_t y, int32_t r, uint32_t color),
  62. drawCircleHelper(int32_t x, int32_t y, int32_t r, uint8_t cornername, uint32_t color),
  63. fillCircle(int32_t x, int32_t y, int32_t r, uint32_t color),
  64. fillCircleHelper(int32_t x, int32_t y, int32_t r, uint8_t cornername, int32_t delta, uint32_t color),
  65. drawEllipse(int16_t x, int16_t y, int32_t rx, int32_t ry, uint16_t color),
  66. fillEllipse(int16_t x, int16_t y, int32_t rx, int32_t ry, uint16_t color),
  67. // Corner 1 Corner 2 Corner 3
  68. drawTriangle(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t x3, int32_t y3, uint32_t color),
  69. fillTriangle(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t x3, int32_t y3, uint32_t color);
  70. // Image rendering
  71. // Swap the byte order for pushImage() and pushPixels() - corrects endianness
  72. void setSwapBytes(bool swap);
  73. bool getSwapBytes(void);
  74. // Draw bitmap
  75. void drawBitmap( int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t fgcolor),
  76. drawBitmap( int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t fgcolor, uint16_t bgcolor),
  77. drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t fgcolor),
  78. drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t fgcolor, uint16_t bgcolor),
  79. setBitmapColor(uint16_t fgcolor, uint16_t bgcolor); // Define the 2 colours for 1bpp sprites
  80. // Set TFT pivot point (use when rendering rotated sprites)
  81. void setPivot(int16_t x, int16_t y);
  82. int16_t getPivotX(void), // Get pivot x
  83. getPivotY(void); // Get pivot y
  84. // The next functions can be used as a pair to copy screen blocks (or horizontal/vertical lines) to another location
  85. // Read a block of pixels to a data buffer, buffer is 16 bit and the size must be at least w * h
  86. void readRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data);
  87. // Write a block of pixels to the screen which have been read by readRect()
  88. void pushRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data);
  89. // These are used to render images or sprites stored in RAM arrays (used by Sprite class for 16bpp Sprites)
  90. void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data);
  91. void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data, uint16_t transparent);
  92. // These are used to render images stored in FLASH (PROGMEM)
  93. void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *data, uint16_t transparent);
  94. void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *data);
  95. // These are used by Sprite class pushSprite() member function for 1, 4 and 8 bits per pixel (bpp) colours
  96. // They are not intended to be used with user sketches (but could be)
  97. // Set bpp8 true for 8bpp sprites, false otherwise. The cmap pointer must be specified for 4bpp
  98. void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *data, bool bpp8 = true, uint16_t *cmap = nullptr);
  99. 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);
  100. // This next function has been used successfully to dump the TFT screen to a PC for documentation purposes
  101. // It reads a screen area and returns the 3 RGB 8 bit colour values of each pixel in the buffer
  102. // Set w and h to 1 to read 1 pixel's colour. The data buffer must be at least w * h * 3 bytes
  103. void readRectRGB(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *data);
  104. // Text rendering - value returned is the pixel width of the rendered text
  105. int16_t drawNumber(long intNumber, int32_t x, int32_t y, uint8_t font), // Draw integer using specified font number
  106. drawNumber(long intNumber, int32_t x, int32_t y), // Draw integer using current font
  107. // Decimal is the number of decimal places to render
  108. // Use with setTextDatum() to position values on TFT, and setTextPadding() to blank old displayed values
  109. drawFloat(float floatNumber, uint8_t decimal, int32_t x, int32_t y, uint8_t font), // Draw float using specified font number
  110. drawFloat(float floatNumber, uint8_t decimal, int32_t x, int32_t y), // Draw float using current font
  111. // Handle char arrays
  112. // Use with setTextDatum() to position string on TFT, and setTextPadding() to blank old displayed strings
  113. drawString(const char *string, int32_t x, int32_t y, uint8_t font), // Draw string using specifed font number
  114. drawString(const char *string, int32_t x, int32_t y), // Draw string using current font
  115. drawString(const String &string, int32_t x, int32_t y, uint8_t font),// Draw string using specifed font number
  116. drawString(const String &string, int32_t x, int32_t y), // Draw string using current font
  117. drawCentreString(const char *string, int32_t x, int32_t y, uint8_t font), // Deprecated, use setTextDatum() and drawString()
  118. drawRightString(const char *string, int32_t x, int32_t y, uint8_t font), // Deprecated, use setTextDatum() and drawString()
  119. drawCentreString(const String &string, int32_t x, int32_t y, uint8_t font),// Deprecated, use setTextDatum() and drawString()
  120. drawRightString(const String &string, int32_t x, int32_t y, uint8_t font); // Deprecated, use setTextDatum() and drawString()
  121. // Text rendering and font handling support funtions
  122. void setCursor(int16_t x, int16_t y), // Set cursor for tft.print()
  123. setCursor(int16_t x, int16_t y, uint8_t font); // Set cursor and font number for tft.print()
  124. int16_t getCursorX(void), // Read current cursor x position (moves with tft.print())
  125. getCursorY(void); // Read current cursor y position
  126. void setTextColor(uint16_t color), // Set character (glyph) color only (background not over-written)
  127. setTextColor(uint16_t fgcolor, uint16_t bgcolor),// Set character (glyph) foreground and backgorund colour
  128. setTextSize(uint8_t size); // Set character size multiplier (this increases pixel size)
  129. void setTextWrap(bool wrapX, bool wrapY = false); // Turn on/off wrapping of text in TFT width and/or height
  130. void setTextDatum(uint8_t datum); // Set text datum position (default is top left), see Section 6 above
  131. uint8_t getTextDatum(void);
  132. void setTextPadding(uint16_t x_width); // Set text padding (background blanking/over-write) width in pixels
  133. uint16_t getTextPadding(void); // Get text padding
  134. #ifdef LOAD_GFXFF
  135. void setFreeFont(const GFXfont *f = NULL), // Select the GFX Free Font
  136. setTextFont(uint8_t font); // Set the font number to use in future
  137. #else
  138. void setFreeFont(uint8_t font), // Not used, historical fix to prevent an error
  139. setTextFont(uint8_t font); // Set the font number to use in future
  140. #endif
  141. int16_t textWidth(const char *string, uint8_t font), // Returns pixel width of string in specified font
  142. textWidth(const char *string), // Returns pixel width of string in current font
  143. textWidth(const String &string, uint8_t font), // As above for String types
  144. textWidth(const String &string),
  145. fontHeight(int16_t font), // Returns pixel height of string in specified font
  146. fontHeight(void); // Returns pixel width of string in current font
  147. // Used by library and Smooth font class to extract Unicode point codes from a UTF8 encoded string
  148. uint16_t decodeUTF8(uint8_t *buf, uint16_t *index, uint16_t remaining),
  149. decodeUTF8(uint8_t c);
  150. // Support function to UTF8 decode and draw characters piped through print stream
  151. size_t write(uint8_t);
  152. // Used by Smooth font class to fetch a pixel colour for the anti-aliasing
  153. void setCallback(getColorCallback getCol);
  154. uint16_t fontsLoaded(void); // Each bit in returned value represents a font type that is loaded - used for debug/error handling only
  155. // Low level read/write
  156. void spiwrite(uint8_t); // legacy support only
  157. void writecommand(uint8_t c), // Send a command, function resets DC/RS high ready for data
  158. writedata(uint8_t d); // Send data with DC/RS set high
  159. void commandList(const uint8_t *addr); // Send a initialisation sequence to TFT stored in FLASH
  160. uint8_t readcommand8( uint8_t cmd_function, uint8_t index = 0); // read 8 bits from TFT
  161. uint16_t readcommand16(uint8_t cmd_function, uint8_t index = 0); // read 16 bits from TFT
  162. uint32_t readcommand32(uint8_t cmd_function, uint8_t index = 0); // read 32 bits from TFT
  163. // Colour conversion
  164. // Convert 8 bit red, green and blue to 16 bits
  165. uint16_t color565(uint8_t red, uint8_t green, uint8_t blue);
  166. // Convert 8 bit colour to 16 bits
  167. uint16_t color8to16(uint8_t color332);
  168. // Convert 16 bit colour to 8 bits
  169. uint8_t color16to8(uint16_t color565);
  170. // Convert 16 bit colour to/from 24 bit, R+G+B concatenated into LS 24 bits
  171. uint32_t color16to24(uint16_t color565);
  172. uint32_t color24to16(uint32_t color888);
  173. // Alpha blend 2 colours, see generic "alphaBlend_Test" example
  174. // alpha = 0 = 100% background colour
  175. // alpha = 255 = 100% foreground colour
  176. uint16_t alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc);
  177. // 16 bit colour alphaBlend with alpha dither (dither reduces colour banding)
  178. uint16_t alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc, uint8_t dither);
  179. // 24 bit colour alphaBlend with optional alpha dither
  180. uint32_t alphaBlend24(uint8_t alpha, uint32_t fgc, uint32_t bgc, uint8_t dither = 0);
  181. // DMA support functions - these are currently just for SPI writes whe using the STM32 processors
  182. // Bear in mind DMA will only be of benefit in particular circumstances and can be tricky
  183. // to manage by noobs. The functions have however been designed to be noob friendly and
  184. // avoid a few DMA behaviour "gotchas".
  185. //
  186. // At best you will get a 2x TFT rendering performance improvement when using DMA because
  187. // this library handles the SPI bus so efficiently during normal (non DMA) transfers. The best
  188. // performance improvement scenario is the DMA transfer time is exactly the same as the time it
  189. // takes for the processor to prepare the next image buffer and initiate another DMA transfer.
  190. //
  191. // DMA transfer to the TFT is done while the processor moves on to handle other tasks. Bear
  192. // this in mind and watch out for "gotchas" like the image buffer going out of scope as the
  193. // processor leaves a function or its content being changed while the DMA engine is reading it.
  194. //
  195. // The compiler MAY change the implied scope of a buffer which has been set aside by creating
  196. // and an array. For example a buffer defined before a "for-next" loop may get de-allocated when
  197. // the loop ends. To avoid this use, for example, malloc() and free() to take control of when
  198. // the buffer space is available and ensure it is not released until DMA is complete.
  199. //
  200. // Clearly you should not modify a buffer that is being DMA'ed to the TFT until the DMA is over.
  201. // Use the dmaBusy() function to check this. Use tft.startWrite() before invoking DMA so the
  202. // TFT chip select stays low. If you use tft.endWrite() before DMA is complete then the endWrite
  203. // function will wait for the DMA to complete, so this may defeat any DMA performance benefit.
  204. //
  205. bool initDMA(void); // Initialise the DMA engine and attach to SPI bus - typically used in setup()
  206. void deInitDMA(void); // De-initialise the DMA engine and detach from SPI bus - typically not used
  207. // Push an image to the TFT using DMA, buffer is optional and grabs (double buffers) a copy of the image
  208. // Use the buffer if the image data will get over-written or destroyed while DMA is in progress
  209. // If swapping colour bytes is defined, and the double buffer option is NOT used then the bytes
  210. // in the original data image will be swapped by the function before DMA is initiated.
  211. // The function will wait for the last DMA to complete if it is called while a previous DMA is still
  212. // in progress, this simplifies the sketch and helps avoid "gotchas".
  213. void pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data, uint16_t *buffer = nullptr);
  214. // Push a block of pixels into a window set up using setAddrWindow()
  215. void pushPixelsDMA(uint16_t *image, uint32_t len);
  216. // Check if the DMA is complete - use while(tft.dmaBusy); for a blocking wait
  217. bool dmaBusy(void); // returns true if DMA is still in progress
  218. void dmaWait(void); // wait until DMA is complete
  219. bool DMA_Enabled = false; // Flag for DMA enabled state
  220. uint8_t spiBusyCheck = 0; // Number of ESP32 transfer buffers to check
  221. // Bare metal functions
  222. void startWrite(void); // Begin SPI transaction
  223. void writeColor(uint16_t color, uint32_t len); // Deprecated, use pushBlock()
  224. void endWrite(void); // End SPI transaction
  225. // Set/get an arbitrary library configuration attribute or option
  226. // Use to switch ON/OFF capabilities such as UTF8 decoding - each attribute has a unique ID
  227. // id = 0: reserved - may be used in fuuture to reset all attributes to a default state
  228. // id = 1: Turn on (a=true) or off (a=false) GLCD cp437 font character error correction
  229. // id = 2: Turn on (a=true) or off (a=false) UTF8 decoding
  230. // id = 3: Enable or disable use of ESP32 PSRAM (if available)
  231. #define CP437_SWITCH 1
  232. #define UTF8_SWITCH 2
  233. #define PSRAM_ENABLE 3
  234. void setAttribute(uint8_t id = 0, uint8_t a = 0); // Set attribute value
  235. uint8_t getAttribute(uint8_t id = 0); // Get attribute value
  236. // Used for diagnostic sketch to see library setup adopted by compiler, see Section 7 above
  237. void getSetup(setup_t &tft_settings); // Sketch provides the instance to populate
  238. // Global variables
  239. static SPIClass &getSPIinstance(void); // Get SPI class handle
  240. int32_t cursor_x, cursor_y, padX; // Text cursor x,y and padding setting
  241. uint32_t textcolor, textbgcolor; // Text foreground and background colours
  242. uint32_t bitmap_fg, bitmap_bg; // Bitmap foreground (bit=1) and background (bit=0) colours
  243. uint8_t textfont, // Current selected font number
  244. textsize, // Current font size multiplier
  245. textdatum, // Text reference datum
  246. rotation; // Display rotation (0-3)
  247. int16_t _xpivot; // TFT x pivot point coordinate for rotated Sprites
  248. int16_t _ypivot; // TFT x pivot point coordinate for rotated Sprites
  249. uint8_t decoderState = 0; // UTF8 decoder state - not for user access
  250. uint16_t decoderBuffer; // Unicode code-point buffer - not for user access