Fonts special textarea with auto convert proportional to monospaced?

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?

@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. :slight_smile:
image

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.

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! :slight_smile: 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.