LVGL使用华为鸿蒙字体

133 篇文章 113 订阅
本文介绍了如何使用华为鸿蒙字体,并通过工具将其转换为MyFont.c和bin文件,以便在LVGL中实现动态加载。讲解了文件系统驱动的匹配和__user_font_getdata函数的实现,涉及内存管理和LVGL图像处理。
摘要由CSDN通过智能技术生成

转换工具下载

华为鸿蒙字体

字体下载

打开工具生成外部汉字bin文件,这里选择鸿蒙黑体HarmonyOS_Sans_SC_Black.ttf

在这里插入图片描述

加入所有汉字及ascii字符

在这里插入图片描述

转换生成MyFont.c和MyFont.bin两个文件,将MyFont.c文件加入到工程中,实现__user_font_getdata的文件读取驱动

static uint8_t __g_font_buf[364];//如bin文件存在SPI FLASH可使用此buff


static uint8_t *__user_font_getdata(int offset, int size){
    //如字模保存在SPI FLASH, SPIFLASH_Read(__g_font_buf,offset,size);
    //如字模已加载到SDRAM,直接返回偏移地址即可如:return (uint8_t*)(sdram_fontddr+offset);
    lv_fs_file_t file;
    lv_fs_res_t result;
    result = lv_fs_open(&file, "P:/test/myFont.bin", LV_FS_MODE_RD);
    if (result != LV_FS_RES_OK)
        return NULL;

    lv_fs_seek(&file, offset);
    uint32_t len;
    lv_fs_read(&file, __g_font_buf, size, &len);
    lv_fs_close(&file);
    return __g_font_buf;
}

lvgl文件系统驱动匹配

/**
 * @file lv_tutorial_images.h
 *
 */

/*
 * -------------------------------------------------------------------------------------------
 * Learn how to use images stored internally (in a variable) or externally (e.g. on an SD card)
 *-------------------------------------------------------------------------------------------
 *
 *
 * The basic object to display images is 'lv_img'. The displayed image is called 'image source'.
 *
 * IMAGE SOURCES
 * -----------------
 *
 * 1. IMAGE CONVETED TO C ARRAY
 *  With the online image converter tool you can convert your images into C arrays:
 *  https://littlevgl.com/image-to-c-array
 *
 *  If you have the converted file:
 *    - Copy the result C file into your project
 *    - Declare the image variable with 'LV_IMG_DECLARE(image_name);'
 *    - Set it for an image object: 'lv_img_set_src(img1, &image_name);'
 *
 *  In this case you don't need to think about color format because
 *  all color formats are included in the C file and the currently active
 *  (according to 'LV_COLOR_DEPTH' in 'lv_conf.h') will be enabled.
 *
 * 2. IMAGE FROM FILE
 *  With the above mentioned online image converter tool you can convert images to binary files too.
 *  Now you should choose the right color format.
 *  The result of the conversion should be a *.bin file which can be copied to any external device (e.g. SD card)
 *
 *  To read this file you need to provide some functions for LittlevGL. You will see it in the example below.
 *
 *  To set a file for an image object use: 'lv_img_set_src(img, "S:path/to/image.bin")'
 *
 * 3. IMAGE FROM SYMBOL FONT
 *  The symbol fonts are letters however they look like small images.
 *  To set symbols for an image object use: 'lv_img_set_src(img, LV_SYMBOL_CLOSE)'
 *
 * TRANSPARENCY
 * ---------------
 *
 * The images have 2 features related to pixel level transparency:
 *
 * 1. CHROMA KEYING
 *  The LV_COLOR_TRANSP (lv_conf.h) pixels will be transparent.
 *  This feature can be enabled individually in the images in the online image converter tool.
 *  Because Chroma keying can only show/hide a pixel edges on the image might be jagged.
 *  On the other hand it dosn't mean extra memory usage.
 *
 * 2. ALHPA BYTE
 *  It will add an extra byte to every pixel to show its opacity.
 *  This feature also can be enabled in the online converter tool.
 *  In case of 8 and 16 bit images it means extra 8 bit for every pixel.
 *  The 24 bit images are stored on 32 bit independently from Alpha byte settings.
 *  Alpha byte results very smooth edges and high quality images.
 */

/*********************
 *      INCLUDES
 *********************/
#include "lv_tutorial_images.h"
#if LV_USE_TUTORIALS

#include "lvgl/lvgl.h"
#include <stdio.h>
#include <errno.h>

