使用目前最新的 Releases 版本 LVGL v8.2.0 ,移植好 freetype2 后测试,发现每次启动程序时会高概率出现屏幕显示全白色背景,无任何内容的问题。

打开日志开关,出现问题时会有如下打印:

lv_font_get_glyph_bitmap: Asserted at expression: font_p != NULL (NULL pointer)        (in lv_font.c line #51)

Lvgl 检测到了 font_p 参数为空指针,根据日志信息指引,出现问题的代码块如下:

const uint8_t * lv_font_get_glyph_bitmap(const lv_font_t * font_p, uint32_t letter)
{
LV_ASSERT_NULL(font_p); // 报错的地方
return font_p->get_glyph_bitmap(font_p, letter);
}
#if LV_USE_ASSERT_NULL
# define LV_ASSERT_NULL(p) LV_ASSERT_MSG(p != NULL, "NULL pointer");
#else
# define LV_ASSERT_NULL(p)
#endif

回溯分析发现是 lv_draw_sw_letter() 内部通过 lv_font_get_glyph_dsc() 获取:

void lv_draw_sw_letter(lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t * dsc,  const lv_point_t * pos_p,
uint32_t letter)
{
lv_font_glyph_dsc_t g;
bool g_ret = lv_font_get_glyph_dsc(dsc->font, &g, letter, '\0');
if(g_ret == false) {
/*Add warning if the dsc is not found
*but do not print warning for non printable ASCII chars (e.g. '\n')*/
if(letter >= 0x20 &&
letter != 0xf8ff && /*LV_SYMBOL_DUMMY*/
letter != 0x200c) { /*ZERO WIDTH NON-JOINER*/
LV_LOG_WARN("lv_draw_letter: glyph dsc. not found for U+%X", (unsigned int)letter);
}
return;
} /*Don't draw anything if the character is empty. E.g. space*/
if((g.box_h == 0) || (g.box_w == 0)) return; lv_point_t gpos;
gpos.x = pos_p->x + g.ofs_x;
gpos.y = pos_p->y + (dsc->font->line_height - dsc->font->base_line) - g.box_h - g.ofs_y; /*If the letter is completely out of mask don't draw it*/
if(gpos.x + g.box_w < draw_ctx->clip_area->x1 ||
gpos.x > draw_ctx->clip_area->x2 ||
gpos.y + g.box_h < draw_ctx->clip_area->y1 ||
gpos.y > draw_ctx->clip_area->y2) {
return;
}
// 出现问题的时候, g.resolved_font 为空指针
const uint8_t * map_p = lv_font_get_glyph_bitmap(g.resolved_font, letter);
if(map_p == NULL) {
LV_LOG_WARN("lv_draw_letter: character's bitmap not found");
return;
} if(g.resolved_font->subpx) {
#if LV_DRAW_COMPLEX && LV_USE_FONT_SUBPX
draw_letter_subpx(draw_ctx, dsc, &gpos, &g, map_p);
#else
LV_LOG_WARN("Can't draw sub-pixel rendered letter because LV_USE_FONT_SUBPX == 0 in lv_conf.h");
#endif
}
else {
draw_letter_normal(draw_ctx, dsc, &gpos, &g, map_p);
}
}

在 lv_font_get_glyph_dsc() 内部会预先设置为空指针,然后再去寻找对应的描述符:

bool lv_font_get_glyph_dsc(const lv_font_t * font_p, lv_font_glyph_dsc_t * dsc_out, uint32_t letter,
uint32_t letter_next)
{
LV_ASSERT_NULL(font_p);
LV_ASSERT_NULL(dsc_out);
dsc_out->resolved_font = NULL; // 这里直接设置为空指针
const lv_font_t * f = font_p;
bool found = false;
while(f) {
found = f->get_glyph_dsc(f, dsc_out, letter, letter_next);
// 只有找到描述符并且不是占位符的情况下才会重新赋值
if(found && !dsc_out->is_placeholder) {
dsc_out->resolved_font = f;
break;
}
f = f->fallback;
}
return found;
}

问题就出现在寻找字形描述符时,如果没有找到或者找到但是是占位符的情况,那么被设置为空指针的地方并未正确赋值。

可以修改不赋值空指针,而是仍保留原指针的方式来修复此问题:

bool lv_font_get_glyph_dsc(const lv_font_t * font_p, lv_font_glyph_dsc_t * dsc_out, uint32_t letter,
uint32_t letter_next)
{
LV_ASSERT_NULL(font_p);
LV_ASSERT_NULL(dsc_out);
dsc_out->resolved_font = font_p; // 这里保留原有的指针
const lv_font_t * f = font_p;
bool found = false;
while(f) {
found = f->get_glyph_dsc(f, dsc_out, letter, letter_next);
// 只有找到描述符并且不是占位符的情况下才会重新赋值
if(found && !dsc_out->is_placeholder) {
dsc_out->resolved_font = f;
break;
}
f = f->fallback;
}
return found;
}

最新文章

  1. etcd命令说明 etcd Version: 3.0.15
  2. Redis学习笔记(1)-Key
  3. 高通Android平台硬件调试之Camera篇
  4. Labview实现单边带信号调制(SSB)[滤波法]
  5. .Net课程体系
  6. 创建range分区
  7. Mysql学习(慕课学习笔记5)约束
  8. AsyncQueryHandler处理数据
  9. 鸟哥的私房菜上 xpenguins 设备(ubuntu 12.04)
  10. POJ2187(旋转卡壳)
  11. Selenium 运行时出现错误(java.lang.NoClassDefFoundError: com/google/common/base/Function)
  12. 【转】Spring Bean单例与线程安全
  13. 高效的CSS代码(1)
  14. 俄罗斯方块(2D、3D)
  15. 修改pudb颜色
  16. 纯CSS画的基本图形(圆形、三角形、多边形、爱心、八卦等)
  17. GitHub学习二-将本地Git库与Github上的Git库相关联
  18. C# Owin初探 概念理解(一)
  19. Android-LayoutAnimation
  20. Python之时间模块

热门文章

  1. MongoDB - 简单了解
  2. JS逆向实战4--cookie——__jsl_clearance_s 生成
  3. CF620E New Year Tree(树形+dfs序+线段树+状态压缩)
  4. Django系列---理论一
  5. 部署owncloud连接ladp迁移数据
  6. JUC学习笔记——共享模型之不可变
  7. 图解ReentrantLock底层公平锁和非公平锁实现原理
  8. Training: Encodings I
  9. json与字符串的互转
  10. mysql-front连接mysql报错1251解决方法