UVGUI抗锯齿字模符号显示原理
UVGUI抗锯齿字模符号显示原理
@firestaradmin 2020年12月7日14:24:50
一、浅析LVGL Label显示原理
绘制 label 过程:
lv_draw_label
-》 lv_draw_letter
-》draw_letter_normal
lv_draw_label
函数原型如下:
/**
* Write a text
* @param coords coordinates of the label
* @param mask the label will be drawn only in this area
* @param dsc pointer to draw descriptor
* @param txt `\0` terminated text to write
* @param hint pointer to a `lv_draw_label_hint_t` variable.
* It is managed by the drawer to speed up the drawing of very long texts (thousands of lines).
*/
LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, lv_draw_label_dsc_t * dsc, const char * txt, lv_draw_label_hint_t * hint)
{
...
}
- coords:label 的坐标区域位置
- mask:label 的遮罩, 表示要在哪个区域显示
- dsc:绘制主题相关
- txt:要显示的文字字符串指针
- hint:方便计算第一个字符位置的结构体信息
此函数主要收集并判断字符串显示的行数、位置等信息,再去循环调用lv_draw_letter
来显示每一个字符。
lv_draw_letter
/**
* Draw a letter in the Virtual Display Buffer
* @param pos_p left-top coordinate of the latter
* @param clip_area the letter will be drawn only on this area (truncated to VDB area)
* @param font_p pointer to font
* @param letter a letter to draw
* @param color color of letter
* @param opa opacity of letter (0..255)
*/
LV_ATTRIBUTE_FAST_MEM static void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * clip_area, const lv_font_t * font_p, uint32_t letter, lv_color_t color, lv_opa_t opa, lv_blend_mode_t blend_mode)
- pos_p:字符左上角坐标
- clip_area:在此区域的字符部分才会被显示
- font_p:字体结构体指针
- letter:要绘制的字符
- color:字符颜色
- opa:字符不透明度(或者是灰度?)
- blend_mode:混合模式
此函数主要获取字符的描述信息结构体(字体样式,字模的宽、高),并获取字符的字型数据,再调用draw_letter_normal
来显示字符。
draw_letter_normal
LV_ATTRIBUTE_FAST_MEM static void draw_letter_normal(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_dsc_t * g, const lv_area_t * clip_area, const uint8_t * map_p, lv_color_t color, lv_opa_t opa, lv_blend_mode_t blend_mode)
- pos_x:字符左上角坐标 x 值
- pos_y:字符左上角坐标 y 值
- g:字符描述信息结构体指针
- clip_area:只在此区域显示字符
- map_p:字模数据指针
- color:颜色
- …
此函数是核心函数,根据字符信息,判断抗锯齿,并且将字模数据按照对应的抗锯齿解析,并绘制到显存中。
二、LVGL 字体 数据结构
LVGL 的字体统一通过以下数据结构管理:
lv_font_glyph_dsc_t
字形描述结构体:
/** Describes the properties of a glyph. */
typedef struct {
uint16_t adv_w; /**< The glyph needs this space. Draw the next glyph after this width. 8 bit integer, 4 bit fractional */
uint16_t box_w; /**< Width of the glyph's bounding box*/
uint16_t box_h; /**< Height of the glyph's bounding box*/
int16_t ofs_x; /**< x offset of the bounding box*/
int16_t ofs_y; /**< y offset of the bounding box*/
uint8_t bpp; /**< Bit-per-pixel: 1, 2, 4, 8*/
} lv_font_glyph_dsc_t;
- adv_w : 字形的绝对宽度,下一个字形在这么多间距后绘制。
- box_w:字模边框宽度
- box_h:字模边框高度
- ofs_x:边框x 坐标偏移
- ofs_y:边框y 坐标偏移
- bpp:抗锯齿
lv_font_t
字体结构体
/** Describe the properties of a font*/
typedef struct _lv_font_struct {
/** Get a glyph's descriptor from a font*/
bool (*get_glyph_dsc)(const struct _lv_font_struct *, lv_font_glyph_dsc_t *, uint32_t letter, uint32_t letter_next);
/** Get a glyph's bitmap from a font*/
const uint8_t * (*get_glyph_bitmap)(const struct _lv_font_struct *, uint32_t);
/*Pointer to the font in a font pack (must have the same line height)*/
lv_coord_t line_height; /**< The real line height where any text fits*/
lv_coord_t base_line; /**< Base line measured from the top of the line_height*/
uint8_t subpx : 2; /**< An element of `lv_font_subpx_t`*/
void * dsc; /**< Store implementation specific or run_time data or caching here*/
#if LV_USE_USER_DATA
lv_font_user_data_t user_data; /**< Custom user data for font. */
#endif
} lv_font_t;
- get_glyph_dsc:获取字形描述信息的函数指针
- get_glyph_bitmap:获取字形数据的函数指针
- line_height:真实的行高度
- base_line:基线 从行高度的上方开始测量
- dsc:储存细节实现或者运行数据或者缓存
- user_data:自定义数据
take a chestnut☺:
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!