/*********************
 *      DEFINES
 *********************/
#define PC_FILES    1       /*If you are on PC you can add PC file function to 'lv_fs'*/

/**********************
 *      TYPEDEFS
 **********************/
typedef  FILE * pc_file_t;

/**********************
 *  STATIC PROTOTYPES
 **********************/
#if PC_FILES && LV_USE_FILESYSTEM
/*Interface functions to standard C file functions (only the required ones to image handling)*/
static lv_fs_res_t pcfs_open(lv_fs_drv_t * drv, void * file_p, const char * fn, lv_fs_mode_t mode);
static lv_fs_res_t pcfs_close(lv_fs_drv_t * drv, void * file_p);
static lv_fs_res_t pcfs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br);
static lv_fs_res_t pcfs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos);
static lv_fs_res_t pcfs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p);
static lv_fs_res_t pcfs_size(struct _lv_fs_drv_t* drv, void* file_p, uint32_t* size_p);
static lv_fs_res_t pcfs_write(struct _lv_fs_drv_t* drv, void* file_p, const void* buf, uint32_t btw, uint32_t* bw);
#endif

/**********************
 *  STATIC VARIABLES
 **********************/
/*Declare the "source code image" which is stored in the flash*/
LV_IMG_DECLARE(red_flower)
LV_IMG_DECLARE(red_rose_16);
LV_IMG_DECLARE(flower_icon_alpha);

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

void init_fs_config(void)
{
    lv_fs_drv_t pcfs_drv;                         /*A driver descriptor*/
    memset(&pcfs_drv, 0, sizeof(lv_fs_drv_t));    /*Initialization*/

    pcfs_drv.file_size = sizeof(pc_file_t);       /*Set up fields...*/
    pcfs_drv.letter = 'P';
    pcfs_drv.write_cb = pcfs_write;
    pcfs_drv.open_cb = pcfs_open;
    pcfs_drv.close_cb = pcfs_close;
    pcfs_drv.read_cb = pcfs_read;
    pcfs_drv.seek_cb = pcfs_seek;
    pcfs_drv.tell_cb = pcfs_tell;
    pcfs_drv.size_cb = pcfs_size;
    lv_fs_drv_register(&pcfs_drv);
}
/**
 * Create images from variable and file
 */
