twali_screen.cpp 19 KB

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