Hi all, i search properties for manage showed multinumber counters without not cool moving.
For example num 123 121 111 . Align not help here .
My idea is mark textarea as number aligned and render calculate widths from font for 0-9 and use it to convert showing as monospaced .
Ofcourse font editor can change this , but better is switchable choice. Exist or is this doable in LVGL?
mmar22
March 20, 2025, 1:09pm
2
@kisvegabor exist some funct for this now ? lv_label_set_monospace
I can try own func, but how swith render system to use it? GPT recommend
void lv_label_set_fixed_width(lv_obj_t * label, const char * text, lv_font_t * font, uint16_t fixed_width) {
lv_obj_t * label_obj = lv_label_create(lv_scr_act(), NULL);
int16_t offset = 0;
const char * c = text;
while (*c != '\0') {
lv_coord_t char_width = lv_font_get_glyph_dsc(font, *c, NULL, NULL);
int16_t padding = (fixed_width - char_width) / 2;
lv_draw_text(font, offset + padding, 0, c, fixed_width);
offset += fixed_width;
c++;
}
lv_obj_set_size(label_obj, offset, lv_font_get_line_height(font));
}
is this ok ?
lv_draw_text
cannot be called like this. It needs to be called from a LV_EVENT_DRAW_MAIN
event and it has slightly different parameters.
What about setting a custom get_glyph_dsc
for a font which always uses a fixed dsc_out->adv_w
and sets dsc_out->box_x
to center the glyph?
Yes correct glyphs table is good solution, but what if in some text area i need switch mono and in other use proportional? But can you show how i can set your w and x for numbers 0-9 glyphs in some example?
Still for me is most effective have set property for label and all is doing automatic.
We can consider creating a style property for it, but with the fonts you an make it work in a simple way right now.
bool fix_w_get_glyph_dsc(const lv_font_t * f, lv_font_glyph_dsc_t * g, uint32_t letter, uint32_t letter_next)
{
/*Get the original glyph_dsc*/
bool ret = lv_font_get_glyph_dsc_fmt_txt(f, g, letter, letter_next);
if(ret == false) return ret;
g->adv_w = 20;
g->ofs_x = (g->adv_w - g->box_w) / 2;
return true;
}
[...]
static lv_font_t fix_w_font;
fix_w_font = lv_font_montserrat_20;
fix_w_font.get_glyph_dsc = fix_w_get_glyph_dsc;
lv_obj_t * label1 = lv_label_create(lv_screen_active());
lv_obj_set_style_text_font(label1, &lv_font_montserrat_20, 0);
lv_label_set_text(label1, "0123.Wabc");
lv_obj_t * label2 = lv_label_create(lv_screen_active());
lv_obj_set_style_text_font(label2, &fix_w_font, 0);
lv_label_set_text(label2, "0123.Wabc");
lv_obj_set_y(label2, 30);
Seems fine , but im not sure why get_glyph_dsc return bool hope ok. I test next week. THX
I try now but my 8.3 font have
{.bitmap_index = 11122, .adv_w = 1463, .box_w = 76, .box_h = 73, .ofs_x = 8, .ofs_y = 0},
{.bitmap_index = 12509, .adv_w = 603, .box_w = 21, .box_h = 73, .ofs_x = 7, .ofs_y = 0},
{.bitmap_index = 12893, .adv_w = 1272, .box_w = 66, .box_h = 74, .ofs_x = 7, .ofs_y = 0},
then im not sure how set adv.w in my . Too ofs_x isnt zero , then overide it isnt clean.
You shouldn’t edit the font itself, just change the callback as I’ve shown in the code above.
box_x
will be really overwritten to center to glyph to center of the new width.
Ofcourse i dont edit i only check how is values aplyied in cb.
lv_font_get_glyph_dsc_fmt_txt
preprocesses these a little. After that adv_w
is the number of pixels after the next glyph comes. (can be different than box_w
).
Ohh boy better is be concrete, my example is glyps 0 1 2 and i see adv_w 1463 for 0 . Then simply my AI say replace this with new width is nonsense.
It’s upscaled by 16. See here .
However as I mentioned it’s handled and dowscaled in lv_font_get_glyph_dsc_fmt_txt
.
kisvegabor:
g->adv_w = 1463/16;
then this is result for me.
I don’t get it. Just to make it clear: did my proposed solution work? If not, what was the problem?
Working ok . For my design with
g->adv_w = 90-8; // 90 is nominal width 8 is closer spacing for chars num
Then great! Do you think it’s a good enough solution?
Yes now enough and cost only 32 bytes in ram. Optimal is managed W for label. But now i live with it.