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