# Quantum Painter | QMK Firmware
Documentation for QMK Firmware

Skip to content

# 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`:

make

    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`:

make

    QUANTUM_PAINTER_ENABLE = yes
    QUANTUM_PAINTER_DRIVERS += gc9a01_spi

Creating a GC9A01 device in firmware can then be done with the following API:

c

    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):

c

    // 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`:

c

    #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.