lvgl v9.1版本使用lvglFontTool V0.4生成的外部bin字库

前言

有关于LvglFontTool V0.4(网址:[http://dz.lfly.xyz/forum.php?mod=viewthread&tid=24&extra=page%3D1])
生成的外部字体的方法请参考其他人的文章(网上有多教程),
目前为止LvglFontTool V0.4最高只能生成对v6版本的内部字库支持,
所以生成的c文件未对v9版本适配,(目前为止我没有找到关于v9版本的适配,所以写一下)。
本文章主要是针对LvglFontTool V0.4生成的外部bin字库的c文件对lvgl v9.1版本进行适配,
(目前测试可以,暂未发现bug)

提示:以下是本篇文章正文内容,下面案例可供参考

一、代码修改

主要修改:__user_font_get_bitmap、__user_font_get_glyph_dsc和生成字体的结构体const lv_font_t myFontSongJianTi16,代码修改如下:

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;  // 每个字符的编码都是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 = (uint8_t)gdsc->adv_w;
        dsc_out->box_h = (uint8_t)gdsc->box_h;
        dsc_out->box_w = (uint8_t)gdsc->box_w;
        dsc_out->ofs_x = (int8_t)gdsc->ofs_x;
        dsc_out->ofs_y = (int8_t)gdsc->ofs_y;
        //dsc_out->bpp   = __g_xbf_hd.bpp; //改成下面
        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
};

//SimSun,,-1
//字模高度:18
//XBF字体,外部bin文件
const lv_font_t myFontSongJianTi16 = {
    .get_glyph_bitmap = __user_font_get_bitmap,
    .get_glyph_dsc = __user_font_get_glyph_dsc,
    .line_height = 18,
    .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,
};

总结

目前测试是可以的,还没有发现bug,源码已经上传,代码写的比较水,在lvglFoontTool工具还没有适配前,上面的代码仅供参考。

效果如图:
在这里插入图片描述

lvglFontTool V0.4配置如下:
在这里插入图片描述

  • 13
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hydra-Windows-V9.1是一个可用于Windows操作系统的下载工具。它是一个网络爬虫软件,可以从互联网上下载大量的数据和文件。Hydra-Windows-V9.1提供了简单易用的界面和丰富的功能,让用户可以方便地搜索和下载各种资源。 在下载Hydra-Windows-V9.1之前,您需要打开浏览器并搜索Hydra-Windows-V9.1下载页面。选择一个可信任的网站,确保下载软件的安全性和可靠性。在下载页面上,您可能需要提供相关信息,如操作系统版本和用户信息。一旦确认了这些信息,您可以点击下载按钮,开始下载Hydra-Windows-V9.1的安装包。 下载过程可能需要一些时间,具体取决于您的网络速度和软件大小。一旦下载完成,您可以找到文件的存储位置(通常在下载文件夹中),然后双击安装包,按照安装向导的提示逐步完成软件的安装。 安装完成后,您可以在开始菜单中找到Hydra-Windows-V9.1的图标,双击打开该软件。通过它的用户界面,您可以进行搜索和下载操作。在搜索框中输入您需要下载的资源关键词,Hydra-Windows-V9.1将搜索互联网并显示相关的下载链接。您可以选择并下载您感兴趣的资源,同时也可以设置下载速度和下载路径等选项。 总而言之,通过访问Hydra-Windows-V9.1的下载页面并按照提示进行安装,您就可以轻松地在Windows操作系统上使用这个网络爬虫工具进行各种资源的搜索和下载。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值