void lv_tutorial_image(void)
{
    lv_obj_t * scr = lv_disp_get_scr_act(NULL);     /*Get the current screen*/

    /*************************
     * IMAGE FROM SOURCE CODE
     *************************/
#if 0
    lv_obj_t * img_var = lv_img_create(scr, NULL); /*Crate an image object*/
    lv_img_set_src(img_var, &red_flower);  /*Set the created file as image (a red flower)*/
    lv_obj_set_pos(img_var, 10, 10);      /*Set the positions*/
    lv_obj_set_drag(img_var, true);

    img_var = lv_img_create(scr, NULL); /*Crate an image object*/
    lv_img_set_src(img_var, &red_rose_16);  /*Set the created file as image (a red rose)*/
    lv_obj_set_pos(img_var, 10, 100);      /*Set the positions*/
    lv_obj_set_drag(img_var, true);

    static lv_style_t style_red;
    lv_style_copy(&style_red, &lv_style_plain);
    style_red.image.color = LV_COLOR_RED;

    img_var = lv_img_create(scr, NULL); /*Crate an image object*/
    lv_img_set_src(img_var, &flower_icon_alpha);  /*Set the created file as image (a red flower icon)*/
    lv_img_set_style(img_var, LV_IMG_STYLE_MAIN, &style_red);
    lv_obj_set_pos(img_var, 10, 200);      /*Set the positions*/
    lv_obj_set_drag(img_var, true);
#endif
#if PC_FILES && LV_USE_FILESYSTEM
    /**************************
     * IMAGE FROM BINARY FILE
     **************************/

    /* Add a simple drive to open images from PC*/
    lv_fs_drv_t pcfs_drv;                         /*A driver descriptor*/
    memset(&pcfs_drv, 0, sizeof(lv_fs_drv_t));    /*Initialization*/

    pcfs_drv.file_size = sizeof(pc_file_t);       /*Set up fields...*/
    pcfs_drv.letter = 'P';
    pcfs_drv.open_cb = pcfs_open;
    pcfs_drv.close_cb = pcfs_close;
    pcfs_drv.read_cb = pcfs_read;
    pcfs_drv.seek_cb = pcfs_seek;
    pcfs_drv.tell_cb = pcfs_tell;
    pcfs_drv.size_cb = pcfs_size;
    lv_fs_drv_register(&pcfs_drv);


//    lv_obj_t * img_bin = lv_img_create(scr, NULL); /*Create an image object*/
    /* Set the image's file according to the current color depth
     * a blue flower picture*/
#if LV_COLOR_DEPTH == 8
    lv_img_set_src(img_bin, "P:/lv_examples/lv_tutorial/6_images/blue_flower_8.bin");
#elif LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP == 0
    //lv_img_set_src(img_bin, "P:/lv_examples/lv_tutorial/6_images/blue_flower_16.bin");
#elif LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP == 1
 //  lv_img_set_src(img_bin, "P:/lv_examples/lv_tutorial/6_images/blue_flower_16_swap.bin");
#elif LV_COLOR_DEPTH == 32
 //   lv_img_set_src(img_bin, "P:/lv_examples/lv_tutorial/6_images/blue_flower_32.bin");
#endif

  //  lv_obj_set_pos(img_bin, 150, 10);     /*Align next to the source image*/
 //   lv_obj_set_drag(img_bin, true);

    lv_obj_t* img_bin = lv_img_create(scr, NULL); /*Crate an image object*/
   // lv_img_set_src(img_bin, "P:/lv_examples/lv_tutorial/6_images/blue_rose_16.bin");  /*Set the created file as image (a red rose)*/
    lv_img_set_src(img_bin, "P:/watch1.bin");

    lv_obj_set_pos(img_bin, 0, 0);      /*Set the positions*/
    lv_obj_set_drag(img_bin, true);

 //   static lv_style_t style_blue;
  //  lv_style_copy(&style_blue, &lv_style_plain);
  //  style_blue.image.color = LV_COLOR_BLUE;
//
  //  img_bin = lv_img_create(scr, NULL); /*Crate an image object*/
 //   lv_img_set_src(img_bin, "P:/lv_examples/lv_tutorial/6_images/flower_icon_alpha.bin");  /*Set the created file as image (a red flower icon)*/
 //   lv_img_set_style(img_bin, LV_IMG_STYLE_MAIN, &style_blue);
 //   lv_obj_set_pos(img_bin, 150, 200);      /*Set the positions*/
  //  lv_obj_set_drag(img_bin, true);
#endif

   // lv_obj_t * img_symbol = lv_img_create(scr, NULL);
 //   lv_img_set_src(img_symbol, LV_SYMBOL_OK);
  //  lv_obj_set_drag(img_symbol, true);
  //  lv_obj_set_pos(img_symbol, 300, 10);      /*Set the positions*/
}

/**********************
 *   STATIC FUNCTIONS
 **********************/

#if PC_FILES && LV_USE_FILESYSTEM
/**
 * Open a file from the PC
 * @param drv pointer to the current driver
 * @param file_p pointer to a FILE* variable
 * @param fn name of the file.
 * @param mode element of 'fs_mode_t' enum or its 'OR' connection (e.g. FS_MODE_WR | FS_MODE_RD)
 * @return LV_FS_RES_OK: no error, the file is opened
 *         any error from lv_fs_res_t enum
 */
static lv_fs_res_t pcfs_open(lv_fs_drv_t * drv, void * file_p, const char * fn, lv_fs_mode_t mode)
{
    (void) drv; /*Unused*/

    errno = 0;

    const char * flags = "";

    if(mode == LV_FS_MODE_WR) flags = "wb";
    else if(mode == LV_FS_MODE_RD) flags = "rb";
    else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)) flags = "a+";

    /*Make the path relative to the current directory (the projects root folder)*/
    char buf[256];
    sprintf(buf, "./%s", fn);

    pc_file_t f = fopen(buf, flags);
    if(f == NULL) return LV_FS_RES_UNKNOWN;
    else {
        fseek(f, 0, SEEK_SET);

        /* 'file_p' is pointer to a file descriptor and
         * we need to store our file descriptor here*/
        pc_file_t * fp = file_p;        /*Just avoid the confusing casings*/
        *fp = f;
    }

    return LV_FS_RES_OK;
}


static lv_fs_res_t pcfs_write(struct _lv_fs_drv_t* drv, void* file_p, const void* buf, uint32_t btw, uint32_t* bw)
{
    (void)drv; /*Unused*/

    pc_file_t* fp = file_p;        /*Just avoid the confusing casings*/
    *bw = (uint32_t)fwrite(buf, 1, btw, *fp);

    return LV_FS_RES_OK;
}

