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

Fractional font width cannot be aligned with itself #791

Open
SlNPacifist opened this issue Aug 23, 2016 · 2 comments
Open

Fractional font width cannot be aligned with itself #791

SlNPacifist opened this issue Aug 23, 2016 · 2 comments

Comments

@SlNPacifist
Copy link

When working with monospace font it is common to align different parts using spaces. For example, when one wants to align text "abcd" and "efg", he would usually add a separate space before "efg" like this:

Text("abcd");
Text(" ");
SameLine(0, 0);
Text("efg");

Which will lead to the next output:

abcd
 efg

However, dear imgui rounds up calculated text width to the pixel border so after rendering space cursor will be at rounded position and "efg" will not be aligned with "bcd". This makes using monospace font pretty awkward.

Originally issue started at emoon/ProDBG#304.

@ocornut ocornut added the bug label Oct 7, 2016
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.
@SamNChiet
Copy link

I think I'm hitting this issue too. Calling GetCharacterAdvance slightly undershoots a monospace font's width, calling CalcTextSize slightly overshoots it.
When creating a custom text input widget, this makes cursor placement nearly impossible as it d r i f t s from its correct location the longer your text line gets. (even though it works on the default font).

The font I'm running into issues with specifically is Fantasque Sans Mono https://github.com/belluzj/fantasque-sans.
Maybe the font's messed up, switching to Fira Code works great.

But I just wanted to flag this in case it helps nailing down the issue in the future!

@v-ein
Copy link

v-ein commented Feb 6, 2023

I've bumped into a similar issue. If text is pretty long, CalcTextSize() may add an extra pixel to its width - for me, it was happening on texts 280+ pixels wide. Whenever ImFont::CalcTextSizeA() was computing width to be 280.0 pixels, ImGui::CalcTextSize() was returning x=281.0 instead.

PixelSnapH=true in the font config didn't help since characters were already 8.0 pixels wide.

The issue was caused by the following line within CalcTextSize:

    // FIXME: This has been here since Dec 2015 (7b0bf230) but down the line we want this out.
    // FIXME: Investigate using ceilf or e.g.
    // - https://git.musl-libc.org/cgit/musl/tree/src/math/ceilf.c
    // - https://embarkstudios.github.io/rust-gpu/api/src/libm/math/ceilf.rs.html
    text_size.x = IM_FLOOR(text_size.x + 0.99999f);

Apparently for text_size.x==280.0f, the addition of 0.99999f resulted in a number above 281.0f, which doesn't look like proper rounding :).

I've fixed it in my copy of ImGui by replacing that cumbersome rounding with a call to ceilf(); however, I'm extremely curious to know why wasn't ceil() or ceilf() used in the first place.

Neither is floor() used in this code - here's the definition of IM_FLOOR():

#define IM_FLOOR(_VAL)                  ((float)(int)(_VAL))                                    // ImFloor() is not inlined in MSVC debug builds

Does ImGui avoid those standard functions for performance reasons? This thread on StackOverflow hints that floor() implementation may be suboptimal:

https://stackoverflow.com/questions/824118/why-is-floor-so-slow

One of the answers there also gives a better implementation of ceil() based on conversion to int (I mean, better than adding 0.99999f):

int c(double x)
{
    return (int) x + (x > (int) x);
}

Is it time to finally fix this issue?

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

4 participants