1 /** 2 * @file lv_font_fmt_txt.h 3 * 4 */ 5 6 #ifndef LV_FONT_FMT_TXT_H 7 #define LV_FONT_FMT_TXT_H 8 9 #ifdef __cplusplus 10 extern "C" { 11 #endif 12 13 /********************* 14 * INCLUDES 15 *********************/ 16 #include <stdint.h> 17 #include <stddef.h> 18 #include <stdbool.h> 19 #include "lv_font.h" 20 21 /********************* 22 * DEFINES 23 *********************/ 24 25 /********************** 26 * TYPEDEFS 27 **********************/ 28 29 /** This describes a glyph.*/ 30 typedef struct { 31 #if LV_FONT_FMT_TXT_LARGE == 0 32 uint32_t bitmap_index : 20; /**< Start index of the bitmap. A font can be max 1 MB.*/ 33 uint32_t adv_w : 12; /**< Draw the next glyph after this width. 8.4 format (real_value * 16 is stored).*/ 34 uint8_t box_w; /**< Width of the glyph's bounding box*/ 35 uint8_t box_h; /**< Height of the glyph's bounding box*/ 36 int8_t ofs_x; /**< x offset of the bounding box*/ 37 int8_t ofs_y; /**< y offset of the bounding box. Measured from the top of the line*/ 38 #else 39 uint32_t bitmap_index; /**< Start index of the bitmap. A font can be max 4 GB.*/ 40 uint32_t adv_w; /**< Draw the next glyph after this width. 28.4 format (real_value * 16 is stored).*/ 41 uint16_t box_w; /**< Width of the glyph's bounding box*/ 42 uint16_t box_h; /**< Height of the glyph's bounding box*/ 43 int16_t ofs_x; /**< x offset of the bounding box*/ 44 int16_t ofs_y; /**< y offset of the bounding box. Measured from the top of the line*/ 45 #endif 46 } lv_font_fmt_txt_glyph_dsc_t; 47 48 /** Format of font character map.*/ 49 enum { 50 LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL, 51 LV_FONT_FMT_TXT_CMAP_SPARSE_FULL, 52 LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY, 53 LV_FONT_FMT_TXT_CMAP_SPARSE_TINY, 54 }; 55 56 typedef uint8_t lv_font_fmt_txt_cmap_type_t; 57 58 /** 59 * Map codepoints to a `glyph_dsc`s 60 * Several formats are supported to optimize memory usage 61 * See https://github.com/lvgl/lv_font_conv/blob/master/doc/font_spec.md 62 */ 63 typedef struct { 64 /** First Unicode character for this range*/ 65 uint32_t range_start; 66 67 /** Number of Unicode characters related to this range. 68 * Last Unicode character = range_start + range_length - 1*/ 69 uint16_t range_length; 70 71 /** First glyph ID (array index of `glyph_dsc`) for this range*/ 72 uint16_t glyph_id_start; 73 74 /* 75 According the specification there are 4 formats: 76 https://github.com/lvgl/lv_font_conv/blob/master/doc/font_spec.md 77 78 For simplicity introduce "relative code point": 79 rcp = codepoint - range_start 80 81 and a search function: 82 search a "value" in an "array" and returns the index of "value". 83 84 Format 0 tiny 85 unicode_list == NULL && glyph_id_ofs_list == NULL 86 glyph_id = glyph_id_start + rcp 87 88 Format 0 full 89 unicode_list == NULL && glyph_id_ofs_list != NULL 90 glyph_id = glyph_id_start + glyph_id_ofs_list[rcp] 91 92 Sparse tiny 93 unicode_list != NULL && glyph_id_ofs_list == NULL 94 glyph_id = glyph_id_start + search(unicode_list, rcp) 95 96 Sparse full 97 unicode_list != NULL && glyph_id_ofs_list != NULL 98 glyph_id = glyph_id_start + glyph_id_ofs_list[search(unicode_list, rcp)] 99 */ 100 101 const uint16_t * unicode_list; 102 103 /** if(type == LV_FONT_FMT_TXT_CMAP_FORMAT0_...) it's `uint8_t *` 104 * if(type == LV_FONT_FMT_TXT_CMAP_SPARSE_...) it's `uint16_t *` 105 */ 106 const void * glyph_id_ofs_list; 107 108 /** Length of `unicode_list` and/or `glyph_id_ofs_list`*/ 109 uint16_t list_length; 110 111 /** Type of this character map*/ 112 lv_font_fmt_txt_cmap_type_t type; 113 } lv_font_fmt_txt_cmap_t; 114 115 /** A simple mapping of kern values from pairs*/ 116 typedef struct { 117 /*To get a kern value of two code points: 118 1. Get the `glyph_id_left` and `glyph_id_right` from `lv_font_fmt_txt_cmap_t 119 2. for(i = 0; i < pair_cnt * 2; i += 2) 120 if(gylph_ids[i] == glyph_id_left && 121 gylph_ids[i+1] == glyph_id_right) 122 return values[i / 2]; 123 */ 124 const void * glyph_ids; 125 const int8_t * values; 126 uint32_t pair_cnt : 30; 127 uint32_t glyph_ids_size : 2; /*0: `glyph_ids` is stored as `uint8_t`; 1: as `uint16_t`*/ 128 } lv_font_fmt_txt_kern_pair_t; 129 130 /** More complex but more optimal class based kern value storage*/ 131 typedef struct { 132 /*To get a kern value of two code points: 133 1. Get the `glyph_id_left` and `glyph_id_right` from `lv_font_fmt_txt_cmap_t 134 2. Get the class of the left and right glyphs as `left_class` and `right_class` 135 left_class = left_class_mapping[glyph_id_left]; 136 right_class = right_class_mapping[glyph_id_right]; 137 3. value = class_pair_values[(left_class-1)*right_class_cnt + (right_class-1)] 138 */ 139 140 const int8_t * class_pair_values; /*left_class_cnt * right_class_cnt value*/ 141 const uint8_t * left_class_mapping; /*Map the glyph_ids to classes: index -> glyph_id -> class_id*/ 142 const uint8_t * right_class_mapping; /*Map the glyph_ids to classes: index -> glyph_id -> class_id*/ 143 uint8_t left_class_cnt; 144 uint8_t right_class_cnt; 145 } lv_font_fmt_txt_kern_classes_t; 146 147 /** Bitmap formats*/ 148 typedef enum { 149 LV_FONT_FMT_TXT_PLAIN = 0, 150 LV_FONT_FMT_TXT_COMPRESSED = 1, 151 LV_FONT_FMT_TXT_COMPRESSED_NO_PREFILTER = 1, 152 } lv_font_fmt_txt_bitmap_format_t; 153 154 typedef struct { 155 uint32_t last_letter; 156 uint32_t last_glyph_id; 157 } lv_font_fmt_txt_glyph_cache_t; 158 159 /*Describe store additional data for fonts*/ 160 typedef struct { 161 /*The bitmaps of all glyphs*/ 162 const uint8_t * glyph_bitmap; 163 164 /*Describe the glyphs*/ 165 const lv_font_fmt_txt_glyph_dsc_t * glyph_dsc; 166 167 /*Map the glyphs to Unicode characters. 168 *Array of `lv_font_cmap_fmt_txt_t` variables*/ 169 const lv_font_fmt_txt_cmap_t * cmaps; 170 171 /** 172 * Store kerning values. 173 * Can be `lv_font_fmt_txt_kern_pair_t * or `lv_font_kern_classes_fmt_txt_t *` 174 * depending on `kern_classes` 175 */ 176 const void * kern_dsc; 177 178 /*Scale kern values in 12.4 format*/ 179 uint16_t kern_scale; 180 181 /*Number of cmap tables*/ 182 uint16_t cmap_num : 9; 183 184 /*Bit per pixel: 1, 2, 3, 4, 8*/ 185 uint16_t bpp : 4; 186 187 /*Type of `kern_dsc`*/ 188 uint16_t kern_classes : 1; 189 190 /* 191 * storage format of the bitmap 192 * from `lv_font_fmt_txt_bitmap_format_t` 193 */ 194 uint16_t bitmap_format : 2; 195 196 /*Cache the last letter and is glyph id*/ 197 lv_font_fmt_txt_glyph_cache_t * cache; 198 } lv_font_fmt_txt_dsc_t; 199 200 /********************** 201 * GLOBAL PROTOTYPES 202 **********************/ 203 204 /** 205 * Used as `get_glyph_bitmap` callback in LittelvGL's native font format if the font is uncompressed. 206 * @param font pointer to font 207 * @param unicode_letter an unicode letter which bitmap should be get 208 * @return pointer to the bitmap or NULL if not found 209 */ 210 const uint8_t * lv_font_get_bitmap_fmt_txt(const lv_font_t * font, uint32_t letter); 211 212 /** 213 * Used as `get_glyph_dsc` callback in LittelvGL's native font format if the font is uncompressed. 214 * @param font_p pointer to font 215 * @param dsc_out store the result descriptor here 216 * @param letter an UNICODE letter code 217 * @return true: descriptor is successfully loaded into `dsc_out`. 218 * false: the letter was not found, no data is loaded to `dsc_out` 219 */ 220 bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, 221 uint32_t unicode_letter_next); 222 223 /** 224 * Free the allocated memories. 225 */ 226 void _lv_font_clean_up_fmt_txt(void); 227 228 /********************** 229 * MACROS 230 **********************/ 231 232 /********************** 233 * ADD BUILT IN FONTS 234 **********************/ 235 236 #ifdef __cplusplus 237 } /*extern "C"*/ 238 #endif 239 240 #endif /*LV_FONT_FMT_TXT_H*/ 241