mirror of
https://github.com/ocornut/imgui.git
synced 2026-05-27 11:05:26 +08:00
Fonts: A font source can specify its own loader/backend.
This commit is contained in:
@@ -3444,7 +3444,9 @@ struct ImFontConfig
|
|||||||
|
|
||||||
// [Internal]
|
// [Internal]
|
||||||
char Name[40]; // Name (strictly to ease debugging)
|
char Name[40]; // Name (strictly to ease debugging)
|
||||||
|
ImFontFlags Flags; // Font flags (don't use just yet)
|
||||||
ImFont* DstFont; // Target font (as we merging fonts, multiple ImFontConfig may target the same font)
|
ImFont* DstFont; // Target font (as we merging fonts, multiple ImFontConfig may target the same font)
|
||||||
|
const ImFontLoader* FontLoader; // Custom font backend for this source (other use one stored in ImFontAtlas)
|
||||||
void* FontLoaderData; // Font loader opaque storage (per font config)
|
void* FontLoaderData; // Font loader opaque storage (per font config)
|
||||||
|
|
||||||
IMGUI_API ImFontConfig();
|
IMGUI_API ImFontConfig();
|
||||||
|
|||||||
+55
-27
@@ -2607,14 +2607,18 @@ ImFontAtlas::ImFontAtlas()
|
|||||||
ImFontAtlas::~ImFontAtlas()
|
ImFontAtlas::~ImFontAtlas()
|
||||||
{
|
{
|
||||||
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
|
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
|
||||||
Clear();
|
RendererHasTextures = false; // Full Clear() is supported, but ClearTexData() only isn't.
|
||||||
|
ClearFonts();
|
||||||
|
ClearTexData();
|
||||||
|
TexList.clear_delete();
|
||||||
|
TexData = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImFontAtlas::Clear()
|
void ImFontAtlas::Clear()
|
||||||
{
|
{
|
||||||
ClearFonts();
|
|
||||||
bool backup_renderer_has_textures = RendererHasTextures;
|
bool backup_renderer_has_textures = RendererHasTextures;
|
||||||
RendererHasTextures = false; // Full Clear() is supported, but ClearTexData() only isn't.
|
RendererHasTextures = false; // Full Clear() is supported, but ClearTexData() only isn't.
|
||||||
|
ClearFonts();
|
||||||
ClearTexData();
|
ClearTexData();
|
||||||
if (Builder != NULL)
|
if (Builder != NULL)
|
||||||
ImFontAtlasBuildClearTexture(this);
|
ImFontAtlasBuildClearTexture(this);
|
||||||
@@ -2631,8 +2635,9 @@ void ImFontAtlas::ClearInputData()
|
|||||||
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
|
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
|
||||||
for (ImFontConfig& font_cfg : Sources)
|
for (ImFontConfig& font_cfg : Sources)
|
||||||
{
|
{
|
||||||
if (FontLoader && FontLoader->FontSrcDestroy != NULL)
|
const ImFontLoader* loader = font_cfg.FontLoader ? font_cfg.FontLoader : FontLoader;
|
||||||
FontLoader->FontSrcDestroy(this, &font_cfg);
|
if (loader && loader->FontSrcDestroy != NULL)
|
||||||
|
loader->FontSrcDestroy(this, &font_cfg);
|
||||||
if (font_cfg.FontData && font_cfg.FontDataOwnedByAtlas)
|
if (font_cfg.FontData && font_cfg.FontDataOwnedByAtlas)
|
||||||
{
|
{
|
||||||
IM_FREE(font_cfg.FontData);
|
IM_FREE(font_cfg.FontData);
|
||||||
@@ -2957,7 +2962,7 @@ bool ImFontAtlas::Build()
|
|||||||
ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
|
ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
|
||||||
{
|
{
|
||||||
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
|
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
|
||||||
IM_ASSERT(font_cfg->FontData != NULL && font_cfg->FontDataSize > 0);
|
IM_ASSERT((font_cfg->FontData != NULL && font_cfg->FontDataSize > 0) || (font_cfg->FontLoader != NULL));
|
||||||
IM_ASSERT(font_cfg->SizePixels > 0.0f && "Is ImFontConfig struct correctly initialized?");
|
IM_ASSERT(font_cfg->SizePixels > 0.0f && "Is ImFontConfig struct correctly initialized?");
|
||||||
IM_ASSERT(font_cfg->RasterizerDensity > 0.0f && "Is ImFontConfig struct correctly initialized?");
|
IM_ASSERT(font_cfg->RasterizerDensity > 0.0f && "Is ImFontConfig struct correctly initialized?");
|
||||||
|
|
||||||
@@ -2971,6 +2976,7 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
|
|||||||
{
|
{
|
||||||
font = IM_NEW(ImFont)();
|
font = IM_NEW(ImFont)();
|
||||||
font->FontId = FontNextUniqueID++;
|
font->FontId = FontNextUniqueID++;
|
||||||
|
font->Flags = font_cfg->Flags;
|
||||||
Fonts.push_back(font);
|
Fonts.push_back(font);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2998,6 +3004,9 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
|
|||||||
IM_ASSERT((size & 1) == 0 && "GlyphExcludeRanges[] size must be multiple of two!");
|
IM_ASSERT((size & 1) == 0 && "GlyphExcludeRanges[] size must be multiple of two!");
|
||||||
IM_ASSERT((size <= 64) && "GlyphExcludeRanges[] size must be small!");
|
IM_ASSERT((size <= 64) && "GlyphExcludeRanges[] size must be small!");
|
||||||
}
|
}
|
||||||
|
if (font_cfg->FontLoader != NULL)
|
||||||
|
IM_ASSERT(font_cfg->FontLoader->FontBakedAddGlyph != NULL);
|
||||||
|
IM_ASSERT(font_cfg->FontLoaderData == NULL);
|
||||||
|
|
||||||
// Round font size
|
// Round font size
|
||||||
// - We started rounding in 1.90 WIP (18991) as our layout system currently doesn't support non-rounded font size well yet.
|
// - We started rounding in 1.90 WIP (18991) as our layout system currently doesn't support non-rounded font size well yet.
|
||||||
@@ -3165,8 +3174,9 @@ void ImFontAtlas::RemoveFont(ImFont* font)
|
|||||||
for (int src_n = 0; src_n < font->SourcesCount; src_n++)
|
for (int src_n = 0; src_n < font->SourcesCount; src_n++)
|
||||||
{
|
{
|
||||||
ImFontConfig* src = (ImFontConfig*)(void*)&font->Sources[src_n];
|
ImFontConfig* src = (ImFontConfig*)(void*)&font->Sources[src_n];
|
||||||
if (FontLoader && FontLoader->FontSrcDestroy != NULL)
|
const ImFontLoader* loader = src->FontLoader ? src->FontLoader : FontLoader;
|
||||||
FontLoader->FontSrcDestroy(this, src);
|
if (loader && loader->FontSrcDestroy != NULL)
|
||||||
|
loader->FontSrcDestroy(this, src);
|
||||||
if (src->FontData != NULL && src->FontDataOwnedByAtlas)
|
if (src->FontData != NULL && src->FontDataOwnedByAtlas)
|
||||||
IM_FREE(src->FontData);
|
IM_FREE(src->FontData);
|
||||||
}
|
}
|
||||||
@@ -3317,6 +3327,8 @@ void ImFontAtlasBuildGetOversampleFactors(ImFontConfig* src, float size, int* ou
|
|||||||
*out_oversample_v = (src->OversampleV != 0) ? src->OversampleV : 1;
|
*out_oversample_v = (src->OversampleV != 0) ? src->OversampleV : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup main font loader for the atlas
|
||||||
|
// Every font source (ImFontConfig) will use this unless ImFontConfig::FontLoader specify a custom loader.
|
||||||
void ImFontAtlasBuildSetupFontLoader(ImFontAtlas* atlas, const ImFontLoader* font_loader)
|
void ImFontAtlasBuildSetupFontLoader(ImFontAtlas* atlas, const ImFontLoader* font_loader)
|
||||||
{
|
{
|
||||||
if (atlas->FontLoader == font_loader)
|
if (atlas->FontLoader == font_loader)
|
||||||
@@ -3521,9 +3533,10 @@ bool ImFontAtlasBuildAddFont(ImFontAtlas* atlas, ImFontConfig* src)
|
|||||||
IM_ASSERT(font->Sources == src);
|
IM_ASSERT(font->Sources == src);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ImFontLoader* font_loader = atlas->FontLoader;
|
const ImFontLoader* loader = src->FontLoader ? src->FontLoader : atlas->FontLoader;
|
||||||
if (!font_loader->FontSrcInit(atlas, src))
|
if (loader->FontSrcInit != NULL)
|
||||||
return false;
|
if (!loader->FontSrcInit(atlas, src))
|
||||||
|
return false;
|
||||||
|
|
||||||
ImFontAtlasBuildSetupFontSpecialGlyphs(atlas, font, src);
|
ImFontAtlasBuildSetupFontSpecialGlyphs(atlas, font, src);
|
||||||
return true;
|
return true;
|
||||||
@@ -3680,15 +3693,22 @@ ImFontBaked* ImFontAtlasBuildAddFontBaked(ImFontAtlas* atlas, ImFont* font, floa
|
|||||||
baked->LastUsedFrame = atlas->Builder->FrameCount;
|
baked->LastUsedFrame = atlas->Builder->FrameCount;
|
||||||
|
|
||||||
// Initialize backend data
|
// Initialize backend data
|
||||||
size_t loader_data_size = font->SourcesCount * atlas->FontLoader->FontBakedSrcLoaderDataSize;
|
size_t loader_data_size = 0;
|
||||||
|
for (int src_n = 0; src_n < font->SourcesCount; src_n++) // Cannot easily be cached as we allow changing backend
|
||||||
|
{
|
||||||
|
ImFontConfig* src = &font->Sources[src_n];
|
||||||
|
const ImFontLoader* loader = src->FontLoader ? src->FontLoader : atlas->FontLoader;
|
||||||
|
loader_data_size += loader->FontBakedSrcLoaderDataSize;
|
||||||
|
}
|
||||||
baked->FontLoaderDatas = (loader_data_size > 0) ? IM_ALLOC(loader_data_size) : NULL;
|
baked->FontLoaderDatas = (loader_data_size > 0) ? IM_ALLOC(loader_data_size) : NULL;
|
||||||
char* backend_user_data_p = (char*)baked->FontLoaderDatas;
|
char* loader_data_p = (char*)baked->FontLoaderDatas;
|
||||||
for (int src_n = 0; src_n < font->SourcesCount; src_n++)
|
for (int src_n = 0; src_n < font->SourcesCount; src_n++)
|
||||||
{
|
{
|
||||||
ImFontConfig* src = &font->Sources[src_n];
|
ImFontConfig* src = &font->Sources[src_n];
|
||||||
if (atlas->FontLoader->FontBakedInit)
|
const ImFontLoader* loader = src->FontLoader ? src->FontLoader : atlas->FontLoader;
|
||||||
atlas->FontLoader->FontBakedInit(atlas, src, baked, backend_user_data_p);
|
if (loader->FontBakedInit)
|
||||||
backend_user_data_p += atlas->FontLoader->FontBakedSrcLoaderDataSize;
|
loader->FontBakedInit(atlas, src, baked, loader_data_p);
|
||||||
|
loader_data_p += loader->FontBakedSrcLoaderDataSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImFontAtlasBuildSetupFontBakedSpecialGlyphs(atlas, baked->ContainerFont, baked);
|
ImFontAtlasBuildSetupFontBakedSpecialGlyphs(atlas, baked->ContainerFont, baked);
|
||||||
@@ -3704,13 +3724,14 @@ void ImFontAtlasBuildDiscardFontBaked(ImFontAtlas* atlas, ImFont* font, ImFontBa
|
|||||||
if (glyph.PackId >= 0)
|
if (glyph.PackId >= 0)
|
||||||
ImFontAtlasPackDiscardRect(atlas, glyph.PackId);
|
ImFontAtlasPackDiscardRect(atlas, glyph.PackId);
|
||||||
|
|
||||||
char* backend_user_data_p = (char*)baked->FontLoaderDatas;
|
char* loader_data_p = (char*)baked->FontLoaderDatas;
|
||||||
for (int src_n = 0; src_n < font->SourcesCount; src_n++)
|
for (int src_n = 0; src_n < font->SourcesCount; src_n++)
|
||||||
{
|
{
|
||||||
ImFontConfig* src = &font->Sources[src_n];
|
ImFontConfig* src = &font->Sources[src_n];
|
||||||
if (atlas->FontLoader->FontBakedDestroy)
|
const ImFontLoader* loader = src->FontLoader ? src->FontLoader : atlas->FontLoader;
|
||||||
atlas->FontLoader->FontBakedDestroy(atlas, src, baked, backend_user_data_p);
|
if (loader->FontBakedDestroy)
|
||||||
backend_user_data_p += atlas->FontLoader->FontBakedSrcLoaderDataSize;
|
loader->FontBakedDestroy(atlas, src, baked, loader_data_p);
|
||||||
|
loader_data_p += loader->FontBakedSrcLoaderDataSize;
|
||||||
}
|
}
|
||||||
if (baked->FontLoaderDatas)
|
if (baked->FontLoaderDatas)
|
||||||
{
|
{
|
||||||
@@ -4094,9 +4115,12 @@ void ImFontAtlasBuildDestroy(ImFontAtlas* atlas)
|
|||||||
{
|
{
|
||||||
for (ImFont* font : atlas->Fonts)
|
for (ImFont* font : atlas->Fonts)
|
||||||
font->ClearOutputData();
|
font->ClearOutputData();
|
||||||
if (atlas->FontLoader && atlas->FontLoader->FontSrcDestroy != NULL)
|
for (ImFontConfig& font_cfg : atlas->Sources)
|
||||||
for (ImFontConfig& font_cfg : atlas->Sources)
|
{
|
||||||
atlas->FontLoader->FontSrcDestroy(atlas, &font_cfg);
|
const ImFontLoader* loader = font_cfg.FontLoader ? font_cfg.FontLoader : atlas->FontLoader;
|
||||||
|
if (loader && loader->FontSrcDestroy != NULL)
|
||||||
|
loader->FontSrcDestroy(atlas, &font_cfg);
|
||||||
|
}
|
||||||
|
|
||||||
IM_DELETE(atlas->Builder);
|
IM_DELETE(atlas->Builder);
|
||||||
atlas->Builder = NULL;
|
atlas->Builder = NULL;
|
||||||
@@ -4258,19 +4282,19 @@ ImFontGlyph* ImFontBaked::BuildLoadGlyph(ImWchar codepoint)
|
|||||||
ImFontConfig* srcs = (font->LockSingleSrcConfigIdx != -1) ? &font->Sources[font->LockSingleSrcConfigIdx] : font->Sources;
|
ImFontConfig* srcs = (font->LockSingleSrcConfigIdx != -1) ? &font->Sources[font->LockSingleSrcConfigIdx] : font->Sources;
|
||||||
|
|
||||||
// Call backend
|
// Call backend
|
||||||
const ImFontLoader* font_loader = atlas->FontLoader;
|
char* loader_user_data_p = (char*)baked->FontLoaderDatas;
|
||||||
char* backend_user_data_p = (char*)baked->FontLoaderDatas;
|
|
||||||
for (int src_n = 0; src_n < srcs_count; src_n++)
|
for (int src_n = 0; src_n < srcs_count; src_n++)
|
||||||
{
|
{
|
||||||
ImFontConfig* src = &srcs[src_n];
|
ImFontConfig* src = &srcs[src_n];
|
||||||
|
const ImFontLoader* loader = src->FontLoader ? src->FontLoader : atlas->FontLoader;
|
||||||
if (!src->GlyphExcludeRanges || ImFontAtlasBuildAcceptCodepointForSource(src, codepoint))
|
if (!src->GlyphExcludeRanges || ImFontAtlasBuildAcceptCodepointForSource(src, codepoint))
|
||||||
if (font_loader->FontBakedAddGlyph(atlas, src, baked, backend_user_data_p, codepoint))
|
if (loader->FontBakedAddGlyph(atlas, src, baked, loader_user_data_p, codepoint))
|
||||||
{
|
{
|
||||||
// FIXME: Add hooks for e.g. #7962
|
// FIXME: Add hooks for e.g. #7962
|
||||||
ImFontGlyph* glyph = &baked->Glyphs.back();
|
ImFontGlyph* glyph = &baked->Glyphs.back();
|
||||||
return glyph;
|
return glyph;
|
||||||
}
|
}
|
||||||
backend_user_data_p += font_loader->FontBakedSrcLoaderDataSize;
|
loader_user_data_p += loader->FontBakedSrcLoaderDataSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark index as not found, so we don't attempt the search twice
|
// Mark index as not found, so we don't attempt the search twice
|
||||||
@@ -5017,8 +5041,12 @@ bool ImFont::IsGlyphInFont(ImWchar c)
|
|||||||
{
|
{
|
||||||
ImFontAtlas* atlas = ContainerAtlas;
|
ImFontAtlas* atlas = ContainerAtlas;
|
||||||
for (int src_n = 0; src_n < SourcesCount; src_n++)
|
for (int src_n = 0; src_n < SourcesCount; src_n++)
|
||||||
if (atlas->FontLoader->FontSrcContainsGlyph(atlas, &Sources[src_n], c))
|
{
|
||||||
|
ImFontConfig* src = &Sources[src_n];
|
||||||
|
const ImFontLoader* loader = src->FontLoader ? src->FontLoader : atlas->FontLoader;
|
||||||
|
if (loader->FontSrcContainsGlyph != NULL && loader->FontSrcContainsGlyph(atlas, src, c))
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user