跳转至

27 hzfont-合宙矢量字库

作者:江访 | 最后修改:2026-04-08

一、概述

hzfont 是 LuatOS 专为嵌入式 UI 开发设计的矢量字库,能够高效、清晰地支持界面中的各类字符显示。它不仅内置便捷,还可灵活加载外部字体,显著降低开发成本与复杂度,并可搭配 lcd、AirUI、exeasyui 等核心库,大幅拓展 UI 表现力。

核心优势:

  • 全字号无级缩放:完整支持 14-255 字号,可随意指定任意大小,满足精细化的界面排版需求。
  • 智能抗锯齿优化:支持可调节的抗锯齿等级,有效平滑字体边缘,提升显示细腻度与视觉效果。
  • 字体使用高度自由:既可使用固件内置字库快速上手,也能轻松加载外部 .ttf 字体文件,便于对定制字体与多国语言的支持。

注意事项

  1. 当前 Air8000/Air780EXX 系列仅 V2020 及以上版本的 14 号和 114 号 LuatOS 固件版本支持 hzfont 且内置了.ttf 字体文件;

  2. Air8000 系列的模组可以参考:https://docs.openluat.com/air8000/luatos/firmware/

  3. Air7XX 系列模组可以参考:https://docs.openluat.com/air780epm/luatos/firmware/780ehm_version/
  4. Air8101 仅 V2004 及以上版本的 102 号和 104 号 LuatOS 固件版本支持 hzfont,固件内没有内置.ttf 字体文件,需要在下载固件时手动将.ttf 文件字体文件在烧录固件和脚本时一并烧录到模组的文件系统中

  5. Air8101 可以参考:https://docs.openluat.com/air8101/luatos/firmware/

二、核心示例

1、核心示例是指:使用本库文件提供的核心 API,开发的基础业务逻辑的演示代码;

2、核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单;

3、更加完整和详细的 demo,请参考 LuatOS 仓库 中各个产品目录下的 demo/ui/hzfont

2.1 核心代码

-- hzfont搭配lcd核心库使用的演示代码

-- 加载exlcd扩展库
local exlcd = require("exlcd")

local function hzfont_test()
    -- 初始化LCD
    local result = exlcd.init({ lcd_model = "AirLCD_1000", direction = 3, w = 480, h = 320 })

    log.info("lcd.init", result)

    if result then
        -- 显示设置
        lcd.setupBuff(nil, true)
        lcd.autoFlush(false)

        -- 设置颜色,黑底白字,背景色:黑色(0x0000), 前景色:白色(0xFFFF)
        lcd.setColor(0x0000, 0xFFFF)

        -- 初始化方式三选一
        -- 1.使用14号固件内置hzfont字体初始化
        hzfont.init()

--[[         
        -- 2.使用文件系统中的字体初始化
        -- hzfont.init("/luadb/icomoon.ttf") 
]]

