UnrealImGui icon indicating copy to clipboard operation
UnrealImGui copied to clipboard

How to use custom fonts once they are added?

Open BanTheRewind opened this issue 11 months ago • 3 comments

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 avatar Mar 23 '24 20:03 BanTheRewind

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.

BanTheRewind avatar Apr 09 '24 16:04 BanTheRewind

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

Would you consider opening a pull request with that change?

jonpas avatar Apr 09 '24 16:04 jonpas

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.

BanTheRewind avatar Apr 09 '24 17:04 BanTheRewind

This is now available in 834d545.

jonpas avatar Jul 03 '24 14:07 jonpas