LVGL9.1使用lvglFontToolV0.5 bin文件字库
Published on 2025-02-19 23:08 in 分类: littlevgl with 萧海~
分类: littlevgl

LVGL9.1使用lvglFontToolV0.5 bin文件字库

    /*
    *---------------------------------------------------------------
    * Lvgl Font Tool
    *
    * 注:使用unicode编码
    * 注:本字体文件由Lvgl Font Tool V0.5测试版 生成
    * 作者:阿里(qq:617622104)
    *---------------------------------------------------------------
    */
    #include "lvgl.h"
    typedef struct{
    uint16_t min;
    uint16_t max;
    uint8_t bpp;
    uint8_t reserved[3];
    }x_header_t;
    typedef struct{
    uint32_t pos;
    }x_table_t;
    typedef struct{
    uint8_t adv_w;
    uint8_t box_w;
    uint8_t box_h;
    int8_t ofs_x;
    int8_t ofs_y;
    uint8_t r;
    }glyph_dsc_t;
    static x_header_t __g_xbf_hd = {
    .min = 0x0020,
    .max = 0x9fa0,
    .bpp = 4,
    };
    //static uint8_t __g_font_buf[0];//如bin文件存在SPI FLASH可使用此buff
    char *myFontBuf;
    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);
    return myFontBuf + offset;
    }
    static const uint8_t opa4_table[16] = { 0, 17, 34, 51,
    68, 85, 102, 119,
    136, 153, 170, 187,
    204, 221, 238, 255
    };
    static const uint8_t opa2_table[4] = { 0, 85, 170, 255 };
    // lv_draw_buf_t * draw_buf 看了原版的参数,这里都不用填
    static const void * __user_font_get_bitmap(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf)
    {
    uint32_t unicode_letter = g_dsc->gid.index;
    uint8_t * bitmap_out = draw_buf->data;
    const lv_font_t *font = g_dsc->resolved_font;
    lv_font_fmt_txt_dsc_t * fdsc = (lv_font_fmt_txt_dsc_t *)font->dsc;
    if (unicode_letter > __g_xbf_hd.max || unicode_letter < __g_xbf_hd.min) {
    return NULL;
    }
    uint32_t unicode_offset = sizeof(x_header_t) + (unicode_letter - __g_xbf_hd.min) * 4;
    uint32_t *p_pos = (uint32_t *)__user_font_getdata(unicode_offset, 4);
    if (p_pos[0] != 0) {
    uint32_t pos = p_pos[0];
    glyph_dsc_t * gdsc = (glyph_dsc_t*)__user_font_getdata(pos, sizeof(glyph_dsc_t));
    glyph_dsc_t gdscPoint = { 0 };
    memcpy(&gdscPoint, gdsc, sizeof(glyph_dsc_t));
    gdsc = &gdscPoint;
    int32_t gsize = (int32_t)gdsc->box_w * gdsc->box_h;
    if (gsize == 0) return NULL;
    if (fdsc->bitmap_format == LV_FONT_FMT_TXT_PLAIN) {
    const uint8_t * bitmap_in = __user_font_getdata(pos + sizeof(glyph_dsc_t), gdsc->box_w*gdsc->box_h*__g_xbf_hd.bpp / 8);
    uint8_t * bitmap_out_tmp = bitmap_out;
    int32_t i = 0;
    int32_t x, y;
    uint32_t stride = lv_draw_buf_width_to_stride(gdsc->box_w, LV_COLOR_FORMAT_A8);
    if (fdsc->bpp == 1) {
    for (y = 0; y < gdsc->box_h; y++) {
    for (x = 0; x < gdsc->box_w; x++, i++) {
    i = i & 0x7;
    if (i == 0) bitmap_out_tmp[x] = (*bitmap_in) & 0x80 ? 0xff : 0x00;
    else if (i == 1) bitmap_out_tmp[x] = (*bitmap_in) & 0x40 ? 0xff : 0x00;
    else if (i == 2) bitmap_out_tmp[x] = (*bitmap_in) & 0x20 ? 0xff : 0x00;
    else if (i == 3) bitmap_out_tmp[x] = (*bitmap_in) & 0x10 ? 0xff : 0x00;
    else if (i == 4) bitmap_out_tmp[x] = (*bitmap_in) & 0x08 ? 0xff : 0x00;
    else if (i == 5) bitmap_out_tmp[x] = (*bitmap_in) & 0x04 ? 0xff : 0x00;
    else if (i == 6) bitmap_out_tmp[x] = (*bitmap_in) & 0x02 ? 0xff : 0x00;
    else if (i == 7) {
    bitmap_out_tmp[x] = (*bitmap_in) & 0x01 ? 0xff : 0x00;
    bitmap_in++;
    }
    }
    bitmap_out_tmp += stride;
    }
    }
    else if (fdsc->bpp == 2) {
    for (y = 0; y < gdsc->box_h; y++) {
    for (x = 0; x < gdsc->box_w; x++, i++) {
    i = i & 0x3;
    if (i == 0) bitmap_out_tmp[x] = opa2_table[(*bitmap_in) >> 6];
    else if (i == 1) bitmap_out_tmp[x] = opa2_table[((*bitmap_in) >> 4) & 0x3];
    else if (i == 2) bitmap_out_tmp[x] = opa2_table[((*bitmap_in) >> 2) & 0x3];
    else if (i == 3) {
    bitmap_out_tmp[x] = opa2_table[((*bitmap_in) >> 0) & 0x3];
    bitmap_in++;
    }
    }
    bitmap_out_tmp += stride;
    }
    }
    else if (fdsc->bpp == 4) {
    for (y = 0; y < gdsc->box_h; y++) {
    for (x = 0; x < gdsc->box_w; x++, i++) {
    i = i & 0x1;
    if (i == 0) {
    bitmap_out_tmp[x] = opa4_table[(*bitmap_in) >> 4];
    }
    else if (i == 1) {
    bitmap_out_tmp[x] = opa4_table[(*bitmap_in) & 0xF];
    bitmap_in++;
    }
    }
    bitmap_out_tmp += stride;
    }
    }
    return draw_buf;
    }
    }
    return NULL;
    }
    static bool __user_font_get_glyph_dsc(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next) {
    if( unicode_letter>__g_xbf_hd.max || unicode_letter<__g_xbf_hd.min ) {
    return NULL;
    }
    uint32_t unicode_offset = sizeof(x_header_t)+(unicode_letter-__g_xbf_hd.min)*4;
    uint32_t *p_pos = (uint32_t *)__user_font_getdata(unicode_offset, 4);
    if( p_pos[0] != 0 ) {
    glyph_dsc_t * gdsc = (glyph_dsc_t*)__user_font_getdata(p_pos[0], sizeof(glyph_dsc_t));
    dsc_out->adv_w = gdsc->adv_w;
    dsc_out->box_h = gdsc->box_h;
    dsc_out->box_w = gdsc->box_w;
    dsc_out->ofs_x = gdsc->ofs_x;
    dsc_out->ofs_y = gdsc->ofs_y;
    dsc_out->format = (uint8_t)__g_xbf_hd.bpp;
    dsc_out->gid.index = unicode_letter; //官方工具生成的字库赋的值就是uicode的id
    dsc_out->is_placeholder = false;
    return true;
    }
    return false;
    }
    #if LVGL_VERSION_MAJOR >= 8
    static const lv_font_fmt_txt_dsc_t font_dsc = {
    #else
    static lv_font_fmt_txt_dsc_t font_dsc = {
    #endif
    .glyph_bitmap = NULL,
    .glyph_dsc = NULL,
    .cmaps = NULL,
    .kern_dsc = NULL,
    .kern_scale = 0,
    .cmap_num = 0,
    .bpp = 4,
    .kern_classes = 0,
    .bitmap_format = LV_FONT_FMT_TXT_PLAIN,
    #if LVGL_VERSION_MAJOR == 8
    .cache = &cache
    #endif
    };
    //黑体,Regular,28
    //字模高度:0
    //XBF字体,外部bin文件
    const lv_font_t myFont = {
    .get_glyph_bitmap = __user_font_get_bitmap,
    .get_glyph_dsc = __user_font_get_glyph_dsc,
    .line_height = 28,
    .base_line = 0,
    #if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0)
    .subpx = LV_FONT_SUBPX_NONE,
    #endif
    #if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8
    .underline_position = -2,
    .underline_thickness = 1,
    #endif
    .dsc = &font_dsc, /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */
    #if LV_VERSION_CHECK(8, 2, 0) || LVGL_VERSION_MAJOR >= 9
    .fallback = NULL,
    #endif
    .user_data = NULL,
    };
    int myFontInit(char *filePath, lv_font_t *retLvFont)
    {
    // 打开文件
    HANDLE hFile = CreateFileA(
    filePath, // 文件名
    GENERIC_READ, // 访问模式:读取
    0, // 共享模式:不共享
    NULL, // 安全属性
    OPEN_EXISTING, // 创建方式:打开现有文件
    FILE_ATTRIBUTE_NORMAL, // 文件属性
    NULL // 模板文件句柄
    );
    if (hFile == INVALID_HANDLE_VALUE) {
    // 打开文件失败,输出错误信息
    printf("Could not open file (error %lu)\n", GetLastError());
    return 1;
    }
    // 获取文件大小
    DWORD fileSize = GetFileSize(hFile, NULL);
    if (fileSize == INVALID_FILE_SIZE) {
    // 获取文件大小失败,输出错误信息
    printf("Could not get file size (error %lu)\n", GetLastError());
    CloseHandle(hFile);
    return 1;
    }
    // 分配内存以存储文件数据
    myFontBuf = (char *)malloc(fileSize + 1); // +1 用于结尾的空字符
    if (myFontBuf == NULL) {
    // 内存分配失败,输出错误信息
    printf("Could not allocate memory\n");
    CloseHandle(hFile);
    return 1;
    }
    // 读取文件内容
    DWORD bytesRead;
    BOOL readResult = ReadFile(
    hFile, // 文件句柄
    myFontBuf, // 缓冲区
    fileSize, // 要读取的字节数
    &bytesRead, // 实际读取的字节数
    NULL // 重叠结构
    );
    if (!readResult || bytesRead != fileSize) {
    // 读取文件失败或读取字节数不匹配,输出错误信息
    printf("Could not read file (error %lu)\n", GetLastError());
    free(myFontBuf);
    CloseHandle(hFile);
    return 1;
    }
    CloseHandle(hFile);
    retLvFont = &myFont;
    return 0;
    }
    int myFontUninit()
    {
    free(myFontBuf);
    return 0;
    }
    posted @   萧海~  阅读(38)  评论(0编辑  收藏  举报
    相关博文:
    阅读排行:
    · winform 绘制太阳,地球,月球 运作规律
    · AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
    · 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
    · 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
    · 上周热点回顾(3.3-3.9)
    历史上的今天:
    2024-02-19 软件搜索工具
    2023-02-19 MQTT连接阿里云IoT(一)
    2021-02-19 【转】STL常见问题
    2021-02-19 【设计模式 - 结构型模式】5. 外观模式
    2021-02-19 APU、BPU、CPU、DPU、FPU、GPU、HPU、IPU、MPU、NPU、RPU、TPU、VPU、WPU、XPU、ZPU 都是什么?
    2021-02-19 MySQL8.0.18版本的数据库安装过程
    2021-02-19 MySQL5.7.24版本的数据库安装过程
    点击右上角即可分享
    微信分享提示
    电磁波切换