使用目前最新的 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;
}

【分析笔记】LVGL v8.2.0 使用 freetype 概率性无显示的问题的更多相关文章

  1. zeromq源码分析笔记之准备(0)

    zeromq这个库主要用于进程通信,包括本地进程.网络通信,涉及到一些基础知识,主要包括管道通信,socket编程的内容,反应器模式(使用IO多路复用实现),无锁队列这几块比较重要的部分,下面的几个链 ...

  2. 《linux 内核全然剖析》 fork.c 代码分析笔记

    fork.c 代码分析笔记 verifiy_area long last_pid=0; //全局变量,用来记录眼下最大的pid数值 void verify_area(void * addr,int s ...

  3. glusterfs 4.0.1 api 分析笔记1

    一般来说,我们写个客户端程序大概的样子是这样的: /* glfs_example.c */ // gcc -o glfs_example glfs_example.c -L /usr/lib64/ - ...

  4. 3.View绘制分析笔记之onLayout

    上一篇文章我们了解了View的onMeasure,那么今天我们继续来学习Android View绘制三部曲的第二步,onLayout,布局. ViewRootImpl#performLayout pr ...

  5. 4.View绘制分析笔记之onDraw

    上一篇文章我们了解了View的onLayout,那么今天我们来学习Android View绘制三部曲的最后一步,onDraw,绘制. ViewRootImpl#performDraw private ...

  6. 2.View绘制分析笔记之onMeasure

    今天主要学习记录一下Android View绘制三部曲的第一步,onMeasure,测量. 起源 在Activity中,所有的View都是DecorView的子View,然后DecorView又是被V ...

  7. 1.Android 视图及View绘制分析笔记之setContentView

    自从1983年第一台图形用户界面的个人电脑问世以来,几乎所有的PC操作系统都支持可视化操作,Android也不例外.对于所有Android Developer来说,我们接触最多的控件就是View.通常 ...

  8. zeromq源码分析笔记之线程间收发命令(2)

    在zeromq源码分析笔记之架构说到了zmq的整体架构,可以看到线程间通信包括两类,一类是用于收发命令,告知对象该调用什么方法去做什么事情,命令的结构由command_t结构体确定:另一类是socke ...

  9. SEH分析笔记(X64篇)

    SEH分析笔记(X64篇) v1.0.0 boxcounter 历史: v1.0.0, 2011-11-4:最初版本. [不介意转载,但请注明出处 www.boxcounter.com  附件里有本文 ...

  10. 【转载】Instagram架构分析笔记

    原文地址:http://chengxu.org/p/401.html Instagram 架构分析笔记 全部 技术博客 Instagram团队上个月才迎来第 7 名员工,是的,7个人的团队.作为 iP ...

随机推荐

  1. UBOOT编译--- make xxx_deconfig过程详解(一)

    make xxx_deconfig过程详解 1. 前言 2. 概述 3. build变量的定义 4. 目标%config的定义 4.1 依赖 scripts_basic 4.1.1 语句$(if $ ...

  2. 快速构建页面结构的 3D Visualization

    对 Chrome 扩展功能熟悉的小伙伴,可能都有用过 Chrome 的 3D 展示页面层级关系这个功能. 可以通过 控制台 --> 右边的三个小点 --> More Tools --> ...

  3. 使用repo上传代码

    前言~ repo是一款安卓用于管理源码的工具,由python实现,基于git工具 本文介绍了repo的常用使用方式. 一,下载代码 1. repo init 初始化命令 此命令常用选项就那几个,此处取 ...

  4. 树莓派编译opencv4

    前言 我用的是 树莓派3b 编译的 opencv4.1.0,如果不想编译可以直接下载我编译好的. 下载地址 直接 make install,或者按照我后续步骤复制动态链接库. 准备 需要调节虚拟内存大 ...

  5. HCIE Routing&Switching之MPLS LDP理论

    前文我们了解了MPLS的静态LSP配置相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/16937104.html:今天我们来聊一聊标签分发协议LDP相关 ...

  6. 第五章:matplotlib水印和桑基图

    1.Matplotlib水印 1 import matplotlib.pyplot as plt 2 import numpy as np 3 4 x = np.linspace(0.0,10,40) ...

  7. 4.4:Sqoop数据导入实验

    〇.概述 1.拓扑结构 2.目标 使用sqoop工具将数据从mysql数据库导入到HDFS和Hbase 一.配置免密登录hdfs 三.导入到hdfs中 sqoop import --connect j ...

  8. 【Day02】Spring Cloud组件的使用--Nacos配置中心、sentinel流量控制、服务网关Gateway、RocketMQ、服务调用链路(Sleuth、zipkin)

    今日内容 一.配置中心 1.遗留问题 yml配置,每一次都需要重启项目 需要不重启项目拿到更新的结果 引出:配置中心 选择:Spring Cloud Config组件 / Alibaba的Nacos( ...

  9. 【每日一题】【回溯】2021年12月29日-93. 复原 IP 地址

    有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔. 例如:"0.1.2.201" 和 "192.1 ...

  10. flutter系列之:flutter中的变形金刚Transform

    目录 简介 Transform简介 Transform的使用 总结 简介 虽然我们在开发APP的过程中是以功能为主,但是有时候为了美观或者其他的特殊的需求,需要对组件进行一些变换.在Flutter中这 ...