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