--[[         
        -- 3.使用SD卡中的字体初始化
        -- 初始化SPI1和TF卡
        -- 在Air780EHM/EHV/EGH核心板上TF卡的的pin_cs为gpio8,spi_id为0.请根据实际硬件修改
        local spi_id, pin_cs = 0, 8
        --初始化后拉高pin_cs,准备开始挂载TF卡
        gpio.setup(pin_cs, 1)

        -- 挂载TF卡;
        local max_retries = 3
        local retry_count = 0
        local result, err
        local mount_success = false -- TF卡挂载状态

        -- 以SPI对象的方式初始化SPI接口
        spi_sd_device = spi.deviceSetup(spi_id, pin_cs, 0, 0, 8, 24000000)

        -- 尝试多次挂载文件系统
        while retry_count < max_retries and not mount_success do
            -- 尝试挂载
            result, err = fatfs.mount(fatfs.SPI, "/sd", spi_sd_device)
            if result then
                mount_success = true
                log.info("TF Browser", "挂载成功! (尝试次数: " .. (retry_count + 1) .. ")")
            else
                log.warn("TF Browser", "挂载失败 (尝试 " .. (retry_count + 1) .. "):", err)
                retry_count = retry_count + 1
                sys.wait(500) -- 等待500ms后重试

                -- 尝试重置TF卡
                gpio.setup(pin_cs, 0)
                sys.wait(1000)
                gpio.setup(pin_cs, 1)
                sys.wait(1000)
            end
        end

        -- 获取SD卡的可用空间信息并打印。
        local data, err = fatfs.getfree("/sd")
        if not data then return end

        --打印SD卡的可用空间信息
        log.info("fatfs", "getfree", json.encode(data))

        if not io.exists("/sd/MiSans-Light.ttf") then return end

        -- 从SD卡加载,使用默认缓存 256
        hzfont.init("/sd/MiSans-Light.ttf")
 ]]
        -- hzfont调试信息开关
        -- hzfont.debug(true)

        -- 主显示循环
        while true do
            -- 清屏(黑色背景)
            lcd.clear(0x0000)

            -- 接口格式lcd.drawHzfontUtf8(x, y, str, fontSize, [color], [antialias])
            lcd.drawHzfontUtf8(10, 10, "合宙LuatOS字体演示", 10, 0xF800, 1)
            lcd.drawHzfontUtf8(10, 30, "合宙LuatOS字体演示", 20, 0x07E0, 1)
            lcd.drawHzfontUtf8(10, 70, "合宙LuatOS字体演示", 40, 0x001F, 1)
            lcd.drawHzfontUtf8(10, 130, "合宙LuatOS字体演示", 60, 0xFD20, 1)
            lcd.drawHzfontUtf8(10, 210, "合宙LuatOS字体演示", 80, 0x9E66, 1)
            lcd.drawHzfontUtf8(10, 310, "合宙LuatOS字体演示", 100, 0xFFFF, 1)

            -- 刷新显示
            lcd.flush()

            -- 延时2秒
            sys.wait(2000)
        end
    else
        log.error("LCD初始化失败")
    end
end

-- 启动显示协程
sys.taskInit(hzfont_test)

2.2 内置 hzfont 显示效果

三、常量详解

核心库常量,顾名思义是由合宙 LuatOS 内核固件中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用,包含以下常量;

3.1 HZFONT_CACHE_128

参数含义:缓存最近显示文字数据的内存空间可容纳文字的个数最大值为128个;
数据类型:number
是否必选:可选;
注意事项:用于hzfont.init(ttf_path, cache_size, load_to_psram)接口的cache_size参数
参数示例:hzfont.init("/sd/font.ttf", hzfont.HZFONT_CACHE_128)

3.2 HZFONT_CACHE_256

参数含义:缓存最近显示文字数据的内存空间可容纳文字的个数最大值为256个;
数据类型:number
是否必选:可选;
注意事项:用于hzfont.init(ttf_path, cache_size, load_to_psram)接口的cache_size参数
参数示例:hzfont.init("/sd/font.ttf", hzfont.HZFONT_CACHE_256)

3.3 HZFONT_CACHE_512

参数含义:缓存最近显示文字数据的内存空间可容纳文字的个数最大值为512个;
数据类型:number
是否必选:可选;
注意事项:用于hzfont.init(ttf_path, cache_size, load_to_psram)接口的cache_size参数
参数示例:hzfont.init("/sd/font.ttf", hzfont.HZFONT_CACHE_512)

3.4 HZFONT_CACHE_1024

参数含义:缓存最近显示文字数据的内存空间可容纳文字的个数最大值为1024个;
数据类型:number
是否必选:可选;
注意事项:用于hzfont.init(ttf_path, cache_size, load_to_psram)接口的cache_size参数
参数示例:hzfont.init("/sd/font.ttf", hzfont.HZFONT_CACHE_1024)

3.5 HZFONT_CACHE_2048

参数含义:缓存最近显示文字数据的内存空间可容纳文字的个数最大值为2048个;
数据类型:number
是否必选:可选;
注意事项:用于hzfont.init(ttf_path, cache_size, load_to_psram)接口的cache_size参数
参数示例:hzfont.init("/sd/font.ttf", hzfont.HZFONT_CACHE_2048)

四、函数详解

4.1 hzfont.init(ttf_path, cache_size, load_to_psram)

功能

初始化 hzfont 字体库,加载.ttf 字库,LuatOS 固件内置 hzfont 字体库包含:

_注意:不包含的字符会以"*"_号打印,使用时需要注意

当内置字库不能满足你的 ui 需求时,再尝试加载自己的 ttf 字库

