<divid="app"><divclass="Layout"data-v-5d98c3a5><!--[--><!--]--><!--[--><spantabindex="-1"data-v-0f60ec36></span><ahref="#VPContent"class="VPSkipLink visually-hidden"data-v-0f60ec36> Skip to content </a><!--]--><!----><headerclass="VPNav"data-v-5d98c3a5data-v-ae24b3ad><divclass="VPNavBar has-sidebar top"data-v-ae24b3addata-v-ccf7ddec><divclass="wrapper"data-v-ccf7ddec><divclass="container"data-v-ccf7ddec><divclass="title"data-v-ccf7ddec><divclass="VPNavBarTitle has-sidebar"data-v-ccf7ddecdata-v-ab179fa1><aclass="title"href="/"data-v-ab179fa1><!--[--><!--]--><!--[--><!--[--><!--[--><imgclass="VPImage dark logo"src="/qmk-logo-dark.svg"altdata-v-8426fc1a><!--]--><!--[--><imgclass="VPImage light logo"src="/qmk-logo-light.svg"altdata-v-8426fc1a><!--]--><!--]--><!--]--><spandata-v-ab179fa1>QMK Firmware</span><!--[--><!--]--></a></div></div><divclass="content"data-v-ccf7ddec><divclass="content-body"data-v-ccf7ddec><!--[--><!--]--><divclass="VPNavBarSearch search"data-v-ccf7ddec><!--[--><!----><divid="local-search"><buttontype="button"class="DocSearch DocSearch-Button"aria-label="Search"><spanclass="DocSearch-Button-Container"><spanclass="vp-icon DocSearch-Search-Icon"></span><spanclass="DocSearch-Button-Placeholder">Search</span></span><spanclass="DocSearch-Button-Keys"><kbdclass="DocSearch-Button-Key"></kbd><kbdclass="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><navaria-labelledby="main-nav-aria-label"class="VPNavBarMenu menu"data-v-ccf7ddecdata-v-7f418b0f><spanid="main-nav-aria-label"class="visually-hidden"data-v-7f418b0f>Main Navigation</span><!--[--><!--[--><aclass="VPLink link VPNavBarMenuLink"href="/"tabindex="0"data-v-7f418b0fdata-v-9c663999><!--[--><spandata-v-9c663999>Home</span><!--]--></a><!--]--><!--]--></nav><!----><divclass="VPNavBarAppearance appearance"data-v-ccf7ddecdata-v-e6aabb21><buttonclass="VPSwitch VPSwitchAppearance"type="button"role="switch"title="Switch to dark theme"aria-checked="false"data-v-e6aabb21data-v-d1f28634data-v-1d5665e3><spanclass="check"data-v-1d5665e3><spanclass="icon"data-v-1d5665e3><!--[--><spanclass="vpi-sun sun"data-v-d1f28634></span><spanclass="vpi-moon moon"data-v-d1f28634></span><!--]--></span></span></button></div><divclass="VPSocialLinks VPNavBarSocialLinks social-links"data-v-ccf7ddecdata-v-0394ad82data-v-7bc22406><!--[--><aclass="VPSocialLink no-icon"href="https://reddit.com/r/olkb"aria-labeltarget="_blank"rel="noopener"data-v-7bc22406data-v-eee4e7cb><svgxmlns="http://www.w3.org/2000/svg"viewBox="0 0 50 50"width="50px"height="50px"><pathd="M293C28.0625327.1640633.38281326.54C25.8359384.61718825.3632815.433594256.40625C24.3554698.14062524.08593810.39453124.0312513.03125C19.23437513.17968814.82031314.42187511.2812516.46875C10.21484415.468758.85546914.968757.514.96875C6.08984414.968754.67578115.5117193.5937516.59375C1.42578118.7617191.42578122.2382813.5937524.40625L3.8437524.65625C3.312526.035156327.488281329C333.5273445.56640637.5859389.562540.4375C13.55859443.28906319.007813452545C30.9921884536.44140643.28906340.437540.4375C44.43359437.5859384733.5273444729C4727.48828146.687526.03515646.1562524.65625L46.4062524.40625C48.57421922.23828148.57421918.76171946.4062516.59375C45.32421915.51171943.91015614.9687542.514.96875C41.14453114.9687539.78515615.4687538.7187516.46875C35.19531314.43359430.80078113.19140626.0312513.03125C26.0937510.54687526.3632818.4687526.8757.09375C27.1640636.31640627.5273445.75781327.8755.4375C28.2226565.11718828.5390635295C29.460938529.6835945.12530.031255.40625C30.3789065.687530.7851566.14843831.31256.6875C32.2539067.65234433.6953138.71484436.093758.9375C36.53906311.23828138.574219134113C43.75134610.75468C465.2543.753413C38.605469336.5742194.71093836.093756.96875C34.31256.79687533.5273446.10937532.755.3125C32.3007814.85156331.8867194
<spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">QUANTUM_PAINTER_DRIVERS += ......</span></span></code></pre></div><p>You will also likely need to select an appropriate driver in <code>rules.mk</code>, which is listed below.</p><divclass="warning custom-block"><pclass="custom-block-title">WARNING</p><p>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.</p></div><p>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.</p><p>Supported devices:</p><table><thead><tr><th>Display Panel</th><th>Panel Type</th><th>Size</th><th>Comms Transport</th><th>Driver</th></tr></thead><tbody><tr><td>GC9A01</td><td>RGB LCD (circular)</td><td>240x240</td><td>SPI + D/C + RST</td><td><code>QUANTUM_PAINTER_DRIVERS += gc9a01_spi</code></td></tr><tr><td>ILI9163</td><td>RGB LCD</td><td>128x128</td><td>SPI + D/C + RST</td><td><code>QUANTUM_PAINTER_DRIVERS += ili9163_spi</code></td></tr><tr><td>ILI9341</td><td>RGB LCD</td><td>240x320</td><td>SPI + D/C + RST</td><td><code>QUANTUM_PAINTER_DRIVERS += ili9341_spi</code></td></tr><tr><td>ILI9486</td><td>RGB LCD</td><td>320x480</td><td>SPI + D/C + RST</td><td><code>QUANTUM_PAINTER_DRIVERS += ili9486_spi</code></td></tr><tr><td>ILI9488</td><td>RGB LCD</td><td>320x480</td><td>SPI + D/C + RST</td><td><code>QUANTUM_PAINTER_DRIVERS += ili9488_spi</code></td></tr><tr><td>LD7032 (SPI)</td><td>Monochrome OLED</td><td>128x40</td><td>SPI + D/C + RST</td><td><code>QUANTUM_PAINTER_DRIVERS += ld7032_spi</code></td></tr><tr><td>LD7032 (I2C)</td><td>Monochrome OLED</td><td>128x40</td><td>I2C</td><td><code>QUANTUM_PAINTER_DRIVERS += ld7032_i2c</code></td></tr><tr><td>SSD1351</td><td>RGB OLED</td><td>128x128</td><td>SPI + D/C + RST</td><td><code>QUANTUM_PAINTER_DRIVERS += ssd1351_spi</code></td></tr><tr><td>ST7735</td><td>RGB LCD</td><td>132x162, 80x160</td><td>SPI + D/C + RST</td><td><code>QUANTUM_PAINTER_DRIVERS += st7735_spi</code></td></tr><tr><td>ST7789</td><td>RGB LCD</td><td>240x320, 240x240</td><td>SPI + D/C + RST</td><td><code>QUANTUM_PAINTER_DRIVERS += st7789_spi</code></td></tr><tr><td>SH1106 (SPI)</td><td>Monochrome OLED</td><td>128x64</td><td>SPI + D/C + RST</td><td><code>QUANTUM_PAINTER_DRIVERS += sh1106_spi</code></td></tr><tr><td>SH1106 (I2C)</td><td>Monochrome OLED</td><td>128x64</td><td>I2C</td><td><code>QUANTUM_PAINTER_DRIVERS += sh1106_i2c</code></td></tr><tr><td>SSD1306 (SPI)</td><td>Monochrome OLED</td><td>128x64</td><td>SPI + D/C + RST</td><td><code>QUANTUM_PAINTER_DRIVERS += sh1106_spi</code></td></tr><tr><td>SSD1306 (I2C)</td><td>Monochrome OLED</td><td>128x32</td><td>I2C</td><td><code>QUANTUM_PAINTER_DRIVERS += sh1106_i2c</code></td></tr><tr><td>Surface</td><td>Virtual</td><td>User-defined</td><td>None</td><td><code>QUANTUM_PAINTER_DRIVERS += surface</code></td></tr></tbody></table><h2id="quantum-painter-config"tabindex="-1">Quantum Painter Configuration <aclass="header-anchor"href="#quantum-painter-config"aria-label="Permalink to "Quantum Painter Configuration {#quantum-painter-config}""></a></h2><table><thead><tr><th>Option</th><th>Default</th><th>Purpose</th></tr></thead><tbody><tr><td><code>QUANTUM_PAINTER_DISPLAY_TIMEOUT</code></td><td><code>30000</code></td><td>This controls the amount of time (in milliseconds) that all displays will remain on after the last user input. If set to <code>0</code>, the display will remain on indefinitely.</td></tr><tr><td><code>QUANTUM_PAINTER_TASK_THROTTLE</code></td><td><code>1</code></td><td>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.</td></tr><tr><td><code>QUANTUM_PAINTER_NUM_IMAGES</code></td><td><code>8</code></td><td>The maximum number of images/animations that can be loaded at any one time.</td></tr><tr><td><code>QUANTUM_PAINTER_NUM_FONTS</code></td><td><code>4</code><
<spanclass="line"><span> -v, --verbose Turns on verbose output.</span></span></code></pre></div><p>The <code>INPUT</code> argument can be any image file loadable by Python's Pillow module. Common formats include PNG, or Animated GIF.</p><p>The <code>OUTPUT</code> argument needs to be a directory, and will default to the same directory as the input argument.</p><p>The <code>FORMAT</code> argument can be any of the following:</p><table><thead><tr><th>Format</th><th>Meaning</th></tr></thead><tbody><tr><td><code>rgb888</code></td><td>16,777,216 colors in 8-8-8 RGB format (requires <code>QUANTUM_PAINTER_SUPPORTS_NATIVE_COLORS</code>)</td></tr><tr><td><code>rgb565</code></td><td>65,536 colors in 5-6-5 RGB format (requires <code>QUANTUM_PAINTER_SUPPORTS_NATIVE_COLORS</code>)</td></tr><tr><td><code>pal256</code></td><td>256-color palette (requires <code>QUANTUM_PAINTER_SUPPORTS_256_PALETTE</code>)</td></tr><tr><td><code>pal16</code></td><td>16-color palette</td></tr><tr><td><code>pal4</code></td><td>4-color palette</td></tr><tr><td><code>pal2</code></td><td>2-color palette</td></tr><tr><td><code>mono256</code></td><td>256-shade grayscale (requires <code>QUANTUM_PAINTER_SUPPORTS_256_PALETTE</code>)</td></tr><tr><td><code>mono16</code></td><td>16-shade grayscale</td></tr><tr><td><code>mono4</code></td><td>4-shade grayscale</td></tr><tr><td><code>mono2</code></td><td>2-shade grayscale</td></tr></tbody></table><p><strong>Examples</strong>:</p><divclass="language- vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang"></span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><span>$ cd /home/qmk/qmk_firmware/keyboards/my_keeb</span></span>
<spanclass="line"><span>Writing /home/qmk/qmk_firmware/keyboards/my_keeb/generated/my_image.qgf.c...</span></span></code></pre></div><!--]--></div><!----><!----><!--]--></div><h2id="quantum-painter-drivers"tabindex="-1">Quantum Painter Display Drivers <aclass="header-anchor"href="#quantum-painter-drivers"aria-label="Permalink to "Quantum Painter Display Drivers {#quantum-painter-drivers}""></a></h2><divclass="plugin-tabs"><divclass="plugin-tabs--tab-list"role="tablist"><!--[--><buttonid="tab-LCD-9"role="tab"class="plugin-tabs--tab"aria-selected="true"aria-controls="panel-LCD-9"tabindex="0">LCD</button><buttonid="tab-OLED-9"role="tab"class="plugin-tabs--tab"aria-selected="false"aria-controls="panel-OLED-9"tabindex="-1">OLED</button><buttonid="tab-Surface-9"role="tab"class="plugin-tabs--tab"aria-selected="false"aria-controls="panel-Surface-9"tabindex="-1">Surface</button><!--]--></div><!--[--><divid="panel-LCD-9"class="plugin-tabs--content"role="tabpanel"tabindex="0"aria-labelledby="tab-LCD-9"data-v-b2b19630><!--[--><p>Most TFT display panels use a 5-pin interface -- SPI SCK, SPI MOSI, SPI CS, D/C, and RST pins.</p><p>For these displays, QMK's <code>spi_master</code> must already be correctly configured for the platform you're building for.</p><p>The pin assignments for SPI CS, D/C, and RST are specified during device construction.</p><divclass="plugin-tabs"><divclass="plugin-tabs--tab-list"role="tablist"><!--[--><buttonid="tab-GC9A01-10"role="tab"class="plugin-tabs--tab"aria-selected="true"aria-controls="panel-GC9A01-10"tabindex="0">GC9A01</button><buttonid="tab-ILI9163-10"role="tab"class="plugin-tabs--tab"aria-selected="false"aria-controls="panel-ILI9163-10"tabindex="-1">ILI9163</button><buttonid="tab-ILI9341-10"role="tab"class="plugin-tabs--tab"aria-selected="false"aria-controls="panel-ILI9341-10"tabindex="-1">ILI9341</button><buttonid="tab-ILI9486-10"role="tab"class="plugin-tabs--tab"aria-selected="false"aria-controls="panel-ILI9486-10"tabindex="-1">ILI9486</button><buttonid="tab-ILI9488-10"role="tab"class="plugin-tabs--tab"aria-selected="false"aria-controls="panel-ILI9488-10"tabindex="-1">ILI9488</button><buttonid="tab-ST7735-10"role="tab"class="plugin-tabs--tab"aria-selected="false"aria-controls="panel-ST7735-10"tabindex="-1">ST7735</button><buttonid="tab-ST7789-10"role="tab"class="plugin-tabs--tab"aria-selected="false"aria-controls="panel-ST7789-10"tabindex="-1">ST7789</button><!--]--></div><!--[--><divid="panel-GC9A01-10"class="plugin-tabs--content"role="tabpanel"tabindex="0"aria-labelledby="tab-GC9A01-10"data-v-b2b19630><!--[--><p>Enabling support for the GC9A01 in Quantum Painter is done by adding the following to <code>rules.mk</code>:</p><divclass="language-make vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">make</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">QUANTUM_PAINTER_ENABLE = yes</span></span>
<spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">QUANTUM_PAINTER_DRIVERS += gc9a01_spi</span></span></code></pre></div><p>Creating a GC9A01 device in firmware can then be done with the following API:</p><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">painter_device_t</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> qp_gc9a01_make_spi_device</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">uint16_t</span><spanstyle="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> panel_width</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">uint16_t</span><spanstyle="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> panel_height</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">pin_t</span><spanstyle="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> chip_select_pin</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">pin_t</span><spanstyle="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> dc_pin</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">pin_t</span><spanstyle="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> reset_pin</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">uint16_t</span><spanstyle="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> spi_divisor</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><spanstyle="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> spi_mode</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span></code></pre></div><p>The device handle returned from the <code>qp_gc9a01_make_spi_device</code> function can be used to perform all other drawing operations.</p><p>The maximum number of displays can be configured by changing the following in your <code>config.h</code> (default is 1):</p><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// 3 displays:</span></span>
<spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> GC9A01_NUM_DEVICES</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 3</span></span></code></pre></div><p>Native color format rgb565 is compatible with GC9A01</p><!--]--></div><!----><!----><!----><!----><!----><!----><!--]--></div><!--]--></div><!----><!----><!--]--></div><h2id="quantum-painter-api"tabindex="-1">Quantum Painter Drawing API <aclass="header-anchor"href="#quantum-painter-api"aria-label="Permalink to "Quantum Painter Drawing API {#quantum-painter-api}""></a></h2><p>All APIs require a <code>painter_device_t</code> 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.</p><p>To use any of the APIs, you need to include <code>qp.h</code>:</p><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#include</span><spanstyle="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"><qp.h></span></span></code></pre></div><divclass="plugin-tabs"><divclass="plugin-tabs--tab-list"role="tablist"><!--[--><buttonid="tab-General Notes-11"role="tab"class="plugin-tabs--tab"aria-selected="true"aria-controls="panel-General Notes-11"tabindex="0">General Notes</button><buttonid="tab-Device Control-11"role="tab"class="plugin-tabs--tab"aria-selected="false"aria-controls="panel-Device Control-11"tabindex="-1">Device Control</button><buttonid="tab-Drawing Primitives-11"role="tab"class="plugin-tabs--tab"aria-selected="false"aria-controls="panel-Drawing Primitives-11"tabindex="-1">Drawing Primitives</button><buttonid="tab-Image Functions-11"role="tab"class="plugin-tabs--tab"aria-selected="false"aria-controls="panel-Image Functions-11"tabindex="-1">Image Functions</button><buttonid="tab-Font Functions-11"role="tab"class="plugin-tabs--tab"aria-selected="false"aria-controls="panel-Font Functions-11"tabindex="-1">Font Functions</button><buttonid="tab-Advanced Functions-11"role="tab"class="plugin-tabs--tab"aria-selected="false"aria-controls="panel-Advanced Functions-11"tabindex="-1">Advanced Functions</button><!--]--></div><!--[--><divid="panel-General Notes-11"class="plugin-tabs--content"role="tabpanel"tabindex="0"aria-labelledby="tab-General Notes-11"data-v-b2b19630><!--[--><p>The coordinate system used in Quantum Painter generally accepts <code>left</code>, <code>top</code>, <code>right</code>, and <code>bottom</code> 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 <code>255</code> -- for any value or geometry extent that matches <code>256</code>, this would be represented as a <code>0</code>, instead.</p><divclass="tip custom-block"><pclass="custom-block-title">TIP</p><p>Drawing a horizontal line 8 pixels long, starting from 4 pixels inside the left side of the display, will need <code>left=4</code>, <code>right=11</code>.</p></div><p>All color data matches the standard QMK HSV triplet definitions:</p><ul><li>Hue is of the range <code>0...255</code> and is internally mapped to 0...360 degrees.</li><li>Saturation is of the range <code>0...255</code> and is internally mapped to 0...100% saturation.</li><li>Value is of the range <code>0...255</code> and is internally mapped to 0...100% brightness.</li></ul><divclass="tip custom-block"><pclass="custom-block-title">TIP</p><p>Colors used in Quantum Painter are not subject to the RGB lighting CIE curve, if it is enabled.</p></div><!--]--></div><!----><!----><!----><!----><!----><!--]--></div></div></div></main><footerclass="VPDocFooter"data-v-39a288b8data-v-09de1c0f><!--[--><!--]--><divclass="edit-info"data-