Adding support to dynamic font loading.

This commit is contained in:
Fabio Guerra
2020-08-03 19:33:52 -03:00
parent c85295b5ea
commit f58d97d990
10 changed files with 909 additions and 0 deletions

View File

@@ -30,6 +30,7 @@ CSRCS += lv_test_assert.c
CSRCS += lv_test_core/lv_test_core.c
CSRCS += lv_test_core/lv_test_obj.c
CSRCS += lv_test_core/lv_test_style.c
CSRCS += lv_test_core/lv_test_font_loader.c
OBJEXT ?= .o

View File

@@ -97,6 +97,15 @@ void lv_test_error(const char * s, ...)
exit(1);
}
void lv_test_assert_true(int32_t expression, const char * s)
{
if(!expression) {
lv_test_error(" FAIL: %s. (Expected: not zero)", s, expression);
} else {
lv_test_print(" PASS: %s. (Expected: not zero)", s, expression);
}
}
void lv_test_assert_int_eq(int32_t n_ref, int32_t n_act, const char * s)
{
if(n_ref != n_act) {

View File

@@ -32,6 +32,7 @@ extern "C" {
void lv_test_print(const char * s, ...);
void lv_test_exit(const char * s, ...);
void lv_test_error(const char * s, ...);
void lv_test_assert_true(int32_t expression, const char * s);
void lv_test_assert_int_eq(int32_t n1, int32_t n2, const char * s);
void lv_test_assert_int_gt(int32_t n_ref, int32_t n_act, const char * s);
void lv_test_assert_int_lt(int32_t n_ref, int32_t n_act, const char * s);

View File

@@ -12,6 +12,7 @@
#include "lv_test_core.h"
#include "lv_test_obj.h"
#include "lv_test_style.h"
#include "lv_test_font_loader.h"
/*********************
* DEFINES
@@ -46,6 +47,7 @@ void lv_test_core(void)
lv_test_obj();
lv_test_style();
lv_test_font_loader();
}

View File

@@ -0,0 +1,154 @@
/**
* @file lv_test_font_loader.c
*
*/
/*********************
* INCLUDES
*********************/
#include "../lv_test_assert.h"
#if LV_BUILD_TEST
#include "../lvgl.h"
#include "../src/lv_font/lv_font_fmt_txt.h"
#include "../src/lv_font/lv_font.h"
#include "../src/lv_font/lv_font_loader.h"
#include "lv_test_font_loader.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static int compare_fonts(lv_font_t * f1, lv_font_t * f2);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void lv_test_font_loader(void)
{
lv_font_t * font = lv_font_load("f:lv_font_montserrat_12.bin");
compare_fonts(&lv_font_montserrat_12, font);
}
static int compare_fonts(lv_font_t * f1, lv_font_t * f2)
{
lv_test_assert_true(f1 != NULL && f2 != NULL, "error loading font");
lv_test_assert_ptr_eq(f1->get_glyph_dsc, f2->get_glyph_dsc, "glyph_dsc");
lv_test_assert_ptr_eq(f1->get_glyph_bitmap, f2->get_glyph_bitmap, "glyph_bitmap");
lv_test_assert_int_eq(f1->line_height, f2->line_height, "line_height");
lv_test_assert_int_eq(f1->base_line, f2->base_line, "base_line");
#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0)
lv_test_assert_int_eq(f1->subpx, f2->subpx, "subpx");
#endif
lv_font_fmt_txt_dsc_t * dsc1 = (lv_font_fmt_txt_dsc_t *) f1->dsc;
lv_font_fmt_txt_dsc_t * dsc2 = (lv_font_fmt_txt_dsc_t *) f2->dsc;
lv_test_assert_int_eq(dsc1->kern_scale, dsc2->kern_scale, "kern_scale");
lv_test_assert_int_eq(dsc1->cmap_num, dsc2->cmap_num, "cmap_num");
lv_test_assert_int_eq(dsc1->bpp, dsc2->bpp, "bpp");
lv_test_assert_int_eq(dsc1->kern_classes, dsc2->kern_classes, "kern_classes");
lv_test_assert_int_eq(dsc1->bitmap_format, dsc2->bitmap_format, "bitmap_format");
// cmaps
int total_glyphs = 0;
for(int i = 0; i < dsc1->cmap_num; ++i) {
lv_font_fmt_txt_cmap_t * cmaps1 = (lv_font_fmt_txt_cmap_t *) &dsc1->cmaps[i];
lv_font_fmt_txt_cmap_t * cmaps2 = (lv_font_fmt_txt_cmap_t *) &dsc2->cmaps[i];
lv_test_assert_int_eq(cmaps1->range_start, cmaps2->range_start, "range_start");
lv_test_assert_int_eq(cmaps1->range_length, cmaps2->range_length, "range_length");
lv_test_assert_int_eq(cmaps1->glyph_id_start, cmaps2->glyph_id_start, "glyph_id_start");
lv_test_assert_int_eq(cmaps1->type, cmaps2->type, "type");
lv_test_assert_int_eq(cmaps1->list_length, cmaps2->list_length, "list_length");
if(cmaps1->unicode_list != NULL && cmaps2->unicode_list != NULL) {
lv_test_assert_true(cmaps1->unicode_list && cmaps2->unicode_list, "unicode_list");
for(int k = 0; k < cmaps1->list_length; ++k) {
lv_test_assert_int_eq(cmaps1->unicode_list[k], cmaps2->unicode_list[k], "unicode_list");
}
total_glyphs += cmaps1->list_length;
}
else {
total_glyphs += cmaps1->range_length;
lv_test_assert_ptr_eq(cmaps1->unicode_list, cmaps2->unicode_list, "unicode_list");
}
if(cmaps1->glyph_id_ofs_list != NULL && cmaps2->glyph_id_ofs_list != NULL) {
uint8_t * ids1 = (uint8_t *) cmaps1->glyph_id_ofs_list;
uint8_t * ids2 = (uint8_t *) cmaps2->glyph_id_ofs_list;
for(int j = 0; j < cmaps1->range_length; j++) {
lv_test_assert_int_eq(ids1[j], ids2[j], "glyph_id_ofs_list");
}
}
else {
lv_test_assert_ptr_eq(cmaps1->glyph_id_ofs_list, cmaps2->glyph_id_ofs_list, "glyph_id_ofs_list");
}
}
// kern_dsc
lv_font_fmt_txt_kern_classes_t * kern1 = (lv_font_fmt_txt_kern_classes_t *) dsc1->kern_dsc;
lv_font_fmt_txt_kern_classes_t * kern2 = (lv_font_fmt_txt_kern_classes_t *) dsc2->kern_dsc;
lv_test_assert_int_eq(kern1->right_class_cnt, kern2->right_class_cnt, "right_class_cnt");
lv_test_assert_int_eq(kern1->left_class_cnt, kern2->left_class_cnt, "left_class_cnt");
for(int i = 0; i < kern1->left_class_cnt; ++i) {
lv_test_assert_int_eq(kern1->left_class_mapping[i],
kern2->left_class_mapping[i], "left_class_mapping");
}
for(int i = 0; i < kern1->right_class_cnt; ++i) {
lv_test_assert_int_eq(kern1->right_class_mapping[i],
kern2->right_class_mapping[i], "right_class_mapping");
}
for(int i = 0; i < kern1->right_class_cnt * kern1->left_class_cnt; ++i) {
lv_test_assert_int_eq(kern1->class_pair_values[i],
kern2->class_pair_values[i], "class_pair_values");
}
// TODO: glyph_bitmap
lv_font_fmt_txt_glyph_dsc_t * glyph_dsc1 = (lv_font_fmt_txt_glyph_dsc_t *) dsc1->glyph_dsc;
lv_font_fmt_txt_glyph_dsc_t * glyph_dsc2 = (lv_font_fmt_txt_glyph_dsc_t *) dsc2->glyph_dsc;
for(int i = 0; i < total_glyphs; ++i) {
//lv_test_assert_int_eq(glyph_dsc1[i].bitmap_index, glyph_dsc2[i].bitmap_index, "bitmap_index");
lv_test_assert_int_eq(glyph_dsc1[i].adv_w, glyph_dsc2[i].adv_w, "adv_w");
lv_test_assert_int_eq(glyph_dsc1[i].box_w, glyph_dsc2[i].box_w, "box_w");
lv_test_assert_int_eq(glyph_dsc1[i].box_h, glyph_dsc2[i].box_h, "box_h");
lv_test_assert_int_eq(glyph_dsc1[i].ofs_x, glyph_dsc2[i].ofs_x, "ofs_x");
lv_test_assert_int_eq(glyph_dsc1[i].ofs_y, glyph_dsc2[i].ofs_y, "ofs_y");
}
LV_LOG_INFO("No differences found!");
return 0;
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif // LV_BUILD_TEST

View File

@@ -0,0 +1,39 @@
/**
* @file lv_font_loader.h
*
*/
#ifndef LV_TEST_FONT_LOADER_H
#define LV_TEST_FONT_LOADER_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_test_font_loader(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_TEST_FONT_LOADER_H*/

View File

@@ -23,6 +23,61 @@ int main(void)
}
static lv_fs_res_t open_cb(struct _lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode)
{
(void) drv;
(void) mode;
FILE * fp = fopen(path, "rb"); // only reading is supported
*((FILE **)file_p) = fp;
return NULL == fp ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK;
}
static lv_fs_res_t close_cb(struct _lv_fs_drv_t * drv, void * file_p)
{
(void) drv;
FILE * fp = *((FILE **) file_p);
fclose(fp);
return LV_FS_RES_OK;
}
static lv_fs_res_t read_cb(struct _lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br)
{
(void) drv;
FILE * fp = *((FILE **) file_p);
*br = fread(buf, 1, btr, fp);
return (*br <= 0) ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK;
}
static lv_fs_res_t seek_cb(struct _lv_fs_drv_t * drv, void * file_p, uint32_t pos)
{
(void) drv;
FILE * fp = *((FILE **) file_p);
fseek (fp, pos, SEEK_SET);
return LV_FS_RES_OK;
}
static lv_fs_res_t tell_cb(struct _lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
{
(void) drv;
FILE * fp = *((FILE **) file_p);
*pos_p = ftell(fp);
return LV_FS_RES_OK;
}
static bool ready_cb(struct _lv_fs_drv_t * drv)
{
(void) drv;
return true;
}
static void hal_init(void)
{
static lv_disp_buf_t disp_buf;
@@ -35,6 +90,20 @@ static void hal_init(void)
disp_drv.buffer = &disp_buf;
disp_drv.flush_cb = dummy_flush_cb;
lv_disp_drv_register(&disp_drv);
lv_fs_drv_t drv;
lv_fs_drv_init(&drv); /*Basic initialization*/
drv.letter = 'f'; /*An uppercase letter to identify the drive */
drv.file_size = sizeof(FILE *); /*Size required to store a file object*/
drv.ready_cb = ready_cb; /*Callback to tell if the drive is ready to use */
drv.open_cb = open_cb; /*Callback to open a file */
drv.close_cb = close_cb; /*Callback to close a file */
drv.read_cb = read_cb; /*Callback to read a file */
drv.seek_cb = seek_cb; /*Callback to seek in a file (Move cursor) */
drv.tell_cb = tell_cb; /*Callback to tell the cursor position */
lv_fs_drv_register(&drv); /*Finally register the drive*/
}