Skip to content

nk_raylib_font_get_text_width() returns incorrect glyph size #88

@malazar

Description

@malazar

When called in the context of a nk_edit_string(), the returned size is incorrect, when using a font size different than raylib's default.

Image

As you can hopefully see in the picture, the text in the edit box is trimmed, and the cursor is not located in the correct place.
The issue arises because nk_edit_string and the related widgets calculated the text width per character and accumulate them to the get
the final text width.
Getting the width character by character with MeasureText() introduces two errors that accumulate:

  1. MeasureText returns an int, so the width of the glyph gets rounded.
  2. MeasureText (and MeasureTextEx) append "spacing" between characters, the spacing is proportional to the input string length - 1.
    So when checking a string with length = 1, we don't get any spacing.
    https://github.com/raysan5/raylib/blob/8115b7e92202b2c43dc9852b3ac678e45bf3649b/src/rtext.c#L1389

What I did to resolve this issue:

NK_API float
nk_raylib_font_get_text_width(nk_handle handle, float height, const char *text, int len)
{
    NK_UNUSED(handle);

    if(len > 0) {
        int spacing = 1; 
        float addSpacing = 0.0;
        int fontSize = (int)height;
        int defaultFontSize = 10;
        Font font;
        if (GetFontDefault().texture.id != 0){
            font = GetFontDefault();
            if (fontSize < defaultFontSize) fontSize = defaultFontSize; //This copies the behaviour of raylib's MeasureText
            spacing = (fontSize/defaultFontSize);//Spacing it at least 1 pixel, depending on this ratio
        } else return 0;

        //When nuklear checks the string characater by character we have to add the spacing                              
        if(len == 1){
            addSpacing = spacing;
        }
        const char *subtext = TextSubtext(text, 0, len);
        
        Vector2 textSize = MeasureTextEx(font, subtext, (float)fontSize, (float)spacing);
        return textSize.x + addSpacing;
    }
    
    return 0;
}

Of course there is the caveat that the final width that nuklear calculates will be off by spacing/(TextLength(text) -1). Or about 1 pixel.
A similar fix can be applied to nk_raylib_font_get_text_width_user_font(), but I haven't investigated it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions