mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-19 03:02:27 +08:00
fix(font): impore static bitmap handling with stride
This commit is contained in:
+11
-15
@@ -598,22 +598,18 @@ void lv_draw_unit_draw_letter(lv_draw_task_t * t, lv_draw_glyph_dsc_t * dsc, co
|
||||
|
||||
if(g.resolved_font) {
|
||||
lv_draw_buf_t * draw_buf = NULL;
|
||||
/*If LVGL uses static bitmaps, the buffer allocation and deallocation is not necessary*/
|
||||
const bool static_bitmap = lv_font_has_static_bitmap(g.resolved_font);
|
||||
if(!static_bitmap) {
|
||||
if(LV_FONT_GLYPH_FORMAT_NONE < g.format && g.format < LV_FONT_GLYPH_FORMAT_IMAGE) {
|
||||
/*Only check draw buf for bitmap glyph*/
|
||||
draw_buf = lv_draw_buf_reshape(dsc->_draw_buf, 0, g.box_w, g.box_h, LV_STRIDE_AUTO);
|
||||
if(draw_buf == NULL) {
|
||||
if(dsc->_draw_buf) lv_draw_buf_destroy(dsc->_draw_buf);
|
||||
if(LV_FONT_GLYPH_FORMAT_NONE < g.format && g.format < LV_FONT_GLYPH_FORMAT_IMAGE) {
|
||||
/*Only check draw buf for bitmap glyph*/
|
||||
draw_buf = lv_draw_buf_reshape(dsc->_draw_buf, 0, g.box_w, g.box_h, LV_STRIDE_AUTO);
|
||||
if(draw_buf == NULL) {
|
||||
if(dsc->_draw_buf) lv_draw_buf_destroy(dsc->_draw_buf);
|
||||
|
||||
uint32_t h = g.box_h;
|
||||
if(h * g.box_w < 64) h *= 2; /*Alloc a slightly larger buffer*/
|
||||
draw_buf = lv_draw_buf_create_ex(font_draw_buf_handlers, g.box_w, h, LV_COLOR_FORMAT_A8, LV_STRIDE_AUTO);
|
||||
LV_ASSERT_MALLOC(draw_buf);
|
||||
draw_buf->header.h = g.box_h;
|
||||
dsc->_draw_buf = draw_buf;
|
||||
}
|
||||
uint32_t h = g.box_h;
|
||||
if(h * g.box_w < 64) h *= 2; /*Alloc a slightly larger buffer*/
|
||||
draw_buf = lv_draw_buf_create_ex(font_draw_buf_handlers, g.box_w, h, LV_COLOR_FORMAT_A8, LV_STRIDE_AUTO);
|
||||
LV_ASSERT_MALLOC(draw_buf);
|
||||
draw_buf->header.h = g.box_h;
|
||||
dsc->_draw_buf = draw_buf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ static void _draw_vglite_letter(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case LV_FONT_GLYPH_FORMAT_A1 ... LV_FONT_GLYPH_FORMAT_A8_ALIGNED: {
|
||||
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;
|
||||
|
||||
@@ -77,7 +77,7 @@ static void lv_draw_dave2d_draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case LV_FONT_GLYPH_FORMAT_A1 ... LV_FONT_GLYPH_FORMAT_A8_ALIGNED: {
|
||||
case LV_FONT_GLYPH_FORMAT_A1 ... LV_FONT_GLYPH_FORMAT_A8: {
|
||||
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;
|
||||
|
||||
@@ -149,10 +149,6 @@ static void LV_ATTRIBUTE_FAST_MEM draw_letter_cb(lv_draw_task_t * t, lv_draw_gly
|
||||
case LV_FONT_GLYPH_FORMAT_A3:
|
||||
case LV_FONT_GLYPH_FORMAT_A4:
|
||||
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:
|
||||
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);
|
||||
|
||||
@@ -145,11 +145,7 @@ static void draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_
|
||||
case LV_FONT_GLYPH_FORMAT_A2:
|
||||
case LV_FONT_GLYPH_FORMAT_A3:
|
||||
case LV_FONT_GLYPH_FORMAT_A4:
|
||||
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: {
|
||||
case LV_FONT_GLYPH_FORMAT_A8: {
|
||||
glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf);
|
||||
if(!glyph_draw_dsc->glyph_data) {
|
||||
return;
|
||||
|
||||
+1
-1
@@ -114,7 +114,7 @@ bool lv_font_get_glyph_dsc(const lv_font_t * font_p, lv_font_glyph_dsc_t * dsc_o
|
||||
dsc_out->box_w = 0;
|
||||
dsc_out->adv_w = 0;
|
||||
#endif
|
||||
|
||||
dsc_out->stride = 0;
|
||||
dsc_out->resolved_font = NULL;
|
||||
dsc_out->box_h = font_p->line_height;
|
||||
dsc_out->ofs_x = 0;
|
||||
|
||||
+1
-11
@@ -43,12 +43,6 @@ typedef enum {
|
||||
LV_FONT_GLYPH_FORMAT_A4 = 0x04, /**< 4 bit per pixel*/
|
||||
LV_FONT_GLYPH_FORMAT_A8 = 0x08, /**< 8 bit per pixel*/
|
||||
|
||||
/**< 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*/
|
||||
@@ -66,15 +60,11 @@ typedef struct {
|
||||
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 stride;
|
||||
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*/
|
||||
int32_t outline_stroke_width; /**< used with freetype vector fonts - width of the letter outline */
|
||||
|
||||
/** 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*/
|
||||
|
||||
+34
-30
@@ -98,21 +98,20 @@ 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;
|
||||
|
||||
bool byte_aligned = fdsc->bitmap_format == LV_FONT_FMT_PLAIN_ALIGNED;
|
||||
uint16_t stride_in = g_dsc->stride;
|
||||
|
||||
if(fdsc->bitmap_format == LV_FONT_FMT_TXT_PLAIN || fdsc->bitmap_format == LV_FONT_FMT_PLAIN_ALIGNED) {
|
||||
if(fdsc->bitmap_format == LV_FONT_FMT_TXT_PLAIN) {
|
||||
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);
|
||||
uint32_t stride_out = 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 ++) {
|
||||
uint16_t line_rem = stride_in != 0 ? stride_in : gdsc->box_w;
|
||||
for(x = 0; x < gdsc->box_w; x++, i++) {
|
||||
i = i & 0x7;
|
||||
if(i == 0) bitmap_out_tmp[x] = (*bitmap_in) & 0x80 ? 0xff : 0x00;
|
||||
@@ -124,20 +123,21 @@ const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf
|
||||
else if(i == 6) bitmap_out_tmp[x] = (*bitmap_in) & 0x02 ? 0xff : 0x00;
|
||||
else if(i == 7) {
|
||||
bitmap_out_tmp[x] = (*bitmap_in) & 0x01 ? 0xff : 0x00;
|
||||
line_rem--;
|
||||
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++;
|
||||
/*Handle stride*/
|
||||
if(stride_in) {
|
||||
i = 0; /*If there is a stride start from the next byte in the next line*/
|
||||
bitmap_in += line_rem;
|
||||
}
|
||||
bitmap_out_tmp += stride;
|
||||
bitmap_out_tmp += stride_out;
|
||||
}
|
||||
}
|
||||
else if(fdsc->bpp == 2) {
|
||||
for(y = 0; y < gdsc->box_h; y ++) {
|
||||
uint16_t line_rem = stride_in != 0 ? stride_in : gdsc->box_w;
|
||||
for(x = 0; x < gdsc->box_w; x++, i++) {
|
||||
i = i & 0x3;
|
||||
if(i == 0) bitmap_out_tmp[x] = opa2_table[(*bitmap_in) >> 6];
|
||||
@@ -145,23 +145,23 @@ const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf
|
||||
else if(i == 2) bitmap_out_tmp[x] = opa2_table[((*bitmap_in) >> 2) & 0x3];
|
||||
else if(i == 3) {
|
||||
bitmap_out_tmp[x] = opa2_table[((*bitmap_in) >> 0) & 0x3];
|
||||
line_rem--;
|
||||
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++;
|
||||
/*Handle stride*/
|
||||
if(stride_in) {
|
||||
i = 0; /*If there is a stride start from the next byte in the next line*/
|
||||
bitmap_in += line_rem;
|
||||
}
|
||||
|
||||
bitmap_out_tmp += stride;
|
||||
bitmap_out_tmp += stride_out;
|
||||
}
|
||||
|
||||
}
|
||||
else if(fdsc->bpp == 4) {
|
||||
for(y = 0; y < gdsc->box_h; y ++) {
|
||||
uint16_t line_rem = stride_in != 0 ? stride_in : gdsc->box_w;
|
||||
for(x = 0; x < gdsc->box_w; x++, i++) {
|
||||
i = i & 0x1;
|
||||
if(i == 0) {
|
||||
@@ -169,27 +169,29 @@ const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf
|
||||
}
|
||||
else if(i == 1) {
|
||||
bitmap_out_tmp[x] = opa4_table[(*bitmap_in) & 0xF];
|
||||
line_rem--;
|
||||
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++;
|
||||
/*Handle stride*/
|
||||
if(stride_in) {
|
||||
i = 0; /*If there is a stride start from the next byte in the next line*/
|
||||
bitmap_in += line_rem;
|
||||
}
|
||||
|
||||
bitmap_out_tmp += stride;
|
||||
bitmap_out_tmp += stride_out;
|
||||
}
|
||||
}
|
||||
else if(fdsc->bpp == 8) {
|
||||
for(y = 0; y < gdsc->box_h; y ++) {
|
||||
uint16_t line_rem = stride_in != 0 ? stride_in : gdsc->box_w;
|
||||
for(x = 0; x < gdsc->box_w; x++, i++) {
|
||||
bitmap_out_tmp[x] = *bitmap_in;
|
||||
line_rem--;
|
||||
bitmap_in++;
|
||||
}
|
||||
bitmap_out_tmp += stride;
|
||||
bitmap_out_tmp += stride_out;
|
||||
bitmap_in += line_rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,11 +252,13 @@ bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t *
|
||||
dsc_out->box_w = gdsc->box_w;
|
||||
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;
|
||||
if(fdsc->stride == 0) dsc_out->stride = 0;
|
||||
else {
|
||||
/*font_dsc stride is is e.g. 4 to align to 4 byte boundary.
|
||||
*In glyph_dsc store the actual line length*/
|
||||
dsc_out->stride = LV_ROUND_UP(dsc_out->box_w, fdsc->stride);
|
||||
}
|
||||
dsc_out->format = (uint8_t)fdsc->bpp;
|
||||
dsc_out->is_placeholder = false;
|
||||
dsc_out->gid.index = gid;
|
||||
|
||||
|
||||
@@ -145,7 +145,6 @@ typedef enum {
|
||||
LV_FONT_FMT_TXT_PLAIN = 0,
|
||||
LV_FONT_FMT_TXT_COMPRESSED = 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 */
|
||||
@@ -185,6 +184,12 @@ typedef struct {
|
||||
*/
|
||||
uint16_t bitmap_format : 2;
|
||||
|
||||
/**
|
||||
* Bytes to which each line is padded.
|
||||
* 0: means no align and padding
|
||||
* 1: e.g. with bpp=4 lines are aligned to 1 byte, so there can be a 4 bits of padding
|
||||
* 4, 8, 16, 32, 64: each line is padded to the given byte boundaries
|
||||
*/
|
||||
uint8_t stride;
|
||||
} lv_font_fmt_txt_dsc_t;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user