/** * @file lv_font.h * */ #ifndef LV_FONT_FMT_TXT_H #define LV_FONT_FMT_TXT_H #ifdef __cplusplus extern "C" { #endif /********************* * INCLUDES *********************/ #ifdef LV_CONF_INCLUDE_SIMPLE #include "lv_conf.h" #else #include "../../lv_conf.h" #endif #include #include #include #include "lv_font.h" /********************* * DEFINES *********************/ /********************** * TYPEDEFS **********************/ /** This describes a glyph. */ typedef struct { #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). */ #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). */ #endif 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*/ uint8_t ofs_y; /**< y offset of the bounding box. Measured from the top of the line*/ }lv_font_fmt_txt_glyph_dsc_t; /** Format of font character map. */ enum { LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY, LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL, LV_FONT_FMT_TXT_CMAP_SPARSE_TINY, LV_FONT_FMT_TXT_CMAP_SPARSE_FULL, }; typedef uint8_t 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/littlevgl/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/littlevgl/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 :2; }lv_font_fmt_txt_cmap_t; /** 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(gylph_ids[i] == glyph_id_left && gylph_ids[i+1] == glyph_id_right) return values[i / 2]; */ const void * glyph_ids; const int8_t * values; uint32_t pair_cnt :24; 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; /** More complex but more optimal class based kern value storage*/ 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 Get the class of the left and right glyphs as `left_class` and `right_class` left_class = left_class_mapping[glyph_id_left]; right_class = right_class_mapping[glyph_id_right]; 3. value = class_pair_values[(left_class-1)*right_class_cnt + (righ_class-1)] */ const uint8_t * class_pair_values; /*left_class_num * right_class_num value*/ const uint8_t * left_class_mapping; /*Map the glyph_ids to classes: index -> glyph_id -> class_id*/ const uint8_t * right_class_mapping; /*Map the glyph_ids to classes: index -> glyph_id -> class_id*/ uint8_t left_class_cnt; uint8_t right_class_cnt; }lv_font_fmt_txt_kern_classes_t; /** Bitmap formats*/ typedef enum { LV_FONT_FMT_TXT_PLAIN = 0, LV_FONT_FMT_TXT_COMPRESSED = 1, }lv_font_fmt_txt_bitmap_format_t; /*Describe store additional data for fonts */ typedef struct { /*The bitmaps os 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 :10; /*Bit per pixel: 1, 2, 4 or 8*/ uint16_t bpp :3; /*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; /*Cache the last letter and is glyph id*/ uint32_t last_letter; uint32_t last_glyph_id; }lv_font_fmt_txt_dsc_t; /********************** * GLOBAL PROTOTYPES **********************/ /** * Used as `get_glyph_bitmap` callback in LittelvGL's native font format if the font is uncompressed. * @param font pointer to font * @param unicode_letter an unicode letter which bitmap should be get * @return pointer to the bitmap or NULL if not found */ const uint8_t * lv_font_get_bitmap_fmt_txt(const lv_font_t * font, uint32_t letter); /** * Used as `get_glyph_dsc` callback in LittelvGL's native font format if the font is uncompressed. * @param font_p pointer to font * @param dsc_out store the result descriptor here * @param letter an 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_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next); /********************** * MACROS **********************/ /********************** * ADD BUILT IN FONTS **********************/ #ifdef __cplusplus } /* extern "C" */ #endif #endif /*LV_FONT_FMT_TXT_H*/