/**
 * Close an opened file
 * @param drv pointer to the current driver
 * @param file_p pointer to a FILE* variable. (opened with lv_ufs_open)
 * @return LV_FS_RES_OK: no error, the file is read
 *         any error from lv__fs_res_t enum
 */
static lv_fs_res_t pcfs_close(lv_fs_drv_t * drv, void * file_p)
{
    (void) drv; /*Unused*/

    pc_file_t * fp = file_p;        /*Just avoid the confusing casings*/
    fclose(*fp);
    return LV_FS_RES_OK;
}

/**
 * Read data from an opened file
 * @param drv pointer to the current driver
 * @param file_p pointer to a FILE variable.
 * @param buf pointer to a memory block where to store the read data
 * @param btr number of Bytes To Read
 * @param br the real number of read bytes (Byte Read)
 * @return LV_FS_RES_OK: no error, the file is read
 *         any error from lv__fs_res_t enum
 */
static lv_fs_res_t pcfs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br)
{
    (void) drv; /*Unused*/

    pc_file_t * fp = file_p;        /*Just avoid the confusing casings*/
    *br = (uint32_t)fread(buf, 1, btr, *fp);
    return LV_FS_RES_OK;
}

/**
 * Set the read write pointer. Also expand the file size if necessary.
 * @param drv pointer to the current driver
 * @param file_p pointer to a FILE* variable. (opened with lv_ufs_open )
 * @param pos the new position of read write pointer
 * @return LV_FS_RES_OK: no error, the file is read
 *         any error from lv__fs_res_t enum
 */
static lv_fs_res_t pcfs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos)
{
    (void) drv; /*Unused*/

    pc_file_t * fp = file_p;        /*Just avoid the confusing casings*/
    fseek(*fp, pos, SEEK_SET);
    return LV_FS_RES_OK;
}

/**
 * Give the position of the read write pointer
 * @param drv pointer to the current driver
 * @param file_p pointer to a FILE* variable.
 * @param pos_p pointer to to store the result
 * @return LV_FS_RES_OK: no error, the file is read
 *         any error from lv__fs_res_t enum
 */
static lv_fs_res_t pcfs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
{
    (void) drv; /*Unused*/
    pc_file_t * fp = file_p;        /*Just avoid the confusing casings*/
    *pos_p = ftell(*fp);
    return LV_FS_RES_OK;
}

static lv_fs_res_t pcfs_size(struct _lv_fs_drv_t* drv, void* file_p, uint32_t* size_p)
{
    (void)drv; /*Unused*/
    pc_file_t* fp = file_p;        /*Just avoid the confusing casings*/
    fseek(*fp, 0L, SEEK_END);
    *size_p = ftell(*fp);
    fseek(*fp, 0L, SEEK_SET);
    return LV_FS_RES_OK;
}

#endif

#endif /*LV_USE_TUTORIALS*/

鸿蒙字体展示

#pragma execution_character_set("utf-8")
LV_FONT_DECLARE(myFont)
int main(int argc, char** argv)
{
	/*Initialize LittlevGL*/
	lv_init();
	init_fs_config();
	/*Initialize the HAL for LittlevGL*/
	hal_init();
		
	lv_obj_t* scr = lv_scr_act();
	lv_obj_t* cont = lv_cont_create(scr, NULL);
	lv_obj_set_size(cont, LV_HOR_RES_MAX, LV_VER_RES_MAX);
	lv_obj_t* label = lv_label_create(cont, NULL);
	lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0);
	lv_obj_set_auto_realign(label, true);
	lv_obj_set_style_local_text_font(label, LV_LABEL_PART_MAIN,  \
	  LV_STATE_DEFAULT, &myFont);
	lv_obj_set_style_local_text_color(label, LV_LABEL_PART_MAIN,   \
	LV_STATE_DEFAULT, LV_COLOR_MAKE(0XFF,0X00,0XFF));
	lv_label_set_text(label, "华为鸿蒙字体!\r\nHuawei Hongmeng font!");
	while (1) {
		/* Periodically call the lv_task handler.
		* It could be done in a timer interrupt or an OS task too.*/
		lv_task_handler();
		Sleep(10);       /*Just to let the system breathe */
	}
	return 0;
}

运行效果图

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风雨依依

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值