参数

ttf_path

参数含义:TTF字体文件路径
数据类型:string
取值范围:有效的字体路径;
是否必选:可选;
注意事项:缺省则使用内置字库;
参数示例:hzfont.init("/sd/font.ttf")

cache_size

参数含义:缓存最近显示文字数据的内存空间可容纳文字个数的最大值;
数据类型:number
取值范围:章节3.1-3.5中的常量;
         1.直接从.ttf文件中加载字体并在屏幕上进行显示每个字所需时间约100ms
         2.从内存空间加载字体数据到屏幕显示每个字所需时间约1ms
         3.此参数为设置默认内存空间可存储文字数据的个数,每个字占用内存不超过100b空间
           笔画越复杂占用内存越多;
是否必选:可选;
注意事项:缺省默认为HZFONT_CACHE_256
参数示例:hzfont.init("/sd/font.ttf", hzfont.HZFONT_CACHE_1024)

load_to_psram

参数含义:是否将字库整包拷贝到PSRAM
数据类型:boolean
取值范围:true或false
是否必选:可选;
注意事项:1.将字库整包拷贝至PSRAM,每个字占用内存最大空间为100b,PSRAM空间不够会初始化失败
         2.使用rtos.meminfo("psram")接口可查询内存使用情况,
           系统运行后可以根据剩余内存空间大小选择是否加载;
         3.字库整包拷贝至PSRAM,每个字显示至屏幕所需时间约为1ms
         4.缺省.ttf字库文件不加载到psram,显示时先从文字缓存空间搜索,
           搜索不到则从.ttf文件中搜索
参数示例:hzfont.init("/sd/font.ttf", nil, true)

返回值

local result = hzfont.init(ttf_path, cache_size, load_to_psram)

参数含义:hzfont是否初始化成功
数据类型:boolean
取值范围:true或false
注意事项:成功返回true,失败返回false
参数示例:local result = hzfont.init()
         if result then
            lcd.drawHzfontUtf8(10, 10, "合宙LuatOS字体演示", 10, 0xF800, 1)
         end

示例 1: 使用 LCD 核心库加载 hzfont

-- 使用固件内置字库
hzfont.init()

-- 从文件加载,使用默认缓存 256
hzfont.init("/sd/font.ttf")

-- 从文件加载,指定缓1024
hzfont.init("/sd/font.ttf", hzfont.HZFONT_CACHE_1024)

-- 从luadb文件系统加载
hzfont.init("/luadb/font.ttf")

-- lcd库显示utf-8字符方式
lcd.drawHzfontUtf8(10, 10, "合宙LuatOS字体演示", 10, 0xF800, 1)
lcd.drawHzfontUtf8(10, 30, "合宙LuatOS字体演示", 20, 0x07E0, 1)
lcd.drawHzfontUtf8(10, 70, "合宙LuatOS字体演示", 40, 0x001F, 1)
lcd.drawHzfontUtf8(10, 130, "合宙LuatOS字体演示", 60, 0xFD20, 1)
lcd.drawHzfontUtf8(10, 210, "合宙LuatOS字体演示", 80, 0x9E66, 1)
lcd.drawHzfontUtf8(10, 310, "合宙LuatOS字体演示", 100, 0xFFFF, 1)

示例 2: 使用 AirUI 核心库加载 hzfont

-- PC端/Air8000/780EHM 从14号固件/114号固件中加载hzfont字库,从而支持12-255号中文显示
airui.font_load({
    type = "hzfont", -- 字体类型,可选 "hzfont" 或 "bin"
    path = nil,    -- 字体路径,对于 "hzfont",传 nil 则使用内置字库
    size = 20,     -- 字体大小,默认 16
    cache_size = 1048, -- 缓存字数大小,默认 2048
    antialias = 1, -- 抗锯齿等级,默认 4
})

-- Air8101使用104号固件将字体文件烧录到文件系统,从文件系统中加载hzfont字库,从而支持12-255号中文显示
airui.font_load({
    type = "hzfont",             -- 字体类型,可选 "hzfont" 或 "bin"
    path = "/MiSans_gb2312.ttf", -- 字体路径,对于 "hzfont",传 nil 则使用内置字库
    size = 20,                   -- 字体大小,默认 16
    cache_size = 1048,           -- 缓存字数大小,默认 2048
    antialias = 2,               -- 抗锯齿等级,默认 4
})

