LuatOS之LVGL字体篇

前言

之前展示过Luatos在win32上运行LVGL的效果,今天带来LVGL的字体篇

介绍

LVGL字体支持很全,支持 UTF-8 编码的 Unicode 字符,分内部字体和外部字体,字体制作工具也很多:LVGL官方的字体制作工具,第三方的LvglFontToolMCU_Font等。本文会介绍不同字体制作方法时分别使用不同工具使大家对其都有了解。

内部字体

LVGL的内部字体分为 LVGL自带字体和自己制作的自定义内部字体。

内部自支持字体

LVGL的内部就已经支持多种字体大小,可通过 LV_FONT_… 定义在 lv_conf.h 中启用即可

/* Montserrat fonts with bpp = 4
 * https://fonts.google.com/specimen/Montserrat  */
#define LV_FONT_MONTSERRAT_8     0
#define LV_FONT_MONTSERRAT_10    0
#define LV_FONT_MONTSERRAT_12    0
#define LV_FONT_MONTSERRAT_14    1
#define LV_FONT_MONTSERRAT_16    0
#define LV_FONT_MONTSERRAT_18    0
#define LV_FONT_MONTSERRAT_20    0
#define LV_FONT_MONTSERRAT_22    0
#define LV_FONT_MONTSERRAT_24    0
#define LV_FONT_MONTSERRAT_26    0
#define LV_FONT_MONTSERRAT_28    0
#define LV_FONT_MONTSERRAT_30    0
#define LV_FONT_MONTSERRAT_32    0
#define LV_FONT_MONTSERRAT_34    0
#define LV_FONT_MONTSERRAT_36    0
#define LV_FONT_MONTSERRAT_38    0
#define LV_FONT_MONTSERRAT_40    0
#define LV_FONT_MONTSERRAT_42    0
#define LV_FONT_MONTSERRAT_44    0
#define LV_FONT_MONTSERRAT_46    0
#define LV_FONT_MONTSERRAT_48    0

/* Demonstrate special features */
#define LV_FONT_MONTSERRAT_12_SUBPX      0
#define LV_FONT_MONTSERRAT_28_COMPRESSED 0  /*bpp = 3*/
#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0  /*Hebrew, Arabic, PErisan letters and all their forms*/
#define LV_FONT_SIMSUN_16_CJK            0  /*1000 most common CJK radicals*/

/*Pixel perfect monospace font
 * http://pelulamu.net/unscii/ */
#define LV_FONT_UNSCII_8     0
#define LV_FONT_UNSCII_16     0

同时支持多国语言:希伯来语、阿拉伯语、波斯语字母及其所有形式,并且支持中文,但是实际上中文的支持是使用1000多个最常见的部首组成的,实际测试会发现很多汉字都没有~

内部自定义字体

当你要使用一些好看的字体,或者中文等LVGL没有集成的字体怎么办呢?当然可以自己制作字库,首先介绍的是使用LvglFontTool制作内部字体,打开LvglFontTool

image.png

抗锯齿选择默认,我们的lvgl是7.11版本,所以此处版本选择用于6.0版本以上,英文和数字根据自己需要勾选,类型选择内部字体,剩下都勾选上即可,字体名自己设置,包含里加上lvgl.h头文件,之后我们点击选择字体

image.png

字体我们选择我们的ttf字体,选择字体大小,点击确定
之后写入需要的汉字或者根据自己需要点击加入常用汉字、全部汉字、图标

image.png
之后点击保存,开始转换
image.png
稍作等待
image.png
之后将生成的.c文件放在LuatOS\components\lvgl\font目录下,在luat_lvgl_fonts.h中声明你的字库

#ifndef LUAT_LIB_FONTS_H
#define LUAT_LIB_FONTS_H

#include "luat_base.h"

