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