1
0
Fork 0
mirror of https://github.com/ocornut/imgui.git synced 2026-01-11 00:04:24 +00:00

Fonts: Rework ImFontLoader signatures.

InitBaked may return false to signify this size is not supported.
This commit is contained in:
ocornut 2025-02-07 18:48:01 +01:00
parent c06a7585a3
commit 18c8a93cca
3 changed files with 22 additions and 27 deletions

View file

@ -3005,7 +3005,7 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
IM_ASSERT((size <= 64) && "GlyphExcludeRanges[] size must be small!"); IM_ASSERT((size <= 64) && "GlyphExcludeRanges[] size must be small!");
} }
if (font_cfg->FontLoader != NULL) if (font_cfg->FontLoader != NULL)
IM_ASSERT(font_cfg->FontLoader->FontBakedAddGlyph != NULL); IM_ASSERT(font_cfg->FontLoader->FontBakedLoadGlyph != NULL);
IM_ASSERT(font_cfg->FontLoaderData == NULL); IM_ASSERT(font_cfg->FontLoaderData == NULL);
// Round font size // Round font size
@ -4288,12 +4288,8 @@ ImFontGlyph* ImFontBaked::BuildLoadGlyph(ImWchar codepoint)
ImFontConfig* src = &srcs[src_n]; ImFontConfig* src = &srcs[src_n];
const ImFontLoader* loader = src->FontLoader ? src->FontLoader : atlas->FontLoader; const ImFontLoader* loader = src->FontLoader ? src->FontLoader : atlas->FontLoader;
if (!src->GlyphExcludeRanges || ImFontAtlasBuildAcceptCodepointForSource(src, codepoint)) if (!src->GlyphExcludeRanges || ImFontAtlasBuildAcceptCodepointForSource(src, codepoint))
if (loader->FontBakedAddGlyph(atlas, src, baked, loader_user_data_p, codepoint)) if (ImFontGlyph* glyph = loader->FontBakedLoadGlyph(atlas, src, baked, loader_user_data_p, codepoint))
{ return glyph; // FIXME: Add hooks for e.g. #7962
// FIXME: Add hooks for e.g. #7962
ImFontGlyph* glyph = &baked->Glyphs.back();
return glyph;
}
loader_user_data_p += loader->FontBakedSrcLoaderDataSize; loader_user_data_p += loader->FontBakedSrcLoaderDataSize;
} }
@ -4406,7 +4402,7 @@ static bool ImGui_ImplStbTrueType_FontSrcContainsGlyph(ImFontAtlas* atlas, ImFon
return glyph_index != 0; return glyph_index != 0;
} }
static void ImGui_ImplStbTrueType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void*) static bool ImGui_ImplStbTrueType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void*)
{ {
IM_UNUSED(atlas); IM_UNUSED(atlas);
@ -4421,16 +4417,17 @@ static void ImGui_ImplStbTrueType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig
baked->Ascent = ImCeil(unscaled_ascent * scale_for_layout); baked->Ascent = ImCeil(unscaled_ascent * scale_for_layout);
baked->Descent = ImFloor(unscaled_descent * scale_for_layout); baked->Descent = ImFloor(unscaled_descent * scale_for_layout);
} }
return true;
} }
static bool ImGui_ImplStbTrueType_FontBakedAddGlyph(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void*, ImWchar codepoint) static ImFontGlyph* ImGui_ImplStbTrueType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void*, ImWchar codepoint)
{ {
// Search for first font which has the glyph // Search for first font which has the glyph
ImGui_ImplStbTrueType_FontSrcData* bd_font_data = (ImGui_ImplStbTrueType_FontSrcData*)src->FontLoaderData; ImGui_ImplStbTrueType_FontSrcData* bd_font_data = (ImGui_ImplStbTrueType_FontSrcData*)src->FontLoaderData;
IM_ASSERT(bd_font_data); IM_ASSERT(bd_font_data);
int glyph_index = stbtt_FindGlyphIndex(&bd_font_data->FontInfo, (int)codepoint); int glyph_index = stbtt_FindGlyphIndex(&bd_font_data->FontInfo, (int)codepoint);
if (glyph_index == 0) if (glyph_index == 0)
return false; // Not found return NULL;
// Fonts unit to pixels // Fonts unit to pixels
int oversample_h, oversample_v; int oversample_h, oversample_v;
@ -4463,7 +4460,7 @@ static bool ImGui_ImplStbTrueType_FontBakedAddGlyph(ImFontAtlas* atlas, ImFontCo
{ {
// Pathological out of memory case (TexMaxWidth/TexMaxHeight set too small?) // Pathological out of memory case (TexMaxWidth/TexMaxHeight set too small?)
IM_ASSERT_USER_ERROR(pack_id >= 0, "Out of texture memory."); IM_ASSERT_USER_ERROR(pack_id >= 0, "Out of texture memory.");
return false; return NULL;
} }
ImFontAtlasRect* r = ImFontAtlasPackGetRect(atlas, pack_id); ImFontAtlasRect* r = ImFontAtlasPackGetRect(atlas, pack_id);
@ -4512,7 +4509,7 @@ static bool ImGui_ImplStbTrueType_FontBakedAddGlyph(ImFontAtlas* atlas, ImFontCo
glyph = ImFontAtlasBakedAddFontGlyph(atlas, baked, src, glyph); glyph = ImFontAtlasBakedAddFontGlyph(atlas, baked, src, glyph);
} }
return true; return glyph;
} }
const ImFontLoader* ImFontAtlasGetFontLoaderForStbTruetype() const ImFontLoader* ImFontAtlasGetFontLoaderForStbTruetype()
@ -4524,7 +4521,7 @@ const ImFontLoader* ImFontAtlasGetFontLoaderForStbTruetype()
loader.FontSrcContainsGlyph = ImGui_ImplStbTrueType_FontSrcContainsGlyph; loader.FontSrcContainsGlyph = ImGui_ImplStbTrueType_FontSrcContainsGlyph;
loader.FontBakedInit = ImGui_ImplStbTrueType_FontBakedInit; loader.FontBakedInit = ImGui_ImplStbTrueType_FontBakedInit;
loader.FontBakedDestroy = NULL; loader.FontBakedDestroy = NULL;
loader.FontBakedAddGlyph = ImGui_ImplStbTrueType_FontBakedAddGlyph; loader.FontBakedLoadGlyph = ImGui_ImplStbTrueType_FontBakedLoadGlyph;
return &loader; return &loader;
} }

