Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

u8g2_UserInterfaceSelectionList text centering is sometimes inconsistent #2588

Open
dkonigsberg opened this issue Feb 9, 2025 · 3 comments

Comments

@dkonigsberg
Copy link

The u8g2_UserInterfaceSelectionList() function creates a menu where each line on the display is supposed to be centered.

When using this function, I frequently want lines to instead appear "fully justified" by using a monospace font and having all of them be the exact same number of characters.

I recently discovered a bug where these lines can end up out of position by one pixel:

Image
(If you look closely at the "]" characters on the end of the first two option lines, it should be easy to see.)

I did some investigation, and I think I found the cause (and perhaps a simple fix).

The lines of text on the menu are drawn using the u8g2_DrawUTF8Line() function, which centers the text based on a simple calculation using u8g2_GetUTF8Width(). However, if the first character of the provided string has an X rendering offset, then the returned width will include this offset and do the centering calculation with it. Meanwhile, the rest of the drawing code likely isn't taking that offset into account.

Here's a useful code snippet to show this for reference:

size_t len1;
size_t len2;
u8g2_uint_t width1;
u8g2_uint_t width2;

u8g2_SetFont(&u8g2, u8g2_font_pxplusibmvga9_tf);

len1 = strlen(str1);
width1 = u8g2_GetUTF8Width(&u8g2, str1);

len2 = strlen(str2);
width2 = u8g2_GetUTF8Width(&u8g2, str2);

printf("len1 = %d, width1 = %d\n", len1, width1);
printf("len2 = %d, width2 = %d\n", len2, width2);

u8g2_ClearBuffer(&u8g2);
u8g2_DrawUTF8Line(&u8g2, 0, 10, 128, str1, 0, false);
u8g2_DrawUTF8Line(&u8g2, 0, 22, 128, str2, 0, false);
u8g2_SendBuffer(&u8g2);

You'll note that both strings are the same length (14 chars), return different widths (123 and 125 pixels), and the u8g2_DrawUTF8Line() function doesn't render them properly aligned with each other.

A simple fix for this problem is to make u8g2_DrawUTF8Line() subtract the X offset for a string before doing its centering calculation. This means to change the code at the top of this function (which is in u8g2_selection_list.c, around line 63) from:

  /* calculate the width of the string in pixel */
  str_width = u8g2_GetUTF8Width(u8g2, s);

to

  /* calculate the width of the string in pixel */
  str_width = u8g2_GetUTF8Width(u8g2, s) - u8g2_GetXOffsetUTF8(u8g2, s);

Its possible that there could be side-effects to this change, or that its relevance depends on whether U8G2_BALANCED_STR_WIDTH_CALCULATION is defined, so I'll let someone else take the lead in actually fixing it in the repo.

@olikraus
Copy link
Owner

olikraus commented Feb 9, 2025

Nice finding... However, I now added MUI (https://github.com/olikraus/u8g2/wiki/muimanual), which should replace the UserInterface functions...

@dkonigsberg
Copy link
Author

I do need to look into the MUI stuff for the future, but right now I have a lot of code built on top of the UserInterface functions (either directly, or by re-implementation of portions). So even though MUI exists, I still need UserInterface to work as expected.

dkonigsberg added a commit to dektronics/printalyzer-uvdensitometer that referenced this issue Feb 10, 2025
This bug is better described in the upstream issue:
olikraus/u8g2#2588

Basically there can be minor alignment errors in menu text because of
how the position is calculated. This was not seen before, because it
pretty much requires the first character of the text to be narrow and
the text to span the full width of the display.
@olikraus
Copy link
Owner

Maybe you can sent the PR also to this repo. I could then include your suggestion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants