From ddc1bdf81566b1d84de938bc3bc9e2b5ab96d691 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 13 Nov 2023 13:59:22 +0100 Subject: [PATCH] feat(font_load): add lv_font_* as paramater to lv_font_load This way if a font is used by styles or widgets it can be easily reloaded without updating the font pointer on all places. --- src/font/lv_font_loader.c | 46 +++++------ src/font/lv_font_loader.h | 18 +++-- tests/ref_imgs/font_loader_2.png | Bin 0 -> 3348 bytes tests/ref_imgs/font_loader_3.png | Bin 0 -> 5825 bytes tests/src/test_cases/test_font_loader.c | 100 ++++++++++++++++++------ 5 files changed, 111 insertions(+), 53 deletions(-) create mode 100644 tests/ref_imgs/font_loader_2.png create mode 100644 tests/ref_imgs/font_loader_3.png diff --git a/src/font/lv_font_loader.c b/src/font/lv_font_loader.c index 650e6384a..881013233 100644 --- a/src/font/lv_font_loader.c +++ b/src/font/lv_font_loader.c @@ -78,40 +78,43 @@ static unsigned int read_bits(bit_iterator_t * it, int n_bits, lv_fs_res_t * res * GLOBAL FUNCTIONS **********************/ -lv_font_t * lv_font_load(const char * font_name) +lv_result_t lv_font_load(lv_font_t * font, const char * path) { - lv_fs_file_t file; - lv_fs_res_t res = lv_fs_open(&file, font_name, LV_FS_MODE_RD); - if(res != LV_FS_RES_OK) - return NULL; + LV_ASSERT_NULL(font); + LV_ASSERT_NULL(path); - lv_font_t * font = lv_malloc(sizeof(lv_font_t)); - if(font) { - memset(font, 0, sizeof(lv_font_t)); - if(!lvgl_load_font(&file, font)) { - LV_LOG_WARN("Error loading font file: %s\n", font_name); - /* - * When `lvgl_load_font` fails it can leak some pointers. - * All non-null pointers can be assumed as allocated and - * `lv_font_free` should free them correctly. - */ - lv_font_free(font); - font = NULL; - } + lv_result_t result = LV_RESULT_INVALID; + + lv_fs_file_t file; + lv_fs_res_t fs_res = lv_fs_open(&file, path, LV_FS_MODE_RD); + if(fs_res != LV_FS_RES_OK) return result; + + lv_memzero(font, sizeof(lv_font_t)); + if(lvgl_load_font(&file, font)) { + result = LV_RESULT_OK; + } + else { + LV_LOG_WARN("Error loading font file: %s\n", path); + /* + * When `lvgl_load_font` fails it can leak some pointers. + * All non-null pointers can be assumed as allocated and + * `lv_font_free` should free them correctly. + */ + lv_font_free(font); } lv_fs_close(&file); - return font; + return result; } #if LV_USE_FS_MEMFS -lv_font_t * lv_font_load_from_buffer(void * buffer, uint32_t size) +lv_result_t lv_font_load_from_buffer(lv_font_t * font, void * buffer, uint32_t size) { lv_fs_path_ex_t mempath; lv_fs_make_path_from_buffer(&mempath, LV_FS_MEMFS_LETTER, buffer, size); - return lv_font_load((const char *)&mempath); + return lv_font_load(font, (const char *)&mempath); } #endif @@ -175,7 +178,6 @@ void lv_font_free(lv_font_t * font) } lv_free(dsc); } - lv_free(font); } } diff --git a/src/font/lv_font_loader.h b/src/font/lv_font_loader.h index 9f8e16462..fc23e7286 100644 --- a/src/font/lv_font_loader.h +++ b/src/font/lv_font_loader.h @@ -28,25 +28,27 @@ extern "C" { /** * Loads a `lv_font_t` object from a binary font file - * @param font_name filename where the font file is located - * @return a pointer to the font or NULL in case of error + * @param font pointer to font where to load + * @param path path where the font file is located + * @return LV_RESULT_OK on success; LV_RESULT_INVALID on error */ -lv_font_t * lv_font_load(const char * fontName); +lv_result_t lv_font_load(lv_font_t * font, const char * font_name); #if LV_USE_FS_MEMFS /** * Loads a `lv_font_t` object from a memory buffer containing the binary font file. * Requires LV_USE_FS_MEMFS - * @param buffer address of the font file in the memory - * @param size size of the font file buffer - * @return a pointer to the font or NULL in case of error + * @param font pointer to font where to load + * @param buffer address of the font file in the memory + * @param size size of the font file buffer + * @return LV_RESULT_OK on success; LV_RESULT_INVALID on error */ -lv_font_t * lv_font_load_from_buffer(void * buffer, uint32_t size); +lv_result_t lv_font_load_from_buffer(lv_font_t * font, void * buffer, uint32_t size); #endif /** * Frees the memory allocated by the `lv_font_load()` function - * @param font lv_font_t object created by the lv_font_load function + * @param font lv_font_t object created by the lv_font_load function */ void lv_font_free(lv_font_t * font); diff --git a/tests/ref_imgs/font_loader_2.png b/tests/ref_imgs/font_loader_2.png new file mode 100644 index 0000000000000000000000000000000000000000..6fd7a5ffe962e769845d0ca7d60557bd720f1a38 GIT binary patch literal 3348 zcmeHK{a2D_7=CrDlV#c0B+Y5dmB)_5R;HO>)tux?EQ@q2&^FO!pcRHnOzdN_=E|L# zrv&jmCsP|VF>}CpQ8coS`9VcU4iVA7>{UP!J%qsC?dQ(fKfv|lbDr~@>$&dhxu5I4 zauADIzSMsy007IA_a&wQzy})uz++^IC$jQ_SbG})yw%BxdyW*>ObzYH+o<+@q7zp} z`Jz^~0Lk(c->h7Z>x+Jx-MR1aM!%?0&pQTkKSR%RCQ;jrlx)b0MRZQ>;(V|(p4D%aKdvLu;DCdunRdIqFK0WukJaFJHK~nI za6jX>U_PG@Y4UM6NMoFv6L7iMMny#5>7682PHdow3bEPj=ij#ul9K8UMK^G{6NO?1 zgzyYl5spSb<+J;8wpF*1V**yhaIkn42b;T#6IgqmLOE=V2ynAt60)idY8#$T4{J}LXEAom%vvE$bJ$ox9i(8XV0cBo|v~Y z&!^#(&bGO^V}-4kZFHwj#w^gbPo-+}g+wLM1&fDCkv;kr73`SVySBdjss7f1%|%5; z?7oJRteLmtauB%~JwC{Laeb)I_#B-}jOJh)x!i`6&TDr1?w>m@&fihNeK`+a1nA3; z+C+H13Xuwj`^>jub+V6-k3H29d=4K}eguajs|k2~N~1z{3=(|+t>CF8isnn(aap%j4!U5Qt zz3nfFWOCk4yq}_Yc`nZXDyw0z!2Vnx!^&$^gi4K6C>4x%(4jKnrsk2jP;gX}FC?px zqQX{mcz6+{(cy2@jqQ(^G_fRihX%OtyO2sVfxf$>q~z<`@A}6r-PvjWypt?hiSz6s z{Vf66Cw-c3AogM#50}0Ii(7|faf1o{YH((B^;03IT&AN!2veuiiK!%JmV9!Qr_9IN$PfBe$4Xuu!6~g)>(ta# z-k)2*XDAekr+oY7)ED|k$~>H7zEgo5C>H0b1w%cd%pEC*M<<$rS`Z4aEtN_MeB^It z1X3`;h;W@*2aRw*yoGkg5WcG>SE@}Iy3w*8w!XXB!-wA)jm9^#bx~XPBc8p~Ibtir zpl+}8UR=?2TY?ZEMV?X%VyR*Bv~-?QhnLlPC4g_8DiF2KY;e*Lz|jDsV!C+2*xq2V z!YV7R&1Dz}uQJuQ87kMfBJ_5$Vqz9SRpTTT5;v&@WHmLy-%-t23atG%EA+ZL-_r@) n(ZQXb+yT;^q5pr3m`sqLd-n2B#iNbLv;!o6iA`+Un|1LY@megB literal 0 HcmV?d00001 diff --git a/tests/ref_imgs/font_loader_3.png b/tests/ref_imgs/font_loader_3.png new file mode 100644 index 0000000000000000000000000000000000000000..d1b1810dd66376455f51a627b6590b428c9ea6d5 GIT binary patch literal 5825 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 C7E^iv literal 0 HcmV?d00001 diff --git a/tests/src/test_cases/test_font_loader.c b/tests/src/test_cases/test_font_loader.c index 58f15a73b..2b72361c5 100644 --- a/tests/src/test_cases/test_font_loader.c +++ b/tests/src/test_cases/test_font_loader.c @@ -9,7 +9,6 @@ #if LV_BUILD_TEST #include "../../lvgl.h" -//#include "lvgl.h" #include "unity/unity.h" @@ -52,9 +51,9 @@ extern uint8_t const font_1_buf[6876]; extern uint8_t const font_2_buf[7252]; extern uint8_t const font_3_buf[4892]; -static lv_font_t * font_1_bin; -static lv_font_t * font_2_bin; -static lv_font_t * font_3_bin; +static lv_font_t font_1_bin; +static lv_font_t font_2_bin; +static lv_font_t font_3_bin; void setUp(void) { @@ -64,18 +63,14 @@ void setUp(void) void tearDown(void) { /* Function run after every test */ - lv_obj_clean(lv_screen_active()); - lv_font_free(font_1_bin); - lv_font_free(font_2_bin); - lv_font_free(font_3_bin); } static void common(void) { - compare_fonts(&font_1, font_1_bin); - compare_fonts(&font_2, font_2_bin); - compare_fonts(&font_3, font_3_bin); + compare_fonts(&font_1, &font_1_bin); + compare_fonts(&font_2, &font_2_bin); + compare_fonts(&font_3, &font_3_bin); /* create labels for testing */ lv_obj_t * scr = lv_screen_active(); @@ -87,21 +82,34 @@ static void common(void) lv_obj_set_flex_align(scr, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_label_set_text(label1, "The quick brown fox jumped over the lazy dog"); - lv_obj_set_style_text_font(label1, font_1_bin, 0); + lv_obj_set_style_text_font(label1, &font_1_bin, 0); lv_label_set_text(label2, "The quick brown fox jumped over the lazy dog"); - lv_obj_set_style_text_font(label2, font_2_bin, 0); + lv_obj_set_style_text_font(label2, &font_2_bin, 0); lv_label_set_text(label3, "The quick brown fox jumped over the lazy dog"); - lv_obj_set_style_text_font(label3, font_3_bin, 0); + lv_obj_set_style_text_font(label3, &font_3_bin, 0); TEST_ASSERT_EQUAL_SCREENSHOT("font_loader_1.png"); + + lv_obj_clean(lv_screen_active()); + + lv_font_free(&font_1_bin); + lv_font_free(&font_2_bin); + lv_font_free(&font_3_bin); } void test_font_loader_with_cache(void) { /*Test with cache ('A' has cache)*/ - font_1_bin = lv_font_load("A:src/test_assets/font_1.fnt"); - font_2_bin = lv_font_load("A:src/test_assets/font_2.fnt"); - font_3_bin = lv_font_load("A:src/test_assets/font_3.fnt"); + lv_result_t res; + + res = lv_font_load(&font_1_bin, "A:src/test_assets/font_1.fnt"); + TEST_ASSERT_EQUAL(LV_RESULT_OK, res); + + res = lv_font_load(&font_2_bin, "A:src/test_assets/font_2.fnt"); + TEST_ASSERT_EQUAL(LV_RESULT_OK, res); + + res = lv_font_load(&font_3_bin, "A:src/test_assets/font_3.fnt"); + TEST_ASSERT_EQUAL(LV_RESULT_OK, res); common(); } @@ -109,9 +117,16 @@ void test_font_loader_with_cache(void) void test_font_loader_no_cache(void) { /*Test without cache ('B' has NO cache)*/ - font_1_bin = lv_font_load("B:src/test_assets/font_1.fnt"); - font_2_bin = lv_font_load("B:src/test_assets/font_2.fnt"); - font_3_bin = lv_font_load("B:src/test_assets/font_3.fnt"); + lv_result_t res; + + res = lv_font_load(&font_1_bin, "B:src/test_assets/font_1.fnt"); + TEST_ASSERT_EQUAL(LV_RESULT_OK, res); + + res = lv_font_load(&font_2_bin, "B:src/test_assets/font_2.fnt"); + TEST_ASSERT_EQUAL(LV_RESULT_OK, res); + + res = lv_font_load(&font_3_bin, "B:src/test_assets/font_3.fnt"); + TEST_ASSERT_EQUAL(LV_RESULT_OK, res); common(); } @@ -119,13 +134,52 @@ void test_font_loader_no_cache(void) void test_font_loader_from_buffer(void) { /*Test with memfs*/ - font_1_bin = lv_font_load_from_buffer((void *)&font_1_buf, sizeof(font_1_buf)); - font_2_bin = lv_font_load_from_buffer((void *)&font_2_buf, sizeof(font_2_buf)); - font_3_bin = lv_font_load_from_buffer((void *)&font_3_buf, sizeof(font_3_buf)); + lv_result_t res; + + res = lv_font_load_from_buffer(&font_1_bin, (void *)&font_1_buf, sizeof(font_1_buf)); + TEST_ASSERT_EQUAL(LV_RESULT_OK, res); + + res = lv_font_load_from_buffer(&font_2_bin, (void *)&font_2_buf, sizeof(font_2_buf)); + TEST_ASSERT_EQUAL(LV_RESULT_OK, res); + + res = lv_font_load_from_buffer(&font_3_bin, (void *)&font_3_buf, sizeof(font_3_buf)); + TEST_ASSERT_EQUAL(LV_RESULT_OK, res); common(); } +void test_font_loader_reload(void) +{ + /*Reload a font which is being used by a label*/ + lv_obj_t * scr = lv_screen_active(); + lv_obj_t * label = lv_label_create(scr); + lv_obj_center(label); + lv_label_set_text(label, "The quick brown fox jumped over the lazy dog"); + + lv_font_t font; + lv_result_t res; + res = lv_font_load(&font, "A:src/test_assets/font_2.fnt"); + TEST_ASSERT_EQUAL(LV_RESULT_OK, res); + + lv_obj_set_style_text_font(label, &font, 0); + + TEST_ASSERT_EQUAL_SCREENSHOT("font_loader_2.png"); + + lv_font_free(&font); + + res = lv_font_load(&font, "A:src/test_assets/font_3.fnt"); + TEST_ASSERT_EQUAL(LV_RESULT_OK, res); + + lv_obj_report_style_change(NULL); + + TEST_ASSERT_EQUAL_SCREENSHOT("font_loader_3.png"); + + lv_obj_delete(label); + + lv_font_free(&font); +} + + static int compare_fonts(lv_font_t * f1, lv_font_t * f2) { TEST_ASSERT_NOT_NULL_MESSAGE(f1, "font not null");