IDI-Systems / UnrealImGui

Unreal plug-in that integrates Dear ImGui framework into Unreal Engine 4/5.
MIT License
121 stars 27 forks source link

How to use custom fonts once they are added? #24

Closed BanTheRewind closed 2 days ago

BanTheRewind commented 3 months ago

Following the README, I have created binary headers for two fonts (Helvetica and Helvetica Bold). I have added the fonts successfully, but I don't see how to access the ImFont* for use with ImGui::PushFont(). Outside of Unreal, I use the IO->Fonts directly and get an ImFont* to reference when I add a font. Inside this plug-in, it looks like nothing captures/references the ImFont* when it is added (ImGuiContextManager.cpp:282). Help?

#pragma once

#ifdef IMGUI_API
#define WITH_IMGUI 1
#else
#define WITH_IMGUI 0
#endif

#if WITH_IMGUI
#include <imgui.h>
#endif
#include "ImGuiModule.h"
#include "Helvetica.h"
#include "HelveticaBold.h"
#include "IconsFontAwesome6.h"

#include <map>

enum class FontType : uint8_t
{
    Default,
    LargeTitle,
    Title,
    Small
};

typedef std::map<FontType, float> FontSizeMap;
typedef std::map<FontType, ImFont*> FontTypeMap;

class MyClass {
public:
    FontTypeMap mFontTypeMap {};

    // Called from actor+
    inline void loadFonts()
    {
        static const ImWchar IconRange[] { ICON_MIN_FA, ICON_MAX_FA, 0 };

        FontSizeMap fontSizeMap {
            { FontType::Default, 14.0f },
            { FontType::LargeTitle, 32.0f },
            { FontType::Title, 16.0f },
            { FontType::Small, 9.0f }
        };

        for ( const auto& iter : fontSizeMap ) {

            const FontType t { iter.first };
            const float sz { iter.second };
            const bool bold { t == FontType::LargeTitle };

            if ( TSharedPtr<ImFontConfig> fontConfig { MakeShareable( new ImFontConfig {} ) } ) {

                fontConfig->FontDataOwnedByAtlas = false;
                fontConfig->FontData = bold ? (void*)HelveticaBold_data : (void*)Helvetica_data;
                fontConfig->FontDataSize = bold ? HelveticaBold_size : Helvetica_size;
                fontConfig->SizePixels = sz;
                fontConfig->MergeMode = true;
                fontConfig->GlyphRanges = IconRange;
                fontConfig->GlyphMinAdvanceX = 16.0f;
                fontConfig->PixelSnapH = false;
                fontConfig->GlyphOffset = { 0, 3 };

                std::string fontName { bold ? "HelveticaBold" : "Helvetica" };
                fontName += std::to_string( (int32_t)sz );

                FImGuiModule::Get().GetProperties().AddCustomFont( UTF8_TO_TCHAR( fontName.c_str() ), fontConfig );
                FImGuiModule::Get().RebuildFontAtlas();

                ImFont* font = nullptr; /* How do I access this font for use with ImGui::PushFont() ? */
                mFontTypeMap[ t ] = font;
            }
        }

        // Fonts were added successfully
        if ( GEngine ) {
            for ( const auto& iter : FImGuiModule::Get().GetProperties().GetCustomFonts() ) {=
                //iter.Value is ImFontConfig -- how do I get the actual font?
                GEngine->AddOnScreenDebugMessage( -1, 15.0f, FColor::Yellow, TCHAR_TO_UTF8( *iter.Key.ToString() ) );
            }
        }
    }
};
BanTheRewind commented 2 months ago

I figured it out. I changed this: https://github.com/IDI-Systems/UnrealImGui/blob/master/Source/ImGui/Private/ImGuiContextManager.cpp#L282

FontAtlas.AddFont(CustomFontConfig.Get());

To this:

ImFont* font { FontAtlas.AddFont( CustomFontConfig.Get() ) };
font->ContainerAtlas = &FontAtlas;

You need to tell the font which container atlas it is using if you aren't managing fonts through IO.

jonpas commented 2 months ago

Oh sorry, I remember reading this and then totally forgot about it!

Would you consider opening a pull request with that change?

BanTheRewind commented 2 months ago

I'll try. Against a deadline atm. The issue there is that I did a lot of other project-specific customization to this plug-in that you wouldn't want in a PR.

jonpas commented 2 days ago

This is now available in 834d545.