feat(draw_sw): draw A8 static fonts directly in SW render

This commit is contained in:
Gabor Kiss-Vamosi
2025-05-07 11:47:10 +02:00
parent ccbbfcca2b
commit 102b63357f
5 changed files with 86 additions and 21 deletions
+2 -2
View File
@@ -42,8 +42,8 @@ struct _lv_draw_label_hint_t {
};
struct _lv_draw_glyph_dsc_t {
const void *
glyph_data; /**< Depends on `format` field, it could be image source or draw buf of bitmap or vector data. */
/** Depends on `format` field, it could be image source or draw buf of bitmap or vector data. */
const void * glyph_data;
lv_font_glyph_format_t format;
const lv_area_t * letter_coords;
const lv_area_t * bg_coords;
+31 -13
View File
@@ -151,20 +151,38 @@ static void LV_ATTRIBUTE_FAST_MEM draw_letter_cb(lv_draw_task_t * t, lv_draw_gly
case LV_FONT_GLYPH_FORMAT_A8:
case LV_FONT_GLYPH_FORMAT_IMAGE: {
if(glyph_draw_dsc->rotation % 3600 == 0 && glyph_draw_dsc->format != LV_FONT_GLYPH_FORMAT_IMAGE) {
glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf);
lv_area_t mask_area = *glyph_draw_dsc->letter_coords;
mask_area.x2 = mask_area.x1 + lv_draw_buf_width_to_stride(lv_area_get_width(&mask_area), LV_COLOR_FORMAT_A8) - 1;
lv_draw_sw_blend_dsc_t blend_dsc;
lv_memzero(&blend_dsc, sizeof(blend_dsc));
blend_dsc.color = glyph_draw_dsc->color;
blend_dsc.opa = glyph_draw_dsc->opa;
const lv_draw_buf_t * draw_buf = glyph_draw_dsc->glyph_data;
blend_dsc.mask_buf = draw_buf->data;
blend_dsc.mask_area = &mask_area;
blend_dsc.mask_stride = draw_buf->header.stride;
blend_dsc.blend_area = glyph_draw_dsc->letter_coords;
blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED;
lv_draw_sw_blend(t, &blend_dsc);
if(lv_font_has_static_bitmap(glyph_draw_dsc->g->resolved_font) &&
glyph_draw_dsc->g->format == LV_FONT_GLYPH_FORMAT_A8) {
glyph_draw_dsc->g->req_raw_bitmap = 1;
const void * bitmap = lv_font_get_glyph_static_bitmap(glyph_draw_dsc->g);
lv_draw_sw_blend_dsc_t blend_dsc;
lv_memzero(&blend_dsc, sizeof(blend_dsc));
blend_dsc.color = glyph_draw_dsc->color;
blend_dsc.opa = glyph_draw_dsc->opa;
blend_dsc.mask_buf = bitmap;
blend_dsc.mask_area = &mask_area;
blend_dsc.mask_stride = glyph_draw_dsc->g->stride;
blend_dsc.blend_area = glyph_draw_dsc->letter_coords;
blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED;
lv_draw_sw_blend(t, &blend_dsc);
}
else {
glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf);
mask_area.x2 = mask_area.x1 + lv_draw_buf_width_to_stride(lv_area_get_width(&mask_area), LV_COLOR_FORMAT_A8) - 1;
lv_draw_sw_blend_dsc_t blend_dsc;
lv_memzero(&blend_dsc, sizeof(blend_dsc));
blend_dsc.color = glyph_draw_dsc->color;
blend_dsc.opa = glyph_draw_dsc->opa;
const lv_draw_buf_t * draw_buf = glyph_draw_dsc->glyph_data;
blend_dsc.mask_buf = draw_buf->data;
blend_dsc.mask_area = &mask_area;
blend_dsc.mask_stride = draw_buf->header.stride;
blend_dsc.blend_area = glyph_draw_dsc->letter_coords;
blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED;
lv_draw_sw_blend(t, &blend_dsc);
}
}
else {
glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf);
+26 -1
View File
@@ -50,7 +50,31 @@ const void * lv_font_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t
{
const lv_font_t * font_p = g_dsc->resolved_font;
LV_ASSERT_NULL(font_p);
return font_p->get_glyph_bitmap(g_dsc, draw_buf);
const uint8_t save_req = g_dsc->req_raw_bitmap;
g_dsc->req_raw_bitmap = 0;
const void * bitmap = font_p->get_glyph_bitmap(g_dsc, draw_buf);
g_dsc->req_raw_bitmap = save_req;
return bitmap;
}
const void * lv_font_get_glyph_static_bitmap(lv_font_glyph_dsc_t * g_dsc)
{
const lv_font_t * font_p = g_dsc->resolved_font;
LV_ASSERT_NULL(font_p);
if(font_p->static_bitmap == 0) {
LV_LOG_WARN("Requesting static bitmap of a non-static bitmap of %p font", (void *)font_p);
return NULL;
}
const uint8_t save_req = g_dsc->req_raw_bitmap;
g_dsc->req_raw_bitmap = 1;
const void * bitmap = font_p->get_glyph_bitmap(g_dsc, NULL);
g_dsc->req_raw_bitmap = save_req;
return bitmap;
}
void lv_font_glyph_release_draw_data(lv_font_glyph_dsc_t * g_dsc)
@@ -122,6 +146,7 @@ bool lv_font_get_glyph_dsc(const lv_font_t * font_p, lv_font_glyph_dsc_t * dsc_o
dsc_out->format = LV_FONT_GLYPH_FORMAT_A1;
dsc_out->is_placeholder = true;
return false;
}
+24 -4
View File
@@ -63,6 +63,11 @@ typedef struct {
uint16_t stride;/**< Bytes in each line. If 0 than there is no padding at the end of the line. */
lv_font_glyph_format_t format; /**< Font format of the glyph see lv_font_glyph_format_t */
uint8_t is_placeholder: 1; /**< Glyph is missing. But placeholder will still be displayed*/
/** 0: Get bitmap should return an A8 or ARGB8888 image.
* 1: return the bitmap as it is (Maybe A1/2/4 or any proprietary formats). */
uint8_t req_raw_bitmap: 1;
int32_t outline_stroke_width; /**< used with freetype vector fonts - width of the letter outline */
union {
@@ -134,13 +139,28 @@ struct _lv_font_info_t {
/**
* Return with the bitmap of a font.
* @note You must call lv_font_get_glyph_dsc() to get `g_dsc` (lv_font_glyph_dsc_t) before you can call this function.
* @param g_dsc the glyph descriptor including which font to use, which supply the glyph_index and the format.
* @param draw_buf a draw buffer that can be used to store the bitmap of the glyph, it's OK not to use it.
* @return pointer to the glyph's data. It can be a draw buffer for bitmap fonts or an image source for imgfonts.
* It always converts the normal fonts to A8 format in a draw_buf with
* LV_DRAW_BUF_ALIGN and LV_DRAW_BUF_STRIDE_ALIGN
* @note You must call lv_font_get_glyph_dsc() to get `g_dsc` (lv_font_glyph_dsc_t)
* before you can call this function.
* @param g_dsc the glyph descriptor including which font to use, which supply the glyph_index
* and the format.
* @param draw_buf a draw buffer that can be used to store the bitmap of the glyph.
* @return pointer to the glyph's data.
* It can be a draw buffer for bitmap fonts or an image source for imgfonts.
*/
const void * lv_font_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf);
/**
* Return the bitmap as it is. It works only if the font stores the bitmap in
* a non-volitile memory.
* @param g_dsc the glyph descriptor including which font to use, which supply the glyph_index
* and the format.
* @return the bitmap as it is
*/
const void * lv_font_get_glyph_static_bitmap(lv_font_glyph_dsc_t * g_dsc);
/**
* Get the descriptor of a glyph
* @param font pointer to font
+3 -1
View File
@@ -90,7 +90,6 @@ const lv_font_class_t lv_builtin_font_class = {
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;
uint32_t gid = g_dsc->gid.index;
@@ -98,6 +97,9 @@ const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf
const lv_font_fmt_txt_glyph_dsc_t * gdsc = &fdsc->glyph_dsc[gid];
if(g_dsc->req_raw_bitmap) return &fdsc->glyph_bitmap[gdsc->bitmap_index];
uint8_t * bitmap_out = draw_buf->data;
int32_t gsize = (int32_t) gdsc->box_w * gdsc->box_h;
if(gsize == 0) return NULL;