View file

@ -3668,9 +3668,9 @@ struct ImFontLoader
bool (*FontSrcInit)(ImFontAtlas* atlas, ImFontConfig* src); bool (*FontSrcInit)(ImFontAtlas* atlas, ImFontConfig* src);
void (*FontSrcDestroy)(ImFontAtlas* atlas, ImFontConfig* src); void (*FontSrcDestroy)(ImFontAtlas* atlas, ImFontConfig* src);
bool (*FontSrcContainsGlyph)(ImFontAtlas* atlas, ImFontConfig* src, ImWchar codepoint); bool (*FontSrcContainsGlyph)(ImFontAtlas* atlas, ImFontConfig* src, ImWchar codepoint);
void (*FontBakedInit)(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src); bool (*FontBakedInit)(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src);
void (*FontBakedDestroy)(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src); void (*FontBakedDestroy)(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src);
bool (*FontBakedAddGlyph)(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src, ImWchar codepoint); ImFontGlyph* (*FontBakedLoadGlyph)(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src, ImWchar codepoint);
// Size of backend data, Per Baked * Per Source. Buffers are managed by core to avoid excessive allocations. // Size of backend data, Per Baked * Per Source. Buffers are managed by core to avoid excessive allocations.
// FIXME: At this point the two other types of buffers may be managed by core to be consistent? // FIXME: At this point the two other types of buffers may be managed by core to be consistent?

View file