示例 3: 使用 exeasyui 扩展库加载 hzfont

-- 必须加载才能启用exeasyui的功能
local ui = require("exeasyui")

-- 启用14号固件内置HzFont矢量字体方式驱动
ui.hw_init({
    font_config = { type = "hzfont", size = 24, antialias = -1 }, -- 默认-1,表示自动抗锯齿

    -- lcd_config参数填写可以参考合宙exlcd显示扩展库exlcd.init(param)接口说明:https://docs.openluat.com/osapi/ext/exlcd/#31-exlcdinitparam
    lcd_config = {
        lcd_model = "AirLCD_1010", -- LCD型号
        -- pin_vcc = 24,           -- 供电引脚,使用GPIO控制屏幕供电可配置
        pin_rst = 36,              -- 复位引脚
        pin_pwr = 1,               -- 背光控制引脚GPIO ID号
        pin_pwm = 0,               -- 背光控制引脚PWM ID号
        port = lcd.HWID_0,         -- 驱动端口
        -- pin_dc = 0xFF,          -- lcd数据/命令选择引脚GPIO ID号,使用lcd 专用 SPI 接口 lcd.HWID_0不需要填此参数,使用通用SPI接口需要赋值
        direction = 0,             -- lcd屏幕方向 0:0° 1:90° 2:180° 3:270°,屏幕方向和分辨率保存一致
        w = 320,                   -- lcd 水平分辨率
        h = 480,                   -- lcd 竖直分辨率
        xoffset = 0,               -- x偏移(不同屏幕ic 不同屏幕方向会有差异)
        yoffset = 0,               -- y偏移(不同屏幕ic 不同屏幕方向会有差异)
        sleepcmd = 0X10,           -- 睡眠命令,默认0X10
        wakecmd = 0X11,            -- 唤醒命令,默认0X11
    }
})

4.2 hzfont.debug(enable)

功能

开启 hzfont 调试日志并进行打印开关

参数

enable

参数含义:是否开启hzfont调试日志
数据类型:boolean
取值范围:true或false
是否必选:必选;
注意事项:1.默认不打开debug日志
         2.打开时会打印大量加载字体具体耗时的日志;
参数示例:hzfont.debug(true) -- 开启debug
         hzfont.debug(false) -- 关闭debug

返回值

local result = hzfont.debug(enable)

result

参数含义:无;
数据类型:boolean
取值范围:总是返回true
注意事项:无法做为初始化成功判断信息;
参数示例:无

例子

-- hzfont调试信息开关
hzfont.debug(true)

五、产品支持说明

  1. hzfont 是 ui 显示的一部分, 请确认你的设备有屏幕接口,可以查看选型手册对应型号及固件是否支持 lcd 核心库和 easylvgl 核心库
  2. 当前仅 V2020 及以上版本的 14 号和 114 号 LuatOS 固件版本支持 hzfont;

  3. 例如:Air8000 系列的模组可以参考:https://docs.openluat.com/air8000/luatos/firmware/

  4. Air7XX 系列模组可以参考:https://docs.openluat.com/air780epm/luatos/firmware/780ehm_version/
  5. 使用 hzfont.init()接口初始化 hzfont 后才能进行调用

六、从外部从外部加载.ttf 操作说明

  1. Air8101 支持 hzfont 的固件中未内置.ttf 文件,可以选择从 SD 卡或者模组文件系统中加载。如果选择从模组文件系统中加载,那么在烧录固件时需要手动将.ttf 文件字体文件一并烧录到模组的文件系统中,且初始化 hzfont 时选择所烧录的字体文件。
  2. 字体文件大小不能超过固件所支持的文件系统空间。
  3. 烧录步骤如下:

  4. 将.ttf 文件准备好,或者下载 MiSans_gb2312.ttf,单独放入一个空文件夹中

  5. 烧录固件时选择对应的文件夹,然后选择下载底层和脚本
  6. 使用方式:搭配 lcd 核心库、AirUI 核心库、exeasyui 扩展库使用方式,可以参考见 4.1 章节 初始化示例,在此不重复赘述