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

ImGui::CalcTextSize is inconsistent with ImGui::TextWrapped at certain font sizes #3776

Closed
Web-eWorks opened this issue Feb 1, 2021 · 2 comments

Comments

@Web-eWorks
Copy link

Version/Branch of Dear ImGui:

Version: 1.80
Branch: master / tag v1.8.0

Back-end/Renderer/Compiler/OS

Back-ends: "plain" example_sdl_opengl3 (imgui_impl_sdl.cpp / imgui.impl_opengl3.cpp)
Compiler: GCC 10.2.0
Operating System: Solus Linux

My Issue/Question:

I've found a very subtle bug with ImGui::TextWrapped and ImGui::CalcTextSize producing slightly different results that causes the end character of a string to wrap - so far I've managed to reproduce it 100% with a single specific font at a specific size, but I have the feeling that this affects more than just my one font. I've boiled the test-case down from where we're seeing it in production on Pioneer Space Sim to a minimal test case that affects both ImGui v1.78 (what we use) and v1.80 (which we haven't upgraded to yet).

The testcase below uses full integer multiples for the font size and coordinates instead of fractional numbers and is a very minimal modification to the default ImGui demo application. It's worth noting that this happens with certain specific strings - "Harmless" in this case being the easiest to reproduce in production. A more involved case of the bug (that I haven't had time to port) that starts drawing the string on a fractional window coordinate causes the shown wrapping behavior over a much larger selection of strings.

This is rather a problem, because I depend upon ImGui::CalcTextSize (with the appropriate wrap width pushed) to return the proper length of the string for right-aligned "pseudo table" display, as shown in the second screenshot.

Mid-issue edit: This can also be reproduced with the default ProggyClean font at a font scale of 1.09, 1.34, etc.

Screenshots/Video

imgui_wrapping_bug-2021-02-01_02.57.07.mp4

image

Standalone, minimal, complete and verifiable example: (see #2261)
Excerpt from the complete patch + font zip:

    // a window without padding helps reproduce this immensely
    ImGui::BeginChild("TestFrame", ImVec2(0, 50));

    ImGui::Text("This is some test...");
    const char *str = "Harmless";
    float textWidth = ImGui::CalcTextSize(str).x;
    ImGui::SameLine(ImGui::GetColumnWidth() - textWidth, 0.0);
    // debug rectangle around the textbox to show that the wrapping is in error
    ImVec2 cursorPos = ImGui::GetCursorScreenPos();
    ImGui::GetWindowDrawList()->AddRect(cursorPos, { cursorPos.x + textWidth, cursorPos.y + ImGui::GetTextLineHeight() }, IM_COL32(255, 128, 128, 255));
    ImGui::TextWrapped("%s", str);

    ImGui::EndChild();

This zip contains the font in question and the full patch (it's short) to be applied to a fresh checkout of ImGui v1.78 / v1.80. The font should go in the examples/example_sdl_opengl3 folder alongside main.cpp.
font_and_patch.zip

ocornut added a commit that referenced this issue Feb 1, 2021
…ceil. (#3776)

his is in order for text wrapping to have enough space when provided width precisely calculated with CalcTextSize().x. Amend 7b0bf23.
Note that the rounding of either positions and widths are technically undesirable (e.g. #3437, #791) but variety of code is currently on it so we are first fixing current behavior before we'll eventually change it.
@ocornut
Copy link
Owner

ocornut commented Feb 1, 2021

Hello @Web-eWorks and thanks for the detailed report and repro.
I have pushed a fix in 4622fa4

Note that even though there is a definitive bug here, since you are manually right-aligning it is surprising you used TextWrapped and not TextUnformatted?

Also note that your SameLine() call may also be expressed as SetCursorPosX() call.

@ocornut ocornut closed this as completed Feb 1, 2021
@Web-eWorks
Copy link
Author

Thank you for the extremely timely fix!

Note that even though there is a definitive bug here, since you are manually right-aligning it is surprising you used TextWrapped and not TextUnformatted?

This functionality is used to draw right-aligned multi-line text as well as the single lines as shown above. It's being used from inside a custom Lua wrapper, and there isn't an easy way (that I've found) to get line fragment information out of ImGui's CalcTextSize to manually wrap lines, so instead of a fully right-aligned manually-wrapped text with TextUnformatted, I've used TextWrapped for speed and simplicity.

Also note that your SameLine() call may also be expressed as SetCursorPosX() call.

Thanks, I'll have to remember that! This example is copied almost verbatim from Lua code; we've not (yet) exposed and adopted some of the newer / lower-level calls like SetCursorPosX().

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

2 participants