diff --git a/src/draw/lv_draw_label.c b/src/draw/lv_draw_label.c index d072b449d..2bfca9cf5 100644 --- a/src/draw/lv_draw_label.c +++ b/src/draw/lv_draw_label.c @@ -541,8 +541,7 @@ static void draw_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * dsc, } } - dsc->glyph_data = (void *) lv_font_get_glyph_bitmap(&g, draw_buf); - dsc->format = dsc->glyph_data ? g.format : LV_FONT_GLYPH_FORMAT_NONE; + dsc->format = g.format; } else { dsc->format = LV_FONT_GLYPH_FORMAT_NONE; diff --git a/src/draw/lv_draw_label_private.h b/src/draw/lv_draw_label_private.h index 4d225d5e3..d0a8af497 100644 --- a/src/draw/lv_draw_label_private.h +++ b/src/draw/lv_draw_label_private.h @@ -42,11 +42,12 @@ struct _lv_draw_label_hint_t { }; struct _lv_draw_glyph_dsc_t { - void * glyph_data; /**< Depends on `format` field, it could be image source or draw buf of bitmap or vector data. */ + const void * + glyph_data; /**< Depends on `format` field, it could be image source or draw buf of bitmap or vector data. */ lv_font_glyph_format_t format; const lv_area_t * letter_coords; const lv_area_t * bg_coords; - const lv_font_glyph_dsc_t * g; + lv_font_glyph_dsc_t * g; lv_color_t color; lv_opa_t opa; lv_draw_buf_t * _draw_buf; /**< a shared draw buf for get_bitmap, do not use it directly, use glyph_data instead */ diff --git a/src/draw/nema_gfx/lv_draw_nema_gfx_label.c b/src/draw/nema_gfx/lv_draw_nema_gfx_label.c index 45d093cf9..dc7e05596 100644 --- a/src/draw/nema_gfx/lv_draw_nema_gfx_label.c +++ b/src/draw/nema_gfx/lv_draw_nema_gfx_label.c @@ -137,7 +137,7 @@ static void _draw_nema_gfx_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_ #endif } else if(glyph_draw_dsc->format >= LV_FONT_GLYPH_FORMAT_A1 && - glyph_draw_dsc->format <= LV_FONT_GLYPH_FORMAT_A8) { + glyph_draw_dsc->format <= LV_FONT_GLYPH_FORMAT_A8_ALIGNED) { /*Do not draw transparent things*/ if(glyph_draw_dsc->opa <= LV_OPA_MIN) return; @@ -153,6 +153,7 @@ static void _draw_nema_gfx_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_ const void * mask_buf = draw_buf->data; + glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); int32_t x = glyph_draw_dsc->letter_coords->x1 - layer->buf_area.x1; int32_t y = glyph_draw_dsc->letter_coords->y1 - layer->buf_area.y1; int32_t w = glyph_draw_dsc->g->box_w; diff --git a/src/draw/nxp/vglite/lv_draw_vglite_label.c b/src/draw/nxp/vglite/lv_draw_vglite_label.c index 9af7c6837..45c54ae6a 100644 --- a/src/draw/nxp/vglite/lv_draw_vglite_label.c +++ b/src/draw/nxp/vglite/lv_draw_vglite_label.c @@ -80,6 +80,7 @@ static void _draw_vglite_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area) { if(glyph_draw_dsc) { + switch(glyph_draw_dsc->format) { case LV_FONT_GLYPH_FORMAT_NONE: { @@ -94,60 +95,62 @@ static void _draw_vglite_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t #endif } break; - case LV_FONT_GLYPH_FORMAT_A1 ... LV_FONT_GLYPH_FORMAT_A8: { - /*Do not draw transparent things*/ - if(glyph_draw_dsc->opa <= LV_OPA_MIN) - return; + case LV_FONT_GLYPH_FORMAT_A1 ... LV_FONT_GLYPH_FORMAT_A8_ALIGNED: + /*Do not draw transparent things*/ + if(glyph_draw_dsc->opa <= LV_OPA_MIN) + return; - lv_layer_t * layer = draw_unit->target_layer; + lv_layer_t * layer = draw_unit->target_layer; - lv_area_t blend_area; - if(!lv_area_intersect(&blend_area, glyph_draw_dsc->letter_coords, draw_unit->clip_area)) - return; - lv_area_move(&blend_area, -layer->buf_area.x1, -layer->buf_area.y1); + lv_area_t blend_area; + if(!lv_area_intersect(&blend_area, glyph_draw_dsc->letter_coords, draw_unit->clip_area)) + return; + lv_area_move(&blend_area, -layer->buf_area.x1, -layer->buf_area.y1); - const lv_draw_buf_t * draw_buf = glyph_draw_dsc->glyph_data; - const void * mask_buf = draw_buf->data; + const lv_draw_buf_t * draw_buf = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); + const void * mask_buf = draw_buf->data; - uint32_t mask_width = lv_area_get_width(glyph_draw_dsc->letter_coords); - uint32_t mask_height = lv_area_get_height(glyph_draw_dsc->letter_coords); - uint32_t mask_stride = draw_buf->header.stride; + uint32_t mask_width = lv_area_get_width(glyph_draw_dsc->letter_coords); + uint32_t mask_height = lv_area_get_height(glyph_draw_dsc->letter_coords); + uint32_t mask_stride = draw_buf->header.stride; - lv_area_t mask_area; - mask_area.x1 = blend_area.x1 - (glyph_draw_dsc->letter_coords->x1 - layer->buf_area.x1); - mask_area.y1 = blend_area.y1 - (glyph_draw_dsc->letter_coords->y1 - layer->buf_area.y1); - mask_area.x2 = mask_width - 1; - mask_area.y2 = mask_height - 1; + lv_area_t mask_area; + mask_area.x1 = blend_area.x1 - (glyph_draw_dsc->letter_coords->x1 - layer->buf_area.x1); + mask_area.y1 = blend_area.y1 - (glyph_draw_dsc->letter_coords->y1 - layer->buf_area.y1); + mask_area.x2 = mask_width - 1; + mask_area.y2 = mask_height - 1; - /* Set src_vgbuf structure. */ - vglite_set_src_buf(mask_buf, mask_width, mask_height, mask_stride, LV_COLOR_FORMAT_A8); + /* Set src_vgbuf structure. */ + vglite_set_src_buf(mask_buf, mask_width, mask_height, mask_stride, LV_COLOR_FORMAT_A8); - /* Set vgmatrix. */ - vglite_set_translation_matrix(&blend_area); + /* Set vgmatrix. */ + vglite_set_translation_matrix(&blend_area); - lv_draw_buf_invalidate_cache(draw_buf, &mask_area); + lv_draw_buf_invalidate_cache(draw_buf, &mask_area); - _vglite_draw_letter(&mask_area, glyph_draw_dsc->color, glyph_draw_dsc->opa); - } - break; - case LV_FONT_GLYPH_FORMAT_IMAGE: { -#if LV_USE_IMGFONT - lv_draw_image_dsc_t img_dsc; - lv_draw_image_dsc_init(&img_dsc); - img_dsc.opa = glyph_draw_dsc->opa; - img_dsc.src = glyph_draw_dsc->glyph_data; - lv_draw_vglite_img(draw_unit, &img_dsc, glyph_draw_dsc->letter_coords); -#endif - } - break; - default: - break; + _vglite_draw_letter(&mask_area, glyph_draw_dsc->color, glyph_draw_dsc->opa); } + break; + case LV_FONT_GLYPH_FORMAT_IMAGE: { +#if LV_USE_IMGFONT + glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); + lv_draw_image_dsc_t img_dsc; + lv_draw_image_dsc_init(&img_dsc); + img_dsc.opa = glyph_draw_dsc->opa; + img_dsc.src = glyph_draw_dsc->glyph_data; + lv_draw_vglite_img(draw_unit, &img_dsc, glyph_draw_dsc->letter_coords); +#endif + } + break; + default: + break; } +} - if(fill_draw_dsc && fill_area) { - lv_draw_vglite_fill(draw_unit, fill_draw_dsc, fill_area); - } +if(fill_draw_dsc && fill_area) +{ + lv_draw_vglite_fill(draw_unit, fill_draw_dsc, fill_area); +} } static void _vglite_draw_letter(const lv_area_t * mask_area, lv_color_t color, lv_opa_t opa) diff --git a/src/draw/renesas/dave2d/lv_draw_dave2d_label.c b/src/draw/renesas/dave2d/lv_draw_dave2d_label.c index abc417375..33feb416c 100644 --- a/src/draw/renesas/dave2d/lv_draw_dave2d_label.c +++ b/src/draw/renesas/dave2d/lv_draw_dave2d_label.c @@ -78,7 +78,8 @@ static void lv_draw_dave2d_draw_letter_cb(lv_draw_unit_t * u, lv_draw_glyph_dsc_ #endif } break; - case LV_FONT_GLYPH_FORMAT_A1 ... LV_FONT_GLYPH_FORMAT_A8: { + case LV_FONT_GLYPH_FORMAT_A1 ... LV_FONT_GLYPH_FORMAT_A8_ALIGNED: { + glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); lv_area_t mask_area = 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; @@ -125,6 +126,7 @@ static void lv_draw_dave2d_draw_letter_cb(lv_draw_unit_t * u, lv_draw_glyph_dsc_ break; case LV_FONT_GLYPH_FORMAT_IMAGE: { #if LV_USE_IMGFONT + glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); lv_draw_image_dsc_t img_dsc; lv_draw_image_dsc_init(&img_dsc); img_dsc.rotation = 0; diff --git a/src/draw/sw/lv_draw_sw_letter.c b/src/draw/sw/lv_draw_sw_letter.c index c88a9d64e..78fe61e38 100644 --- a/src/draw/sw/lv_draw_sw_letter.c +++ b/src/draw/sw/lv_draw_sw_letter.c @@ -84,14 +84,19 @@ static void LV_ATTRIBUTE_FAST_MEM draw_letter_cb(lv_draw_unit_t * draw_unit, lv_ case LV_FONT_GLYPH_FORMAT_A1: case LV_FONT_GLYPH_FORMAT_A2: case LV_FONT_GLYPH_FORMAT_A4: - case LV_FONT_GLYPH_FORMAT_A8: { + case LV_FONT_GLYPH_FORMAT_A8: + case LV_FONT_GLYPH_FORMAT_A1_ALIGNED: + case LV_FONT_GLYPH_FORMAT_A2_ALIGNED: + case LV_FONT_GLYPH_FORMAT_A4_ALIGNED: + case LV_FONT_GLYPH_FORMAT_A8_ALIGNED: { + 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; - lv_draw_buf_t * draw_buf = glyph_draw_dsc->glyph_data; + 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; @@ -102,6 +107,7 @@ static void LV_ATTRIBUTE_FAST_MEM draw_letter_cb(lv_draw_unit_t * draw_unit, lv_ } break; case 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_draw_image_dsc_t img_dsc; lv_draw_image_dsc_init(&img_dsc); img_dsc.rotation = 0; diff --git a/src/draw/vg_lite/lv_draw_vg_lite_label.c b/src/draw/vg_lite/lv_draw_vg_lite_label.c index 2dc8b5418..009ca983b 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite_label.c +++ b/src/draw/vg_lite/lv_draw_vg_lite_label.c @@ -101,7 +101,12 @@ static void draw_letter_cb(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * gly case LV_FONT_GLYPH_FORMAT_A1: case LV_FONT_GLYPH_FORMAT_A2: case LV_FONT_GLYPH_FORMAT_A4: - case LV_FONT_GLYPH_FORMAT_A8: { + case LV_FONT_GLYPH_FORMAT_A8: + case LV_FONT_GLYPH_FORMAT_A1_ALIGNED: + case LV_FONT_GLYPH_FORMAT_A2_ALIGNED: + case LV_FONT_GLYPH_FORMAT_A4_ALIGNED: + case LV_FONT_GLYPH_FORMAT_A8_ALIGNED: { + glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); draw_letter_bitmap(u, glyph_draw_dsc); } break; @@ -109,6 +114,7 @@ static void draw_letter_cb(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * gly #if LV_USE_FREETYPE case LV_FONT_GLYPH_FORMAT_VECTOR: { if(lv_freetype_is_outline_font(glyph_draw_dsc->g->resolved_font)) { + glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); draw_letter_outline(u, glyph_draw_dsc); } } @@ -116,6 +122,7 @@ static void draw_letter_cb(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * gly #endif /* LV_USE_FREETYPE */ case 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_draw_image_dsc_t image_dsc; lv_draw_image_dsc_init(&image_dsc); image_dsc.opa = glyph_draw_dsc->opa; @@ -168,7 +175,7 @@ static void draw_letter_bitmap(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_d vg_lite_translate(image_area.x1, image_area.y1, &matrix); vg_lite_buffer_t src_buf; - lv_draw_buf_t * draw_buf = dsc->glyph_data; + const lv_draw_buf_t * draw_buf = dsc->glyph_data; lv_vg_lite_buffer_from_draw_buf(&src_buf, draw_buf); vg_lite_color_t color; diff --git a/src/font/lv_font.c b/src/font/lv_font.c index 35ae352e3..ee8bcce78 100644 --- a/src/font/lv_font.c +++ b/src/font/lv_font.c @@ -72,6 +72,7 @@ bool lv_font_get_glyph_dsc(const lv_font_t * font_p, lv_font_glyph_dsc_t * dsc_o const lv_font_t * f = font_p; dsc_out->resolved_font = NULL; + dsc_out->req_raw_bitmap = 0; while(f) { bool found = f->get_glyph_dsc(f, dsc_out, letter, f->kerning == LV_FONT_KERNING_NONE ? 0 : letter_next); diff --git a/src/font/lv_font.h b/src/font/lv_font.h index 7c869378d..d7eec0de9 100644 --- a/src/font/lv_font.h +++ b/src/font/lv_font.h @@ -36,17 +36,23 @@ extern "C" { typedef enum { LV_FONT_GLYPH_FORMAT_NONE = 0, /**< Maybe not visible*/ - /**< Legacy simple formats*/ + /**< Legacy simple formats with no byte padding at end of the lines*/ LV_FONT_GLYPH_FORMAT_A1 = 0x01, /**< 1 bit per pixel*/ LV_FONT_GLYPH_FORMAT_A2 = 0x02, /**< 2 bit per pixel*/ LV_FONT_GLYPH_FORMAT_A4 = 0x04, /**< 4 bit per pixel*/ LV_FONT_GLYPH_FORMAT_A8 = 0x08, /**< 8 bit per pixel*/ - LV_FONT_GLYPH_FORMAT_IMAGE = 0x09, /**< Image format*/ + /**< Legacy simple formats with byte padding at end of the lines*/ + LV_FONT_GLYPH_FORMAT_A1_ALIGNED = 0x011, /**< 1 bit per pixel*/ + LV_FONT_GLYPH_FORMAT_A2_ALIGNED = 0x012, /**< 2 bit per pixel*/ + LV_FONT_GLYPH_FORMAT_A4_ALIGNED = 0x014, /**< 4 bit per pixel*/ + LV_FONT_GLYPH_FORMAT_A8_ALIGNED = 0x018, /**< 8 bit per pixel*/ + + LV_FONT_GLYPH_FORMAT_IMAGE = 0x19, /**< Image format*/ /**< Advanced formats*/ - LV_FONT_GLYPH_FORMAT_VECTOR = 0x0A, /**< Vectorial format*/ - LV_FONT_GLYPH_FORMAT_SVG = 0x0B, /**< SVG format*/ + LV_FONT_GLYPH_FORMAT_VECTOR = 0x1A, /**< Vectorial format*/ + LV_FONT_GLYPH_FORMAT_SVG = 0x1B, /**< SVG format*/ LV_FONT_GLYPH_FORMAT_CUSTOM = 0xFF, /**< Custom format*/ } lv_font_glyph_format_t; @@ -62,6 +68,10 @@ typedef struct { 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; + union { uint32_t index; /**< Unicode code point*/ const void * src; /**< Pointer to the source data used by image fonts*/ diff --git a/src/font/lv_font_fmt_txt.c b/src/font/lv_font_fmt_txt.c index 12f5407ee..7d818d7a8 100644 --- a/src/font/lv_font_fmt_txt.c +++ b/src/font/lv_font_fmt_txt.c @@ -86,16 +86,19 @@ 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]; + int32_t gsize = (int32_t) gdsc->box_w * gdsc->box_h; if(gsize == 0) return NULL; - if(fdsc->bitmap_format == LV_FONT_FMT_TXT_PLAIN) { + bool byte_aligned = fdsc->bitmap_format == LV_FONT_FMT_PLAIN_ALIGNED; + + if(fdsc->bitmap_format == LV_FONT_FMT_TXT_PLAIN || fdsc->bitmap_format == LV_FONT_FMT_PLAIN_ALIGNED) { const uint8_t * bitmap_in = &fdsc->glyph_bitmap[gdsc->bitmap_index]; uint8_t * bitmap_out_tmp = bitmap_out; int32_t i = 0; int32_t x, y; uint32_t stride = lv_draw_buf_width_to_stride(gdsc->box_w, LV_COLOR_FORMAT_A8); - if(fdsc->bpp == 1) { for(y = 0; y < gdsc->box_h; y ++) { for(x = 0; x < gdsc->box_w; x++, i++) { @@ -112,6 +115,12 @@ const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf bitmap_in++; } } + /*Go to the next byte if stopped in the middle of a byte and + *the next line is byte aligned*/ + if(byte_aligned && i != 0) { + i = 0; + bitmap_in++; + } bitmap_out_tmp += stride; } } @@ -127,6 +136,14 @@ const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf bitmap_in++; } } + + /*Go to the next byte if stopped in the middle of a byte and + *the next line is byte aligned*/ + if(byte_aligned && i != 0) { + i = 0; + bitmap_in++; + } + bitmap_out_tmp += stride; } @@ -143,6 +160,14 @@ const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf bitmap_in++; } } + + /*Go to the next byte if stopped in the middle of a byte and + *the next line is byte aligned*/ + if(byte_aligned && i != 0) { + i = 0; + bitmap_in++; + } + bitmap_out_tmp += stride; } } @@ -211,6 +236,10 @@ bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out->ofs_x = gdsc->ofs_x; dsc_out->ofs_y = gdsc->ofs_y; dsc_out->format = (uint8_t)fdsc->bpp; + if(fdsc->bitmap_format == LV_FONT_FMT_PLAIN_ALIGNED) { + /*Offset in the enum to the ALIGNED values */ + dsc_out->format += LV_FONT_GLYPH_FORMAT_A1_ALIGNED - LV_FONT_GLYPH_FORMAT_A1; + } dsc_out->is_placeholder = false; dsc_out->gid.index = gid; diff --git a/src/font/lv_font_fmt_txt.h b/src/font/lv_font_fmt_txt.h index 4eeb0c6e1..f534b8abe 100644 --- a/src/font/lv_font_fmt_txt.h +++ b/src/font/lv_font_fmt_txt.h @@ -144,7 +144,8 @@ typedef struct { typedef enum { LV_FONT_FMT_TXT_PLAIN = 0, LV_FONT_FMT_TXT_COMPRESSED = 1, - LV_FONT_FMT_TXT_COMPRESSED_NO_PREFILTER = 1, + LV_FONT_FMT_TXT_COMPRESSED_NO_PREFILTER = 2, + LV_FONT_FMT_PLAIN_ALIGNED = 3, } lv_font_fmt_txt_bitmap_format_t; /** Describe store for additional data for fonts */