1 /**
2  * @file lv_test_font_loader.c
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 
10 #include "lvgl/lvgl.h"
11 #if LV_BUILD_TEST
12 #include "../lv_test_assert.h"
13 #include "lvgl/src/lv_font/lv_font_fmt_txt.h"
14 #include "lvgl/src/lv_font/lv_font.h"
15 #include "lvgl/src/lv_font/lv_font_loader.h"
16 
17 #include "lv_test_font_loader.h"
18 
19 /*********************
20  *      DEFINES
21  *********************/
22 
23 /**********************
24  *      TYPEDEFS
25  **********************/
26 
27 /**********************
28  *  STATIC PROTOTYPES
29  **********************/
30 
31 #if LV_USE_FILESYSTEM
32 static int compare_fonts(lv_font_t * f1, lv_font_t * f2);
33 #endif
34 
35 /**********************
36  *  STATIC VARIABLES
37  **********************/
38 
39 /**********************
40  *      MACROS
41  **********************/
42 
43 /**********************
44  *   GLOBAL FUNCTIONS
45  **********************/
46 
47 extern lv_font_t font_1;
48 extern lv_font_t font_2;
49 extern lv_font_t font_3;
50 
lv_test_font_loader(void)51 void lv_test_font_loader(void)
52 {
53 #if LV_USE_FILESYSTEM
54     lv_font_t * font_1_bin = lv_font_load("f:font_1.fnt");
55     lv_font_t * font_2_bin = lv_font_load("f:font_2.fnt");
56     lv_font_t * font_3_bin = lv_font_load("f:font_3.fnt");
57 
58     compare_fonts(&font_1, font_1_bin);
59     compare_fonts(&font_2, font_2_bin);
60     compare_fonts(&font_3, font_3_bin);
61 
62     lv_font_free(font_1_bin);
63     lv_font_free(font_2_bin);
64     lv_font_free(font_3_bin);
65 #else
66     lv_test_print("SKIP: font load test because it requires LV_USE_FILESYSTEM 1 and LV_FONT_FMT_TXT_LARGE 0");
67 #endif
68 }
69 
70 #if LV_USE_FILESYSTEM
compare_fonts(lv_font_t * f1,lv_font_t * f2)71 static int compare_fonts(lv_font_t * f1, lv_font_t * f2)
72 {
73     lv_test_assert_true(f1 != NULL && f2 != NULL, "font not null");
74 
75     lv_test_assert_ptr_eq(f1->get_glyph_dsc, f2->get_glyph_dsc, "glyph_dsc");
76     lv_test_assert_ptr_eq(f1->get_glyph_bitmap, f2->get_glyph_bitmap, "glyph_bitmap");
77     lv_test_assert_int_eq(f1->line_height, f2->line_height, "line_height");
78     lv_test_assert_int_eq(f1->base_line, f2->base_line, "base_line");
79 #if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0)
80     lv_test_assert_int_eq(f1->subpx, f2->subpx, "subpx");
81 #endif
82     lv_font_fmt_txt_dsc_t * dsc1 = (lv_font_fmt_txt_dsc_t *) f1->dsc;
83     lv_font_fmt_txt_dsc_t * dsc2 = (lv_font_fmt_txt_dsc_t *) f2->dsc;
84 
85     lv_test_assert_int_eq(dsc1->kern_scale, dsc2->kern_scale, "kern_scale");
86     lv_test_assert_int_eq(dsc1->cmap_num, dsc2->cmap_num, "cmap_num");
87     lv_test_assert_int_eq(dsc1->bpp, dsc2->bpp, "bpp");
88     lv_test_assert_int_eq(dsc1->kern_classes, dsc2->kern_classes, "kern_classes");
89     lv_test_assert_int_eq(dsc1->bitmap_format, dsc2->bitmap_format, "bitmap_format");
90 
91     // cmaps
92     int total_glyphs = 0;
93     for(int i = 0; i < dsc1->cmap_num; ++i) {
94         lv_font_fmt_txt_cmap_t * cmaps1 = (lv_font_fmt_txt_cmap_t *) &dsc1->cmaps[i];
95         lv_font_fmt_txt_cmap_t * cmaps2 = (lv_font_fmt_txt_cmap_t *) &dsc2->cmaps[i];
96 
97         lv_test_assert_int_eq(cmaps1->range_start, cmaps2->range_start, "range_start");
98         lv_test_assert_int_eq(cmaps1->range_length, cmaps2->range_length, "range_length");
99         lv_test_assert_int_eq(cmaps1->glyph_id_start, cmaps2->glyph_id_start, "glyph_id_start");
100         lv_test_assert_int_eq(cmaps1->type, cmaps2->type, "type");
101         lv_test_assert_int_eq(cmaps1->list_length, cmaps2->list_length, "list_length");
102 
103         if(cmaps1->unicode_list != NULL && cmaps2->unicode_list != NULL) {
104             lv_test_assert_true(cmaps1->unicode_list && cmaps2->unicode_list, "unicode_list");
105 
106             lv_test_assert_array_eq(
107                     (uint8_t *) cmaps1->unicode_list,
108                     (uint8_t *) cmaps2->unicode_list,
109                     sizeof(uint16_t) * cmaps1->list_length,
110                     "unicode_list");
111             total_glyphs += cmaps1->list_length;
112         }
113         else {
114             total_glyphs += cmaps1->range_length;
115             lv_test_assert_ptr_eq(cmaps1->unicode_list, cmaps2->unicode_list, "unicode_list");
116         }
117 
118         if(cmaps1->glyph_id_ofs_list != NULL && cmaps2->glyph_id_ofs_list != NULL) {
119             uint8_t * ids1 = (uint8_t *) cmaps1->glyph_id_ofs_list;
120             uint8_t * ids2 = (uint8_t *) cmaps2->glyph_id_ofs_list;
121 
122             lv_test_assert_array_eq(ids1, ids2, cmaps1->list_length, "glyph_id_ofs_list");
123         }
124         else {
125             lv_test_assert_ptr_eq(cmaps1->glyph_id_ofs_list, cmaps2->glyph_id_ofs_list, "glyph_id_ofs_list");
126         }
127     }
128 
129     // kern_dsc
130     if (dsc1->kern_classes == 1 && dsc2->kern_classes == 1) {
131         lv_font_fmt_txt_kern_classes_t * kern1 = (lv_font_fmt_txt_kern_classes_t *) dsc1->kern_dsc;
132         lv_font_fmt_txt_kern_classes_t * kern2 = (lv_font_fmt_txt_kern_classes_t *) dsc2->kern_dsc;
133         if (kern1 != NULL && kern2 != NULL) {
134             lv_test_assert_int_eq(kern1->right_class_cnt, kern2->right_class_cnt, "right_class_cnt");
135             lv_test_assert_int_eq(kern1->left_class_cnt, kern2->left_class_cnt, "left_class_cnt");
136 
137             lv_test_assert_array_eq(
138                     (uint8_t *) kern1->left_class_mapping,
139                     (uint8_t *) kern2->left_class_mapping,
140                     kern1->left_class_cnt,
141                     "left_class_mapping");
142 
143             lv_test_assert_array_eq(
144                     (uint8_t *) kern1->right_class_mapping,
145                     (uint8_t *) kern2->right_class_mapping,
146                     kern1->right_class_cnt,
147                     "right_class_mapping");
148 
149             lv_test_assert_array_eq(
150                     (uint8_t *) kern1->class_pair_values,
151                     (uint8_t *) kern2->class_pair_values,
152                     kern1->right_class_cnt * kern1->left_class_cnt,
153                     "class_pair_values");
154         }
155         else {
156             lv_test_assert_ptr_eq(kern1, kern2, "kern");
157         }
158     }
159     else if (dsc1->kern_classes == 0 && dsc2->kern_classes == 0) {
160         lv_font_fmt_txt_kern_pair_t * kern1 = (lv_font_fmt_txt_kern_pair_t *) dsc1->kern_dsc;
161         lv_font_fmt_txt_kern_pair_t * kern2 = (lv_font_fmt_txt_kern_pair_t *) dsc2->kern_dsc;
162         if (kern1 != NULL && kern2 != NULL) {
163             lv_test_assert_int_eq(kern1->glyph_ids_size, kern2->glyph_ids_size, "glyph_ids_size");
164             lv_test_assert_int_eq(kern1->pair_cnt, kern2->pair_cnt, "pair_cnt");
165 
166             int ids_size;
167 
168             if (kern1->glyph_ids_size == 0) {
169                 ids_size = sizeof(int8_t) * 2 * kern1->pair_cnt;
170             }
171             else {
172                 ids_size = sizeof(int16_t) * 2 * kern1->pair_cnt;
173             }
174 
175             lv_test_assert_array_eq(kern1->glyph_ids, kern2->glyph_ids, ids_size, "glyph_ids");
176             lv_test_assert_array_eq(
177                     (uint8_t * ) kern1->values,
178                     (uint8_t * ) kern2->values,
179                     kern1->pair_cnt,
180                     "glyph_values");
181         }
182     }
183 
184     lv_font_fmt_txt_glyph_dsc_t * glyph_dsc1 = (lv_font_fmt_txt_glyph_dsc_t *) dsc1->glyph_dsc;
185     lv_font_fmt_txt_glyph_dsc_t * glyph_dsc2 = (lv_font_fmt_txt_glyph_dsc_t *) dsc2->glyph_dsc;
186 
187     for(int i = 0; i < total_glyphs; ++i) {
188         if (i < total_glyphs - 1) {
189             int size1 = glyph_dsc1[i+1].bitmap_index - glyph_dsc1[i].bitmap_index;
190 
191             if (size1 > 0) {
192                 lv_test_assert_array_eq(
193                         dsc1->glyph_bitmap + glyph_dsc1[i].bitmap_index,
194                         dsc2->glyph_bitmap + glyph_dsc2[i].bitmap_index,
195                         size1 - 1, "glyph_bitmap");
196             }
197         }
198         lv_test_assert_int_eq(glyph_dsc1[i].adv_w, glyph_dsc2[i].adv_w, "adv_w");
199         lv_test_assert_int_eq(glyph_dsc1[i].box_w, glyph_dsc2[i].box_w, "box_w");
200         lv_test_assert_int_eq(glyph_dsc1[i].box_h, glyph_dsc2[i].box_h, "box_h");
201         lv_test_assert_int_eq(glyph_dsc1[i].ofs_x, glyph_dsc2[i].ofs_x, "ofs_x");
202         lv_test_assert_int_eq(glyph_dsc1[i].ofs_y, glyph_dsc2[i].ofs_y, "ofs_y");
203     }
204 
205     LV_LOG_INFO("No differences found!");
206     return 0;
207 }
208 #endif
209 
210 /**********************
211  *   STATIC FUNCTIONS
212  **********************/
213 
214 #endif // LV_BUILD_TEST
215 
216