Quantum Painter
Quantum Painter is the standardised API for graphical displays. It currently includes support for basic drawing primitives, as well as custom images, animations, and fonts.
Due to the complexity, there is no support for Quantum Painter on AVR-based boards.
To enable overall Quantum Painter to be built into your firmware, add the following to rules.mk
:
QUANTUM_PAINTER_ENABLE = yes
QUANTUM_PAINTER_DRIVERS += ......
You will also likely need to select an appropriate driver in rules.mk
, which is listed below.
WARNING
Quantum Painter is not currently integrated with system-level operations such as when the keyboard goes into suspend. Users will need to handle this manually at the current time.
The QMK CLI can be used to convert from normal images such as PNG files or animated GIFs, as well as fonts from TTF files.
Supported devices:
Display Panel | Panel Type | Size | Comms Transport | Driver |
---|---|---|---|---|
GC9A01 | RGB LCD (circular) | 240x240 | SPI + D/C + RST | QUANTUM_PAINTER_DRIVERS += gc9a01_spi |
ILI9163 | RGB LCD | 128x128 | SPI + D/C + RST | QUANTUM_PAINTER_DRIVERS += ili9163_spi |
ILI9341 | RGB LCD | 240x320 | SPI + D/C + RST | QUANTUM_PAINTER_DRIVERS += ili9341_spi |
ILI9486 | RGB LCD | 320x480 | SPI + D/C + RST | QUANTUM_PAINTER_DRIVERS += ili9486_spi |
ILI9488 | RGB LCD | 320x480 | SPI + D/C + RST | QUANTUM_PAINTER_DRIVERS += ili9488_spi |
LD7032 (SPI) | Monochrome OLED | 128x40 | SPI + D/C + RST | QUANTUM_PAINTER_DRIVERS += ld7032_spi |
LD7032 (I2C) | Monochrome OLED | 128x40 | I2C | QUANTUM_PAINTER_DRIVERS += ld7032_i2c |
SSD1351 | RGB OLED | 128x128 | SPI + D/C + RST | QUANTUM_PAINTER_DRIVERS += ssd1351_spi |
ST7735 | RGB LCD | 132x162, 80x160 | SPI + D/C + RST | QUANTUM_PAINTER_DRIVERS += st7735_spi |
ST7789 | RGB LCD | 240x320, 240x240 | SPI + D/C + RST | QUANTUM_PAINTER_DRIVERS += st7789_spi |
SH1106 (SPI) | Monochrome OLED | 128x64 | SPI + D/C + RST | QUANTUM_PAINTER_DRIVERS += sh1106_spi |
SH1106 (I2C) | Monochrome OLED | 128x64 | I2C | QUANTUM_PAINTER_DRIVERS += sh1106_i2c |
SSD1306 (SPI) | Monochrome OLED | 128x64 | SPI + D/C + RST | QUANTUM_PAINTER_DRIVERS += sh1106_spi |
SSD1306 (I2C) | Monochrome OLED | 128x32 | I2C | QUANTUM_PAINTER_DRIVERS += sh1106_i2c |
Surface | Virtual | User-defined | None | QUANTUM_PAINTER_DRIVERS += surface |
Quantum Painter Configuration
Option | Default | Purpose |
---|---|---|
QUANTUM_PAINTER_DISPLAY_TIMEOUT | 30000 | This controls the amount of time (in milliseconds) that all displays will remain on after the last user input. If set to 0 , the display will remain on indefinitely. |
QUANTUM_PAINTER_TASK_THROTTLE | 1 | This controls the amount of time (in milliseconds) that the Quantum Painter internal task will wait between each execution. Affects animations, display timeout, and LVGL timing if enabled. |
QUANTUM_PAINTER_NUM_IMAGES | 8 | The maximum number of images/animations that can be loaded at any one time. |
QUANTUM_PAINTER_NUM_FONTS | 4 | The maximum number of fonts that can be loaded at any one time. |
QUANTUM_PAINTER_CONCURRENT_ANIMATIONS | 4 | The maximum number of animations that can be executed at the same time. |
QUANTUM_PAINTER_LOAD_FONTS_TO_RAM | FALSE | Whether or not fonts should be loaded to RAM. Relevant for fonts stored in off-chip persistent storage, such as external flash. |
QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE | 1024 | The limit of the amount of pixel data that can be transmitted in one transaction to the display. Higher values require more RAM on the MCU. |
QUANTUM_PAINTER_SUPPORTS_256_PALETTE | FALSE | If 256-color palettes are supported. Requires significantly more RAM on the MCU. |
QUANTUM_PAINTER_SUPPORTS_NATIVE_COLORS | FALSE | If native color range is supported. Requires significantly more RAM on the MCU. |
QUANTUM_PAINTER_DEBUG | unset | Prints out significant amounts of debugging information to CONSOLE output. Significant performance degradation, use only for debugging. |
QUANTUM_PAINTER_DEBUG_ENABLE_FLUSH_TASK_OUTPUT | unset | By default, debug output is disabled while the internal task is flushing the display(s). If you want to keep it enabled, add this to your config.h . Note: Console will get clogged. |
Drivers have their own set of configurable options, and are described in their respective sections.
Quantum Painter CLI Commands
This command converts images to a format usable by QMK, i.e. the QGF File Format.
Usage:
usage: qmk painter-convert-graphics [-h] [-w] [-d] [-r] -f FORMAT [-o OUTPUT] -i INPUT [-v]
options:
-h, --help show this help message and exit
-w, --raw Writes out the QGF file as raw data instead of c/h combo.
-d, --no-deltas Disables the use of delta frames when encoding animations.
-r, --no-rle Disables the use of RLE when encoding images.
-f FORMAT, --format FORMAT
Output format, valid types: rgb888, rgb565, pal256, pal16, pal4, pal2, mono256, mono16, mono4, mono2
-o OUTPUT, --output OUTPUT
Specify output directory. Defaults to same directory as input.
-i INPUT, --input INPUT
Specify input graphic file.
-v, --verbose Turns on verbose output.
The INPUT
argument can be any image file loadable by Python's Pillow module. Common formats include PNG, or Animated GIF.
The OUTPUT
argument needs to be a directory, and will default to the same directory as the input argument.
The FORMAT
argument can be any of the following:
Format | Meaning |
---|---|
rgb888 | 16,777,216 colors in 8-8-8 RGB format (requires QUANTUM_PAINTER_SUPPORTS_NATIVE_COLORS ) |
rgb565 | 65,536 colors in 5-6-5 RGB format (requires QUANTUM_PAINTER_SUPPORTS_NATIVE_COLORS ) |
pal256 | 256-color palette (requires QUANTUM_PAINTER_SUPPORTS_256_PALETTE ) |
pal16 | 16-color palette |
pal4 | 4-color palette |
pal2 | 2-color palette |
mono256 | 256-shade grayscale (requires QUANTUM_PAINTER_SUPPORTS_256_PALETTE ) |
mono16 | 16-shade grayscale |
mono4 | 4-shade grayscale |
mono2 | 2-shade grayscale |
Examples:
$ cd /home/qmk/qmk_firmware/keyboards/my_keeb
$ qmk painter-convert-graphics -f mono16 -i my_image.gif -o ./generated/
Writing /home/qmk/qmk_firmware/keyboards/my_keeb/generated/my_image.qgf.h...
Writing /home/qmk/qmk_firmware/keyboards/my_keeb/generated/my_image.qgf.c...
Quantum Painter Display Drivers
Most TFT display panels use a 5-pin interface -- SPI SCK, SPI MOSI, SPI CS, D/C, and RST pins.
For these displays, QMK's spi_master
must already be correctly configured for the platform you're building for.
The pin assignments for SPI CS, D/C, and RST are specified during device construction.
Enabling support for the GC9A01 in Quantum Painter is done by adding the following to rules.mk
:
QUANTUM_PAINTER_ENABLE = yes
QUANTUM_PAINTER_DRIVERS += gc9a01_spi
Creating a GC9A01 device in firmware can then be done with the following API:
painter_device_t qp_gc9a01_make_spi_device(uint16_t panel_width, uint16_t panel_height, pin_t chip_select_pin, pin_t dc_pin, pin_t reset_pin, uint16_t spi_divisor, int spi_mode);
The device handle returned from the qp_gc9a01_make_spi_device
function can be used to perform all other drawing operations.
The maximum number of displays can be configured by changing the following in your config.h
(default is 1):
// 3 displays:
#define GC9A01_NUM_DEVICES 3
Native color format rgb565 is compatible with GC9A01
Quantum Painter Drawing API
All APIs require a painter_device_t
object as their first parameter -- this object comes from the specific device initialisation, and instructions on creating it can be found in each driver's respective section.
To use any of the APIs, you need to include qp.h
:
#include <qp.h>
The coordinate system used in Quantum Painter generally accepts left
, top
, right
, and bottom
instead of x/y/width/height, and each coordinate is inclusive of where pixels should be drawn. This is required as some datatypes used by display panels have a maximum value of 255
-- for any value or geometry extent that matches 256
, this would be represented as a 0
, instead.
TIP
Drawing a horizontal line 8 pixels long, starting from 4 pixels inside the left side of the display, will need left=4
, right=11
.
All color data matches the standard QMK HSV triplet definitions:
- Hue is of the range
0...255
and is internally mapped to 0...360 degrees. - Saturation is of the range
0...255
and is internally mapped to 0...100% saturation. - Value is of the range
0...255
and is internally mapped to 0...100% brightness.
TIP
Colors used in Quantum Painter are not subject to the RGB lighting CIE curve, if it is enabled.