前言

有关于LvglFontTool V0.5 [软件](http://dz.lfly.xyz/forum.php?mod=viewthread&tid=72&extra=page=1)
生成的内部字体的方法请参考其他人的文章(网上有多教程),
但是到目前为止LvglFontTool V0.5最高只能生成对v8版本的内部字库支持,
生成的c文件对v8版本进行了适配,但是对v9版本不适用

(目前为止我没有找到关于v9版本的适配,所以写一下)。
本文章主要是针对lvlgl v9版本的LvglFontTool V0.5生成内部字库c文件进行适配。
(目前测试可以,暂未发现bug)

一、代码修改

主要是修改__user_font_get_bitmap和__user_font_get_glyph_dsc函数,修改如下:
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)
{
const lv_font_t *font = g_dsc->resolved_font;
uint32_t unicode_letter = g_dsc->gid.index;
uint8_t * bitmap_out = draw_buf->data;

lv_font_fmt_txt_dsc_t * fdsc = (lv_font_fmt_txt_dsc_t *) font->dsc;

if( unicode_letter<fdsc->cmaps[0].range_start || unicode_letter>fdsc->cmaps[0].range_length ) return false;

int i;
i = binsearch(fdsc->cmaps[0].unicode_list, fdsc->cmaps[0].list_length, unicode_letter);
if( i != -1 ) {
    const lv_font_fmt_txt_glyph_dsc_t * gdsc = &fdsc->glyph_dsc[i];
    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 = &fdsc->glyph_bitmap[gdsc->bitmap_index];
        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) {
lv_font_fmt_txt_dsc_t * fdsc = (lv_font_fmt_txt_dsc_t *) font->dsc;

if( unicode_letter<fdsc->cmaps[0].range_start || unicode_letter>fdsc->cmaps[0].range_length ) return false;

int i;
i = binsearch(fdsc->cmaps[0].unicode_list, fdsc->cmaps[0].list_length, unicode_letter);
if( i != -1 ) {
    const lv_font_fmt_txt_glyph_dsc_t * gdsc = &fdsc->glyph_dsc[i];
    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 = fdsc->bpp;
    dsc_out->gid.index = unicode_letter; //官方工具生成的字库赋的值就是uicode的id
    dsc_out->is_placeholder = false;
    return true;
}
return false;

}

总结

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

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

lvglFontToolV0.5上传的代码配置如下:
在这里插入图片描述

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