qp.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. // Copyright 2021 Nick Brassel (@tzarc)
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <stdint.h>
  5. #include <stdbool.h>
  6. #include "deferred_exec.h"
  7. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8. // Quantum Painter global configurables (add to your keyboard's config.h)
  9. #ifndef QUANTUM_PAINTER_NUM_IMAGES
  10. /**
  11. * @def This controls the maximum number of images that Quantum Painter can load at any one time. Images can be loaded
  12. * using \ref qp_load_image_mem, and can be unloaded by calling \ref qp_close_image. Increasing this number in
  13. * order to load more images increases the amount of RAM required. Image data is not held in RAM, just metadata.
  14. */
  15. # define QUANTUM_PAINTER_NUM_IMAGES 8
  16. #endif // QUANTUM_PAINTER_NUM_IMAGES
  17. #ifndef QUANTUM_PAINTER_NUM_FONTS
  18. /**
  19. * @def This controls the maximum number of fonts that Quantum Painter can load. Fonts can be loaded using
  20. * \ref qp_load_font_mem, and can be unloaded by calling \ref qp_close_font. Increasing this number in order to
  21. * load more fonts increases the amount of RAM required. Font data is not held in RAM, unless
  22. * \ref QUANTUM_PAINTER_LOAD_FONTS_TO_RAM is set to TRUE.
  23. */
  24. # define QUANTUM_PAINTER_NUM_FONTS 4
  25. #endif // QUANTUM_PAINTER_NUM_FONTS
  26. #ifndef QUANTUM_PAINTER_LOAD_FONTS_TO_RAM
  27. /**
  28. * @def This controls whether or not fonts should be cached in RAM. Under normal circumstances, fonts can have quite
  29. * random access patterns, and due to timing of flash memory or external storage, it may be a significant speedup
  30. * moving the font into RAM before use. Defaults to "off", but if it's enabled it will fallback to reading from the
  31. * original location if corresponding RAM could not be allocated (such as being too large).
  32. */
  33. # define QUANTUM_PAINTER_LOAD_FONTS_TO_RAM FALSE
  34. #endif
  35. #ifndef QUANTUM_PAINTER_CONCURRENT_ANIMATIONS
  36. /**
  37. * @def This controls the maximum number of animations that Quantum Painter can play simultaneously. Increasing this
  38. * number in order to play more animations at the same time increases the amount of RAM required.
  39. */
  40. # define QUANTUM_PAINTER_CONCURRENT_ANIMATIONS 4
  41. #endif // QUANTUM_PAINTER_CONCURRENT_ANIMATIONS
  42. #ifndef QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE
  43. /**
  44. * @def This controls the maximum size of the pixel data buffer used for single blocks of transmission. Larger buffers
  45. * means more data is processed at one time, with less frequent transmissions, at the cost of RAM.
  46. */
  47. # define QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE 32
  48. #endif
  49. #ifndef QUANTUM_PAINTER_SUPPORTS_256_PALETTE
  50. /**
  51. * @def This controls whether 256-color palettes are supported. This has relatively hefty requirements on RAM -- at
  52. * least 1kB extra is required just to store the palette information, with more required for other metadata.
  53. */
  54. # define QUANTUM_PAINTER_SUPPORTS_256_PALETTE FALSE
  55. #endif
  56. #ifndef QUANTUM_PAINTER_SUPPORTS_NATIVE_COLORS
  57. /**
  58. * @def This controls whether the native color range is supported. This avoids the use of palettes but each image
  59. * requires more storage space.
  60. */
  61. # define QUANTUM_PAINTER_SUPPORTS_NATIVE_COLORS FALSE
  62. #endif
  63. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  64. // Quantum Painter types
  65. /**
  66. * @typedef A handle to a Quantum Painter device, such as an LCD or OLED. Most Quantum Painter APIs require this
  67. * argument in order to perform operations on the display.
  68. */
  69. typedef const void *painter_device_t;
  70. /**
  71. * @typedef The desired rotation of a panel. Used as a parameter to \ref qp_init, and can be queried by
  72. * \ref qp_get_geometry.
  73. */
  74. typedef enum { QP_ROTATION_0, QP_ROTATION_90, QP_ROTATION_180, QP_ROTATION_270 } painter_rotation_t;
  75. /**
  76. * @typedef A descriptor for a Quantum Painter image.
  77. */
  78. typedef struct painter_image_desc_t {
  79. uint16_t width; ///< Image width
  80. uint16_t height; ///< Image height
  81. uint16_t frame_count; ///< Number of frames in this image
  82. } painter_image_desc_t;
  83. /**
  84. * @typedef A handle to a Quantum Painter image.
  85. */
  86. typedef const painter_image_desc_t *painter_image_handle_t;
  87. /**
  88. * @typedef A descriptor for a Quantum Painter font.
  89. */
  90. typedef struct painter_font_desc_t {
  91. uint8_t line_height; ///< The number of pixels in height for each line
  92. } painter_font_desc_t;
  93. /**
  94. * @typedef A handle to a Quantum Painter font.
  95. */
  96. typedef const painter_font_desc_t *painter_font_handle_t;
  97. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  98. // Quantum Painter External API
  99. /**
  100. * Initialize a device and set its rotation.
  101. *
  102. * @param device[in] the handle of the device to initialize
  103. * @param rotation[in] the rotation to use
  104. * @return true if initialization succeeded
  105. * @return false if initialization failed
  106. */
  107. bool qp_init(painter_device_t device, painter_rotation_t rotation);
  108. /**
  109. * Controls whether a display is on or off.
  110. *
  111. * @note If backlighting is used to control brightness (such as for an LCD), it will need to be handled external to
  112. * Quantum Painter.
  113. *
  114. * @param device[in] the handle of the device to control
  115. * @param power_on[in] whether or not the device should be on
  116. * @return true if controlling the power state succeeded
  117. * @return false if controlling the power state failed
  118. */
  119. bool qp_power(painter_device_t device, bool power_on);
  120. /**
  121. * Clears a device's screen.
  122. *
  123. * @param device[in] the handle of the device to control
  124. * @return true if clearing the screen succeeded
  125. * @return false if clearing the screen failed
  126. */
  127. bool qp_clear(painter_device_t device);
  128. /**
  129. * Transmits any outstanding data to the screen in order to persist all changes to the display.
  130. *
  131. * @note Drivers without internal framebuffers will likely ignore this API.
  132. *
  133. * @param device[in] the handle of the device to control
  134. * @return true if flushing changes to the screen succeeded
  135. * @return false if flushing changes to the screen failed
  136. */
  137. bool qp_flush(painter_device_t device);
  138. /**
  139. * Retrieves the size, rotation, and offsets for the display.
  140. *
  141. * @note Any arguments of NULL will be ignored.
  142. *
  143. * @param device[in] the handle of the device to control
  144. * @param width[out] the device's width
  145. * @param height[out] the device's height
  146. * @param rotation[out] the device's rotation
  147. * @param offset_x[out] the device's x-offset applied while drawing
  148. * @param offset_y[out] the device's y-offset applied while drawing
  149. */
  150. void qp_get_geometry(painter_device_t device, uint16_t *width, uint16_t *height, painter_rotation_t *rotation, uint16_t *offset_x, uint16_t *offset_y);
  151. /**
  152. * Allows repositioning of the viewport if the panel geometry offsets are non-zero.
  153. *
  154. * @param device[in] the handle of the device to control
  155. * @param offset_x[in] the device's x-offset applied while drawing
  156. * @param offset_y[in] the device's y-offset applied while drawing
  157. */
  158. void qp_set_viewport_offsets(painter_device_t device, uint16_t offset_x, uint16_t offset_y);
  159. /**
  160. * Sets a pixel to the specified color.
  161. *
  162. * @param device[in] the handle of the device to control
  163. * @param x[in] the x-position to draw onto the device
  164. * @param y[in] the y-position to draw onto the device
  165. * @param hue[in] the hue to use, with 0-360 mapped to 0-255
  166. * @param sat[in] the saturation to use, with 0-100% mapped to 0-255
  167. * @param val[in] the value to use, with 0-100% mapped to 0-255
  168. * @return true if setting the pixel succeeded
  169. * @return false if setting the pixel failed
  170. */
  171. bool qp_setpixel(painter_device_t device, uint16_t x, uint16_t y, uint8_t hue, uint8_t sat, uint8_t val);
  172. /**
  173. * Draws a line using the specified color.
  174. *
  175. * @param device[in] the handle of the device to control
  176. * @param x0[in] the device's x-position to start
  177. * @param y0[in] the device's y-position to start
  178. * @param x1[in] the device's x-position to finish
  179. * @param y1[in] the device's y-position to finish
  180. * @param hue[in] the hue to use, with 0-360 mapped to 0-255
  181. * @param sat[in] the saturation to use, with 0-100% mapped to 0-255
  182. * @param val[in] the value to use, with 0-100% mapped to 0-255
  183. * @return true if drawing the line succeeded
  184. * @return false if drawing the line failed
  185. */
  186. bool qp_line(painter_device_t device, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t hue, uint8_t sat, uint8_t val);
  187. /**
  188. * Draws a rectangle using the specified color, optionally filled.
  189. *
  190. * @param device[in] the handle of the device to control
  191. * @param left[in] the device's x-position to start
  192. * @param top[in] the device's y-position to start
  193. * @param right[in] the device's x-position to finish
  194. * @param bottom[in] the device's y-position to finish
  195. * @param hue[in] the hue to use, with 0-360 mapped to 0-255
  196. * @param sat[in] the saturation to use, with 0-100% mapped to 0-255
  197. * @param val[in] the value to use, with 0-100% mapped to 0-255
  198. * @param filled[in] whether the rectangle should be filled
  199. * @return true if drawing the rectangle succeeded
  200. * @return false if drawing the rectangle failed
  201. */
  202. bool qp_rect(painter_device_t device, uint16_t left, uint16_t top, uint16_t right, uint16_t bottom, uint8_t hue, uint8_t sat, uint8_t val, bool filled);
  203. /**
  204. * Draws a circle using the specified color, optionally filled.
  205. *
  206. * @param device[in] the handle of the device to control
  207. * @param x[in] the x-position of the centre of the circle to draw onto the device
  208. * @param y[in] the y-position of the centre of the circle to draw onto the device
  209. * @param radius[in] the radius of the circle to draw
  210. * @param hue[in] the hue to use, with 0-360 mapped to 0-255
  211. * @param sat[in] the saturation to use, with 0-100% mapped to 0-255
  212. * @param val[in] the value to use, with 0-100% mapped to 0-255
  213. * @param filled[in] whether the circle should be filled
  214. * @return true if drawing the circle succeeded
  215. * @return false if drawing the circle failed
  216. */
  217. bool qp_circle(painter_device_t device, uint16_t x, uint16_t y, uint16_t radius, uint8_t hue, uint8_t sat, uint8_t val, bool filled);
  218. /**
  219. * Draws a ellipse using the specified color, optionally filled.
  220. *
  221. * @param device[in] the handle of the device to control
  222. * @param x[in] the x-position of the centre of the ellipse to draw onto the device
  223. * @param y[in] the y-position of the centre of the ellipse to draw onto the device
  224. * @param sizex[in] the horizontal size of the ellipse
  225. * @param sizey[in] the vertical size of the ellipse
  226. * @param hue[in] the hue to use, with 0-360 mapped to 0-255
  227. * @param sat[in] the saturation to use, with 0-100% mapped to 0-255
  228. * @param val[in] the value to use, with 0-100% mapped to 0-255
  229. * @param filled[in] whether the ellipse should be filled
  230. * @return true if drawing the ellipse succeeded
  231. * @return false if drawing the ellipse failed
  232. */
  233. bool qp_ellipse(painter_device_t device, uint16_t x, uint16_t y, uint16_t sizex, uint16_t sizey, uint8_t hue, uint8_t sat, uint8_t val, bool filled);
  234. /**
  235. * Sets up the location on the display to stream raw pixel data to the display, using \ref qp_pixdata.
  236. *
  237. * @note This is for advanced uses only, and should not be required for normal Quantum Painter functionality.
  238. *
  239. * @param device[in] the handle of the device to control
  240. * @param left[in] the device's x-position to start
  241. * @param top[in] the device's y-position to start
  242. * @param right[in] the device's x-position to finish
  243. * @param bottom[in] the device's y-position to finish
  244. * @return true if setting the viewport succeeded
  245. * @return false if setting the viewport failed
  246. */
  247. bool qp_viewport(painter_device_t device, uint16_t left, uint16_t top, uint16_t right, uint16_t bottom);
  248. /**
  249. * Streams raw pixel data (in the native panel format) to the area previously set by \ref qp_viewport.
  250. *
  251. * @note This is for advanced uses only, and should not be required for normal Quantum Painter functionality.
  252. *
  253. * @param device[in] the handle of the device to control
  254. * @param pixel_data[in] pointer to buffer data
  255. * @param native_pixel_count[in] the number of pixels to transmit
  256. * @return true if streaming of data succeeded
  257. * @return false if streaming of data failed
  258. */
  259. bool qp_pixdata(painter_device_t device, const void *pixel_data, uint32_t native_pixel_count);
  260. /**
  261. * Loads an image into memory.
  262. *
  263. * @note Images can be unloaded by calling \ref qp_close_image.
  264. *
  265. * @param buffer[in] the image data to load
  266. * @return an image handle usable with \ref qp_drawimage, \ref qp_drawimage_recolor, \ref qp_animate, and
  267. * \ref qp_animate_recolor.
  268. * @return NULL if loading the image failed
  269. */
  270. painter_image_handle_t qp_load_image_mem(const void *buffer);
  271. /**
  272. * Closes an image handle when no longer in use.
  273. *
  274. * @param image[in] the handle of the image to unload
  275. * @return true if unloading the image succeeded
  276. * @return false if unloading the image failed
  277. */
  278. bool qp_close_image(painter_image_handle_t image);
  279. /**
  280. * Draws an image to the display.
  281. *
  282. * @param device[in] the handle of the device to control
  283. * @param x[in] the x-position where the image should be drawn onto the device
  284. * @param y[in] the y-position where the image should be drawn onto the device
  285. * @param image[in] the handle of the image to draw
  286. * @return true if drawing the image succeeded
  287. * @return false if drawing the image failed
  288. */
  289. bool qp_drawimage(painter_device_t device, uint16_t x, uint16_t y, painter_image_handle_t image);
  290. /**
  291. * Draws an image to the display, recoloring monochrome images to the desired foreground/background.
  292. *
  293. * @param device[in] the handle of the device to control
  294. * @param x[in] the x-position where the image should be drawn onto the device
  295. * @param y[in] the y-position where the image should be drawn onto the device
  296. * @param image[in] the handle of the image to draw
  297. * @param hue_fg[in] the foreground hue to use, with 0-360 mapped to 0-255
  298. * @param sat_fg[in] the foreground saturation to use, with 0-100% mapped to 0-255
  299. * @param val_fg[in] the foreground value to use, with 0-100% mapped to 0-255
  300. * @param hue_bg[in] the background hue to use, with 0-360 mapped to 0-255
  301. * @param sat_bg[in] the background saturation to use, with 0-100% mapped to 0-255
  302. * @param val_bg[in] the background value to use, with 0-100% mapped to 0-255
  303. * @return true if drawing the image succeeded
  304. * @return false if drawing the image failed
  305. */
  306. bool qp_drawimage_recolor(painter_device_t device, uint16_t x, uint16_t y, painter_image_handle_t image, uint8_t hue_fg, uint8_t sat_fg, uint8_t val_fg, uint8_t hue_bg, uint8_t sat_bg, uint8_t val_bg);
  307. /**
  308. * Draws an animation to the display.
  309. *
  310. * @param device[in] the handle of the device to control
  311. * @param x[in] the x-position where the image should be drawn onto the device
  312. * @param y[in] the y-position where the image should be drawn onto the device
  313. * @param image[in] the handle of the image to draw
  314. * @return the \ref deferred_token to use with \ref qp_stop_animation in order to stop animating
  315. * @return INVALID_DEFERRED_TOKEN if animating the image failed
  316. */
  317. deferred_token qp_animate(painter_device_t device, uint16_t x, uint16_t y, painter_image_handle_t image);
  318. /**
  319. * Draws an animation to the display, recoloring monochrome images to the desired foreground/background.
  320. *
  321. * @param device[in] the handle of the device to control
  322. * @param x[in] the x-position where the image should be drawn onto the device
  323. * @param y[in] the y-position where the image should be drawn onto the device
  324. * @param image[in] the handle of the image to draw
  325. * @param hue_fg[in] the foreground hue to use, with 0-360 mapped to 0-255
  326. * @param sat_fg[in] the foreground saturation to use, with 0-100% mapped to 0-255
  327. * @param val_fg[in] the foreground value to use, with 0-100% mapped to 0-255
  328. * @param hue_bg[in] the background hue to use, with 0-360 mapped to 0-255
  329. * @param sat_bg[in] the background saturation to use, with 0-100% mapped to 0-255
  330. * @param val_bg[in] the background value to use, with 0-100% mapped to 0-255
  331. * @return the \ref deferred_token to use with \ref qp_stop_animation in order to stop animating
  332. * @return INVALID_DEFERRED_TOKEN if animating the image failed
  333. */
  334. deferred_token qp_animate_recolor(painter_device_t device, uint16_t x, uint16_t y, painter_image_handle_t image, uint8_t hue_fg, uint8_t sat_fg, uint8_t val_fg, uint8_t hue_bg, uint8_t sat_bg, uint8_t val_bg);
  335. /**
  336. * Cancels a running animation.
  337. *
  338. * @param anim_token[in] the animation token returned by \ref qp_animate, or \ref qp_animate_recolor.
  339. */
  340. void qp_stop_animation(deferred_token anim_token);
  341. /**
  342. * Loads a font into memory.
  343. *
  344. * @note Fonts can be unloaded by calling \ref qp_close_font.
  345. *
  346. * @param buffer[in] the font data to load
  347. * @return an image handle usable with \ref qp_textwidth, \ref qp_drawtext, and \ref qp_drawtext_recolor.
  348. * @return NULL if loading the font failed
  349. */
  350. painter_font_handle_t qp_load_font_mem(const void *buffer);
  351. /**
  352. * Closes a font handle when no longer in use.
  353. *
  354. * @param font[in] the handle of the font to unload
  355. * @return true if unloading the font succeeded
  356. * @return false if unloading the font failed
  357. */
  358. bool qp_close_font(painter_font_handle_t font);
  359. /**
  360. * Measures the width (in pixels) of the supplied string, given the specified font.
  361. *
  362. * @param font[in] the handle of the font
  363. * @param str[in] the string to measure
  364. * @return the width (in pixels) needed to draw the specified string
  365. */
  366. int16_t qp_textwidth(painter_font_handle_t font, const char *str);
  367. /**
  368. * Draws text to the display.
  369. *
  370. * @param device[in] the handle of the device to control
  371. * @param x[in] the x-position where the text should be drawn onto the device
  372. * @param y[in] the y-position where the text should be drawn onto the device
  373. * @param font[in] the handle of the font
  374. * @param str[in] the string to draw
  375. * @return the width (in pixels) used when drawing the specified string
  376. */
  377. int16_t qp_drawtext(painter_device_t device, uint16_t x, uint16_t y, painter_font_handle_t font, const char *str);
  378. /**
  379. * Draws text to the display, recoloring monochrome fonts to the desired foreground/background.
  380. *
  381. * @param device[in] the handle of the device to control
  382. * @param x[in] the x-position where the text should be drawn onto the device
  383. * @param y[in] the y-position where the text should be drawn onto the device
  384. * @param font[in] the handle of the font
  385. * @param str[in] the string to draw
  386. * @param hue_fg[in] the foreground hue to use, with 0-360 mapped to 0-255
  387. * @param sat_fg[in] the foreground saturation to use, with 0-100% mapped to 0-255
  388. * @param val_fg[in] the foreground value to use, with 0-100% mapped to 0-255
  389. * @param hue_bg[in] the background hue to use, with 0-360 mapped to 0-255
  390. * @param sat_bg[in] the background saturation to use, with 0-100% mapped to 0-255
  391. * @param val_bg[in] the background value to use, with 0-100% mapped to 0-255
  392. * @return the width (in pixels) used when drawing the specified string
  393. */
  394. int16_t qp_drawtext_recolor(painter_device_t device, uint16_t x, uint16_t y, painter_font_handle_t font, const char *str, uint8_t hue_fg, uint8_t sat_fg, uint8_t val_fg, uint8_t hue_bg, uint8_t sat_bg, uint8_t val_bg);
  395. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  396. // Quantum Painter Drivers
  397. #ifdef QUANTUM_PAINTER_RGB565_SURFACE_ENABLE
  398. # include "qp_rgb565_surface.h"
  399. #endif // QUANTUM_PAINTER_RGB565_SURFACE_ENABLE
  400. #ifdef QUANTUM_PAINTER_ILI9163_ENABLE
  401. # include "qp_ili9163.h"
  402. #endif // QUANTUM_PAINTER_ILI9163_ENABLE
  403. #ifdef QUANTUM_PAINTER_ILI9341_ENABLE
  404. # include "qp_ili9341.h"
  405. #endif // QUANTUM_PAINTER_ILI9341_ENABLE
  406. #ifdef QUANTUM_PAINTER_ILI9488_ENABLE
  407. # include "qp_ili9488.h"
  408. #endif // QUANTUM_PAINTER_ILI9488_ENABLE
  409. #ifdef QUANTUM_PAINTER_ST7789_ENABLE
  410. # include "qp_st7789.h"
  411. #endif // QUANTUM_PAINTER_ST7789_ENABLE
  412. #ifdef QUANTUM_PAINTER_ST7735_ENABLE
  413. # include "qp_st7735.h"
  414. #endif // QUANTUM_PAINTER_ST7735_ENABLE
  415. #ifdef QUANTUM_PAINTER_GC9A01_ENABLE
  416. # include "qp_gc9a01.h"
  417. #endif // QUANTUM_PAINTER_GC9A01_ENABLE
  418. #ifdef QUANTUM_PAINTER_SSD1351_ENABLE
  419. # include "qp_ssd1351.h"
  420. #endif // QUANTUM_PAINTER_SSD1351_ENABLE
  421. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  422. // Quantum Painter Extras
  423. #ifdef QUANTUM_PAINTER_LVGL_INTEGRATION_ENABLE
  424. # include "qp_lvgl.h"
  425. #endif // QUANTUM_PAINTER_LVGL_INTEGRATION_ENABLE