@ -437,7 +437,7 @@ void ImGui_ImplFreeType_FontSrcDestroy(ImFontAtlas* atlas, ImFontConfig* src)
src->FontLoaderData = NULL; src->FontLoaderData = NULL;
} }
void ImGui_ImplFreeType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src) bool ImGui_ImplFreeType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src)
{ {
IM_UNUSED(atlas); IM_UNUSED(atlas);
const float size = baked->Size; const float size = baked->Size;
@ -479,6 +479,7 @@ void ImGui_ImplFreeType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* src, ImF
baked->Ascent = bd_baked_data->Ascender; baked->Ascent = bd_baked_data->Ascender;
baked->Descent = bd_baked_data->Descender; baked->Descent = bd_baked_data->Descender;
} }
return true;
} }
void ImGui_ImplFreeType_FontBakedDestroy(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src) void ImGui_ImplFreeType_FontBakedDestroy(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src)
@ -492,12 +493,12 @@ void ImGui_ImplFreeType_FontBakedDestroy(ImFontAtlas* atlas, ImFontConfig* src,
bd_baked_data->~ImGui_ImplFreeType_FontSrcBakedData(); // ~IM_PLACEMENT_DELETE() bd_baked_data->~ImGui_ImplFreeType_FontSrcBakedData(); // ~IM_PLACEMENT_DELETE()
} }
bool ImGui_ImplFreeType_FontBakedAddGlyph(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src, ImWchar codepoint) ImFontGlyph* ImGui_ImplFreeType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src, ImWchar codepoint)
{ {
ImGui_ImplFreeType_FontSrcData* bd_font_data = (ImGui_ImplFreeType_FontSrcData*)src->FontLoaderData; ImGui_ImplFreeType_FontSrcData* bd_font_data = (ImGui_ImplFreeType_FontSrcData*)src->FontLoaderData;
uint32_t glyph_index = FT_Get_Char_Index(bd_font_data->FtFace, codepoint); uint32_t glyph_index = FT_Get_Char_Index(bd_font_data->FtFace, codepoint);
if (glyph_index == 0) if (glyph_index == 0)
return false; // Not found return NULL;
if (bd_font_data->BakedLastActivated != baked) if (bd_font_data->BakedLastActivated != baked)
{ {
@ -509,18 +510,15 @@ bool ImGui_ImplFreeType_FontBakedAddGlyph(ImFontAtlas* atlas, ImFontConfig* src,
const FT_Glyph_Metrics* metrics = bd_font_data->LoadGlyph(codepoint); const FT_Glyph_Metrics* metrics = bd_font_data->LoadGlyph(codepoint);
if (metrics == NULL) if (metrics == NULL)
return false; return NULL;
// Render glyph into a bitmap (currently held by FreeType) // Render glyph into a bitmap (currently held by FreeType)
FT_Face face = bd_font_data->FtFace; FT_Face face = bd_font_data->FtFace;
FT_GlyphSlot slot = face->glyph; FT_GlyphSlot slot = face->glyph;
FT_Error error = FT_Render_Glyph(slot, bd_font_data->RenderMode); FT_Error error = FT_Render_Glyph(slot, bd_font_data->RenderMode);
if (error != 0)
return false;
const FT_Bitmap* ft_bitmap = &slot->bitmap; const FT_Bitmap* ft_bitmap = &slot->bitmap;
if (ft_bitmap == nullptr) if (error != 0 || ft_bitmap == nullptr)
return false; return NULL;
const int w = (int)ft_bitmap->width; const int w = (int)ft_bitmap->width;
const int h = (int)ft_bitmap->rows; const int h = (int)ft_bitmap->rows;
@ -540,7 +538,7 @@ bool ImGui_ImplFreeType_FontBakedAddGlyph(ImFontAtlas* atlas, ImFontConfig* src,
{ {
// Pathological out of memory case (TexMaxWidth/TexMaxHeight set too small?) // Pathological out of memory case (TexMaxWidth/TexMaxHeight set too small?)
IM_ASSERT_USER_ERROR(pack_id >= 0, "Out of texture memory."); IM_ASSERT_USER_ERROR(pack_id >= 0, "Out of texture memory.");
return false; return NULL;
} }
ImFontAtlasRect* r = ImFontAtlasPackGetRect(atlas, pack_id); ImFontAtlasRect* r = ImFontAtlasPackGetRect(atlas, pack_id);
@ -576,7 +574,7 @@ bool ImGui_ImplFreeType_FontBakedAddGlyph(ImFontAtlas* atlas, ImFontConfig* src,
{ {
glyph = ImFontAtlasBakedAddFontGlyph(atlas, baked, src, glyph); glyph = ImFontAtlasBakedAddFontGlyph(atlas, baked, src, glyph);
} }
return true; return glyph;
} }
bool ImGui_ImplFreetype_FontSrcContainsGlyph(ImFontAtlas* atlas, ImFontConfig* src, ImWchar codepoint) bool ImGui_ImplFreetype_FontSrcContainsGlyph(ImFontAtlas* atlas, ImFontConfig* src, ImWchar codepoint)
@ -598,7 +596,7 @@ const ImFontLoader* ImGuiFreeType::GetFontLoader()
loader.FontSrcContainsGlyph = ImGui_ImplFreetype_FontSrcContainsGlyph; loader.FontSrcContainsGlyph = ImGui_ImplFreetype_FontSrcContainsGlyph;
loader.FontBakedInit = ImGui_ImplFreeType_FontBakedInit; loader.FontBakedInit = ImGui_ImplFreeType_FontBakedInit;
loader.FontBakedDestroy = ImGui_ImplFreeType_FontBakedDestroy; loader.FontBakedDestroy = ImGui_ImplFreeType_FontBakedDestroy;
loader.FontBakedAddGlyph = ImGui_ImplFreeType_FontBakedAddGlyph; loader.FontBakedLoadGlyph = ImGui_ImplFreeType_FontBakedLoadGlyph;
loader.FontBakedSrcLoaderDataSize = sizeof(ImGui_ImplFreeType_FontSrcBakedData); loader.FontBakedSrcLoaderDataSize = sizeof(ImGui_ImplFreeType_FontSrcBakedData);
return &loader; return &loader;
} }