mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-19 11:52:04 +08:00
feat(draw_sw): draw A8 static fonts directly in SW render
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user