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