Daandelange / ofxImGui

Please refer to the develop branch in https://github.com/jvcleave/ofxImGui. I'll keep this fork in sync until it's merged in master.
12 stars 1 forks source link

How to perform an AddFontFromMemoryTTF instead of addFont/AddFontFromFileTTF #13

Closed moebiussurfing closed 1 year ago

moebiussurfing commented 1 year ago

Hello @Daandelange ,

I am trying to integrate that repo: https://github.com/patrickcjk/imgui-notify

--

It's working well here on nightly builds, as uses C++17. But I am not being able to enable the font icons. (without crashing or breaking the atlas to white squares)

The repo adds the fonts as cpp .h files instead as in your implemented method to load ttf files:

customFont = gui.addFont("Roboto-Medium.ttf",16.f, nullptr, true?polishCharRanges:normalCharRanges);

ImFont* font = io.Fonts->AddFontFromFileTTF(filePath.c_str(), fontSize, _fontConfig, _glyphRanges);

--

Do you have any clue to make that work?

Here are some notes by the author:

Requirements You must use a font other than the default one. Font-Awesome icons used in this library cannot be merged with default font. You can use Tahoma (provided in the example project). If you load the font using AddFontFromMemoryTTF (from memory, instead of from a file on disk) and memory is read-only as in the example, you must pass a ImFontConfig structure with FontDataOwnedByAtlas = false to prevent imgui from attempting to free the buffer (which will lead into a crash).

And the code that must be initiated in some way: Initialisation (after impl call, e.g ImGui_ImplDX12_Init)

ImGuiIO* io = &ImGui::GetIO();

ImFontConfig font_cfg;
font_cfg.FontDataOwnedByAtlas = false;
io->Fonts->AddFontFromMemoryTTF((void*)tahoma, sizeof(tahoma), 17.f, &font_cfg);

// Initialize notify
ImGui::MergeIconsWithLatestFont(16.f, false);

// If you use multiple fonts, repeat the same thing!
// io->Fonts->AddFontFromMemoryTTF((void*)another_font, sizeof(another_font), 17.f, &font_cfg);
// ImGui::MergeIconsWithLatestFont(16.f, false);

--

I am trying to figure out something here, but no success: https://github.com/ocornut/imgui/blob/master/docs/FONTS.md https://github.com/Daandelange/ofxImGui/tree/master/example-fonts

Regards

Daandelange commented 1 year ago

Hey Manu, Oh nice, oF nightly builds now support C++17 :)

It looks like the .cpp file is a TTF file too, they're just using AddFontFromMemoryTTF (), probably to bundle the font within the app binary. https://github.com/patrickcjk/imgui-notify/blob/2e2eba3d1814ef886401120f7248b6db86714dbc/example/main.cpp#L68

ofxImGui uses AddFontFromFileTTF(). https://github.com/Daandelange/ofxImGui/blob/ab228a68d2989b7465b90c1e0d25c10c62ab8748/src/Gui.cpp#L272

So I think it would make sense to duplicate the addFont() function to provide an alternative from memory within ofxImGui. https://github.com/Daandelange/ofxImGui/blob/ab228a68d2989b7465b90c1e0d25c10c62ab8748/src/Gui.h#L40

On the other side, you might not need to modify ofxImGui, you could call the init() function within ofxImGui. Did you try to call imgui-notify::init() after ofxImGui::setup() ? Providing a custom ImFontConfig is already possible in ofxImGui too, so even the native functions should work if you get a tahoma.ttf file.

I got to load the tahoma font in both ways mentioned above using example-fonts. I was not able to call ImGui::MergeIconsWithLatestFont(16.f, false); as that requires the extension. I'm not able to compile the extension as it requires C++17 an I'm on osx atm.

ImFontConfig font_cfg;
font_cfg.FontDataOwnedByAtlas = false;
gui.addFontFromMemory((void*)tahoma, sizeof(tahoma), 17.f, &font_cfg);
// ImGui::MergeIconsWithLatestFont(16.f, false);
moebiussurfing commented 1 year ago

cool thanks, @Daandelange

It worked after adding the memory-based addFont method

I was getting crashes, black panels, and white squares on fonts.

I copy pasted it here just in case or do you prefer a pull maybe?

Gui.h

    public:
        ImFont* addFont(void* ttf_data, int ttf_size, float fontSize = 13.0f, const ImFontConfig* _fontConfig = nullptr, const ImWchar* _glyphRanges = nullptr, bool _setAsDefaultFont = false);

Gui.cpp

    //--------------------------------------------------------------
    ImFont* Gui::addFont(void* ttf_data, int ttf_size, float fontSize, const ImFontConfig* _fontConfig, const ImWchar* _glyphRanges, bool _setAsDefaultFont) {

        if (context == nullptr) {
            ofLogWarning() << "You must load fonts after gui.setup() ! (ignoring this call)";
            return nullptr;
        }

        //ImFontConfig structure allows you to configure oversampling.
        //By default OversampleH = 3 and OversampleV = 1 which will make your font texture data 3 times larger
        //than necessary, so you may reduce that to 1.

        ImGui::SetCurrentContext(context);
        ImGuiIO& io = ImGui::GetIO();
        //std::string filePath = ofFilePath::getAbsolutePath(fontPath);

        // ensure default font gets loaded once
        if (io.Fonts->Fonts.size() == 0) io.Fonts->AddFontDefault();

        ImFont* font = io.Fonts->AddFontFromMemoryTTF(ttf_data, ttf_size, fontSize, _fontConfig, _glyphRanges);

        if (io.Fonts->Fonts.size() > 0) {
            io.Fonts->Build();
            if (engine.updateFontsTexture()) {
                if (_setAsDefaultFont) setDefaultFont(font);
                return font;
            }
            else return nullptr;
        }
        else {
            return nullptr;
        }
    }
Daandelange commented 1 year ago

Hey, Yes it already is committed to develop (0c12244), I thought you'd see the mention above your post...
And you're right, the ofxImGui::addFont way also updates the fonts texture.

Daandelange commented 1 year ago

See also using-font-data-embedded-in-source-code