#ifdef __cplusplus
extern "C" {
#endif
#include "../src/lv_font/lv_font.h"

LV_FONT_DECLARE(lv_font_opposans_m_8)
LV_FONT_DECLARE(lv_font_opposans_m_10)
LV_FONT_DECLARE(lv_font_opposans_m_12)
LV_FONT_DECLARE(lv_font_opposans_m_14)
LV_FONT_DECLARE(lv_font_opposans_m_16)
LV_FONT_DECLARE(lv_font_opposans_m_18)
LV_FONT_DECLARE(lv_font_opposans_m_20)
LV_FONT_DECLARE(lv_font_opposans_m_22)
LV_FONT_DECLARE(lv_font_simsun_48)

#ifdef __cplusplus
}
#endif
#endif

之后在luat_lib_lvgl_font.c中对lua暴露你的字库就可以了

/*
获取内置字体
@api lvgl.font_get(name)
@string 字体名称+字号, 例如 opposans_m_10 simsun_48
@return userdata 字体指针
@usage

local font = lvgl.font_get("simsun_48")
*/
int luat_lv_font_get(lua_State *L) {
    lv_font_t* font = NULL;
    const char* fontname = luaL_checkstring(L, 1);
    if (!strcmp("", fontname)) {
    }
#ifdef LV_FONT_MONTSERRAT_14
    else if (!strcmp("montserrat_14", fontname)) { font = &lv_font_montserrat_14;}
#endif
#ifdef LV_FONT_OPPOSANS_M_8
    else if (!strcmp("opposans_m_8", fontname)) { font = &lv_font_opposans_m_8;}
#endif
#ifdef LV_FONT_OPPOSANS_M_10
    else if (!strcmp("opposans_m_10", fontname)) { font = &lv_font_opposans_m_10;}
#endif
#ifdef LV_FONT_OPPOSANS_M_12
    else if (!strcmp("opposans_m_12", fontname)) { font = &lv_font_opposans_m_12;}
#endif
#ifdef LV_FONT_OPPOSANS_M_14
    else if (!strcmp("opposans_m_14", fontname)) { font = &lv_font_opposans_m_14;}
#endif
#ifdef LV_FONT_OPPOSANS_M_16
    else if (!strcmp("opposans_m_16", fontname)) { font = &lv_font_opposans_m_16;}
#endif
#ifdef LV_FONT_OPPOSANS_M_18
    else if (!strcmp("opposans_m_18", fontname)) { font = &lv_font_opposans_m_18;}
#endif
#ifdef LV_FONT_OPPOSANS_M_20
    else if (!strcmp("opposans_m_20", fontname)) { font = &lv_font_opposans_m_20;}
#endif
#ifdef LV_FONT_OPPOSANS_M_22
    else if (!strcmp("opposans_m_22", fontname)) { font = &lv_font_opposans_m_22;}
#endif
#ifdef USE_LVGL_SIMSUN_48
    else if (!strcmp("simsun_48", fontname)) { font = &lv_font_simsun_48;}
#endif

    if (font) {
        lua_pushlightuserdata(L, font);
        return 1;
    }
    return 0;
}

注意:编译时别忘了在luat_conf_bsp.h中启用lvgl和字库呦~

外部字体

LVGL同时支持外部字体,你可以将.bin格式字体放在flash中或sd中,在程序运行中加载字体,这种方式无需修改固件

这里我们用离线版LVGL官方工具生成外部字体

首先安装nodejs这里不做介绍,下载安装即可

打开cmd运行

npm i lv_font_conv -g

即可安装好lv_font_conv

我们cmd运行lv_font_conv测试

image.png

证明lv_font_conv 已正常运行

下面我们了解一下lv_font_conv命令:

