ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
59.56k stars 10.15k forks source link

imgui_freetype is broken with freetype 2.11 #4567

Closed wolfpld closed 2 years ago

wolfpld commented 3 years ago

The following is tested against the up-to-date docking branch. When freetype rendering is enabled (IMGUI_ENABLE_FREETYPE, etc.) and freetype 2.11 is in use, you can observe such behavior that:

#include "misc/freetype/imgui_freetype.h"

ImFontConfig config;
io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\Arial.ttf", 18.0f, &config);

is working as expected. However, adding a config.FontBuilderFlags = ImGuiFreeTypeBuilderFlags_LightHinting; line results in an error somewhere inside the freetype library (writing_system_class was nullptr):

example_win32_directx9.exe!af_face_globals_get_metrics(AF_FaceGlobalsRec_ * globals, unsigned int gindex, unsigned int options, AF_StyleMetricsRec_ * * ametrics) Line 458  C
example_win32_directx9.exe!af_loader_load_glyph(AF_LoaderRec_ * loader, AF_ModuleRec_ * module, FT_FaceRec_ * face, unsigned int glyph_index, int load_flags) Line 306  C
example_win32_directx9.exe!af_autofitter_load_glyph(AF_ModuleRec_ * module, FT_GlyphSlotRec_ * slot, FT_SizeRec_ * size, unsigned int glyph_index, int load_flags) Line 489 C
example_win32_directx9.exe!FT_Load_Glyph(FT_FaceRec_ * face, unsigned int glyph_index, int load_flags) Line 981 C
example_win32_directx9.exe!`anonymous namespace'::FreeTypeFont::LoadGlyph(unsigned int codepoint) Line 229  C++
example_win32_directx9.exe!ImFontAtlasBuildWithFreeTypeEx(FT_LibraryRec_ * ft_library, ImFontAtlas * atlas, unsigned int extra_flags) Line 537  C++
example_win32_directx9.exe!ImFontAtlasBuildWithFreeType(ImFontAtlas * atlas) Line 755   C++
example_win32_directx9.exe!ImFontAtlas::Build() Line 2286   C++
example_win32_directx9.exe!ImFontAtlas::GetTexDataAsAlpha8(unsigned char * * out_pixels, int * out_width, int * out_height, int * out_bytes_per_pixel) Line 2043    C++
example_win32_directx9.exe!ImFontAtlas::GetTexDataAsRGBA32(unsigned char * * out_pixels, int * out_width, int * out_height, int * out_bytes_per_pixel) Line 2057    C++
example_win32_directx9.exe!ImGui_ImplDX9_CreateFontsTexture() Line 337  C++

Similar, but different behavior may be observed in a more complex case, when merge mode is enabled:

static const ImWchar rangesIcons[] = {
    ICON_MIN_FA, ICON_MAX_FA,
    0
};
ImFontConfig configMerge;
configMerge.MergeMode = true;
io.Fonts->AddFontFromMemoryCompressedTTF( tracy::Arimo_compressed_data, tracy::Arimo_compressed_size, 15.0f * dpiScale );
io.Fonts->AddFontFromMemoryCompressedTTF( tracy::FontAwesomeSolid_compressed_data, tracy::FontAwesomeSolid_compressed_size, 14.0f * dpiScale, &configMerge, rangesIcons );

Here the error within freetype is metrics was nullptr, at the following call stack:

Tracy.exe!af_face_globals_get_metrics(AF_FaceGlobalsRec_ * globals, unsigned int gindex, unsigned int options, AF_StyleMetricsRec_ * * ametrics) Line 461   C
Tracy.exe!af_loader_load_glyph(AF_LoaderRec_ * loader, AF_ModuleRec_ * module, FT_FaceRec_ * face, unsigned int glyph_index, int load_flags) Line 306   C
Tracy.exe!af_autofitter_load_glyph(AF_ModuleRec_ * module, FT_GlyphSlotRec_ * slot, FT_SizeRec_ * size, unsigned int glyph_index, int load_flags) Line 489  C
Tracy.exe!FT_Load_Glyph(FT_FaceRec_ * face, unsigned int glyph_index, int load_flags) Line 981  C
Tracy.exe!`anonymous namespace'::FreeTypeFont::LoadGlyph(unsigned int codepoint) Line 228   C++
Tracy.exe!ImFontAtlasBuildWithFreeTypeEx(FT_LibraryRec_ * ft_library, ImFontAtlas * atlas, unsigned int extra_flags) Line 536   C++

(Trying to replicate this with two simple ranges, both on Arial, didn't succeed.)

None of this happens with previous freetype versions.

ocornut commented 2 years ago

Hello, thanks for reporting.

I think I used Freetype 2.11 last time I made a change (will verify). Just to put that put of the way, and because Freetype’s include system is all weird: can you confirm that your crash doesn’t possibly come from linking with a different version that the includes used? (Aka includes pulled from one version and lib from another)

wolfpld commented 2 years ago

I think this is highly unlikely. The CI setup I have does a fresh vcpkg install on each build and the resulting executable is also crashing on startup.

rokups commented 2 years ago

Crash is deep in freetype though. Even if we are doing something wrong (which i am not sure we do), freetype should not be crashing. This definitely is a freetype bug, at least in part.

wolfpld commented 2 years ago

I wonder if this could be the cause: https://gitlab.freedesktop.org/freetype/freetype/-/issues/1076

I have tested imgui_freetype on Arch, which has freetype 2.11 with fixes for this issue (https://github.com/archlinux/svntogit-packages/commit/240e4bbd513dbd4afc0b72f51e53cb0fbb77b458), and it seems to be working fine.

rokups commented 2 years ago

I came up with a workaround for this freetype bug. Would you please try it? https://github.com/ocornut/imgui/compare/master...rokups:rk/freetype

wolfpld commented 2 years ago

This still crashes at FT_Error error = FT_Load_Glyph(Face, glyph_index, LoadFlags); in FreeTypeFont::LoadGlyph().

wolfpld commented 2 years ago

I have tried applying the freetype issue 1076 patches (0006-Return_FT_Err_Ok_while_trying_to_render_bitmap.patch, 0007-Restore_quiet_no-op_rendering_of_bitmap_glyphs.patch) on the vcpkg side, and it doesn't help. It fixes the issue which @rokups workarounds above, but it still crashes on the line I have mentioned in the previous comment.

cfillion commented 2 years ago

FreeType 2.11 has a bug causing that crash in af_face_globals_get_metrics when built using MSVC: https://gitlab.freedesktop.org/freetype/freetype/-/issues/1075. There's a patch here.

wolfpld commented 2 years ago

FWIW, Freetype is now fixed on vcpkg, so that's one way of delivery working as intended. It is quite bizarre there wasn't an upstream bug-fix release, considering this issue is quite critical.

ocornut commented 2 years ago

Thanks! Closing this as a Freetype bug then.

Next commit will add a comment in imgui_freetype.cpp to help users navigate their way out of this issue:

// If this crash for you: FreeType 2.11.0 has a crash bug on some bitmap/colored fonts.
// - https://gitlab.freedesktop.org/freetype/freetype/-/issues/1076
// - https://github.com/ocornut/imgui/issues/4567
// - https://github.com/ocornut/imgui/issues/4566
// You can use FreeType 2.10, or the patched version of 2.11.0 in VcPkg, or probably any upcoming FreeType version.
FT_Error error = FT_Load_Glyph(Face, glyph_index, LoadFlags);
if (error)
    return NULL;