qmk_firmware

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

qff.h (4271B)


      1 // Copyright 2021 Nick Brassel (@tzarc)
      2 // SPDX-License-Identifier: GPL-2.0-or-later
      3 
      4 #pragma once
      5 
      6 // Quantum Font File "QFF" File Format.
      7 // See https://docs.qmk.fm/#/quantum_painter_qff for more information.
      8 
      9 #include <stdint.h>
     10 #include <stdbool.h>
     11 
     12 #include "compiler_support.h"
     13 #include "qp_stream.h"
     14 #include "qp_internal.h"
     15 #include "qgf.h"
     16 
     17 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     18 // QFF structures
     19 
     20 /////////////////////////////////////////
     21 // Font descriptor
     22 
     23 #define QFF_FONT_DESCRIPTOR_TYPEID 0x00
     24 
     25 typedef struct PACKED qff_font_descriptor_v1_t {
     26     qgf_block_header_v1_t header;              // = { .type_id = 0x00, .neg_type_id = (~0x00), .length = 20 }
     27     uint32_t              magic : 24;          // constant, equal to 0x464651 ("QFF")
     28     uint8_t               qff_version;         // constant, equal to 0x01
     29     uint32_t              total_file_size;     // total size of the entire file, starting at offset zero
     30     uint32_t              neg_total_file_size; // negated value of total_file_size, used for detecting parsing errors
     31     uint8_t               line_height;         // glyph height in pixels
     32     bool                  has_ascii_table;     // whether the font has an ascii table of glyphs (0x20...0x7E)
     33     uint16_t              num_unicode_glyphs;  // the number of glyphs in the unicode table -- no table specified if zero
     34     qp_image_format_t     format : 8;          // Frame format, see qp.h.
     35     uint8_t               flags;               // frame flags, see below.
     36     uint8_t               compression_scheme;  // compression scheme, see below.
     37     uint8_t               transparency_index;  // palette index used for transparent pixels (not yet implemented)
     38 } qff_font_descriptor_v1_t;
     39 
     40 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");
     41 
     42 #define QFF_MAGIC 0x464651
     43 
     44 /////////////////////////////////////////
     45 // ASCII glyph table descriptor
     46 
     47 #define QFF_ASCII_GLYPH_DESCRIPTOR_TYPEID 0x01
     48 
     49 #define QFF_GLYPH_WIDTH_BITS 6
     50 #define QFF_GLYPH_WIDTH_MASK ((1 << QFF_GLYPH_WIDTH_BITS) - 1)
     51 #define QFF_GLYPH_OFFSET_BITS 18
     52 #define QFF_GLYPH_OFFSET_MASK (((1 << QFF_GLYPH_OFFSET_BITS) - 1) << QFF_GLYPH_WIDTH_BITS)
     53 
     54 typedef struct PACKED qff_ascii_glyph_v1_t {
     55     uint32_t value : 24; // Uses QFF_GLYPH_*_(BITS|MASK) as bitfield ordering is compiler-defined
     56 } qff_ascii_glyph_v1_t;
     57 
     58 STATIC_ASSERT(sizeof(qff_ascii_glyph_v1_t) == 3, "qff_ascii_glyph_v1_t must be 3 bytes in v1 of QFF");
     59 
     60 typedef struct PACKED qff_ascii_glyph_table_v1_t {
     61     qgf_block_header_v1_t header;    // = { .type_id = 0x01, .neg_type_id = (~0x01), .length = 285 }
     62     qff_ascii_glyph_v1_t  glyph[95]; // 95 glyphs, 0x20..0x7E
     63 } qff_ascii_glyph_table_v1_t;
     64 
     65 STATIC_ASSERT(sizeof(qff_ascii_glyph_table_v1_t) == (sizeof(qgf_block_header_v1_t) + (95 * sizeof(qff_ascii_glyph_v1_t))), "qff_ascii_glyph_table_v1_t must be 290 bytes in v1 of QFF");
     66 
     67 /////////////////////////////////////////
     68 // Unicode glyph table descriptor
     69 
     70 #define QFF_UNICODE_GLYPH_DESCRIPTOR_TYPEID 0x02
     71 
     72 typedef struct PACKED qff_unicode_glyph_v1_t {
     73     uint32_t code_point : 24;
     74     uint32_t value : 24; // Uses QFF_GLYPH_*_(BITS|MASK) as bitfield ordering is compiler-defined
     75 } qff_unicode_glyph_v1_t;
     76 
     77 STATIC_ASSERT(sizeof(qff_unicode_glyph_v1_t) == 6, "qff_unicode_glyph_v1_t must be 6 bytes in v1 of QFF");
     78 
     79 typedef struct PACKED qff_unicode_glyph_table_v1_t {
     80     qgf_block_header_v1_t  header;   // = { .type_id = 0x02, .neg_type_id = (~0x02), .length = (N * 6) }
     81     qff_unicode_glyph_v1_t glyph[0]; // Extent of '0' signifies that this struct is immediately followed by the glyph data
     82 } qff_unicode_glyph_table_v1_t;
     83 
     84 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     85 // QFF API
     86 
     87 bool     qff_validate_stream(qp_stream_t *stream);
     88 uint32_t qff_get_total_size(qp_stream_t *stream);
     89 bool     qff_read_font_descriptor(qp_stream_t *stream, uint8_t *line_height, bool *has_ascii_table, uint16_t *num_unicode_glyphs, uint8_t *bpp, bool *has_palette, bool *is_panel_native, painter_compression_t *compression_scheme, uint32_t *total_bytes);