如何从字体文件中获取字形位图、字形描述符,以及如何进行字形的压缩和解压缩。带着问题,我将逐一解释这些函数,并在最后提供一个简单的示例来展示如何在一个demo中使用这些函数。
函数解释
-
lv_font_get_bitmap_fmt_txt
lv_font_get_bitmap_fmt_txt 函数是 LittlevGL 图形库中用于从字体文件中提取字形位图数据的函数。这个函数处理了字体数据的不同格式,包括未压缩的位图和使用RLE(Run-Length Encoding)压缩的位图。下面我将详细分析这个函数:
函数原型
const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf)
参数
-
g_dsc:指向lv_font_glyph_dsc_t结构体的指针,包含了字形的元数据,如字形的宽度、高度、x偏移量、y偏移量以及字形的ID。 -
draw_buf:指向lv_draw_buf_t结构体的指针,这是一个绘图缓冲区,用于存储提取出来的字形位图数据。
返回值
函数返回一个 const void * 类型的指针,指向 draw_buf,其中包含了字形的位图数据。
函数逻辑
-
获取字体和字形描述信息: 函数从
g_dsc获取字体指针font和字形IDgid。 -
检查字形ID: 如果
gid为0,表示没有字形数据,函数返回NULL。 -
获取字形位图大小: 计算字形位图的大小
gsize,如果gsize为0,表示没有字形数据,函数返回NULL。 -
处理未压缩的位图: 如果字体的位图格式是
LV_FONT_FMT_TXT_PLAIN,函数将根据不同的位深(bpp),将字形位图数据从输入缓冲区bitmap_in复制到输出缓冲区bitmap_out。 -
处理压缩的位图: 如果字体的位图格式不是
LV_FONT_FMT_TXT_PLAIN,函数将调用decompress函数对字形位图进行解压缩,并将结果存储在draw_buf中。 -
返回位图数据: 最终,函数返回
draw_buf的指针,它现在包含了字形的位图数据。
使用场景
这个函数通常在需要将字符渲染到屏幕上时被调用。例如,在文本显示、编辑或者排版过程中,当需要显示一个字符时,程序会先通过 lv_font_get_glyph_dsc_fmt_txt 获取该字符的字形描述符,然后使用 lv_font_get_bitmap_fmt_txt 获取字形的位图数据,并最终将这些数据绘制到屏幕上。
注意事项
- 字体文件必须事先加载并正确初始化,以便
lv_font_get_bitmap_fmt_txt可以正确地访问字形数据。 - 如果字体数据是压缩的,需要确保 LittlevGL 配置中启用了
LV_USE_FONT_COMPRESSED,并且decompress函数被正确实现。 - 返回的位图数据可能会占用大量内存,尤其是在高分辨率或复杂字形的情况下,因此应当谨慎管理这些资源。
以下是 lv_font_get_bitmap_fmt_txt 函数的详细分析和代码注释:
/**
* 获取字体中特定字形的位图数据。
* @param g_dsc 指向字形描述符的指针,包含了字形的元数据。
* @param draw_buf 指向绘制缓冲区的指针,用于存储位图数据。
* @return 返回绘制缓冲区的指针,其中包含了字形的位图数据。
*/
const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf)
{
// 获取字形描述符中已经解析的字体指针
const lv_font_t * font = g_dsc->resolved_font;
// 获取指向绘制缓冲区数据的指针
uint8_t * bitmap_out = draw_buf->data;
// 获取字体数据块的指针
lv_font_fmt_txt_dsc_t * fdsc = (lv_font_fmt_txt_dsc_t *)font->dsc;
// 获取字形ID
uint32_t gid = g_dsc->gid.index;
// 如果gid为0,则表示没有字形数据,返回NULL
if(!gid) return NULL;
// 获取指向字形描述符的指针
const lv_font_fmt_txt_glyph_dsc_t * gdsc = &fdsc->glyph_dsc[gid];
// 计算字形位图的大小
int32_t gsize = (int32_t) gdsc->box_w * gdsc->box_h;
// 如果大小为0,则表示没有字形数据,返回NULL
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);
// 根据每像素的位数(bpp)处理位图数据
if(fdsc->bpp == 1) {
// 1bpp位图处理
for(y = 0; y < gdsc->box_h; y ++) {
for(x = 0; x < gdsc->box_w; x++, i++) {
i = i & 0x7;
// 根据当前位的位置,从输入位图中提取相应的位,并转换为掩码
uint8_t mask = 0x80 >> i;
bitmap_out_tmp[x] = (*bitmap_in & mask) ? 0xff : 0x00;
if(i == 7) {
bitmap_in++;
i = 0;
}
}
bitmap_out_tmp += stride;
}
}
else if(fdsc->bpp == 2) {
// 2bpp位图处理
// ...
// (省略了2bpp和4bpp的代码,逻辑与1bpp类似,只是掩码和位移不同)
}
else if(fdsc->bpp == 4) {
// 4bpp位图处理
// ...
}
// 返回包含未压缩位图数据的绘制缓冲区
return draw_buf;
}
else {
// Handle compressed bitmap
#if LV_USE_FONT_COMPRESSED
// 如果位图是压缩的,进行解压缩处理
bool prefilter = fdsc->bitmap_format == LV_FONT_FMT_TXT_COMPRESSED;
decompress(&fdsc->glyph_bitmap[gdsc->bitmap_index], bitmap_out, gdsc->box_w, gdsc->box_h,
(uint8_t)fdsc->bpp, prefilter);
return draw_buf;
#else /*!LV_USE_FONT_COMPRESSED*/
// 如果没有启用压缩字体支持,输出警告并返回NULL
LV_LOG_WARN("Compressed fonts is used but LV_USE_FONT_COMPRESSED is not enabled in lv_conf.h");
return NULL;
#endif
}
// 如果没有返回,说明字形在字体中未找到
return NULL;
}
这个函数首先检查字形ID是否有效,然后根据字形的位图格式(压缩或未压缩)来处理数据。对于未压缩的位图,它会根据每像素的位数(bpp)来逐位解析位图数据,并将其转换为绘制缓冲区可以识别的格式。如果位图是压缩的,它会调用 decompress 函数来进行解压缩。
请注意,由于这是一个大型函数,我省略了2bpp和4bpp位图处理的具体代码,以及压缩位图解压缩的实现细节。在实际应用中,你需要确保 LV_USE_FONT_COMPRESSED 宏已定义,并且 decompress 函数被正确实现,以支持压缩位图的解压缩。
lv_font_get_glyph_dsc_fmt_txt
lv_font_get_glyph_dsc_fmt_txt 函数是 LittlevGL 图形库中用于检索特定字符的字形描述符(glyph descriptor)的函数。这个函数是字体系统中的重要组成部分,它允许程序确定如何渲染文本以及文本的视觉属性。以下是对 lv_font_get_glyph_dsc_fmt_txt 函数的详细分析:
函数原型
bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next)
参数
-
font:指向lv_font_t结构体的指针,表示要查询的字体。 -
dsc_out:指向lv_font_glyph_dsc_t结构体的指针,用于存储查询到的字形描述符。 -
unicode_letter:要获取描述符的字符的Unicode编码。 -
unicode_letter_next:紧随unicode_letter之后的字符的Unicode编码,用于考虑字距(kerning)效果。
返回值
函数返回一个布尔值,如果找到了对应的字形描述符,则返回 true;否则返回 false。
函数逻辑
-
处理制表符:函数首先检查
unicode_letter是否是制表符('\t'),如果是,则将其替换为空白符(' ')以简化处理。 -
获取字形描述符ID:使用
get_glyph_dsc_id函数获取字符unicode_letter对应的字形描述符ID。 -
检查字形ID:如果得到的字形ID为0,表示没有找到对应的字形,函数返回
false。 -
获取字距值:如果字体支持字距,函数将计算当前字符和其后一个字符之间的字距值。
-
构建字形描述符:使用获取到的字形ID和字距值,函数填充
dsc_out结构体,包括字形的宽度(box_w)、高度(box_h)、x偏移量(ofs_x)、y偏移量(ofs_y)和推荐前进距离(adv_w)。 -
处理制表符宽度:如果原始字符是制表符,函数将字形宽度加倍。
-
返回结果:最终,函数返回
true表示成功找到字形描述符。
使用场景
这个函数通常在需要确定字符的视觉属性时被调用,比如在文本渲染、文本布局或文本宽度计算时。
注意事项
- 字形描述符包含了渲染字符所需的所有必要信息,包括大小、偏移量和字距调整。
- 字距值是通过
get_kern_value函数获取的,它可能依赖于字形的ID或字形的类别。 - 如果
unicode_letter是制表符,函数会将其视为一个特殊的空白符,以简化制表符宽度的处理。
通过上述分析,我们可以看到 lv_f

本文详细介绍了LittlevGL图形库中处理字体文件的函数,包括从字体文件中提取字形位图、字形描述符,以及字形的压缩和解压缩。文中对多个关键函数进行了深入的分析,包括函数逻辑、使用场景和注意事项,展示了如何在实际应用场景中使用这些函数来渲染和管理字体数据。
最低0.47元/天 解锁文章
1597

被折叠的 条评论
为什么被折叠?



