Adding support to dynamic font loading.
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
154
tests/lv_test_core/lv_test_font_loader.c
Normal file
154
tests/lv_test_core/lv_test_font_loader.c
Normal 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
|
||||
|
||||
39
tests/lv_test_core/lv_test_font_loader.h
Normal file
39
tests/lv_test_core/lv_test_font_loader.h
Normal 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*/
|
||||
|
||||
@@ -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*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user