qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

quantum_painter_qff.md (5615B)


      1 # QMK Font Format {#qmk-font-format}
      2 
      3 QMK uses a font format _("Quantum Font Format" - QFF)_ specifically for resource-constrained systems.
      4 
      5 This format is capable of encoding 1-, 2-, 4-, and 8-bit-per-pixel greyscale- and palette-based images into a font. It also includes RLE for pixel data for some basic compression.
      6 
      7 All integer values are in little-endian format.
      8 
      9 The QFF is defined in terms of _blocks_ -- each _block_ contains a _header_ and an optional _blob_ of data. The _header_ contains the block's _typeid_, and the length of the _blob_ that follows. Each block type is denoted by a different _typeid_ has its own block definition below. All blocks are defined as packed structs, containing zero padding between fields.
     10 
     11 The general structure of the file is:
     12 
     13 * _Font descriptor block_
     14 * _ASCII glyph block_ (optional, only if ASCII glyphs are included)
     15 * _Unicode glyph block_ (optional, only if Unicode glyphs are included)
     16 * _Font palette block_ (optional, depending on frame format)
     17 * _Font data block_
     18 
     19 ## Block Header {#qff-block-header}
     20 
     21 The block header is identical to [QGF's block header](quantum_painter_qgf#qgf-block-header), and is present for all blocks, including the font descriptor.
     22 
     23 ## Font descriptor block {#qff-font-descriptor}
     24 
     25 * _typeid_ = 0x00
     26 * _length_ = 20
     27 
     28 This block must be located at the start of the file contents, and can exist a maximum of once in an entire QGF file. It is always followed by either the _ASCII glyph table_ or the _Unicode glyph table_, depending on which glyphs are included in the font.
     29 
     30 _Block_ format:
     31 
     32 ```c
     33 typedef struct __attribute__((packed)) qff_font_descriptor_v1_t {
     34     qgf_block_header_v1_t header;               // = { .type_id = 0x00, .neg_type_id = (~0x00), .length = 20 }
     35     uint24_t              magic;                // constant, equal to 0x464651 ("QFF")
     36     uint8_t               qff_version;          // constant, equal to 0x01
     37     uint32_t              total_file_size;      // total size of the entire file, starting at offset zero
     38     uint32_t              neg_total_file_size;  // negated value of total_file_size, used for detecting parsing errors
     39     uint8_t               line_height;          // glyph height in pixels
     40     bool                  has_ascii_table;      // whether the font has an ascii table of glyphs (0x20...0x7E)
     41     uint16_t              num_unicode_glyphs;   // the number of glyphs in the unicode table -- no table specified if zero
     42     uint8_t               format;               // frame format, see below.
     43     uint8_t               flags;                // frame flags, see below.
     44     uint8_t               compression_scheme;   // compression scheme, see below.
     45     uint8_t               transparency_index;   // palette index used for transparent pixels (not yet implemented)
     46 } qff_font_descriptor_v1_t;
     47 // STATIC_ASSERT(sizeof(qff_font_descriptor_v1_t) == (sizeof(qgf_block_header_v1_t) + 20), "qff_font_descriptor_v1_t must be 25 bytes in v1 of QFF");
     48 ```
     49 
     50 The values for `format`, `flags`, `compression_scheme`, and `transparency_index` match [QGF's frame descriptor block](quantum_painter_qgf#qgf-frame-descriptor), with the exception that the `delta` flag is ignored by QFF.
     51 
     52 ## ASCII glyph table {#qff-ascii-table}
     53 
     54 * _typeid_ = 0x01
     55 * _length_ = 290
     56 
     57 If the font contains ascii characters, the _ASCII glyph block_ must be located directly after the _font descriptor block_.
     58 
     59 ```c
     60 #define QFF_GLYPH_WIDTH_BITS 6
     61 #define QFF_GLYPH_WIDTH_MASK ((1<<QFF_GLYPH_WIDTH_BITS)-1)
     62 #define QFF_GLYPH_OFFSET_BITS 18
     63 #define QFF_GLYPH_OFFSET_MASK (((1<<QFF_GLYPH_OFFSET_BITS)-1) << QFF_GLYPH_WIDTH_BITS)
     64 
     65 typedef struct __attribute__((packed)) qff_ascii_glyph_table_v1_t {
     66     qgf_block_header_v1_t header;  // = { .type_id = 0x01, .neg_type_id = (~0x01), .length = 285 }
     67     uint24_t glyph[95];            // 95 glyphs, 0x20..0x7E, see bits/masks above for values
     68 } qff_ascii_glyph_table_v1_t;
     69 // STATIC_ASSERT(sizeof(qff_ascii_glyph_table_v1_t) == (sizeof(qgf_block_header_v1_t) + 285), "qff_ascii_glyph_table_v1_t must be 290 bytes in v1 of QFF");
     70 ```
     71 
     72 ## Unicode glyph table {#qff-unicode-table}
     73 
     74 * _typeid_ = 0x02
     75 * _length_ = variable
     76 
     77 If this font contains unicode characters, the _unicode glyph block_ must be located directly after the _ASCII glyph table block_, or the _font descriptor block_ if the font does not contain ASCII characters.
     78 
     79 ```c
     80 typedef struct __attribute__((packed)) qff_unicode_glyph_table_v1_t {
     81     qgf_block_header_v1_t header;     // = { .type_id = 0x02, .neg_type_id = (~0x02), .length = (N * 6) }
     82     struct __attribute__((packed)) {  // container for a single unicode glyph
     83         uint24_t code_point;          // the unicode code point
     84         uint24_t glyph;               // the glyph information, as per ASCII glyphs above
     85     } glyph[N];                       // N glyphs worth of data
     86 } qff_unicode_glyph_table_v1_t;
     87 ```
     88 
     89 ## Font palette block {#qff-palette-descriptor}
     90 
     91 * _typeid_ = 0x03
     92 * _length_ = variable
     93 
     94 The _font palette block_ is identical to [QGF's frame palette block](quantum_painter_qgf#qgf-frame-palette-descriptor), retaining the same _typeid_ of 0x03.
     95 
     96 It is only specified in the QFF if the font is palette-based, and follows the _unicode glyph block_ if the font contains any Unicode glyphs, or the _ASCII glyph block_ if the font contains only ASCII glyphs.
     97 
     98 ## Font data block {#qff-data-descriptor}
     99 
    100 * _typeid_ = 0x04
    101 * _length_ = variable
    102 
    103 The _font data block_ is the last block in the file and is identical to [QGF's frame data block](quantum_painter_qgf#qgf-frame-data-descriptor), however has a different _typeid_ of 0x04 in QFF.