ImGui.NET icon indicating copy to clipboard operation
ImGui.NET copied to clipboard

Problem merging font awesome into default font

Open JeffM2501 opened this issue 2 years ago • 8 comments

Hello. I maintain an ImGui backend for the library Raylib (https://www.raylib.com/), for both C++ and C#.

One feature of the backend is that by default we add font awesome icons to the default font so that people can easily use them in ImGui.

I'm having a problem with the C# version of the code, no mater what I try I can't get the font to merge in anymore. This used to work a while ago, but there have been some library updates and refactors since I tested it last (changing over to events, etc..). I'm in the process of updating the C# backend to the current ImGui.net 1.90.1.1, so I know I'm on current code.

This is my font loading code for C# https://github.com/raylib-extras/rlImGui-cs/blob/23df04bc3ee07c2225594e2e378955fec57662c4/rlImGui/rlImGui.cs#L277

C#

unsafe
{
    ImFontConfig icons_config = new ImFontConfig();
    icons_config.MergeMode = 1;                      // merge the glyph ranges into the default font
    icons_config.PixelSnapH = 1;                     // don't try to render on partial pixels
    icons_config.FontDataOwnedByAtlas = 0;           // the font atlas does not own this font data

    icons_config.GlyphMaxAdvanceX = float.MaxValue;
    icons_config.RasterizerMultiply = 1.0f;
    icons_config.OversampleH = 2;
    icons_config.OversampleV = 1;

    ushort[] IconRanges = new ushort[3];
    IconRanges[0] = IconFonts.FontAwesome6.IconMin;
    IconRanges[1] = IconFonts.FontAwesome6.IconMax;
    IconRanges[2] = 0;

    fixed (ushort* range = &IconRanges[0])
    {
        // this unmanaged memory must remain allocated for the entire run of rlImgui
        IconFonts.FontAwesome6.IconFontRanges = Marshal.AllocHGlobal(6);
        Buffer.MemoryCopy(range, IconFonts.FontAwesome6.IconFontRanges.ToPointer(), 6, 6);
        icons_config.GlyphRanges = (ushort*)IconFonts.FontAwesome6.IconFontRanges.ToPointer();

        byte[] fontDataBuffer = Convert.FromBase64String(IconFonts.FontAwesome6.IconFontData);

        fixed (byte* buffer = fontDataBuffer)
        {
            var fontPtr = ImGui.GetIO().Fonts.AddFontFromMemoryTTF(new IntPtr(buffer), fontDataBuffer.Length, 11, &icons_config, IconFonts.FontAwesome6.IconFontRanges);
        }
    }
}

The font atlas that is generated does not have any of the merged characters in it. image

It never seems to load the font. It does not mater if I use the font from memory or a file on disk, so I don't think it's a data issue.

The code very similar to what I do in the C++ version of the backend, and that code does work. https://github.com/raylib-extras/rlImGui/blob/de2c361b5835e6c2075b4f314bc7d949869666f1/rlImGui.cpp#L252 C++

	ImFontConfig icons_config;
	icons_config.MergeMode = true;
	icons_config.PixelSnapH = true;
	icons_config.FontDataOwnedByAtlas = false;

	icons_config.GlyphRanges = icons_ranges;

    ImGuiIO& io = ImGui::GetIO();

	io.Fonts->AddFontFromMemoryCompressedTTF((void*)fa_solid_900_compressed_data, fa_solid_900_compressed_size, FONT_AWESOME_ICON_SIZE, &icons_config, icons_ranges);

With this code in C++, I do see the icon fonts as part of the font atlas. image

I'm sure there is something I'm missing or doing wrong, C# hasn't been my primary language for a while. Anyone have any idea what more I can do to try and track this down? Any help would be appreciated.

JeffM2501 avatar Jan 20 '24 22:01 JeffM2501

I got this working a while ago, and I believe you must call ImGuiNative.ImFontConfig_ImFontConfig to properly create an ImFontConfig:

ImFontConfig* icons_config = ImGuiNative.ImFontConfig_ImFontConfig();
icons_config->MergeMode = 1;
// etc...

Just cloned rlImGui-cs and tried it myself. The font seems to show up correctly now in the Metrics/Debugger window. Will make a PR.

NoahStolk avatar Feb 10 '24 20:02 NoahStolk

Imgui constructors should be optional, looks like a imgui bug and you should report it to imgui repo.

zaafar avatar Feb 11 '24 00:02 zaafar

Imgui constructors should be optional, looks like a imgui bug and you should report it to imgui repo.

The C++ version works just fine, so I don't think it's core ImGui issue. I think the main problem is that I was not allocating a native pointer, but a managed structure and it didn't marshal to the .net C# bindings correctly.

JeffM2501 avatar Feb 11 '24 00:02 JeffM2501

I see, all good then, I was just pointing to “Constructors/destructors” documentation mentioned in https://github.com/dearimgui/dear_bindings repo.

zaafar avatar Feb 11 '24 01:02 zaafar