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

Error in text width calculation? #792

Closed
SlNPacifist opened this issue Aug 23, 2016 · 3 comments
Closed

Error in text width calculation? #792

SlNPacifist opened this issue Aug 23, 2016 · 3 comments

Comments

@SlNPacifist
Copy link

SlNPacifist commented Aug 23, 2016

I assume that text rendered as a whole (i.e. by calling ImGui::TextUnformatted("text")) and symbol by symbol like this:

ImGui::TextUnformatted("t");
ImGui::SameLine(0, 0);
ImGui::TextUnformatted("e");
ImGui::SameLine(0, 0);
...

should give the same result. However, ImGui::CalcTextSize does some substraction that does not seem to be right.
This demonstration is copied from opengl_example. It contains two functions to output text: as a whole and symbol by symbol. They give different results. First string is rendered as a whole and second string is rencder symbol by symbol.
screenshot from 2016-08-23 17-55-22

However, if we change ImGui::CalcTextSize like this:

ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_text_after_double_hash, float wrap_width)
{
    ImGuiContext& g = *GImGui;

    const char* text_display_end;
    if (hide_text_after_double_hash)
        text_display_end = FindRenderedTextEnd(text, text_end);      // Hide anything after a '##' string
    else
        text_display_end = text_end;

    ImFont* font = g.Font;
    const float font_size = g.FontSize;
    if (text == text_display_end)
        return ImVec2(0.0f, font_size);
    ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL);

    // Cancel out character spacing for the last character of a line (it is baked into glyph->XAdvance field)
//    const float font_scale = font_size / font->FontSize;
//    const float character_spacing_x = 1.0f * font_scale;
//    if (text_size.x > 0.0f)
//        text_size.x -= character_spacing_x;
    text_size.x = (float)(int)(text_size.x + 0.95f);

    return text_size;
}

two functions render the same result:
screenshot from 2016-08-23 17-57-08

Tested on Ubuntu 16.04 64 bit.

@wizzard0
Copy link

I believe this is worth a flag in CalcTextSize, because both behaviors are correct, just doing different things (calculate size of a text fragment within a string vs. calculate size of a displayed text string)

@SlNPacifist
Copy link
Author

SlNPacifist commented Aug 23, 2016

If I understand you correctly fixed-width font is not rendered like

symbol, symbol, symbol

but contains spacing between them

symbol spacing symbol spacing symbol

In which case rendering string as a whole and symbol by symbol would cause different results. If this is true, how is developer supposed to pad strings when working with fixed-width font? Copying padding and rendered string into a buffer is not an option for me (would make rendering functions way too complicated).

@ocornut ocornut added the bug label Oct 7, 2016
ocornut added a commit that referenced this issue Feb 12, 2019
…m erroneously subtracting 1.0f*scale to calculated text width. Among noticeable side-effects, it would make sequences of repeated Text/SameLine calls not align the same as a single call, and create mismatch between high-level size calculation and those performed with the lower-level ImDrawList api. (#792)
@ocornut
Copy link
Owner

ocornut commented Feb 12, 2019

Hello,

You'll find it amusing but I have finally fixed this! Better late than never.
While looking at font scaling today I have noticed that although the comment made sense (and complicated things), the assumption it made about extra spacing being baked inside the AdvanceX value was actually wrong, at least it is now.

I'll removed the subtraction now.

Thanks and sorry for taking so long to tackle this!

Omar

@ocornut ocornut closed this as completed Feb 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants