Walnut icon indicating copy to clipboard operation
Walnut copied to clipboard

Adding New and Additional Fonts

Open LilElvis opened this issue 3 years ago • 2 comments

Hi there, I'm currenly working on an application in Walnut, and I wanted to make use of an icon font to include basic icons on my ImGui buttons and windows, this seems to be a fairly common practice and is even suggested in the ImGui documentation. Following the same documentation, I made several attempts to create, push, and pop a new font within the scope of my Walnut::Layer child class. With no success, I went looking for some insight, and a very helpful person pointed out that the fonts needed to be created after the ImGui context is created, but before it's initialized and the fonts are shipped off to Vulkan. They then pointed out to me where that's done internally in Application.cpp, and I managed to make just a few minor adjustments and am now able to use the icons from the font that I'd like, though from a user standpoint it would be nice if there was an easier way to include additional fonts in Walnut out of the box.

Following is a screenshot of the aforementioned Application.cpp including the changes I made to load the additional font characters. Aside from an additional #include, my changes begin around line 480: image

Obviously this solution isn't scalable, but I thought I'd include it for future reference for anyone else who's trying to achieve the same effect in the meantime.

Otherwise, as someone with only experience making games in C++, Walnut feels like a great starting point for making apps so far, it's incredible how quickly you can rapid prototype UI, and link any sort of functionality you want to it without having to write any boiler plate rendering code. Thanks so much for making this, and I'd love to see it grow.

LilElvis avatar May 12 '22 02:05 LilElvis

I have made similar changes to use additional fonts. Would definitely be nice to have a hook so editing Application.cpp can be avoided.

Mikewando avatar May 18 '22 21:05 Mikewando

I think I have found a solution that doesn't require editing Application.cpp using Walnut::Application::GetCommandBuffer(true) and Walnut::Application::FlushCommandBuffer()

In my situation I have created a function 'AddIcons' in a namespace Utils to add Icons gliphs using fontawesome like explained in https://github.com/ocornut/imgui/blob/master/docs/FONTS.md#font-loading-instructions.

// Utils.h
#include "backends/imgui_impl_vulkan.h"
#include "IconsFontAwesome6.h"
#include "Walnut/Application.h"

namespace Utils {
    static void AddIcons(char* path) {
		ImGuiIO& io = ImGui::GetIO();

		ImFontConfig config;
		config.MergeMode = true;
		config.GlyphMinAdvanceX = 13.0f; // Use if you want to make the icon monospaced
		static const ImWchar icon_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
		io.Fonts->AddFontFromFileTTF(path, 13.0f, &config, icon_ranges);

		// Upload Fonts
		{
			
			VkCommandBuffer command_buffer = Walnut::Application::GetCommandBuffer(true);
			VkDevice g_Device = Walnut::Application::GetDevice();
			ImGui_ImplVulkan_CreateFontsTexture(command_buffer);
			Walnut::Application::FlushCommandBuffer(command_buffer);
			auto err = vkDeviceWaitIdle(g_Device);
			check_vk_result(err);
			ImGui_ImplVulkan_DestroyFontUploadObjects();
		}
	}
}

I am not sure where it is the best place to call it but what I did was call AddIcons on an override implementation of OnAttach()

// MyLayer.cpp
#include <filesystem>
#include "Utils.h"

void MyLayer::OnAttach()
{
	std::filesystem::path p = "src\\fa-regular-400.ttf";
	std::filesystem::path absolute_path = std::filesystem::absolute(p);
	Utils::AddIcons(absolute_path.string().data());
}

LorenzoMauro avatar Jan 01 '23 08:01 LorenzoMauro