常用命令:

  • --bpp - 每像素位数(抗锯齿)
  • --size - 输出字体大小(像素)
  • -o, --output- 输出路径(文件或目录,取决于格式)
  • --format - 输出格式
    • --format dump - 转储字形图像和字体信息,用于调试
    • --format bin- 以二进制形式转储字体(如规范中所述
    • --format lvgl- 以LittlevGL格式转储字体
  • --force-fast-kern-format- 始终使用更快速的 kering 存储格式,但要付出一定的代价。如果出现尺寸差异,则会显示出来
  • --lcd - 生成具有 3 倍水平分辨率的位图,用于子像素平滑
  • --lcd-v - 生成具有 3 倍垂直分辨率的位图,用于子像素平滑
  • --use-color-info- 尝试使用字体中的字形颜色信息来创建灰度图标。由于灰色色调是通过透明度模拟的,因此仅在对比背景上效果会很好
  • --lv-include- 仅与--format lvgl,为 设置备用路径lvgl.h

字体命令:

  • --font- 字体文件的路径(ttf/woff/woff2/otf)。可多次用于合并
  • -r, --range- 单个字形或范围 + 可选映射,属于先前声明的--font. 可以多次使用。例子:
    • -r 0x1F450 - 单值、十进制或十六进制格式
    • -r 0x1F450-0x1F470 - 范围
    • -r '0x1F450=>0xF005' - 带有映射的单个字形
    • -r '0x1F450-0x1F470=>0xF005' - 带映射的范围
    • -r 0x1F450 -r 0x1F451-0x1F470 - 2个范围
    • -r 0x1F450,0x1F451-0x1F470- 同上,但定义为 single -r
  • --symbols- 要复制的字符列表(而不是 中的数字格式-r
    • --symbols 0123456789., - 提取字符以显示数字
  • --autohint-off - 不要强制自动提示(默认情况下“灯”是打开的)
  • --autohint-strong - 使用更强大的自动提示(会破坏字距调整)

其他调试选项:

  • --no-compress - 禁用内置 RLE 压缩
  • --no-prefilter - 禁用位图线过滤器(XOR),用于提高压缩率
  • --no-kerning - 删除字距调整信息以减小大小(不推荐)
  • --full-info - 不要缩短“font_info.json”(包括像素数据)

我们输入以下命令即可生成我们想要的.bin外部字库了

lv_font_conv --no-compress --format bin --font H:\OPPOSans-M.ttf -o H:\myfontd\opposans_m_8.bin --bpp 4 --size 8 -r 0x30-0x39 -r 0x41-0x5A -r 0x61-0x7A -r 0x4E00-0x9FFF

不想自己做?好的,我已经做好一些放在LuatOS\docs\markdown\exts\lvgl\fonts目录下了呦~

image.png

字体使用

字体使用非常简单,使用lvgl.obj_set_style_local_text_font设置字体即可,外部字体文件需要使用lvgl.font_load函数加载,下面看一下范例:

注意:使用后记得释放字体

内部字体:

	local screen_label = lvgl.label_create(nil, nil)
	lvgl.label_set_text(screen_label, "中文测试abcdABCD1234")
	local style_screen_label_main = lvgl.style_create()
	lvgl.style_set_text_font(style_screen_label_main, lvgl.STATE_DEFAULT, lvgl.font_get("opposans_m_12"))
	lvgl.obj_add_style(screen_label, lvgl.LABEL_PART_MAIN, style_screen_label4_main)
    lvgl.scr_load(screen_label)

效果:

image.png

外部字体:

	local screen_label = lvgl.label_create(nil, nil)
	lvgl.label_set_text(screen_label, "这是一个中文字体测试程序abcdABCD1234")
    local font = lvgl.font_load("/OPPOSans.bin")
    lvgl.obj_set_style_local_text_font(screen_label, lvgl.LABEL_PART_MAIN, lvgl.STATE_DEFAULT, font)
    lvgl.scr_load(screen_label)

效果:

image.png

字体

本文使用的字体是OPPO的OPPO Sans字体,(含中文及西文,6 款字重)允许个人或企业免费使用,含商业用途,版权归 OPPO 广东移动通信有限公司所有。

您应遵守以下条款,违者必究:

  1. 不对字体进行改编或二次开发;

  2. 不对外售卖字体;

  3. 不向他方提供其他下载渠道;

  4. 不用于违法用途。

相关连接

luatos仓库

bsp-win32

lvgl官网

lvgl仓库

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值