WIP - Core allocates per-baked-per-src backend buffers, to allow having custom backend per font source. Backend BakedInit/Destroy/AddGlyph process a single source.

This commit is contained in:
ocornut 2025-02-06 15:19:23 +01:00
parent a85f7b434b
commit 8d3f361b02
4 changed files with 133 additions and 128 deletions

View file

@ -3751,7 +3751,7 @@ struct ImFontBaked
int LastUsedFrame; // 4 // // Record of that time this was bounds
ImGuiID BakedId; // 4 //
ImFont* ContainerFont; // 4-8 // in // Parent font
void* FontBackendData; // 4-8 // // Font backend opaque storage (per baked font)
void* FontLoaderDatas; // 4-8 // // Font loader opaque storage (per baked font * sources): single contiguous buffer allocated by imgui, passed to loader.
// Functions
IMGUI_API ImFontBaked();

View file

@ -3534,7 +3534,7 @@ bool ImFontAtlasBuildAddFont(ImFontAtlas* atlas, ImFontConfig* src)
// Create a compact, baked "..." if it doesn't exist, by using the ".".
// This may seem overly complicated right now but the point is to exercise and improve a technique which should be increasingly used.
// FIXME-NEWATLAS: This borrows too much from FontLoader's FontLoaderGlyph() handlers and suggest that we should add further helpers.
// FIXME-NEWATLAS: This borrows too much from FontLoader's FontLoadGlyph() handlers and suggest that we should add further helpers.
static ImFontGlyph* ImFontAtlasBuildSetupFontBakedEllipsis(ImFontAtlas* atlas, ImFontBaked* baked)
{
ImFont* font = baked->ContainerFont;
@ -3673,6 +3673,31 @@ void ImFontAtlasBuildDiscardFontBakedGlyph(ImFontAtlas* atlas, ImFont* font, ImF
baked->IndexAdvanceX[c] = baked->FallbackAdvanceX;
}
ImFontBaked* ImFontAtlasBuildAddFontBaked(ImFontAtlas* atlas, ImFont* font, float size, ImGuiID baked_id)
{
IMGUI_DEBUG_LOG_FONT("[font] Created baked %.2fpx\n", size);
ImFontBaked* baked = atlas->Builder->BakedPool.push_back(ImFontBaked());
baked->Size = size;
baked->BakedId = baked_id;
baked->ContainerFont = font;
baked->LastUsedFrame = atlas->Builder->FrameCount;
// Initialize backend data
size_t loader_data_size = font->SourcesCount * atlas->FontLoader->FontBakedSrcLoaderDataSize;
baked->FontLoaderDatas = (loader_data_size > 0) ? IM_ALLOC(loader_data_size) : NULL;
char* backend_user_data_p = (char*)baked->FontLoaderDatas;
for (int src_n = 0; src_n < font->SourcesCount; src_n++)
{
ImFontConfig* src = &font->Sources[src_n];
if (atlas->FontLoader->FontBakedInit)
atlas->FontLoader->FontBakedInit(atlas, src, baked, backend_user_data_p);
backend_user_data_p += atlas->FontLoader->FontBakedSrcLoaderDataSize;
}
ImFontAtlasBuildSetupFontBakedSpecialGlyphs(atlas, baked->ContainerFont, baked);
return baked;
}
void ImFontAtlasBuildDiscardFontBaked(ImFontAtlas* atlas, ImFont* font, ImFontBaked* baked)
{
ImFontAtlasBuilder* builder = atlas->Builder;
@ -3682,9 +3707,19 @@ void ImFontAtlasBuildDiscardFontBaked(ImFontAtlas* atlas, ImFont* font, ImFontBa
if (glyph.PackId >= 0)
ImFontAtlasPackDiscardRect(atlas, glyph.PackId);
if (atlas->FontLoader->FontBakedDestroy)
atlas->FontLoader->FontBakedDestroy(atlas, baked);
char* backend_user_data_p = (char*)baked->FontLoaderDatas;
for (int src_n = 0; src_n < font->SourcesCount; src_n++)
{
ImFontConfig* src = &font->Sources[src_n];
if (atlas->FontLoader->FontBakedDestroy)
atlas->FontLoader->FontBakedDestroy(atlas, src, baked, backend_user_data_p);
backend_user_data_p += atlas->FontLoader->FontBakedSrcLoaderDataSize;
}
if (baked->FontLoaderDatas)
{
IM_FREE(baked->FontLoaderDatas);
baked->FontLoaderDatas = NULL;
}
builder->BakedMap.SetVoidPtr(baked->BakedId, NULL);
builder->BakedDiscardedCount++;
baked->ClearOutputData();
@ -4020,7 +4055,7 @@ void ImFontAtlasBuildInit(ImFontAtlas* atlas)
#else
IM_ASSERT(0); // Invalid Build function
#endif
return; // ImFontAtlasBuildSetupFontBackendIO() automatically call ImFontAtlasBuildInit()
return; // ImFontAtlasBuildSetupFontLoader() automatically call ImFontAtlasBuildInit()
}
// Create initial texture size
@ -4194,6 +4229,16 @@ ImFontAtlasRect* ImFontAtlasPackGetRect(ImFontAtlas* atlas, ImFontAtlasRectId id
return &builder->Rects[index_entry->TargetIndex];
}
// Important! This assume by ImFontConfig::GlyphFilter is a SMALL ARRAY (e.g. <10 entries)
static bool ImFontAtlasBuildAcceptCodepointForSource(ImFontConfig* src, ImWchar codepoint)
{
if (const ImWchar* exclude_list = src->GlyphExcludeRanges)
for (; exclude_list[0] != 0; exclude_list += 2)
if (codepoint >= exclude_list[0] && codepoint <= exclude_list[1])
return false;
return true;
}
ImFontGlyph* ImFontBaked::BuildLoadGlyph(ImWchar codepoint)
{
ImFont* font = ContainerFont;
@ -4217,18 +4262,25 @@ ImFontGlyph* ImFontBaked::BuildLoadGlyph(ImWchar codepoint)
// Call backend
const ImFontLoader* font_loader = atlas->FontLoader;
if (!font_loader->FontBakedAddGlyph(atlas, baked, srcs, srcs_count, codepoint))
char* backend_user_data_p = (char*)baked->FontLoaderDatas;
for (int src_n = 0; src_n < srcs_count; src_n++)
{
// Mark index as not found, so we don't attempt the search twice
baked->BuildGrowIndex(codepoint + 1);
baked->IndexAdvanceX[codepoint] = baked->FallbackAdvanceX;
baked->IndexLookup[codepoint] = IM_FONTGLYPH_INDEX_NOT_FOUND;
return NULL;
ImFontConfig* src = &srcs[src_n];
if (!src->GlyphExcludeRanges || ImFontAtlasBuildAcceptCodepointForSource(src, codepoint))
if (font_loader->FontBakedAddGlyph(atlas, src, baked, backend_user_data_p, codepoint))
{
// FIXME: Add hooks for e.g. #7962
ImFontGlyph* glyph = &baked->Glyphs.back();
return glyph;
}
backend_user_data_p += font_loader->FontBakedSrcLoaderDataSize;
}
// FIXME: Add hooks for e.g. #7962
ImFontGlyph* glyph = &baked->Glyphs.back();
return glyph;
// Mark index as not found, so we don't attempt the search twice
baked->BuildGrowIndex(codepoint + 1);
baked->IndexAdvanceX[codepoint] = baked->FallbackAdvanceX;
baked->IndexLookup[codepoint] = IM_FONTGLYPH_INDEX_NOT_FOUND;
return NULL;
}
// The point of this indirection is to not be inlined in debug mode in order to not bloat inner loop.b
@ -4333,17 +4385,13 @@ static bool ImGui_ImplStbTrueType_FontSrcContainsGlyph(ImFontAtlas* atlas, ImFon
return glyph_index != 0;
}
static void ImGui_ImplStbTrueType_FontBakedInit(ImFontAtlas* atlas, ImFontBaked* baked)
static void ImGui_ImplStbTrueType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void*)
{
IM_UNUSED(atlas);
ImFont* font = baked->ContainerFont;
for (int src_n = 0; src_n < font->SourcesCount; src_n++)
ImGui_ImplStbTrueType_FontSrcData* bd_font_data = (ImGui_ImplStbTrueType_FontSrcData*)src->FontLoaderData;
if (src->MergeMode == false)
{
ImFontConfig* src = &font->Sources[src_n];
ImGui_ImplStbTrueType_FontSrcData* bd_font_data = (ImGui_ImplStbTrueType_FontSrcData*)src->FontLoaderData;
if (src_n != 0)
continue;
// FIXME-NEWFONTS: reevaluate how to use sizing metrics
// FIXME-NEWFONTS: make use of line gap value
float scale_for_layout = bd_font_data->ScaleFactor * baked->Size;
@ -4354,33 +4402,12 @@ static void ImGui_ImplStbTrueType_FontBakedInit(ImFontAtlas* atlas, ImFontBaked*
}
}
// Important! This assume by ImFontConfig::GlyphFilter is a SMALL ARRAY (e.g. <10 entries)
bool ImFontAtlasBuildAcceptCodepointForSource(ImFontConfig* src, ImWchar codepoint)
{
if (const ImWchar* exclude_list = src->GlyphExcludeRanges)
for (; exclude_list[0] != 0; exclude_list += 2)
if (codepoint >= exclude_list[0] && codepoint <= exclude_list[1])
return false;
return true;
}
static bool ImGui_ImplStbTrueType_FontBakedAddGlyph(ImFontAtlas* atlas, ImFontBaked* baked, ImFontConfig* srcs, int srcs_count, ImWchar codepoint)
static bool ImGui_ImplStbTrueType_FontBakedAddGlyph(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void*, ImWchar codepoint)
{
// Search for first font which has the glyph
ImGui_ImplStbTrueType_FontSrcData* bd_font_data = NULL;
ImFontConfig* src = NULL;
int glyph_index = 0;
for (int src_n = 0; src_n < srcs_count; src_n++)
{
src = &srcs[src_n];
if (src->GlyphExcludeRanges && !ImFontAtlasBuildAcceptCodepointForSource(src, codepoint))
continue;
bd_font_data = (ImGui_ImplStbTrueType_FontSrcData*)src->FontLoaderData;
IM_ASSERT(bd_font_data);
glyph_index = stbtt_FindGlyphIndex(&bd_font_data->FontInfo, (int)codepoint);
if (glyph_index != 0)
break;
}
ImGui_ImplStbTrueType_FontSrcData* bd_font_data = (ImGui_ImplStbTrueType_FontSrcData*)src->FontLoaderData;
IM_ASSERT(bd_font_data);
int glyph_index = stbtt_FindGlyphIndex(&bd_font_data->FontInfo, (int)codepoint);
if (glyph_index == 0)
return false; // Not found
@ -5059,17 +5086,9 @@ ImFontBaked* ImFont::GetFontBaked(float size)
IM_ASSERT(!atlas->Locked && "Cannot use dynamic font size with a locked ImFontAtlas!"); // Locked because rendering backend does not support ImGuiBackendFlags_RendererHasTextures!
// Create new
IMGUI_DEBUG_LOG_FONT("[font] Created baked %.2fpx\n", size);
baked = builder->BakedPool.push_back(ImFontBaked());
baked->Size = size;
baked->BakedId = baked_id;
baked->ContainerFont = this;
baked->LastUsedFrame = ContainerAtlas->Builder->FrameCount;
baked = ImFontAtlasBuildAddFontBaked(atlas, this, size, baked_id);
LastBaked = baked;
*p_baked_in_map = baked; // To avoid 'builder->BakedMap.SetVoidPtr(baked_id, baked);' while we can.
if (atlas->FontLoader->FontBakedInit)
atlas->FontLoader->FontBakedInit(atlas, baked);
ImFontAtlasBuildSetupFontBakedSpecialGlyphs(atlas, baked->ContainerFont, baked);
return baked;
}

View file

@ -3954,9 +3954,13 @@ struct ImFontLoader
bool (*FontSrcInit)(ImFontAtlas* atlas, ImFontConfig* src);
void (*FontSrcDestroy)(ImFontAtlas* atlas, ImFontConfig* src);
bool (*FontSrcContainsGlyph)(ImFontAtlas* atlas, ImFontConfig* src, ImWchar codepoint);
void (*FontBakedInit)(ImFontAtlas* atlas, ImFontBaked* baked);
void (*FontBakedDestroy)(ImFontAtlas* atlas, ImFontBaked* baked);
bool (*FontBakedAddGlyph)(ImFontAtlas* atlas, ImFontBaked* baked, ImFontConfig* srcs, int srcs_count, ImWchar codepoint);
void (*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);
bool (*FontBakedAddGlyph)(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.
// FIXME: At this point the two other types of buffers may be managed by core to be consistent?
size_t FontBakedSrcLoaderDataSize;
ImFontLoader() { memset(this, 0, sizeof(*this)); }
};
@ -4056,11 +4060,11 @@ IMGUI_API bool ImFontAtlasBuildAddFont(ImFontAtlas* atlas, ImFontCo
IMGUI_API void ImFontAtlasBuildSetupFontSpecialGlyphs(ImFontAtlas* atlas, ImFont* font, ImFontConfig* src);
IMGUI_API void ImFontAtlasBuildDiscardBakes(ImFontAtlas* atlas, int unused_frames);
IMGUI_API void ImFontAtlasBuildDiscardFont(ImFontAtlas* atlas, ImFont* font);
IMGUI_API ImFontBaked* ImFontAtlasBuildAddFontBaked(ImFontAtlas* atlas, ImFont* font, float font_size, ImGuiID baked_id);
IMGUI_API void ImFontAtlasBuildDiscardFontBaked(ImFontAtlas* atlas, ImFont* font, ImFontBaked* baked);
IMGUI_API void ImFontAtlasBuildDiscardFontBakedGlyph(ImFontAtlas* atlas, ImFont* font, ImFontBaked* baked, ImFontGlyph* glyph);
IMGUI_API void ImFontAtlasBuildPreloadAllGlyphRanges(ImFontAtlas* atlas); // Legacy
IMGUI_API void ImFontAtlasBuildGetOversampleFactors(ImFontConfig* src, float size, int* out_oversample_h, int* out_oversample_v);
IMGUI_API bool ImFontAtlasBuildAcceptCodepointForSource(ImFontConfig* src, ImWchar codepoint);
IMGUI_API ImFontGlyph* ImFontAtlasBakedAddFontGlyph(ImFontAtlas* atlas, ImFontBaked* baked, ImFontConfig* src, const ImFontGlyph* in_glyph);
IMGUI_API void ImFontAtlasBakedSetFontGlyphBitmap(ImFontAtlas* atlas, ImFontBaked* baked, ImFontConfig* src, ImFontGlyph* glyph, ImFontAtlasRect* r, const unsigned char* src_pixels, ImTextureFormat src_fmt, int src_pitch);

View file

@ -143,7 +143,7 @@ namespace
// | |
// |------------- advanceX ----------->|
// Stored in ImFontAtlas::FontLoaderData
// Stored in ImFontAtlas::FontLoaderData. ALLOCATED BY US.
struct ImGui_ImplFreeType_Data
{
FT_Library Library;
@ -151,7 +151,7 @@ namespace
ImGui_ImplFreeType_Data() { memset((void*)this, 0, sizeof(*this)); }
};
// Stored in ImFontBaked::FontBackendData: pointer to SourcesCount instances of this.
// Stored in ImFontBaked::FontLoaderDatas: pointer to SourcesCount instances of this. ALLOCATED BY CORE.
struct ImGui_ImplFreeType_FontSrcBakedData
{
FT_Size FtSize; // This represent a FT_Face with a given size.
@ -166,7 +166,7 @@ namespace
ImGui_ImplFreeType_FontSrcBakedData() { memset((void*)this, 0, sizeof(*this)); }
};
// Stored in ImFontConfig::FontLoaderData
// Stored in ImFontConfig::FontLoaderData. ALLOCATED BY US.
struct ImGui_ImplFreeType_FontSrcData
{
bool InitFont(FT_Library ft_library, ImFontConfig* src, unsigned int extra_user_flags); // Initialize from an external data buffer. Doesn't copy data, and you must ensure it stays valid up to this object lifetime.
@ -437,91 +437,72 @@ void ImGui_ImplFreeType_FontSrcDestroy(ImFontAtlas* atlas, ImFontConfig* src)
src->FontLoaderData = NULL;
}
void ImGui_ImplFreeType_FontBakedInit(ImFontAtlas* atlas, ImFontBaked* baked)
void ImGui_ImplFreeType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src)
{
IM_UNUSED(atlas);
ImFont* font = baked->ContainerFont;
const float size = baked->Size;
IM_ASSERT(baked->FontBackendData == NULL);
ImGui_ImplFreeType_FontSrcBakedData* bd_baked_datas = (ImGui_ImplFreeType_FontSrcBakedData*)IM_ALLOC(sizeof(ImGui_ImplFreeType_FontSrcBakedData) * font->SourcesCount);
baked->FontBackendData = bd_baked_datas;
ImGui_ImplFreeType_FontSrcData* bd_font_data = (ImGui_ImplFreeType_FontSrcData*)src->FontLoaderData;
bd_font_data->BakedLastActivated = baked;
for (int src_n = 0; src_n < font->SourcesCount; src_n++)
// We use one FT_Size per (source + baked) combination.
ImGui_ImplFreeType_FontSrcBakedData* bd_baked_data = (ImGui_ImplFreeType_FontSrcBakedData*)loader_data_for_baked_src;
IM_ASSERT(bd_baked_data != NULL);
IM_PLACEMENT_NEW(bd_baked_data) ImGui_ImplFreeType_FontSrcBakedData();
FT_New_Size(bd_font_data->FtFace, &bd_baked_data->FtSize);
FT_Activate_Size(bd_baked_data->FtSize);
// Vuhdo 2017: "I'm not sure how to deal with font sizes properly. As far as I understand, currently ImGui assumes that the 'pixel_height'
// is a maximum height of an any given glyph, i.e. it's the sum of font's ascender and descender. Seems strange to me.
// FT_Set_Pixel_Sizes() doesn't seem to get us the same result."
// (FT_Set_Pixel_Sizes() essentially calls FT_Request_Size() with FT_SIZE_REQUEST_TYPE_NOMINAL)
FT_Size_RequestRec req;
req.type = (bd_font_data->UserFlags & ImGuiFreeTypeBuilderFlags_Bitmap) ? FT_SIZE_REQUEST_TYPE_NOMINAL : FT_SIZE_REQUEST_TYPE_REAL_DIM;
req.width = 0;
req.height = (uint32_t)(size * 64 * bd_font_data->RasterizationDensity);
req.horiResolution = 0;
req.vertResolution = 0;
FT_Request_Size(bd_font_data->FtFace, &req);
// Read metrics
FT_Size_Metrics metrics = bd_baked_data->FtSize->metrics;
bd_baked_data->Ascender = (float)FT_CEIL(metrics.ascender) * bd_font_data->InvRasterizationDensity;
bd_baked_data->Descender = (float)FT_CEIL(metrics.descender) * bd_font_data->InvRasterizationDensity;
bd_baked_data->LineSpacing = (float)FT_CEIL(metrics.height) * bd_font_data->InvRasterizationDensity;
bd_baked_data->LineGap = (float)FT_CEIL(metrics.height - metrics.ascender + metrics.descender) * bd_font_data->InvRasterizationDensity;
bd_baked_data->MaxAdvanceWidth = (float)FT_CEIL(metrics.max_advance) * bd_font_data->InvRasterizationDensity;
// Output
if (src->MergeMode == false)
{
ImFontConfig* src = &font->Sources[src_n];
ImGui_ImplFreeType_FontSrcData* bd_font_data = (ImGui_ImplFreeType_FontSrcData*)src->FontBackendData;
bd_font_data->BakedLastActivated = baked;
// We need one FT_Size per source, so create one ImGui_ImplFreeType_FontBakedData for each source.
ImGui_ImplFreeType_FontSrcBakedData* bd_baked_data = &bd_baked_datas[src_n];
FT_New_Size(bd_font_data->FtFace, &bd_baked_data->FtSize);
FT_Activate_Size(bd_baked_data->FtSize);
// Vuhdo 2017: "I'm not sure how to deal with font sizes properly. As far as I understand, currently ImGui assumes that the 'pixel_height'
// is a maximum height of an any given glyph, i.e. it's the sum of font's ascender and descender. Seems strange to me.
// FT_Set_Pixel_Sizes() doesn't seem to get us the same result."
// (FT_Set_Pixel_Sizes() essentially calls FT_Request_Size() with FT_SIZE_REQUEST_TYPE_NOMINAL)
FT_Size_RequestRec req;
req.type = (bd_font_data->UserFlags & ImGuiFreeTypeBuilderFlags_Bitmap) ? FT_SIZE_REQUEST_TYPE_NOMINAL : FT_SIZE_REQUEST_TYPE_REAL_DIM;
req.width = 0;
req.height = (uint32_t)(size * 64 * bd_font_data->RasterizationDensity);
req.horiResolution = 0;
req.vertResolution = 0;
FT_Request_Size(bd_font_data->FtFace, &req);
// Read metrics
FT_Size_Metrics metrics = bd_baked_data->FtSize->metrics;
bd_baked_data->Ascender = (float)FT_CEIL(metrics.ascender) * bd_font_data->InvRasterizationDensity;
bd_baked_data->Descender = (float)FT_CEIL(metrics.descender) * bd_font_data->InvRasterizationDensity;
bd_baked_data->LineSpacing = (float)FT_CEIL(metrics.height) * bd_font_data->InvRasterizationDensity;
bd_baked_data->LineGap = (float)FT_CEIL(metrics.height - metrics.ascender + metrics.descender) * bd_font_data->InvRasterizationDensity;
bd_baked_data->MaxAdvanceWidth = (float)FT_CEIL(metrics.max_advance) * bd_font_data->InvRasterizationDensity;
// Output
if (src_n == 0)
{
baked->Ascent = bd_baked_data->Ascender;
baked->Descent = bd_baked_data->Descender;
}
baked->Ascent = bd_baked_data->Ascender;
baked->Descent = bd_baked_data->Descender;
}
}
void ImGui_ImplFreeType_FontBakedDestroy(ImFontAtlas* atlas, ImFontBaked* baked)
void ImGui_ImplFreeType_FontBakedDestroy(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src)
{
IM_UNUSED(atlas);
ImFont* font = baked->ContainerFont;
ImGui_ImplFreeType_FontSrcBakedData* bd_baked_datas = (ImGui_ImplFreeType_FontSrcBakedData*)baked->FontBackendData;
for (int src_n = 0; src_n < font->SourcesCount; src_n++)
FT_Done_Size(bd_baked_datas[src_n].FtSize);
IM_FREE(bd_baked_datas);
baked->FontBackendData = NULL;
IM_UNUSED(baked);
IM_UNUSED(src);
ImGui_ImplFreeType_FontSrcBakedData* bd_baked_data = (ImGui_ImplFreeType_FontSrcBakedData*)loader_data_for_baked_src;
IM_ASSERT(bd_baked_data != NULL);
FT_Done_Size(bd_baked_data->FtSize);
bd_baked_data->~ImGui_ImplFreeType_FontSrcBakedData(); // ~IM_PLACEMENT_DELETE()
}
bool ImGui_ImplFreeType_FontBakedAddGlyph(ImFontAtlas* atlas, ImFontBaked* baked, ImFontConfig* srcs, int srcs_count, ImWchar codepoint)
bool ImGui_ImplFreeType_FontBakedAddGlyph(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src, ImWchar codepoint)
{
// Search for first font which has the glyph
ImGui_ImplFreeType_FontSrcData* bd_font_data = NULL;
ImFontConfig* src = NULL;
uint32_t glyph_index = 0;
for (int src_n = 0; src_n < srcs_count; src_n++)
{
src = &srcs[src_n];
if (src->GlyphExcludeRanges && !ImFontAtlasBuildFilterCodepointForSource(src, codepoint))
continue;
bd_font_data = (ImGui_ImplFreeType_FontSrcData*)src->FontLoaderData;
glyph_index = FT_Get_Char_Index(bd_font_data->FtFace, codepoint);
if (glyph_index != 0)
break;
}
ImGui_ImplFreeType_FontSrcData* bd_font_data = (ImGui_ImplFreeType_FontSrcData*)src->FontLoaderData;
uint32_t glyph_index = FT_Get_Char_Index(bd_font_data->FtFace, codepoint);
if (glyph_index == 0)
return false; // Not found
if (bd_font_data->BakedLastActivated != baked)
{
// Activate current size
int src_n = (int)(font_cfg - srcs);
ImGui_ImplFreeType_FontSrcBakedData* bd_baked_data = &((ImGui_ImplFreeType_FontSrcBakedData*)baked->FontBackendData)[src_n];
ImGui_ImplFreeType_FontSrcBakedData* bd_baked_data = (ImGui_ImplFreeType_FontSrcBakedData*)loader_data_for_baked_src;
FT_Activate_Size(bd_baked_data->FtSize);
bd_font_data->BakedLastActivated = baked;
}
@ -618,6 +599,7 @@ const ImFontLoader* ImGuiFreeType::GetFontLoader()
loader.FontBakedInit = ImGui_ImplFreeType_FontBakedInit;
loader.FontBakedDestroy = ImGui_ImplFreeType_FontBakedDestroy;
loader.FontBakedAddGlyph = ImGui_ImplFreeType_FontBakedAddGlyph;
loader.FontBakedSrcLoaderDataSize = sizeof(ImGui_ImplFreeType_FontSrcBakedData);
return &loader;
}