summaryrefslogtreecommitdiff
path: root/docs/quantum_painter.md
diff options
context:
space:
mode:
authorNick Brassel <nick@tzarc.org>2024-05-30 12:00:41 +1000
committerGitHub <noreply@github.com>2024-05-30 12:00:41 +1000
commit6ef97172889ccd5db376b2a9f8825489e24fdac4 (patch)
tree334e3bf41c8554d4bee73a140822f95f60eb64e9 /docs/quantum_painter.md
parent395766657ff98a4b1fd0dcba5917557f8acbb9e4 (diff)
Vitepress conversion of docs. (#23795)
Diffstat (limited to 'docs/quantum_painter.md')
-rw-r--r--docs/quantum_painter.md215
1 files changed, 121 insertions, 94 deletions
diff --git a/docs/quantum_painter.md b/docs/quantum_painter.md
index 7f524b07ee..1d844d0f94 100644
--- a/docs/quantum_painter.md
+++ b/docs/quantum_painter.md
@@ -1,4 +1,4 @@
1# Quantum Painter :id=quantum-painter 1# Quantum Painter {#quantum-painter}
2 2
3Quantum Painter is the standardised API for graphical displays. It currently includes support for basic drawing primitives, as well as custom images, animations, and fonts. 3Quantum Painter is the standardised API for graphical displays. It currently includes support for basic drawing primitives, as well as custom images, animations, and fonts.
4 4
@@ -13,7 +13,9 @@ QUANTUM_PAINTER_DRIVERS += ......
13 13
14You will also likely need to select an appropriate driver in `rules.mk`, which is listed below. 14You will also likely need to select an appropriate driver in `rules.mk`, which is listed below.
15 15
16!> 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. 16::: warning
17Quantum 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.
18:::
17 19
18The QMK CLI can be used to convert from normal images such as PNG files or animated GIFs, as well as fonts from TTF files. 20The QMK CLI can be used to convert from normal images such as PNG files or animated GIFs, as well as fonts from TTF files.
19 21
@@ -35,7 +37,7 @@ Supported devices:
35| SSD1306 (I2C) | Monochrome OLED | 128x32 | I2C | `QUANTUM_PAINTER_DRIVERS += sh1106_i2c` | 37| SSD1306 (I2C) | Monochrome OLED | 128x32 | I2C | `QUANTUM_PAINTER_DRIVERS += sh1106_i2c` |
36| Surface | Virtual | User-defined | None | `QUANTUM_PAINTER_DRIVERS += surface` | 38| Surface | Virtual | User-defined | None | `QUANTUM_PAINTER_DRIVERS += surface` |
37 39
38## Quantum Painter Configuration :id=quantum-painter-config 40## Quantum Painter Configuration {#quantum-painter-config}
39 41
40| Option | Default | Purpose | 42| Option | Default | Purpose |
41|---------------------------------------------------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 43|---------------------------------------------------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
@@ -54,11 +56,11 @@ Supported devices:
54 56
55Drivers have their own set of configurable options, and are described in their respective sections. 57Drivers have their own set of configurable options, and are described in their respective sections.
56 58
57## Quantum Painter CLI Commands :id=quantum-painter-cli 59## Quantum Painter CLI Commands {#quantum-painter-cli}
58 60
59<!-- tabs:start --> 61:::::tabs
60 62
61### ** `qmk painter-convert-graphics` ** 63==== `qmk painter-convert-graphics`
62 64
63This command converts images to a format usable by QMK, i.e. the QGF File Format. 65This command converts images to a format usable by QMK, i.e. the QGF File Format.
64 66
@@ -109,7 +111,7 @@ Writing /home/qmk/qmk_firmware/keyboards/my_keeb/generated/my_image.qgf.h...
109Writing /home/qmk/qmk_firmware/keyboards/my_keeb/generated/my_image.qgf.c... 111Writing /home/qmk/qmk_firmware/keyboards/my_keeb/generated/my_image.qgf.c...
110``` 112```
111 113
112### ** `qmk painter-make-font-image` ** 114==== `qmk painter-make-font-image`
113 115
114This command converts a TTF font to an intermediate format for editing, before converting to the QFF File Format. 116This command converts a TTF font to an intermediate format for editing, before converting to the QFF File Format.
115 117
@@ -142,7 +144,7 @@ The `UNICODE_GLYPHS` argument allows for specifying extra unicode glyphs to gene
142$ qmk painter-make-font-image --font NotoSans-ExtraCondensedBold.ttf --size 11 -o noto11.png --unicode-glyphs "ĄȽɂɻɣɈʣ" 144$ qmk painter-make-font-image --font NotoSans-ExtraCondensedBold.ttf --size 11 -o noto11.png --unicode-glyphs "ĄȽɂɻɣɈʣ"
143``` 145```
144 146
145### ** `qmk painter-convert-font-image` ** 147==== `qmk painter-convert-font-image`
146 148
147This command converts an intermediate font image to the QFF File Format. 149This command converts an intermediate font image to the QFF File Format.
148 150
@@ -187,14 +189,13 @@ Writing /home/qmk/qmk_firmware/keyboards/my_keeb/generated/noto11.qff.h...
187Writing /home/qmk/qmk_firmware/keyboards/my_keeb/generated/noto11.qff.c... 189Writing /home/qmk/qmk_firmware/keyboards/my_keeb/generated/noto11.qff.c...
188``` 190```
189 191
190<!-- tabs:end --> 192:::::
191 193
192## Quantum Painter Display Drivers :id=quantum-painter-drivers 194## Quantum Painter Display Drivers {#quantum-painter-drivers}
193 195
194<!-- tabs:start --> 196::::::tabs
195 197
196 198===== LCD
197### ** LCD **
198 199
199Most TFT display panels use a 5-pin interface -- SPI SCK, SPI MOSI, SPI CS, D/C, and RST pins. 200Most TFT display panels use a 5-pin interface -- SPI SCK, SPI MOSI, SPI CS, D/C, and RST pins.
200 201
@@ -202,9 +203,9 @@ For these displays, QMK's `spi_master` must already be correctly configured for
202 203
203The pin assignments for SPI CS, D/C, and RST are specified during device construction. 204The pin assignments for SPI CS, D/C, and RST are specified during device construction.
204 205
205<!-- tabs:start --> 206:::::tabs
206 207
207#### ** GC9A01 ** 208==== GC9A01
208 209
209Enabling support for the GC9A01 in Quantum Painter is done by adding the following to `rules.mk`: 210Enabling support for the GC9A01 in Quantum Painter is done by adding the following to `rules.mk`:
210 211
@@ -230,7 +231,7 @@ The maximum number of displays can be configured by changing the following in yo
230 231
231Native color format rgb565 is compatible with GC9A01 232Native color format rgb565 is compatible with GC9A01
232 233
233#### ** ILI9163 ** 234==== ILI9163
234 235
235Enabling support for the ILI9163 in Quantum Painter is done by adding the following to `rules.mk`: 236Enabling support for the ILI9163 in Quantum Painter is done by adding the following to `rules.mk`:
236 237
@@ -256,7 +257,7 @@ The maximum number of displays can be configured by changing the following in yo
256 257
257Native color format rgb565 is compatible with ILI9163 258Native color format rgb565 is compatible with ILI9163
258 259
259#### ** ILI9341 ** 260==== ILI9341
260 261
261Enabling support for the ILI9341 in Quantum Painter is done by adding the following to `rules.mk`: 262Enabling support for the ILI9341 in Quantum Painter is done by adding the following to `rules.mk`:
262 263
@@ -282,7 +283,7 @@ The maximum number of displays can be configured by changing the following in yo
282 283
283Native color format rgb565 is compatible with ILI9341 284Native color format rgb565 is compatible with ILI9341
284 285
285#### ** ILI9486 ** 286==== ILI9486
286 287
287Enabling support for the ILI9486 in Quantum Painter is done by adding the following to `rules.mk`: 288Enabling support for the ILI9486 in Quantum Painter is done by adding the following to `rules.mk`:
288 289
@@ -315,7 +316,7 @@ The maximum number of displays can be configured by changing the following in yo
315Native color format rgb888 is compatible with ILI9486 316Native color format rgb888 is compatible with ILI9486
316Native color format rgb565 is compatible with ILI9486 Waveshare 317Native color format rgb565 is compatible with ILI9486 Waveshare
317 318
318#### ** ILI9488 ** 319==== ILI9488
319 320
320Enabling support for the ILI9488 in Quantum Painter is done by adding the following to `rules.mk`: 321Enabling support for the ILI9488 in Quantum Painter is done by adding the following to `rules.mk`:
321 322
@@ -341,7 +342,7 @@ The maximum number of displays can be configured by changing the following in yo
341 342
342Native color format rgb888 is compatible with ILI9488 343Native color format rgb888 is compatible with ILI9488
343 344
344#### ** ST7735 ** 345==== ST7735
345 346
346Enabling support for the ST7735 in Quantum Painter is done by adding the following to `rules.mk`: 347Enabling support for the ST7735 in Quantum Painter is done by adding the following to `rules.mk`:
347 348
@@ -367,9 +368,11 @@ The maximum number of displays can be configured by changing the following in yo
367 368
368Native color format rgb565 is compatible with ST7735 369Native color format rgb565 is compatible with ST7735
369 370
370!> Some ST7735 devices are known to have different drawing offsets -- despite being a 132x162 pixel display controller internally, some display panels are only 80x160, or smaller. These may require an offset to be applied; see `qp_set_viewport_offsets` above for information on how to override the offsets if they aren't correctly rendered. 371::: warning
372Some ST7735 devices are known to have different drawing offsets -- despite being a 132x162 pixel display controller internally, some display panels are only 80x160, or smaller. These may require an offset to be applied; see `qp_set_viewport_offsets` above for information on how to override the offsets if they aren't correctly rendered.
373:::
371 374
372#### ** ST7789 ** 375==== ST7789
373 376
374Enabling support for the ST7789 in Quantum Painter is done by adding the following to `rules.mk`: 377Enabling support for the ST7789 in Quantum Painter is done by adding the following to `rules.mk`:
375 378
@@ -395,11 +398,13 @@ The maximum number of displays can be configured by changing the following in yo
395 398
396Native color format rgb565 is compatible with ST7789 399Native color format rgb565 is compatible with ST7789
397 400
398!> Some ST7789 devices are known to have different drawing offsets -- despite being a 240x320 pixel display controller internally, some display panels are only 240x240, or smaller. These may require an offset to be applied; see `qp_set_viewport_offsets` above for information on how to override the offsets if they aren't correctly rendered. 401::: warning
402Some ST7789 devices are known to have different drawing offsets -- despite being a 240x320 pixel display controller internally, some display panels are only 240x240, or smaller. These may require an offset to be applied; see `qp_set_viewport_offsets` above for information on how to override the offsets if they aren't correctly rendered.
403:::
399 404
400<!-- tabs:end --> 405:::::
401 406
402### ** OLED ** 407===== OLED
403 408
404OLED displays tend to use 5-pin SPI when at larger resolutions, or when using color -- SPI SCK, SPI MOSI, SPI CS, D/C, and RST pins. Smaller OLEDs may use I2C instead. 409OLED displays tend to use 5-pin SPI when at larger resolutions, or when using color -- SPI SCK, SPI MOSI, SPI CS, D/C, and RST pins. Smaller OLEDs may use I2C instead.
405 410
@@ -407,9 +412,9 @@ When using these displays, either `spi_master` or `i2c_master` must already be c
407 412
408For SPI, the pin assignments for SPI CS, D/C, and RST are specified during device construction -- for I2C the panel's address is specified instead. 413For SPI, the pin assignments for SPI CS, D/C, and RST are specified during device construction -- for I2C the panel's address is specified instead.
409 414
410<!-- tabs:start --> 415:::::tabs
411 416
412#### ** SSD1351 ** 417==== SSD1351
413 418
414Enabling support for the SSD1351 in Quantum Painter is done by adding the following to `rules.mk`: 419Enabling support for the SSD1351 in Quantum Painter is done by adding the following to `rules.mk`:
415 420
@@ -435,7 +440,7 @@ The maximum number of displays can be configured by changing the following in yo
435 440
436Native color format rgb565 is compatible with SSD1351 441Native color format rgb565 is compatible with SSD1351
437 442
438#### ** SH1106 ** 443==== SH1106
439 444
440Enabling support for the SH1106 in Quantum Painter is done by adding the following to `rules.mk`: 445Enabling support for the SH1106 in Quantum Painter is done by adding the following to `rules.mk`:
441 446
@@ -469,17 +474,19 @@ The maximum number of displays of each type can be configured by changing the fo
469 474
470Native color format mono2 is compatible with SH1106 475Native color format mono2 is compatible with SH1106
471 476
472#### ** SSD1306 ** 477==== SSD1306
473 478
474SSD1306 and SH1106 are almost entirely identical, to the point of being indisinguishable by Quantum Painter. Enable SH1106 support in Quantum Painter and create SH1106 devices in firmware to perform drawing operations on SSD1306 displays. 479SSD1306 and SH1106 are almost entirely identical, to the point of being indisinguishable by Quantum Painter. Enable SH1106 support in Quantum Painter and create SH1106 devices in firmware to perform drawing operations on SSD1306 displays.
475 480
476<!-- tabs:end --> 481:::::
477 482
478### ** Surface ** 483===== Surface
479 484
480Quantum Painter has a surface driver which is able to target a buffer in RAM. In general, surfaces keep track of the "dirty" region -- the area that has been drawn to since the last flush -- so that when transferring to the display they can transfer the minimal amount of data to achieve the end result. 485Quantum Painter has a surface driver which is able to target a buffer in RAM. In general, surfaces keep track of the "dirty" region -- the area that has been drawn to since the last flush -- so that when transferring to the display they can transfer the minimal amount of data to achieve the end result.
481 486
482!> These generally require significant amounts of RAM, so at large sizes and/or higher bit depths, they may not be usable on all MCUs. 487::: warning
488These generally require significant amounts of RAM, so at large sizes and/or higher bit depths, they may not be usable on all MCUs.
489:::
483 490
484Enabling support for surfaces in Quantum Painter is done by adding the following to `rules.mk`: 491Enabling support for surfaces in Quantum Painter is done by adding the following to `rules.mk`:
485 492
@@ -533,13 +540,17 @@ bool qp_surface_draw(painter_device_t surface, painter_device_t display, uint16_
533 540
534The `surface` is the surface to copy out from. The `display` is the target display to draw into. `x` and `y` are the target location to draw the surface pixel data. Under normal circumstances, the location should be consistent, as the dirty region is calculated with respect to the `x` and `y` coordinates -- changing those will result in partial, overlapping draws. `entire_surface` whether the entire surface should be drawn, instead of just the dirty region. 541The `surface` is the surface to copy out from. The `display` is the target display to draw into. `x` and `y` are the target location to draw the surface pixel data. Under normal circumstances, the location should be consistent, as the dirty region is calculated with respect to the `x` and `y` coordinates -- changing those will result in partial, overlapping draws. `entire_surface` whether the entire surface should be drawn, instead of just the dirty region.
535 542
536!> The surface and display panel must have the same native pixel format. 543::: warning
544The surface and display panel must have the same native pixel format.
545:::
537 546
538?> Calling `qp_flush()` on the surface resets its dirty region. Copying the surface contents to the display also automatically resets the dirty region. 547::: tip
548Calling `qp_flush()` on the surface resets its dirty region. Copying the surface contents to the display also automatically resets the dirty region.
549:::
539 550
540<!-- tabs:end --> 551::::::
541 552
542## Quantum Painter Drawing API :id=quantum-painter-api 553## Quantum Painter Drawing API {#quantum-painter-api}
543 554
544All 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. 555All 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.
545 556
@@ -548,13 +559,15 @@ To use any of the APIs, you need to include `qp.h`:
548#include <qp.h> 559#include <qp.h>
549``` 560```
550 561
551<!-- tabs:start --> 562::::::tabs
552 563
553### ** General Notes ** 564===== General Notes
554 565
555The 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. 566The 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.
556 567
557?> Drawing a horizontal line 8 pixels long, starting from 4 pixels inside the left side of the display, will need `left=4`, `right=11`. 568::: tip
569Drawing a horizontal line 8 pixels long, starting from 4 pixels inside the left side of the display, will need `left=4`, `right=11`.
570:::
558 571
559All color data matches the standard QMK HSV triplet definitions: 572All color data matches the standard QMK HSV triplet definitions:
560 573
@@ -562,13 +575,15 @@ All color data matches the standard QMK HSV triplet definitions:
562* Saturation is of the range `0...255` and is internally mapped to 0...100% saturation. 575* Saturation is of the range `0...255` and is internally mapped to 0...100% saturation.
563* Value is of the range `0...255` and is internally mapped to 0...100% brightness. 576* Value is of the range `0...255` and is internally mapped to 0...100% brightness.
564 577
565?> Colors used in Quantum Painter are not subject to the RGB lighting CIE curve, if it is enabled. 578::: tip
579Colors used in Quantum Painter are not subject to the RGB lighting CIE curve, if it is enabled.
580:::
566 581
567### ** Device Control ** 582===== Device Control
568 583
569<!-- tabs:start --> 584:::::tabs
570 585
571#### ** Display Initialisation ** 586==== Display Initialisation
572 587
573```c 588```c
574bool qp_init(painter_device_t device, painter_rotation_t rotation); 589bool qp_init(painter_device_t device, painter_rotation_t rotation);
@@ -584,7 +599,7 @@ void keyboard_post_init_kb(void) {
584} 599}
585``` 600```
586 601
587#### ** Display Power ** 602==== Display Power
588 603
589```c 604```c
590bool qp_power(painter_device_t device, bool power_on); 605bool qp_power(painter_device_t device, bool power_on);
@@ -592,7 +607,9 @@ bool qp_power(painter_device_t device, bool power_on);
592 607
593The `qp_power` function instructs the display whether or not the display panel should be on or off. 608The `qp_power` function instructs the display whether or not the display panel should be on or off.
594 609
595!> If there is a separate backlight controlled through the normal QMK backlight API, this is not controlled by the `qp_power` function and needs to be manually handled elsewhere. 610::: warning
611If there is a separate backlight controlled through the normal QMK backlight API, this is not controlled by the `qp_power` function and needs to be manually handled elsewhere.
612:::
596 613
597```c 614```c
598static uint8_t last_backlight = 255; 615static uint8_t last_backlight = 255;
@@ -615,7 +632,7 @@ void suspend_wakeup_init_user(void) {
615} 632}
616``` 633```
617 634
618#### ** Display Clear ** 635==== Display Clear
619 636
620```c 637```c
621bool qp_clear(painter_device_t device); 638bool qp_clear(painter_device_t device);
@@ -623,7 +640,7 @@ bool qp_clear(painter_device_t device);
623 640
624The `qp_clear` function clears the display's screen. 641The `qp_clear` function clears the display's screen.
625 642
626#### ** Display Flush ** 643==== Display Flush
627 644
628```c 645```c
629bool qp_flush(painter_device_t device); 646bool qp_flush(painter_device_t device);
@@ -631,7 +648,9 @@ bool qp_flush(painter_device_t device);
631 648
632The `qp_flush` function ensures that all drawing operations are "pushed" to the display. This should be done as the last operation whenever a sequence of draws occur, and guarantees that any changes are applied. 649The `qp_flush` function ensures that all drawing operations are "pushed" to the display. This should be done as the last operation whenever a sequence of draws occur, and guarantees that any changes are applied.
633 650
634!> Some display panels may seem to work even without a call to `qp_flush` -- this may be because the driver cannot queue drawing operations and needs to display them immediately when invoked. In general, calling `qp_flush` at the end is still considered "best practice". 651::: warning
652Some display panels may seem to work even without a call to `qp_flush` -- this may be because the driver cannot queue drawing operations and needs to display them immediately when invoked. In general, calling `qp_flush` at the end is still considered "best practice".
653:::
635 654
636```c 655```c
637void housekeeping_task_user(void) { 656void housekeeping_task_user(void) {
@@ -645,13 +664,13 @@ void housekeeping_task_user(void) {
645} 664}
646``` 665```
647 666
648<!-- tabs:end --> 667:::::
649 668
650### ** Drawing Primitives ** 669===== Drawing Primitives
651 670
652<!-- tabs:start --> 671:::::tabs
653 672
654#### ** Set Pixel ** 673==== Set Pixel
655 674
656```c 675```c
657bool qp_setpixel(painter_device_t device, uint16_t x, uint16_t y, uint8_t hue, uint8_t sat, uint8_t val); 676bool qp_setpixel(painter_device_t device, uint16_t x, uint16_t y, uint8_t hue, uint8_t sat, uint8_t val);
@@ -659,7 +678,9 @@ bool qp_setpixel(painter_device_t device, uint16_t x, uint16_t y, uint8_t hue, u
659 678
660The `qp_setpixel` can be used to set a specific pixel on the screen to the supplied color. 679The `qp_setpixel` can be used to set a specific pixel on the screen to the supplied color.
661 680
662?> Using `qp_setpixel` for large amounts of drawing operations is inefficient and should be avoided unless they cannot be achieved with other drawing APIs. 681::: tip
682Using `qp_setpixel` for large amounts of drawing operations is inefficient and should be avoided unless they cannot be achieved with other drawing APIs.
683:::
663 684
664```c 685```c
665void housekeeping_task_user(void) { 686void housekeeping_task_user(void) {
@@ -675,7 +696,7 @@ void housekeeping_task_user(void) {
675} 696}
676``` 697```
677 698
678#### ** Draw Line ** 699==== Draw Line
679 700
680```c 701```c
681bool 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); 702bool 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);
@@ -697,7 +718,7 @@ void housekeeping_task_user(void) {
697} 718}
698``` 719```
699 720
700#### ** Draw Rect ** 721==== Draw Rect
701 722
702```c 723```c
703bool 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); 724bool 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);
@@ -719,7 +740,7 @@ void housekeeping_task_user(void) {
719} 740}
720``` 741```
721 742
722#### ** Draw Circle ** 743==== Draw Circle
723 744
724```c 745```c
725bool 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); 746bool 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);
@@ -741,7 +762,7 @@ void housekeeping_task_user(void) {
741} 762}
742``` 763```
743 764
744#### ** Draw Ellipse ** 765==== Draw Ellipse
745 766
746```c 767```c
747bool 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); 768bool 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);
@@ -763,9 +784,9 @@ void housekeeping_task_user(void) {
763} 784}
764``` 785```
765 786
766<!-- tabs:end --> 787:::::
767 788
768### ** Image Functions ** 789===== Image Functions
769 790
770Making an image available for use requires compiling it into your firmware. To do so, assuming you've created `my_image.qgf.c` and `my_image.qgf.h` as per the CLI examples above, you'd add the following to your `rules.mk`: 791Making an image available for use requires compiling it into your firmware. To do so, assuming you've created `my_image.qgf.c` and `my_image.qgf.h` as per the CLI examples above, you'd add the following to your `rules.mk`:
771 792
@@ -778,9 +799,9 @@ SRC += my_image.qgf.c
778#include "my_image.qgf.h" 799#include "my_image.qgf.h"
779``` 800```
780 801
781<!-- tabs:start --> 802:::::tabs
782 803
783#### ** Load Image ** 804==== Load Image
784 805
785```c 806```c
786painter_image_handle_t qp_load_image_mem(const void *buffer); 807painter_image_handle_t qp_load_image_mem(const void *buffer);
@@ -790,9 +811,11 @@ The `qp_load_image_mem` function loads a QGF image from memory or flash.
790 811
791`qp_load_image_mem` returns a handle to the loaded image, which can then be used to draw to the screen using `qp_drawimage`, `qp_drawimage_recolor`, `qp_animate`, or `qp_animate_recolor`. If an image is no longer required, it can be unloaded by calling `qp_close_image` below. 812`qp_load_image_mem` returns a handle to the loaded image, which can then be used to draw to the screen using `qp_drawimage`, `qp_drawimage_recolor`, `qp_animate`, or `qp_animate_recolor`. If an image is no longer required, it can be unloaded by calling `qp_close_image` below.
792 813
793See the [CLI Commands](quantum_painter.md?id=quantum-painter-cli) for instructions on how to convert images to [QGF](quantum_painter_qgf.md). 814See the [CLI Commands](quantum_painter#quantum-painter-cli) for instructions on how to convert images to [QGF](quantum_painter_qgf).
794 815
795?> The total number of images available to load at any one time is controlled by the configurable option `QUANTUM_PAINTER_NUM_IMAGES` in the table above. If more images are required, the number should be increased in `config.h`. 816::: tip
817The total number of images available to load at any one time is controlled by the configurable option `QUANTUM_PAINTER_NUM_IMAGES` in the table above. If more images are required, the number should be increased in `config.h`.
818:::
796 819
797Image information is available through accessing the handle: 820Image information is available through accessing the handle:
798 821
@@ -802,7 +825,7 @@ Image information is available through accessing the handle:
802| Height | `image->height` | 825| Height | `image->height` |
803| Frame Count | `image->frame_count` | 826| Frame Count | `image->frame_count` |
804 827
805#### ** Unload Image ** 828==== Unload Image
806 829
807```c 830```c
808bool qp_close_image(painter_image_handle_t image); 831bool qp_close_image(painter_image_handle_t image);
@@ -810,7 +833,7 @@ bool qp_close_image(painter_image_handle_t image);
810 833
811The `qp_close_image` function releases resources related to the loading of the supplied image. 834The `qp_close_image` function releases resources related to the loading of the supplied image.
812 835
813#### ** Draw image ** 836==== Draw image
814 837
815```c 838```c
816bool qp_drawimage(painter_device_t device, uint16_t x, uint16_t y, painter_image_handle_t image); 839bool qp_drawimage(painter_device_t device, uint16_t x, uint16_t y, painter_image_handle_t image);
@@ -830,7 +853,7 @@ void keyboard_post_init_kb(void) {
830} 853}
831``` 854```
832 855
833#### ** Animate Image ** 856==== Animate Image
834 857
835```c 858```c
836deferred_token qp_animate(painter_device_t device, uint16_t x, uint16_t y, painter_image_handle_t image); 859deferred_token qp_animate(painter_device_t device, uint16_t x, uint16_t y, painter_image_handle_t image);
@@ -855,7 +878,7 @@ void keyboard_post_init_kb(void) {
855} 878}
856``` 879```
857 880
858#### ** Stop Animation ** 881==== Stop Animation
859 882
860```c 883```c
861void qp_stop_animation(deferred_token anim_token); 884void qp_stop_animation(deferred_token anim_token);
@@ -870,9 +893,9 @@ void housekeeping_task_user(void) {
870} 893}
871``` 894```
872 895
873<!-- tabs:end --> 896:::::
874 897
875### ** Font Functions ** 898===== Font Functions
876 899
877Making a font available for use requires compiling it into your firmware. To do so, assuming you've created `my_font.qff.c` and `my_font.qff.h` as per the CLI examples above, you'd add the following to your `rules.mk`: 900Making a font available for use requires compiling it into your firmware. To do so, assuming you've created `my_font.qff.c` and `my_font.qff.h` as per the CLI examples above, you'd add the following to your `rules.mk`:
878 901
@@ -885,9 +908,9 @@ SRC += noto11.qff.c
885#include "noto11.qff.h" 908#include "noto11.qff.h"
886``` 909```
887 910
888<!-- tabs: start --> 911:::::tabs
889 912
890#### ** Load Font ** 913==== Load Font
891 914
892```c 915```c
893painter_font_handle_t qp_load_font_mem(const void *buffer); 916painter_font_handle_t qp_load_font_mem(const void *buffer);
@@ -897,9 +920,11 @@ The `qp_load_font_mem` function loads a QFF font from memory or flash.
897 920
898`qp_load_font_mem` returns a handle to the loaded font, which can then be measured using `qp_textwidth`, or drawn to the screen using `qp_drawtext`, or `qp_drawtext_recolor`. If a font is no longer required, it can be unloaded by calling `qp_close_font` below. 921`qp_load_font_mem` returns a handle to the loaded font, which can then be measured using `qp_textwidth`, or drawn to the screen using `qp_drawtext`, or `qp_drawtext_recolor`. If a font is no longer required, it can be unloaded by calling `qp_close_font` below.
899 922
900See the [CLI Commands](quantum_painter.md?id=quantum-painter-cli) for instructions on how to convert TTF fonts to [QFF](quantum_painter_qff.md). 923See the [CLI Commands](quantum_painter#quantum-painter-cli) for instructions on how to convert TTF fonts to [QFF](quantum_painter_qff).
901 924
902?> The total number of fonts available to load at any one time is controlled by the configurable option `QUANTUM_PAINTER_NUM_FONTS` in the table above. If more fonts are required, the number should be increased in `config.h`. 925::: tip
926The total number of fonts available to load at any one time is controlled by the configurable option `QUANTUM_PAINTER_NUM_FONTS` in the table above. If more fonts are required, the number should be increased in `config.h`.
927:::
903 928
904Font information is available through accessing the handle: 929Font information is available through accessing the handle:
905 930
@@ -907,7 +932,7 @@ Font information is available through accessing the handle:
907|-------------|----------------------| 932|-------------|----------------------|
908| Line Height | `image->line_height` | 933| Line Height | `image->line_height` |
909 934
910#### ** Unload Font ** 935==== Unload Font
911 936
912```c 937```c
913bool qp_close_font(painter_font_handle_t font); 938bool qp_close_font(painter_font_handle_t font);
@@ -915,7 +940,7 @@ bool qp_close_font(painter_font_handle_t font);
915 940
916The `qp_close_font` function releases resources related to the loading of the supplied font. 941The `qp_close_font` function releases resources related to the loading of the supplied font.
917 942
918#### ** Measure Text ** 943==== Measure Text
919 944
920```c 945```c
921int16_t qp_textwidth(painter_font_handle_t font, const char *str); 946int16_t qp_textwidth(painter_font_handle_t font, const char *str);
@@ -923,7 +948,7 @@ int16_t qp_textwidth(painter_font_handle_t font, const char *str);
923 948
924The `qp_textwidth` function allows measurement of how many pixels wide the supplied string would result in, for the given font. 949The `qp_textwidth` function allows measurement of how many pixels wide the supplied string would result in, for the given font.
925 950
926#### ** Draw Text ** 951==== Draw Text
927 952
928```c 953```c
929int16_t qp_drawtext(painter_device_t device, uint16_t x, uint16_t y, painter_font_handle_t font, const char *str); 954int16_t qp_drawtext(painter_device_t device, uint16_t x, uint16_t y, painter_font_handle_t font, const char *str);
@@ -945,49 +970,49 @@ void keyboard_post_init_kb(void) {
945} 970}
946``` 971```
947 972
948<!-- tabs:end --> 973:::::
949 974
950### ** Advanced Functions ** 975===== Advanced Functions
951 976
952<!-- tabs:start --> 977:::::tabs
953 978
954#### ** Gettters ** 979==== Getters
955 980
956These functions allow external code to retrieve the current width, height, rotation, and drawing offsets. 981These functions allow external code to retrieve the current width, height, rotation, and drawing offsets.
957 982
958<!-- tabs:start --> 983::::tabs
959 984
960#### ** Width ** 985=== Width
961 986
962```c 987```c
963uint16_t qp_get_width(painter_device_t device); 988uint16_t qp_get_width(painter_device_t device);
964``` 989```
965 990
966#### ** Height ** 991=== Height
967 992
968```c 993```c
969uint16_t qp_get_height(painter_device_t device); 994uint16_t qp_get_height(painter_device_t device);
970``` 995```
971 996
972#### ** Rotation ** 997=== Rotation
973 998
974```c 999```c
975painter_rotation_t qp_get_rotation(painter_device_t device); 1000painter_rotation_t qp_get_rotation(painter_device_t device);
976``` 1001```
977 1002
978#### ** Offset X ** 1003=== Offset X
979 1004
980```c 1005```c
981uint16_t qp_get_offset_x(painter_device_t device); 1006uint16_t qp_get_offset_x(painter_device_t device);
982``` 1007```
983 1008
984#### ** Offset Y ** 1009=== Offset Y
985 1010
986```c 1011```c
987uint16_t qp_get_offset_y(painter_device_t device); 1012uint16_t qp_get_offset_y(painter_device_t device);
988``` 1013```
989 1014
990##### ** Everything ** 1015=== Everything
991 1016
992Convenience function to call all the previous ones at once. 1017Convenience function to call all the previous ones at once.
993Note: You can pass `NULL` for the values you are not interested in. 1018Note: You can pass `NULL` for the values you are not interested in.
@@ -996,9 +1021,9 @@ Note: You can pass `NULL` for the values you are not interested in.
996void 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); 1021void 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);
997``` 1022```
998 1023
999<!-- tabs:end --> 1024::::
1000 1025
1001#### ** Set Viewport Offsets ** 1026==== Set Viewport Offsets
1002 1027
1003```c 1028```c
1004void qp_set_viewport_offsets(painter_device_t device, uint16_t offset_x, uint16_t offset_y); 1029void qp_set_viewport_offsets(painter_device_t device, uint16_t offset_x, uint16_t offset_y);
@@ -1006,7 +1031,7 @@ void qp_set_viewport_offsets(painter_device_t device, uint16_t offset_x, uint16_
1006 1031
1007The `qp_set_viewport_offsets` function can be used to offset all subsequent drawing operations. For example, if a display controller is internally 240x320, but the display panel is 240x240 and has a Y offset of 80 pixels, you could invoke `qp_set_viewport_offsets(display, 0, 80);` and the drawing positioning would be corrected. 1032The `qp_set_viewport_offsets` function can be used to offset all subsequent drawing operations. For example, if a display controller is internally 240x320, but the display panel is 240x240 and has a Y offset of 80 pixels, you could invoke `qp_set_viewport_offsets(display, 0, 80);` and the drawing positioning would be corrected.
1008 1033
1009#### ** Set Viewport ** 1034==== Set Viewport
1010 1035
1011```c 1036```c
1012bool qp_viewport(painter_device_t device, uint16_t left, uint16_t top, uint16_t right, uint16_t bottom); 1037bool qp_viewport(painter_device_t device, uint16_t left, uint16_t top, uint16_t right, uint16_t bottom);
@@ -1014,7 +1039,7 @@ bool qp_viewport(painter_device_t device, uint16_t left, uint16_t top, uint16_t
1014 1039
1015The `qp_viewport` function controls where raw pixel data is written to. 1040The `qp_viewport` function controls where raw pixel data is written to.
1016 1041
1017#### ** Stream Pixel Data ** 1042==== Stream Pixel Data
1018 1043
1019```c 1044```c
1020bool qp_pixdata(painter_device_t device, const void *pixel_data, uint32_t native_pixel_count); 1045bool qp_pixdata(painter_device_t device, const void *pixel_data, uint32_t native_pixel_count);
@@ -1022,8 +1047,10 @@ bool qp_pixdata(painter_device_t device, const void *pixel_data, uint32_t native
1022 1047
1023The `qp_pixdata` function allows raw pixel data to be streamed to the display. It requires a native pixel count rather than the number of bytes to transfer, to ensure display panel data alignment is respected. E.g. for display panels using RGB565 internal format, sending 10 pixels will result in 20 bytes of transfer. 1048The `qp_pixdata` function allows raw pixel data to be streamed to the display. It requires a native pixel count rather than the number of bytes to transfer, to ensure display panel data alignment is respected. E.g. for display panels using RGB565 internal format, sending 10 pixels will result in 20 bytes of transfer.
1024 1049
1025!> Under normal circumstances, users will not need to manually call either `qp_viewport` or `qp_pixdata`. These allow for writing of raw pixel information, in the display panel's native format, to the area defined by the viewport. 1050::: warning
1051Under normal circumstances, users will not need to manually call either `qp_viewport` or `qp_pixdata`. These allow for writing of raw pixel information, in the display panel's native format, to the area defined by the viewport.
1052:::
1026 1053
1027<!-- tabs:end --> 1054:::::
1028 1055
1029<!-- tabs:end --> 1056::::::