/** * I want to use bitmap fonts generated with lv_font_conv. * This generates a .h bitmap font header from a .TTF file, but it's * designed to be used with the full LVGL library. * This compatibility layer is here so that we can drop * a font .h file into the project and use it without modification. * * This layer includes a lot of code from lv_font_fmt_txt.h to define how * a bitmapped font is expressed. * * See: * - https://github.com/lvgl/lv_font_conv * - https://github.com/lvgl/lvgl/blob/master/src/font/lv_font.h * - https://github.com/lvgl/lvgl/blob/master/src/font/fmt_txt/lv_font_fmt_txt.h * * - Dylan */ #ifndef LVGL_H #define LVGL_H #include "stdint.h" #include "stdbool.h" #ifndef NULL #define NULL 0 #endif /******************************************* */ /* Dummy defines for LVGL font compatibility */ #ifndef LV_ATTRIBUTE_LARGE_CONST #define LV_ATTRIBUTE_LARGE_CONST #endif #ifndef LV_FONT_SUBPX_NONE #define LV_FONT_SUBPX_NONE 0 #endif #ifndef LVGL_VERSION_MAJOR #define LVGL_VERSION_MAJOR 7 #define LV_VERSION_CHECK(X,Y,Z) 0 #endif /******************** */ /* Struct Definitions */ typedef struct _lv_font_t lv_font_t; typedef struct _lv_font_fmt_txt_glyph_dsc_t lv_font_fmt_txt_glyph_dsc_t; typedef struct _lv_draw_buf_t lv_draw_buf_t; struct _lv_font_t { bool (*get_glyph_dsc)(const lv_font_t * font, lv_font_fmt_txt_glyph_dsc_t * dsc_out, uint32_t unicode_letter); /* Function pointer for glyph descriptor */ const void * (*get_glyph_bitmap)(lv_font_fmt_txt_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf); /* Function pointer for glyph bitmap */ uint16_t line_height; /* The maximum line height required by the font */ int16_t base_line; /* Baseline measured from the bottom of the line */ uint8_t subpx; /* Subpixel rendering type */ int16_t underline_position; /* Underline position */ int16_t underline_thickness; /* Underline thickness */ const void * dsc; /* The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ const void * fallback; /* Fallback font (if any) */ void * user_data; /* Custom user data */ }; /** A simple mapping of kern values from pairs*/ typedef struct { /*To get a kern value of two code points: 1. Get the `glyph_id_left` and `glyph_id_right` from `lv_font_fmt_txt_cmap_t 2. for(i = 0; i < pair_cnt * 2; i += 2) if(glyph_ids[i] == glyph_id_left && glyph_ids[i+1] == glyph_id_right) return values[i / 2]; */ const void * glyph_ids; const int8_t * values; uint32_t pair_cnt : 30; uint32_t glyph_ids_size : 2; /**< 0: `glyph_ids` is stored as `uint8_t`; 1: as `uint16_t` */ } lv_font_fmt_txt_kern_pair_t; /** This describes a glyph.*/ struct _lv_font_fmt_txt_glyph_dsc_t { #if LV_FONT_FMT_TXT_LARGE == 0 uint32_t bitmap_index : 20; /**< Start index of the bitmap. A font can be max 1 MB.*/ uint32_t adv_w : 12; /**< Draw the next glyph after this width. 8.4 format (real_value * 16 is stored).*/ uint8_t box_w; /**< Width of the glyph's bounding box*/ uint8_t box_h; /**< Height of the glyph's bounding box*/ int8_t ofs_x; /**< x offset of the bounding box*/ int8_t ofs_y; /**< y offset of the bounding box. Measured from the top of the line*/ #else uint32_t bitmap_index; /**< Start index of the bitmap. A font can be max 4 GB.*/ uint32_t adv_w; /**< Draw the next glyph after this width. 28.4 format (real_value * 16 is stored).*/ uint16_t box_w; /**< Width of the glyph's bounding box*/ uint16_t box_h; /**< Height of the glyph's bounding box*/ int16_t ofs_x; /**< x offset of the bounding box*/ int16_t ofs_y; /**< y offset of the bounding box. Measured from the top of the line*/ #endif }; /** Format of font character map.*/ typedef enum { LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL, LV_FONT_FMT_TXT_CMAP_SPARSE_FULL, LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY, LV_FONT_FMT_TXT_CMAP_SPARSE_TINY, } lv_font_fmt_txt_cmap_type_t; /** * Map codepoints to a `glyph_dsc`s * Several formats are supported to optimize memory usage * See https://github.com/lvgl/lv_font_conv/blob/master/doc/font_spec.md */ typedef struct { /** First Unicode character for this range*/ uint32_t range_start; /** Number of Unicode characters related to this range. * Last Unicode character = range_start + range_length - 1*/ uint16_t range_length; /** First glyph ID (array index of `glyph_dsc`) for this range*/ uint16_t glyph_id_start; /* According the specification there are 4 formats: https://github.com/lvgl/lv_font_conv/blob/master/doc/font_spec.md For simplicity introduce "relative code point": rcp = codepoint - range_start and a search function: search a "value" in an "array" and returns the index of "value". Format 0 tiny unicode_list == NULL && glyph_id_ofs_list == NULL glyph_id = glyph_id_start + rcp Format 0 full unicode_list == NULL && glyph_id_ofs_list != NULL glyph_id = glyph_id_start + glyph_id_ofs_list[rcp] Sparse tiny unicode_list != NULL && glyph_id_ofs_list == NULL glyph_id = glyph_id_start + search(unicode_list, rcp) Sparse full unicode_list != NULL && glyph_id_ofs_list != NULL glyph_id = glyph_id_start + glyph_id_ofs_list[search(unicode_list, rcp)] */ const uint16_t * unicode_list; /** if(type == LV_FONT_FMT_TXT_CMAP_FORMAT0_...) it's `uint8_t *` * if(type == LV_FONT_FMT_TXT_CMAP_SPARSE_...) it's `uint16_t *` */ const void * glyph_id_ofs_list; /** Length of `unicode_list` and/or `glyph_id_ofs_list`*/ uint16_t list_length; /** Type of this character map*/ lv_font_fmt_txt_cmap_type_t type; } lv_font_fmt_txt_cmap_t; /** Bitmap formats*/ typedef enum { LV_FONT_FMT_TXT_PLAIN = 0, LV_FONT_FMT_TXT_COMPRESSED = 1, LV_FONT_FMT_TXT_COMPRESSED_NO_PREFILTER = 2, } lv_font_fmt_txt_bitmap_format_t; /** Describe store for additional data for fonts */ typedef struct { /** The bitmaps of all glyphs */ const uint8_t * glyph_bitmap; /** Describe the glyphs */ const lv_font_fmt_txt_glyph_dsc_t * glyph_dsc; /** Map the glyphs to Unicode characters. *Array of `lv_font_cmap_fmt_txt_t` variables */ const lv_font_fmt_txt_cmap_t * cmaps; /** * Store kerning values. * Can be `lv_font_fmt_txt_kern_pair_t * or `lv_font_kern_classes_fmt_txt_t *` * depending on `kern_classes` */ const void * kern_dsc; /** Scale kern values in 12.4 format */ uint16_t kern_scale; /** Number of cmap tables */ uint16_t cmap_num : 9; /** Bit per pixel: 1, 2, 3, 4, 8 */ uint16_t bpp : 4; /** Type of `kern_dsc` */ uint16_t kern_classes : 1; /** * storage format of the bitmap * from `lv_font_fmt_txt_bitmap_format_t` */ uint16_t bitmap_format : 2; /** * Bytes to which each line is padded. * 0: means no align and padding * 1: e.g. with bpp=4 lines are aligned to 1 byte, so there can be a 4 bits of padding * 4, 8, 16, 32, 64: each line is padded to the given byte boundaries */ uint8_t stride; } lv_font_fmt_txt_dsc_t; struct _lv_draw_buf_t { uint32_t data_size; /**< Total buf size in bytes */ uint8_t * data; }; /********************** * GLOBAL PROTOTYPES **********************/ /** * Used as `get_glyph_bitmap` callback in lvgl's native font format if the font is uncompressed. * @param g_dsc the glyph descriptor including which font to use, which supply the glyph_index and format. * @param draw_buf a draw buffer that can be used to store the bitmap of the glyph, it's OK not to use it. * @return pointer to an A8 bitmap (not necessarily bitmap_out) or NULL if `unicode_letter` not found */ const void * lv_font_get_bitmap_fmt_txt(lv_font_fmt_txt_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf); /** * Used as `get_glyph_dsc` callback in lvgl's native font format if the font is uncompressed. * @param font pointer to font * @param dsc_out store the result descriptor here * @param unicode_letter a UNICODE letter code * @return true: descriptor is successfully loaded into `dsc_out`. * false: the letter was not found, no data is loaded to `dsc_out` */ bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_fmt_txt_glyph_dsc_t * dsc_out, uint32_t unicode_letter); #endif