Fonts: Baked system, with auto-bind, v10.

# Conflicts:
#	imgui_internal.h
This commit is contained in:
ocornut
2025-01-23 15:46:22 +01:00
parent 7aba8da551
commit 093d01269a
7 changed files with 545 additions and 296 deletions
+60 -34
View File
@@ -3738,7 +3738,8 @@ void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, con
const float font_size = draw_list->_Data->FontSize; const float font_size = draw_list->_Data->FontSize;
const float font_scale = draw_list->_Data->FontScale; const float font_scale = draw_list->_Data->FontScale;
const char* text_end_ellipsis = NULL; const char* text_end_ellipsis = NULL;
const float ellipsis_width = font->GetCharAdvance(font->EllipsisChar) * font_scale; ImFontBaked* baked = font->GetFontBaked(font_size);
const float ellipsis_width = baked->GetCharAdvance(font->EllipsisChar) * font_scale;
// We can now claim the space between pos_max.x and ellipsis_max.x // We can now claim the space between pos_max.x and ellipsis_max.x
const float text_avail_width = ImMax((ImMax(pos_max.x, ellipsis_max_x) - ellipsis_width) - pos_min.x, 1.0f); const float text_avail_width = ImMax((ImMax(pos_max.x, ellipsis_max_x) - ellipsis_width) - pos_min.x, 1.0f);
@@ -3939,7 +3940,8 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas)
Initialized = false; Initialized = false;
FontAtlasOwnedByContext = shared_font_atlas ? false : true; FontAtlasOwnedByContext = shared_font_atlas ? false : true;
Font = NULL; Font = NULL;
FontSize = FontBaseSize = FontScale = CurrentDpiScale = 0.0f; FontBaked = NULL;
FontSize = /*FontBaseSize = */FontScale = CurrentDpiScale = 0.0f;
IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)(); IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)();
IO.Fonts->RefCount++; IO.Fonts->RefCount++;
Time = 0.0f; Time = 0.0f;
@@ -4275,6 +4277,7 @@ void ImGui::Shutdown()
g.MenusIdSubmittedThisFrame.clear(); g.MenusIdSubmittedThisFrame.clear();
g.InputTextState.ClearFreeMemory(); g.InputTextState.ClearFreeMemory();
g.InputTextDeactivatedState.ClearFreeMemory(); g.InputTextDeactivatedState.ClearFreeMemory();
g.InputTextPasswordFont.ContainerAtlas = NULL;
g.SettingsWindows.clear(); g.SettingsWindows.clear();
g.SettingsHandlers.clear(); g.SettingsHandlers.clear();
@@ -4371,8 +4374,9 @@ static void SetCurrentWindow(ImGuiWindow* window)
g.CurrentDpiScale = 1.0f; // FIXME-DPI: WIP this is modified in docking g.CurrentDpiScale = 1.0f; // FIXME-DPI: WIP this is modified in docking
if (window) if (window)
{ {
g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize(); // FIXME-BAKED
g.FontScale = g.DrawListSharedData.FontScale = g.FontSize / g.Font->FontSize; //g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize();
//g.FontScale = g.DrawListSharedData.FontScale = g.FontSize / g.Font->FontSize;
ImGui::NavUpdateCurrentWindowIsScrollPushableX(); ImGui::NavUpdateCurrentWindowIsScrollPushableX();
} }
} }
@@ -5186,7 +5190,7 @@ static void ImGui::UpdateTexturesNewFrame()
if (g.FontAtlasOwnedByContext) if (g.FontAtlasOwnedByContext)
{ {
atlas->RendererHasTextures = (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasTextures) != 0; atlas->RendererHasTextures = (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasTextures) != 0;
ImFontAtlasUpdateNewFrame(atlas); ImFontAtlasUpdateNewFrame(atlas, g.FrameCount);
} }
} }
@@ -8399,11 +8403,14 @@ ImVec2 ImGui::GetFontTexUvWhitePixel()
void ImGui::SetWindowFontScale(float scale) void ImGui::SetWindowFontScale(float scale)
{ {
IM_ASSERT(scale > 0.0f); IM_ASSERT(scale > 0.0f);
// FIXME-BAKED
/*
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
window->FontWindowScale = scale; window->FontWindowScale = scale;
g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize(); g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize();
g.FontScale = g.DrawListSharedData.FontScale = g.FontSize / g.Font->FontSize; g.FontScale = g.DrawListSharedData.FontScale = g.FontSize / g.Font->FontSize;
*/
} }
void ImGui::PushFocusScope(ImGuiID id) void ImGui::PushFocusScope(ImGuiID id)
@@ -8570,20 +8577,21 @@ void ImGui::UpdateFontsNewFrame()
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
if ((g.IO.BackendFlags & ImGuiBackendFlags_RendererHasTextures) == 0) if ((g.IO.BackendFlags & ImGuiBackendFlags_RendererHasTextures) == 0)
g.IO.Fonts->Locked = true; g.IO.Fonts->Locked = true;
SetCurrentFont(GetDefaultFont()); SetCurrentFont(GetDefaultFont(), GetDefaultFont()->Sources[0].SizePixels);
IM_ASSERT(g.Font->IsLoaded()); IM_ASSERT(g.Font->IsLoaded());
} }
// Important: this alone doesn't alter current ImDrawList state. This is called by PushFont/PopFont only. // Important: this alone doesn't alter current ImDrawList state. This is called by PushFont/PopFont only.
void ImGui::SetCurrentFont(ImFont* font) void ImGui::SetCurrentFont(ImFont* font, float font_size)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
IM_ASSERT(font && font->IsLoaded()); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ? IM_ASSERT(font && font->IsLoaded()); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ?
IM_ASSERT(font->Scale > 0.0f); IM_ASSERT(font->Scale > 0.0f);
g.Font = font; g.Font = font;
g.FontBaseSize = ImMax(1.0f, g.IO.FontGlobalScale * g.Font->FontSize * g.Font->Scale); //g.FontBaseSize = ImMax(1.0f, g.IO.FontGlobalScale * g.FontBaked->Size * g.Font->Scale);
g.FontSize = g.CurrentWindow ? g.CurrentWindow->CalcFontSize() : 0.0f; g.FontSize = font_size;// g.CurrentWindow ? g.CurrentWindow->CalcFontSize() : 0.0f;
g.FontScale = g.FontSize / g.Font->FontSize; g.FontBaked = g.Font->GetFontBaked(g.FontSize);
g.FontScale = g.FontSize / g.FontBaked->Size;
g.DrawListSharedData.Font = g.Font; g.DrawListSharedData.Font = g.Font;
g.DrawListSharedData.FontSize = g.FontSize; g.DrawListSharedData.FontSize = g.FontSize;
g.DrawListSharedData.FontScale = g.FontScale; g.DrawListSharedData.FontScale = g.FontScale;
@@ -8606,7 +8614,7 @@ void ImGui::PushFont(ImFont* font)
if (font == NULL) if (font == NULL)
font = GetDefaultFont(); font = GetDefaultFont();
g.FontStack.push_back(font); g.FontStack.push_back(font);
SetCurrentFont(font); SetCurrentFont(font, g.FontSize);
} }
void ImGui::PopFont() void ImGui::PopFont()
@@ -8619,7 +8627,14 @@ void ImGui::PopFont()
} }
g.FontStack.pop_back(); g.FontStack.pop_back();
ImFont* font = g.FontStack.Size == 0 ? GetDefaultFont() : g.FontStack.back(); ImFont* font = g.FontStack.Size == 0 ? GetDefaultFont() : g.FontStack.back();
SetCurrentFont(font); SetCurrentFont(font, g.FontSize); // FIXME-BAKED: size in stack
}
void ImGui::SetFontSize(float size)
{
// FIXME-BAKED
ImGuiContext& g = *GImGui;
SetCurrentFont(g.Font, size);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -15512,7 +15527,7 @@ void ImGui::DebugTextEncoding(const char* str)
} }
TableNextColumn(); TableNextColumn();
TextUnformatted(p, p + c_utf8_len); TextUnformatted(p, p + c_utf8_len);
if (GetFont()->FindGlyphNoFallback((ImWchar)c) == NULL) if (!GetFont()->IsGlyphInFont((ImWchar)c))
{ {
SameLine(); SameLine();
TextUnformatted("[missing]"); TextUnformatted("[missing]");
@@ -16478,8 +16493,8 @@ void ImGui::DebugNodeFont(ImFont* font)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiMetricsConfig* cfg = &g.DebugMetricsConfig; ImGuiMetricsConfig* cfg = &g.DebugMetricsConfig;
bool opened = TreeNode(font, "Font: \"%s\": %.2f px, %d glyphs, %d sources(s)", ImFontAtlas* atlas = font->ContainerAtlas;
font->Sources ? font->Sources[0].Name : "", font->FontSize, font->Glyphs.Size, font->SourcesCount); bool opened = TreeNode(font, "Font: \"%s\": %d sources(s)", font->Sources ? font->Sources[0].Name : "", font->SourcesCount);
// Display preview text // Display preview text
if (!opened) if (!opened)
@@ -16499,11 +16514,11 @@ void ImGui::DebugNodeFont(ImFont* font)
} }
if (SmallButton("Set as default")) if (SmallButton("Set as default"))
GetIO().FontDefault = font; GetIO().FontDefault = font;
if (font->ContainerAtlas->Fonts.Size > 1 && !font->ContainerAtlas->Locked) if (atlas->Fonts.Size > 1 && !atlas->Locked)
{ {
SameLine(); SameLine();
if (SmallButton("Remove")) if (SmallButton("Remove"))
font->ContainerAtlas->RemoveFont(font); atlas->RemoveFont(font);
} }
// Display details // Display details
@@ -16515,33 +16530,43 @@ void ImGui::DebugNodeFont(ImFont* font)
"You may oversample them to get some flexibility with scaling. " "You may oversample them to get some flexibility with scaling. "
"You can also render at multiple sizes and select which one to use at runtime.\n\n" "You can also render at multiple sizes and select which one to use at runtime.\n\n"
"(Glimmer of hope: the atlas system will be rewritten in the future to make scaling more flexible.)"); "(Glimmer of hope: the atlas system will be rewritten in the future to make scaling more flexible.)");
Text("Ascent: %f, Descent: %f, Height: %f", font->Ascent, font->Descent, font->Ascent - font->Descent);
char c_str[5]; char c_str[5];
Text("Fallback character: '%s' (U+%04X)", ImTextCharToUtf8(c_str, font->FallbackChar), font->FallbackChar); Text("Fallback character: '%s' (U+%04X)", ImTextCharToUtf8(c_str, font->FallbackChar), font->FallbackChar);
Text("Ellipsis character: '%s' (U+%04X)", ImTextCharToUtf8(c_str, font->EllipsisChar), font->EllipsisChar); Text("Ellipsis character: '%s' (U+%04X)", ImTextCharToUtf8(c_str, font->EllipsisChar), font->EllipsisChar);
const int surface_sqrt = (int)ImSqrt((float)font->MetricsTotalSurface); for (int src_n = 0; src_n < font->SourcesCount; src_n++)
Text("Texture Area: about %d px ~%dx%d px", font->MetricsTotalSurface, surface_sqrt, surface_sqrt); if (ImFontConfig* src = &font->Sources[src_n])
for (int config_i = 0; config_i < font->SourcesCount; config_i++) BulletText("Input %d: \'%s\', Oversample: %d,%d, PixelSnapH: %d, Offset: (%.1f,%.1f)",
if (font->Sources) src_n, src->Name, src->OversampleH, src->OversampleV, src->PixelSnapH, src->GlyphOffset.x, src->GlyphOffset.y);
{
ImFontConfig* src = &font->Sources[config_i];
int oversample_h, oversample_v;
ImFontAtlasBuildGetOversampleFactors(src, &oversample_h, &oversample_v);
BulletText("Input %d: \'%s\', Oversample: (%d=>%d,%d=>%d), PixelSnapH: %d, Offset: (%.1f,%.1f)",
config_i, src->Name, src->OversampleH, oversample_h, src->OversampleV, oversample_v, src->PixelSnapH, src->GlyphOffset.x, src->GlyphOffset.y);
}
// Display all glyphs of the fonts in separate pages of 256 characters // Display all glyphs of the fonts in separate pages of 256 characters
for (int baked_n = 0; baked_n < atlas->Builder->BakedPool.Size; baked_n++)
{ {
if (TreeNode("Glyphs", "Glyphs (%d)", font->Glyphs.Size)) ImFontBaked* baked = &atlas->Builder->BakedPool[baked_n];
if (baked->ContainerFont != font)
continue;
PushID(baked_n);
if (TreeNode("Glyphs", "Baked at %.2fpx: %d glyphs%s", baked->Size, baked->Glyphs.Size, (baked->LastUsedFrame < atlas->Builder->FrameCount - 1) ? " *Unused*" : ""))
{ {
if (SmallButton("Load all")) if (SmallButton("Load all"))
for (unsigned int base = 0; base <= IM_UNICODE_CODEPOINT_MAX; base++) for (unsigned int base = 0; base <= IM_UNICODE_CODEPOINT_MAX; base++)
font->FindGlyph((ImWchar)base); baked->FindGlyph((ImWchar)base);
const int surface_sqrt = (int)ImSqrt((float)baked->MetricsTotalSurface);
Text("Ascent: %f, Descent: %f, Ascent-Descent: %f", baked->Ascent, baked->Descent, baked->Ascent - baked->Descent);
Text("Texture Area: about %d px ~%dx%d px", baked->MetricsTotalSurface, surface_sqrt, surface_sqrt);
for (int src_n = 0; src_n < font->SourcesCount; src_n++)
{
ImFontConfig* src = &font->Sources[src_n];
int oversample_h, oversample_v;
ImFontAtlasBuildGetOversampleFactors(src, baked->Size, &oversample_h, &oversample_v);
BulletText("Input %d: \'%s\', Oversample: (%d=>%d,%d=>%d), PixelSnapH: %d, Offset: (%.1f,%.1f)",
src_n, src->Name, src->OversampleH, oversample_h, src->OversampleV, oversample_v, src->PixelSnapH, src->GlyphOffset.x, src->GlyphOffset.y);
}
ImDrawList* draw_list = GetWindowDrawList(); ImDrawList* draw_list = GetWindowDrawList();
const ImU32 glyph_col = GetColorU32(ImGuiCol_Text); const ImU32 glyph_col = GetColorU32(ImGuiCol_Text);
const float cell_size = font->FontSize * 1; const float cell_size = baked->Size * 1;
const float cell_spacing = GetStyle().ItemSpacing.y; const float cell_spacing = GetStyle().ItemSpacing.y;
for (unsigned int base = 0; base <= IM_UNICODE_CODEPOINT_MAX; base += 256) for (unsigned int base = 0; base <= IM_UNICODE_CODEPOINT_MAX; base += 256)
{ {
@@ -16556,7 +16581,7 @@ void ImGui::DebugNodeFont(ImFont* font)
int count = 0; int count = 0;
for (unsigned int n = 0; n < 256; n++) for (unsigned int n = 0; n < 256; n++)
if (font->IsGlyphLoaded((ImWchar)(base + n))) if (baked->IsGlyphLoaded((ImWchar)(base + n)))
count++; count++;
if (count <= 0) if (count <= 0)
continue; continue;
@@ -16571,7 +16596,7 @@ void ImGui::DebugNodeFont(ImFont* font)
// available here and thus cannot easily generate a zero-terminated UTF-8 encoded string. // available here and thus cannot easily generate a zero-terminated UTF-8 encoded string.
ImVec2 cell_p1(base_pos.x + (n % 16) * (cell_size + cell_spacing), base_pos.y + (n / 16) * (cell_size + cell_spacing)); ImVec2 cell_p1(base_pos.x + (n % 16) * (cell_size + cell_spacing), base_pos.y + (n / 16) * (cell_size + cell_spacing));
ImVec2 cell_p2(cell_p1.x + cell_size, cell_p1.y + cell_size); ImVec2 cell_p2(cell_p1.x + cell_size, cell_p1.y + cell_size);
const ImFontGlyph* glyph = font->IsGlyphLoaded((ImWchar)(base + n)) ? font->FindGlyph((ImWchar)(base + n)) : NULL; const ImFontGlyph* glyph = baked->IsGlyphLoaded((ImWchar)(base + n)) ? baked->FindGlyph((ImWchar)(base + n)) : NULL;
draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255, 255, 255, 100) : IM_COL32(255, 255, 255, 50)); draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255, 255, 255, 100) : IM_COL32(255, 255, 255, 50));
if (!glyph) if (!glyph)
continue; continue;
@@ -16587,6 +16612,7 @@ void ImGui::DebugNodeFont(ImFont* font)
} }
TreePop(); TreePop();
} }
PopID();
} }
TreePop(); TreePop();
Unindent(); Unindent();
+44 -18
View File
@@ -50,7 +50,7 @@ Index of this file:
// [SECTION] Multi-Select API flags and structures (ImGuiMultiSelectFlags, ImGuiMultiSelectIO, ImGuiSelectionRequest, ImGuiSelectionBasicStorage, ImGuiSelectionExternalStorage) // [SECTION] Multi-Select API flags and structures (ImGuiMultiSelectFlags, ImGuiMultiSelectIO, ImGuiSelectionRequest, ImGuiSelectionBasicStorage, ImGuiSelectionExternalStorage)
// [SECTION] Drawing API (ImDrawCallback, ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawFlags, ImDrawListFlags, ImDrawList, ImDrawData) // [SECTION] Drawing API (ImDrawCallback, ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawFlags, ImDrawListFlags, ImDrawList, ImDrawData)
// [SECTION] Texture API (ImTextureFormat, ImTextureStatus, ImTextureRect, ImTextureData) // [SECTION] Texture API (ImTextureFormat, ImTextureStatus, ImTextureRect, ImTextureData)
// [SECTION] Font API (ImFontConfig, ImFontGlyph, ImFontGlyphRangesBuilder, ImFontAtlasFlags, ImFontAtlas, ImFont) // [SECTION] Font API (ImFontConfig, ImFontGlyph, ImFontGlyphRangesBuilder, ImFontAtlasFlags, ImFontAtlas, ImFontBaked, ImFont)
// [SECTION] Viewports (ImGuiViewportFlags, ImGuiViewport) // [SECTION] Viewports (ImGuiViewportFlags, ImGuiViewport)
// [SECTION] ImGuiPlatformIO + other Platform Dependent Interfaces (ImGuiPlatformImeData) // [SECTION] ImGuiPlatformIO + other Platform Dependent Interfaces (ImGuiPlatformImeData)
// [SECTION] Obsolete functions and types // [SECTION] Obsolete functions and types
@@ -172,6 +172,7 @@ struct ImDrawVert; // A single vertex (pos + uv + col = 20 byte
struct ImFont; // Runtime data for a single font within a parent ImFontAtlas struct ImFont; // Runtime data for a single font within a parent ImFontAtlas
struct ImFontAtlas; // Runtime data for multiple fonts, bake multiple fonts into a single texture, TTF/OTF font loader struct ImFontAtlas; // Runtime data for multiple fonts, bake multiple fonts into a single texture, TTF/OTF font loader
struct ImFontAtlasBuilder; // Opaque storage for building a ImFontAtlas struct ImFontAtlasBuilder; // Opaque storage for building a ImFontAtlas
struct ImFontBaked; // Baked data for a ImFont at a given size.
struct ImFontConfig; // Configuration data when adding a font or merging fonts struct ImFontConfig; // Configuration data when adding a font or merging fonts
struct ImFontGlyph; // A single font glyph (code point + coordinates within in ImFontAtlas + offset) struct ImFontGlyph; // A single font glyph (code point + coordinates within in ImFontAtlas + offset)
struct ImFontGlyphRangesBuilder; // Helper to build glyph ranges from text/string data struct ImFontGlyphRangesBuilder; // Helper to build glyph ranges from text/string data
@@ -471,6 +472,8 @@ namespace ImGui
// Parameters stacks (shared) // Parameters stacks (shared)
IMGUI_API void PushFont(ImFont* font); // use NULL as a shortcut to push default font IMGUI_API void PushFont(ImFont* font); // use NULL as a shortcut to push default font
IMGUI_API void PopFont(); IMGUI_API void PopFont();
IMGUI_API void SetFontSize(float size);
//IMGUI_API void PopFontSize();
IMGUI_API void PushStyleColor(ImGuiCol idx, ImU32 col); // modify a style color. always use this if you modify the style after NewFrame(). IMGUI_API void PushStyleColor(ImGuiCol idx, ImU32 col); // modify a style color. always use this if you modify the style after NewFrame().
IMGUI_API void PushStyleColor(ImGuiCol idx, const ImVec4& col); IMGUI_API void PushStyleColor(ImGuiCol idx, const ImVec4& col);
IMGUI_API void PopStyleColor(int count = 1); IMGUI_API void PopStyleColor(int count = 1);
@@ -3419,10 +3422,10 @@ struct ImFontConfig
int OversampleV; // 0 (1) // Rasterize at higher quality for sub-pixel positioning. 0 == auto == 1. This is not really useful as we don't use sub-pixel positions on the Y axis. int OversampleV; // 0 (1) // Rasterize at higher quality for sub-pixel positioning. 0 == auto == 1. This is not really useful as we don't use sub-pixel positions on the Y axis.
float SizePixels; // // Size in pixels for rasterizer (more or less maps to the resulting font height). float SizePixels; // // Size in pixels for rasterizer (more or less maps to the resulting font height).
//ImVec2 GlyphExtraSpacing; // 0, 0 // (REMOVED IN 1.91.9: use GlyphExtraAdvanceX) //ImVec2 GlyphExtraSpacing; // 0, 0 // (REMOVED IN 1.91.9: use GlyphExtraAdvanceX)
ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input. ImVec2 GlyphOffset; // 0, 0 // [FIXME-BAKED] Offset all glyphs from this font input.
const ImWchar* GlyphRanges; // NULL // THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). const ImWchar* GlyphRanges; // NULL // THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list).
float GlyphMinAdvanceX; // 0 // Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font float GlyphMinAdvanceX; // 0 // [FIXME-BAKED] Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font
float GlyphMaxAdvanceX; // FLT_MAX // Maximum AdvanceX for glyphs float GlyphMaxAdvanceX; // FLT_MAX // [FIXME-BAKED] Maximum AdvanceX for glyphs
float GlyphExtraAdvanceX; // 0 // Extra spacing (in pixels) between glyphs. Please contact us if you are using this. float GlyphExtraAdvanceX; // 0 // Extra spacing (in pixels) between glyphs. Please contact us if you are using this.
unsigned int FontBuilderFlags; // 0 // Settings for custom font builder. THIS IS BUILDER IMPLEMENTATION DEPENDENT. Leave as zero if unsure. unsigned int FontBuilderFlags; // 0 // Settings for custom font builder. THIS IS BUILDER IMPLEMENTATION DEPENDENT. Leave as zero if unsure.
float RasterizerMultiply; // 1.0f // Linearly brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable. This is a silly thing we may remove in the future. float RasterizerMultiply; // 1.0f // Linearly brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable. This is a silly thing we may remove in the future.
@@ -3599,6 +3602,7 @@ struct ImFontAtlas
ImVector<ImFontConfig> Sources; // Source/configuration data ImVector<ImFontConfig> Sources; // Source/configuration data
ImVec4 TexUvLines[IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1]; // UVs for baked anti-aliased lines ImVec4 TexUvLines[IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1]; // UVs for baked anti-aliased lines
int TexNextUniqueID; // Next value to be stored in TexData->UniqueID int TexNextUniqueID; // Next value to be stored in TexData->UniqueID
int FontNextUniqueID; // Next value to be stored in ImFont->SourceID
ImVector<ImDrawListSharedData*> DrawListSharedDatas; ImVector<ImDrawListSharedData*> DrawListSharedDatas;
// [Internal] Font builder // [Internal] Font builder
@@ -3616,30 +3620,57 @@ struct ImFontAtlas
//typedef ImFontGlyphRangesBuilder GlyphRangesBuilder; // OBSOLETED in 1.67+ //typedef ImFontGlyphRangesBuilder GlyphRangesBuilder; // OBSOLETED in 1.67+
}; };
// Font runtime data and rendering // Font runtime data for a given size
// ImFontAtlas automatically loads a default embedded font for you when you call GetTexDataAsAlpha8() or GetTexDataAsRGBA32(). // Important: pointers to ImFontBaked are only valid for the current frame.
struct ImFont struct ImFontBaked
{ {
// [Internal] Members: Hot ~20/24 bytes (for CalcTextSize) // [Internal] Members: Hot ~20/24 bytes (for CalcTextSize)
ImVector<float> IndexAdvanceX; // 12-16 // out // Sparse. Glyphs->AdvanceX in a directly indexable way (cache-friendly for CalcTextSize functions which only this info, and are often bottleneck in large UI). ImVector<float> IndexAdvanceX; // 12-16 // out // Sparse. Glyphs->AdvanceX in a directly indexable way (cache-friendly for CalcTextSize functions which only this info, and are often bottleneck in large UI).
float FallbackAdvanceX; // 4 // out // FindGlyph(FallbackChar)->AdvanceX float FallbackAdvanceX; // 4 // out // FindGlyph(FallbackChar)->AdvanceX
float FontSize; // 4 // in // Height of characters/line, set during loading (don't change after loading) float Size; // 4 // in // Height of characters/line, set during loading (doesn't change after loading)
// [Internal] Members: Hot ~28/36 bytes (for RenderText loop) // [Internal] Members: Hot ~28/36 bytes (for RenderText loop)
ImVector<ImU16> IndexLookup; // 12-16 // out // Sparse. Index glyphs by Unicode code-point. ImVector<ImU16> IndexLookup; // 12-16 // out // Sparse. Index glyphs by Unicode code-point.
ImVector<ImFontGlyph> Glyphs; // 12-16 // out // All glyphs. ImVector<ImFontGlyph> Glyphs; // 12-16 // out // All glyphs.
int FallbackGlyphIndex; // 4 // out // Index of FontFallbackChar int FallbackGlyphIndex; // 4 // out // Index of FontFallbackChar
// [Internal] Members: Cold ~32/40/60 bytes // [Internal] Members: Cold
float Ascent, Descent; // 4+4 // out // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize] (unscaled)
unsigned int MetricsTotalSurface:26;// 3 // out // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs)
unsigned int WantDestroy:1; // 1 // // Queued for destroy
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)
// Functions
IMGUI_API ImFontBaked();
IMGUI_API void ClearOutputData();
IMGUI_API ImFontGlyph* FindGlyph(ImWchar c); // Return U+FFFD glyph if requested glyph doesn't exists.
IMGUI_API ImFontGlyph* FindGlyphNoFallback(ImWchar c); // Return NULL if glyph doesn't exist
IMGUI_API float GetCharAdvance(ImWchar c);
IMGUI_API bool IsGlyphLoaded(ImWchar c);
IMGUI_API ImFontGlyph* BuildLoadGlyph(ImWchar c);
IMGUI_API void BuildGrowIndex(int new_size);
};
// Font runtime data and rendering
// - ImFontAtlas automatically loads a default embedded font for you if you didn't load one manually.
// - Since 1.92.X a font may be rendered as any size! Therefore a font doesn't have one specific size.
// - Use 'font->GetBakedForSize(size)' to retrieve the ImFontBaked* corresponding to a given size.
// - If you used g.Font + g.FontSize (which is frequent from the ImGui layer), you can use g.FontBaked as a shortcut, as g.FontBaked == g.Font->GetBakedForSize(g.FontSize).
struct ImFont
{
// [Internal] Members: Cold ~32/40/80 bytes
// Conceptually Sources[] is the list of font sources merged to create this font. // Conceptually Sources[] is the list of font sources merged to create this font.
ImFontBaked* LastBaked; // Cache last bound baked. DO NOT USE. Use GetFontBaked().
ImGuiID FontId; // Unique identifier for the font
short SourcesCount; // 2 // in // Number of ImFontConfig involved in creating this font. Usually 1, or >1 when merging multiple font sources into one ImFont. short SourcesCount; // 2 // in // Number of ImFontConfig involved in creating this font. Usually 1, or >1 when merging multiple font sources into one ImFont.
ImFontConfig* Sources; // 4-8 // in // Pointer within ContainerAtlas->Sources[], to SourcesCount instances ImFontConfig* Sources; // 4-8 // in // Pointer within ContainerAtlas->Sources[], to SourcesCount instances
ImFontAtlas* ContainerAtlas; // 4-8 // out // What we has been loaded into ImFontAtlas* ContainerAtlas; // 4-8 // out // What we has been loaded into
ImWchar EllipsisChar; // 2-4 // out // Character used for ellipsis rendering ('...'). ImWchar EllipsisChar; // 2-4 // out // Character used for ellipsis rendering ('...').
ImWchar FallbackChar; // 2-4 // out // Character used if a glyph isn't found (U+FFFD, '?') ImWchar FallbackChar; // 2-4 // out // Character used if a glyph isn't found (U+FFFD, '?')
float Scale; // 4 // in // Base font scale (~1.0f), multiplied by the per-window font scale which you can adjust with SetWindowFontScale() float Scale; // 4 // in // Base font scale (~1.0f), multiplied by the per-window font scale which you can adjust with SetWindowFontScale()
float Ascent, Descent; // 4+4 // out // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize] (unscaled)
int MetricsTotalSurface;// 4 // out // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs)
ImU8 Used8kPagesMap[(IM_UNICODE_CODEPOINT_MAX+1)/8192/8]; // 1 bytes if ImWchar=ImWchar16, 16 bytes if ImWchar==ImWchar32. Store 1-bit for each block of 4K codepoints that has one active glyph. This is mainly used to facilitate iterations across all used codepoints. ImU8 Used8kPagesMap[(IM_UNICODE_CODEPOINT_MAX+1)/8192/8]; // 1 bytes if ImWchar=ImWchar16, 16 bytes if ImWchar==ImWchar32. Store 1-bit for each block of 4K codepoints that has one active glyph. This is mainly used to facilitate iterations across all used codepoints.
bool LockDisableLoading; bool LockDisableLoading;
short LockSingleSrcConfigIdx; short LockSingleSrcConfigIdx;
@@ -3647,10 +3678,7 @@ struct ImFont
// Methods // Methods
IMGUI_API ImFont(); IMGUI_API ImFont();
IMGUI_API ~ImFont(); IMGUI_API ~ImFont();
IMGUI_API ImFontGlyph* FindGlyph(ImWchar c); // Return fallback glyph if requested glyph doesn't exists. IMGUI_API ImFontBaked* GetFontBaked(float font_size); // Get or create baked data for given size
IMGUI_API ImFontGlyph* FindGlyphNoFallback(ImWchar c); // Return NULL if glyph doesn't exist
IMGUI_API float GetCharAdvance(ImWchar c);
IMGUI_API bool IsGlyphLoaded(ImWchar c);
IMGUI_API bool IsGlyphInFont(ImWchar c); IMGUI_API bool IsGlyphInFont(ImWchar c);
bool IsLoaded() const { return ContainerAtlas != NULL; } bool IsLoaded() const { return ContainerAtlas != NULL; }
const char* GetDebugName() const { return Sources ? Sources->Name : "<unknown>"; } const char* GetDebugName() const { return Sources ? Sources->Name : "<unknown>"; }
@@ -3664,15 +3692,13 @@ struct ImFont
IMGUI_API void RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false); IMGUI_API void RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false);
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
inline const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) { return CalcWordWrapPosition(FontSize * scale, text, text_end, wrap_width); } inline const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) { return CalcWordWrapPosition(Sources[0].SizePixels * scale, text, text_end, wrap_width); }
#endif #endif
// [Internal] Don't use! // [Internal] Don't use!
IMGUI_API void ClearOutputData(); IMGUI_API void ClearOutputData();
IMGUI_API void AddRemapChar(ImWchar from_codepoint, ImWchar to_codepoint, bool overwrite_dst);// , bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built. IMGUI_API void AddRemapChar(ImWchar from_codepoint, ImWchar to_codepoint, bool overwrite_dst);// , bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built.
IMGUI_API bool IsGlyphRangeUnused(unsigned int c_begin, unsigned int c_last); IMGUI_API bool IsGlyphRangeUnused(unsigned int c_begin, unsigned int c_last);
IMGUI_API ImFontGlyph* BuildLoadGlyph(ImWchar c);
IMGUI_API void BuildGrowIndex(int new_size);
}; };
// Added indirection to avoid patching ImDrawCmd after texture updates. // Added indirection to avoid patching ImDrawCmd after texture updates.
+310 -166
View File
File diff suppressed because it is too large Load Diff
+26 -13
View File
@@ -2130,11 +2130,12 @@ struct ImGuiContext
ImGuiIO IO; ImGuiIO IO;
ImGuiPlatformIO PlatformIO; ImGuiPlatformIO PlatformIO;
ImGuiStyle Style; ImGuiStyle Style;
ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() ImFont* Font; // == FontStack.back().Font
float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window. ImFontBaked* FontBaked; // == Font->GetFontBaked(FontSize)
float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height. float FontSize; // == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window.
float FontScale; // == FontSize / Font->FontSize //float FontBaseSize; // == io.FontGlobalScale * Font->Scale * Font->FontSize. Base text height.
float CurrentDpiScale; // Current window/viewport DpiScale float FontScale; // == FontBaked->Size / Font->FontSize. Scale factor over baked size.
float CurrentDpiScale; // Current window/viewport DpiScale == CurrentViewport->DpiScale
ImDrawListSharedData DrawListSharedData; ImDrawListSharedData DrawListSharedData;
ImVector<ImTextureData*>Textures; ImVector<ImTextureData*>Textures;
double Time; double Time;
@@ -2673,7 +2674,7 @@ public:
// We don't use g.FontSize because the window may be != g.CurrentWindow. // We don't use g.FontSize because the window may be != g.CurrentWindow.
ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); } ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
float CalcFontSize() const { ImGuiContext& g = *Ctx; return g.FontBaseSize * FontWindowScale * FontWindowScaleParents; } //float CalcFontSize() const { ImGuiContext& g = *Ctx; return g.FontBaseSize * FontWindowScale * FontWindowScaleParents; }
ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight)); } ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight)); }
ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight; return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight); } ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight; return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight); }
}; };
@@ -3098,7 +3099,7 @@ namespace ImGui
IMGUI_API void SetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags flags); IMGUI_API void SetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags flags);
// Fonts, drawing // Fonts, drawing
IMGUI_API void SetCurrentFont(ImFont* font); IMGUI_API void SetCurrentFont(ImFont* font, float font_size);
inline ImFont* GetDefaultFont() { ImGuiContext& g = *GImGui; return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; } inline ImFont* GetDefaultFont() { ImGuiContext& g = *GImGui; return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; }
IMGUI_API void PushPasswordFont(); IMGUI_API void PushPasswordFont();
inline ImDrawList* GetForegroundDrawList(ImGuiWindow* window) { IM_UNUSED(window); return GetForegroundDrawList(); } // This seemingly unnecessary wrapper simplifies compatibility between the 'master' and 'docking' branches. inline ImDrawList* GetForegroundDrawList(ImGuiWindow* window) { IM_UNUSED(window); return GetForegroundDrawList(); } // This seemingly unnecessary wrapper simplifies compatibility between the 'master' and 'docking' branches.
@@ -3661,7 +3662,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);
bool (*FontAddGlyph)(ImFontAtlas* atlas, ImFont* font, ImFontConfig* srcs, int srcs_count, 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);
ImFontLoader() { memset(this, 0, sizeof(*this)); } ImFontLoader() { memset(this, 0, sizeof(*this)); }
}; };
@@ -3698,6 +3701,7 @@ struct ImFontAtlasPostProcessData
ImFontAtlas* FontAtlas; ImFontAtlas* FontAtlas;
ImFont* Font; ImFont* Font;
ImFontConfig* FontSrc; ImFontConfig* FontSrc;
ImFontBaked* FontBaked;
ImFontGlyph* Glyph; ImFontGlyph* Glyph;
// Pixel data // Pixel data
@@ -3723,11 +3727,17 @@ struct ImFontAtlasBuilder
int RectsPackedSurface; // Number of packed pixels. Used when compacting to heuristically find the ideal texture size. int RectsPackedSurface; // Number of packed pixels. Used when compacting to heuristically find the ideal texture size.
int RectsDiscardedCount; int RectsDiscardedCount;
int RectsDiscardedSurface; int RectsDiscardedSurface;
int FrameCount; // Current frame count
ImVec2i MaxRectSize; // Largest rectangle to pack (de-facto used as a "minimum texture size") ImVec2i MaxRectSize; // Largest rectangle to pack (de-facto used as a "minimum texture size")
ImVec2i MaxRectBounds; // Bottom-right most used pixels ImVec2i MaxRectBounds; // Bottom-right most used pixels
bool LockDisableResize; // Disable resizing texture bool LockDisableResize; // Disable resizing texture
bool PreloadedAllGlyphsRanges; // Set when missing ImGuiBackendFlags_RendererHasTextures features forces atlas to preload everything. bool PreloadedAllGlyphsRanges; // Set when missing ImGuiBackendFlags_RendererHasTextures features forces atlas to preload everything.
// Cache of all ImFontBaked
ImStableVector<ImFontBaked,32> BakedPool;
ImGuiStorage BakedMap;
int BakedDiscardedCount;
// Custom rectangle identifiers // Custom rectangle identifiers
ImFontAtlasRectId PackIdMouseCursors; // White pixel + mouse cursors. Also happen to be fallback in case of packing failure. ImFontAtlasRectId PackIdMouseCursors; // White pixel + mouse cursors. Also happen to be fallback in case of packing failure.
ImFontAtlasRectId PackIdLinesTexData; ImFontAtlasRectId PackIdLinesTexData;
@@ -3750,20 +3760,23 @@ IMGUI_API void ImFontAtlasBuildCompactTexture(ImFontAtlas* atlas);
IMGUI_API ImVec2i ImFontAtlasBuildGetTextureSizeEstimate(ImFontAtlas* atlas); IMGUI_API ImVec2i ImFontAtlasBuildGetTextureSizeEstimate(ImFontAtlas* atlas);
IMGUI_API bool ImFontAtlasBuildAddFont(ImFontAtlas* atlas, ImFontConfig* src); IMGUI_API bool ImFontAtlasBuildAddFont(ImFontAtlas* atlas, ImFontConfig* src);
IMGUI_API ImFontGlyph* ImFontAtlasBuildAddFontGlyph(ImFontAtlas* atlas, ImFont* font, ImFontConfig* src, const ImFontGlyph* in_glyph);
IMGUI_API void ImFontAtlasBuildSetupFontSpecialGlyphs(ImFontAtlas* atlas, ImFont* font, ImFontConfig* src); IMGUI_API void ImFontAtlasBuildSetupFontSpecialGlyphs(ImFontAtlas* atlas, ImFont* font, ImFontConfig* src);
IMGUI_API void ImFontAtlasBuildDiscardFontGlyph(ImFontAtlas* atlas, ImFont* font, ImFontGlyph* glyph); IMGUI_API void ImFontAtlasBuildDiscardUnusedBakes(ImFontAtlas* atlas, ImFont* font_filter);
IMGUI_API void ImFontAtlasBuildDiscardFontGlyphs(ImFontAtlas* atlas, ImFont* font); 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 ImFontAtlasBuildReloadFont(ImFontAtlas* atlas, ImFont* font); // <--- Your future new best friend! IMGUI_API void ImFontAtlasBuildReloadFont(ImFontAtlas* atlas, ImFont* font); // <--- Your future new best friend!
IMGUI_API void ImFontAtlasBuildPreloadAllGlyphRanges(ImFontAtlas* atlas); // Legacy IMGUI_API void ImFontAtlasBuildPreloadAllGlyphRanges(ImFontAtlas* atlas); // Legacy
IMGUI_API void ImFontAtlasBuildGetOversampleFactors(ImFontConfig* src, int* out_oversample_h, int* out_oversample_v); IMGUI_API void ImFontAtlasBuildGetOversampleFactors(ImFontConfig* src, float size, int* out_oversample_h, int* out_oversample_v);
IMGUI_API ImFontGlyph* ImFontAtlasBakedAddFontGlyph(ImFontAtlas* atlas, ImFontBaked* baked, ImFontConfig* src, const ImFontGlyph* in_glyph);
IMGUI_API ImGuiID ImFontAtlasBakedGetId(ImGuiID font_id, float baked_size);
IMGUI_API void ImFontAtlasPackInit(ImFontAtlas* atlas); IMGUI_API void ImFontAtlasPackInit(ImFontAtlas* atlas);
IMGUI_API ImFontAtlasRectId ImFontAtlasPackAddRect(ImFontAtlas* atlas, int w, int h, ImFontAtlasRectEntry* overwrite_entry = NULL); IMGUI_API ImFontAtlasRectId ImFontAtlasPackAddRect(ImFontAtlas* atlas, int w, int h, ImFontAtlasRectEntry* overwrite_entry = NULL);
IMGUI_API ImFontAtlasRect* ImFontAtlasPackGetRect(ImFontAtlas* atlas, ImFontAtlasRectId id); IMGUI_API ImFontAtlasRect* ImFontAtlasPackGetRect(ImFontAtlas* atlas, ImFontAtlasRectId id);
IMGUI_API void ImFontAtlasPackDiscardRect(ImFontAtlas* atlas, ImFontAtlasRectId id); IMGUI_API void ImFontAtlasPackDiscardRect(ImFontAtlas* atlas, ImFontAtlasRectId id);
IMGUI_API void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas); IMGUI_API void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas, int frame_count);
IMGUI_API void ImFontAtlasAddDrawListSharedData(ImFontAtlas* atlas, ImDrawListSharedData* data); IMGUI_API void ImFontAtlasAddDrawListSharedData(ImFontAtlas* atlas, ImDrawListSharedData* data);
IMGUI_API void ImFontAtlasRemoveDrawListSharedData(ImFontAtlas* atlas, ImDrawListSharedData* data); IMGUI_API void ImFontAtlasRemoveDrawListSharedData(ImFontAtlas* atlas, ImDrawListSharedData* data);
IMGUI_API void ImFontAtlasUpdateDrawListsTextures(ImFontAtlas* atlas, ImTextureRef old_tex, ImTextureRef new_tex); IMGUI_API void ImFontAtlasUpdateDrawListsTextures(ImFontAtlas* atlas, ImTextureRef old_tex, ImTextureRef new_tex);
+1 -1
View File
@@ -3375,7 +3375,7 @@ void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label
ButtonBehavior(row_r, row_id, NULL, NULL); ButtonBehavior(row_r, row_id, NULL, NULL);
KeepAliveID(row_id); KeepAliveID(row_id);
const float ascent_scaled = g.Font->Ascent * g.FontScale; // FIXME: Standardize those scaling factors better const float ascent_scaled = g.FontBaked->Ascent * g.FontScale; // FIXME: Standardize those scaling factors better
const float line_off_for_ascent_x = (ImMax((g.FontSize - ascent_scaled) * 0.5f, 0.0f) / -sin_a) * (flip_label ? -1.0f : 1.0f); const float line_off_for_ascent_x = (ImMax((g.FontSize - ascent_scaled) * 0.5f, 0.0f) / -sin_a) * (flip_label ? -1.0f : 1.0f);
const ImVec2 padding = g.Style.CellPadding; // We will always use swapped component const ImVec2 padding = g.Style.CellPadding; // We will always use swapped component
const ImVec2 align = g.Style.TableAngledHeadersTextAlign; const ImVec2 align = g.Style.TableAngledHeadersTextAlign;
+18 -15
View File
@@ -1518,7 +1518,7 @@ bool ImGui::TextLink(const char* label)
ColorConvertHSVtoRGB(h, s, v, line_colf.x, line_colf.y, line_colf.z); ColorConvertHSVtoRGB(h, s, v, line_colf.x, line_colf.y, line_colf.z);
} }
float line_y = bb.Max.y + ImFloor(g.Font->Descent * g.FontScale * 0.20f); float line_y = bb.Max.y + ImFloor(g.FontBaked->Descent * g.FontScale * 0.20f);
window->DrawList->AddLine(ImVec2(bb.Min.x, line_y), ImVec2(bb.Max.x, line_y), GetColorU32(line_colf)); // FIXME-TEXT: Underline mode // FIXME-DPI window->DrawList->AddLine(ImVec2(bb.Min.x, line_y), ImVec2(bb.Max.x, line_y), GetColorU32(line_colf)); // FIXME-TEXT: Underline mode // FIXME-DPI
PushStyleColor(ImGuiCol_Text, GetColorU32(text_colf)); PushStyleColor(ImGuiCol_Text, GetColorU32(text_colf));
@@ -3956,9 +3956,10 @@ static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char**
static ImVec2 InputTextCalcTextSize(ImGuiContext* ctx, const char* text_begin, const char* text_end, const char** remaining, ImVec2* out_offset, bool stop_on_new_line) static ImVec2 InputTextCalcTextSize(ImGuiContext* ctx, const char* text_begin, const char* text_end, const char** remaining, ImVec2* out_offset, bool stop_on_new_line)
{ {
ImGuiContext& g = *ctx; ImGuiContext& g = *ctx;
ImFont* font = g.Font; //ImFont* font = g.Font;
ImFontBaked* baked = g.FontBaked;
const float line_height = g.FontSize; const float line_height = g.FontSize;
const float scale = line_height / font->FontSize; const float scale = line_height / baked->Size;
ImVec2 text_size = ImVec2(0, 0); ImVec2 text_size = ImVec2(0, 0);
float line_width = 0.0f; float line_width = 0.0f;
@@ -3984,7 +3985,7 @@ static ImVec2 InputTextCalcTextSize(ImGuiContext* ctx, const char* text_begin, c
if (c == '\r') if (c == '\r')
continue; continue;
line_width += font->GetCharAdvance((ImWchar)c) * scale; line_width += baked->GetCharAdvance((ImWchar)c) * scale;
} }
if (text_size.x < line_width) if (text_size.x < line_width)
@@ -4011,7 +4012,7 @@ namespace ImStb
{ {
static int STB_TEXTEDIT_STRINGLEN(const ImGuiInputTextState* obj) { return obj->TextLen; } static int STB_TEXTEDIT_STRINGLEN(const ImGuiInputTextState* obj) { return obj->TextLen; }
static char STB_TEXTEDIT_GETCHAR(const ImGuiInputTextState* obj, int idx) { IM_ASSERT(idx <= obj->TextLen); return obj->TextSrc[idx]; } static char STB_TEXTEDIT_GETCHAR(const ImGuiInputTextState* obj, int idx) { IM_ASSERT(idx <= obj->TextLen); return obj->TextSrc[idx]; }
static float STB_TEXTEDIT_GETWIDTH(ImGuiInputTextState* obj, int line_start_idx, int char_idx) { unsigned int c; ImTextCharFromUtf8(&c, obj->TextSrc + line_start_idx + char_idx, obj->TextSrc + obj->TextLen); if ((ImWchar)c == '\n') return IMSTB_TEXTEDIT_GETWIDTH_NEWLINE; ImGuiContext& g = *obj->Ctx; return g.Font->GetCharAdvance((ImWchar)c) * g.FontScale; } static float STB_TEXTEDIT_GETWIDTH(ImGuiInputTextState* obj, int line_start_idx, int char_idx) { unsigned int c; ImTextCharFromUtf8(&c, obj->TextSrc + line_start_idx + char_idx, obj->TextSrc + obj->TextLen); if ((ImWchar)c == '\n') return IMSTB_TEXTEDIT_GETWIDTH_NEWLINE; ImGuiContext& g = *obj->Ctx; return g.FontBaked->GetCharAdvance((ImWchar)c) * g.FontScale; }
static char STB_TEXTEDIT_NEWLINE = '\n'; static char STB_TEXTEDIT_NEWLINE = '\n';
static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, ImGuiInputTextState* obj, int line_start_idx) static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, ImGuiInputTextState* obj, int line_start_idx)
{ {
@@ -4314,19 +4315,21 @@ void ImGui::PushPasswordFont()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImFont* in_font = g.Font; ImFont* in_font = g.Font;
ImFontBaked* in_baked = g.FontBaked;
ImFontGlyph glyph = *in_baked->FindGlyph('*');
glyph.PackId = -1;
ImFont* out_font = &g.InputTextPasswordFont; ImFont* out_font = &g.InputTextPasswordFont;
ImFontGlyph* glyph = in_font->FindGlyph('*');
out_font->FontSize = in_font->FontSize;
out_font->Scale = in_font->Scale; out_font->Scale = in_font->Scale;
out_font->Ascent = in_font->Ascent;
out_font->Descent = in_font->Descent;
out_font->ContainerAtlas = in_font->ContainerAtlas; out_font->ContainerAtlas = in_font->ContainerAtlas;
out_font->Glyphs.resize(0);
out_font->Glyphs.push_back(*glyph);
out_font->FallbackGlyphIndex = 0;
out_font->FallbackAdvanceX = glyph->AdvanceX;
out_font->LockDisableLoading = true; out_font->LockDisableLoading = true;
IM_ASSERT(out_font->Glyphs.Size == 1 && out_font->IndexAdvanceX.Size == 0 && out_font->IndexLookup.Size == 0); ImFontBaked* out_baked = out_font->GetFontBaked(in_baked->Size);
IM_ASSERT(out_baked->Glyphs.Size <= 1 && out_baked->IndexAdvanceX.Size == 0 && out_baked->IndexLookup.Size == 0);
out_baked->Ascent = in_baked->Ascent;
out_baked->Descent = in_baked->Descent;
out_baked->Glyphs.resize(0);
out_baked->Glyphs.push_back(glyph);
out_baked->FallbackGlyphIndex = 0;
out_baked->FallbackAdvanceX = glyph.AdvanceX;
PushFont(out_font); PushFont(out_font);
} }
@@ -5354,7 +5357,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
else else
{ {
ImVec2 rect_size = InputTextCalcTextSize(&g, p, text_selected_end, &p, NULL, true); ImVec2 rect_size = InputTextCalcTextSize(&g, p, text_selected_end, &p, NULL, true);
if (rect_size.x <= 0.0f) rect_size.x = IM_TRUNC(g.Font->GetCharAdvance((ImWchar)' ') * 0.50f); // So we can see selected empty lines if (rect_size.x <= 0.0f) rect_size.x = IM_TRUNC(g.FontBaked->GetCharAdvance((ImWchar)' ') * 0.50f); // So we can see selected empty lines
ImRect rect(rect_pos + ImVec2(0.0f, bg_offy_up - g.FontSize), rect_pos + ImVec2(rect_size.x, bg_offy_dn)); ImRect rect(rect_pos + ImVec2(0.0f, bg_offy_up - g.FontSize), rect_pos + ImVec2(rect_size.x, bg_offy_dn));
rect.ClipWith(clip_rect); rect.ClipWith(clip_rect);
if (rect.Overlaps(clip_rect)) if (rect.Overlaps(clip_rect))
+84 -47
View File
@@ -46,6 +46,7 @@
#include FT_FREETYPE_H // <freetype/freetype.h> #include FT_FREETYPE_H // <freetype/freetype.h>
#include FT_MODULE_H // <freetype/ftmodapi.h> #include FT_MODULE_H // <freetype/ftmodapi.h>
#include FT_GLYPH_H // <freetype/ftglyph.h> #include FT_GLYPH_H // <freetype/ftglyph.h>
#include FT_SIZES_H // <freetype/ftsizes.h>
#include FT_SYNTHESIS_H // <freetype/ftsynth.h> #include FT_SYNTHESIS_H // <freetype/ftsynth.h>
// Handle LunaSVG and PlutoSVG // Handle LunaSVG and PlutoSVG
@@ -150,15 +151,19 @@ namespace
ImGui_ImplFreeType_Data() { memset((void*)this, 0, sizeof(*this)); } ImGui_ImplFreeType_Data() { memset((void*)this, 0, sizeof(*this)); }
}; };
// Font parameters and metrics. // Stored in ImFontBaked::FontBackendData: pointer to SourcesCount instances of this.
struct ImGui_ImplFreeType_FontInfo struct ImGui_ImplFreeType_FontSrcBakedData
{ {
float PixelHeight; // Size this font was generated with. FT_Size FtSize; // This represent a FT_Face with a given size.
// Metrics
float Ascender; // The pixel extents above the baseline in pixels (typically positive). float Ascender; // The pixel extents above the baseline in pixels (typically positive).
float Descender; // The extents below the baseline in pixels (typically negative). float Descender; // The extents below the baseline in pixels (typically negative).
float LineSpacing; // The baseline-to-baseline distance. Note that it usually is larger than the sum of the ascender and descender taken as absolute values. There is also no guarantee that no glyphs extend above or below subsequent baselines when using this distance. Think of it as a value the designer of the font finds appropriate. float LineSpacing; // The baseline-to-baseline distance. Note that it usually is larger than the sum of the ascender and descender taken as absolute values. There is also no guarantee that no glyphs extend above or below subsequent baselines when using this distance. Think of it as a value the designer of the font finds appropriate.
float LineGap; // The spacing in pixels between one row's descent and the next row's ascent. float LineGap; // The spacing in pixels between one row's descent and the next row's ascent.
float MaxAdvanceWidth; // This field gives the maximum horizontal cursor advance for all glyphs in the font. float MaxAdvanceWidth; // This field gives the maximum horizontal cursor advance for all glyphs in the font.
ImGui_ImplFreeType_FontSrcBakedData() { memset((void*)this, 0, sizeof(*this)); }
}; };
// Stored in ImFontConfig::FontLoaderData // Stored in ImFontConfig::FontLoaderData
@@ -166,20 +171,19 @@ namespace
{ {
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. 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.
void CloseFont(); void CloseFont();
void SetPixelHeight(float pixel_height); // Change font pixel size.
const FT_Glyph_Metrics* LoadGlyph(uint32_t in_codepoint); const FT_Glyph_Metrics* LoadGlyph(uint32_t in_codepoint);
void BlitGlyph(const FT_Bitmap* ft_bitmap, uint32_t* dst, uint32_t dst_pitch); void BlitGlyph(const FT_Bitmap* ft_bitmap, uint32_t* dst, uint32_t dst_pitch);
ImGui_ImplFreeType_FontSrcData() { memset((void*)this, 0, sizeof(*this)); } ImGui_ImplFreeType_FontSrcData() { memset((void*)this, 0, sizeof(*this)); }
~ImGui_ImplFreeType_FontSrcData() { CloseFont(); } ~ImGui_ImplFreeType_FontSrcData() { CloseFont(); }
// Members // Members
ImGui_ImplFreeType_FontInfo Info; // Font descriptor of the current font.
FT_Face FtFace; FT_Face FtFace;
unsigned int UserFlags; // = ImFontConfig::RasterizerFlags unsigned int UserFlags; // = ImFontConfig::RasterizerFlags
FT_Int32 LoadFlags; FT_Int32 LoadFlags;
FT_Render_Mode RenderMode; FT_Render_Mode RenderMode;
float RasterizationDensity; float RasterizationDensity;
float InvRasterizationDensity; float InvRasterizationDensity;
ImFontBaked* BakedLastActivated;
}; };
bool ImGui_ImplFreeType_FontSrcData::InitFont(FT_Library ft_library, ImFontConfig* src, unsigned int extra_font_builder_flags) bool ImGui_ImplFreeType_FontSrcData::InitFont(FT_Library ft_library, ImFontConfig* src, unsigned int extra_font_builder_flags)
@@ -222,9 +226,6 @@ namespace
RasterizationDensity = src->RasterizerDensity; RasterizationDensity = src->RasterizerDensity;
InvRasterizationDensity = 1.0f / RasterizationDensity; InvRasterizationDensity = 1.0f / RasterizationDensity;
memset(&Info, 0, sizeof(Info));
SetPixelHeight(src->SizePixels);
return true; return true;
} }
@@ -237,31 +238,6 @@ namespace
} }
} }
void ImGui_ImplFreeType_FontSrcData::SetPixelHeight(float pixel_height)
{
// 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 = (UserFlags & ImGuiFreeTypeBuilderFlags_Bitmap) ? FT_SIZE_REQUEST_TYPE_NOMINAL : FT_SIZE_REQUEST_TYPE_REAL_DIM;
req.width = 0;
req.height = (uint32_t)(pixel_height * 64 * RasterizationDensity);
req.horiResolution = 0;
req.vertResolution = 0;
FT_Request_Size(FtFace, &req);
// Note: To handle multiple sizes later, we may need to use FT_New_Size(), FT_Activate_Size()
// Update font info
FT_Size_Metrics metrics = FtFace->size->metrics;
Info.PixelHeight = pixel_height * InvRasterizationDensity;
Info.Ascender = (float)FT_CEIL(metrics.ascender) * InvRasterizationDensity;
Info.Descender = (float)FT_CEIL(metrics.descender) * InvRasterizationDensity;
Info.LineSpacing = (float)FT_CEIL(metrics.height) * InvRasterizationDensity;
Info.LineGap = (float)FT_CEIL(metrics.height - metrics.ascender + metrics.descender) * InvRasterizationDensity;
Info.MaxAdvanceWidth = (float)FT_CEIL(metrics.max_advance) * InvRasterizationDensity;
}
const FT_Glyph_Metrics* ImGui_ImplFreeType_FontSrcData::LoadGlyph(uint32_t codepoint) const FT_Glyph_Metrics* ImGui_ImplFreeType_FontSrcData::LoadGlyph(uint32_t codepoint)
{ {
uint32_t glyph_index = FT_Get_Char_Index(FtFace, codepoint); uint32_t glyph_index = FT_Get_Char_Index(FtFace, codepoint);
@@ -447,12 +423,6 @@ bool ImGui_ImplFreeType_FontSrcInit(ImFontAtlas* atlas, ImFontConfig* src)
if (!bd_font_data->InitFont(bd->Library, src, atlas->FontBuilderFlags)) if (!bd_font_data->InitFont(bd->Library, src, atlas->FontBuilderFlags))
return false; return false;
if (src->MergeMode == false)
{
ImFont* font = src->DstFont;
font->Ascent = bd_font_data->Info.Ascender;
font->Descent = bd_font_data->Info.Descender;
}
return true; return true;
} }
@@ -464,7 +434,65 @@ void ImGui_ImplFreeType_FontSrcDestroy(ImFontAtlas* atlas, ImFontConfig* src)
src->FontLoaderData = NULL; src->FontLoaderData = NULL;
} }
bool ImGui_ImplFreeType_FontAddGlyph(ImFontAtlas* atlas, ImFont* font, ImFontConfig* srcs, int srcs_count, ImWchar codepoint) void ImGui_ImplFreeType_FontBakedInit(ImFontAtlas* atlas, ImFontBaked* baked)
{
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;
for (int src_n = 0; src_n < font->SourcesCount; src_n++)
{
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
baked->Ascent = bd_baked_data->Ascender;
baked->Descent = bd_baked_data->Descender;
}
}
void ImGui_ImplFreeType_FontBakedDestroy(ImFontAtlas* atlas, ImFontBaked* baked)
{
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;
}
bool ImGui_ImplFreeType_FontBakedAddGlyph(ImFontAtlas* atlas, ImFontBaked* baked, ImFontConfig* srcs, int srcs_count, ImWchar codepoint)
{ {
// Search for first font which has the glyph // Search for first font which has the glyph
ImGui_ImplFreeType_FontSrcData* bd_font_data = NULL; ImGui_ImplFreeType_FontSrcData* bd_font_data = NULL;
@@ -481,6 +509,15 @@ bool ImGui_ImplFreeType_FontAddGlyph(ImFontAtlas* atlas, ImFont* font, ImFontCon
if (glyph_index == 0) if (glyph_index == 0)
return false; // Not found 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];
FT_Activate_Size(bd_baked_data->FtSize);
bd_font_data->BakedLastActivated = baked;
}
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 false;
@@ -515,9 +552,7 @@ bool ImGui_ImplFreeType_FontAddGlyph(ImFontAtlas* atlas, ImFont* font, ImFontCon
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 false;
} }
ImFontAtlasRect* r = ImFontAtlasPackGetRect(atlas, pack_id); ImFontAtlasRect* r = ImFontAtlasPackGetRect(atlas, pack_id);
font->MetricsTotalSurface += w * h;
// Render pixels to our temporary buffer // Render pixels to our temporary buffer
atlas->Builder->TempBuffer.resize(w * h * 4); atlas->Builder->TempBuffer.resize(w * h * 4);
@@ -525,7 +560,7 @@ bool ImGui_ImplFreeType_FontAddGlyph(ImFontAtlas* atlas, ImFont* font, ImFontCon
bd_font_data->BlitGlyph(ft_bitmap, temp_buffer, w); bd_font_data->BlitGlyph(ft_bitmap, temp_buffer, w);
float font_off_x = src->GlyphOffset.x; float font_off_x = src->GlyphOffset.x;
float font_off_y = src->GlyphOffset.y + IM_ROUND(font->Ascent); float font_off_y = src->GlyphOffset.y + IM_ROUND(baked->Ascent);
float recip_h = 1.0f / src->RasterizerDensity; float recip_h = 1.0f / src->RasterizerDensity;
float recip_v = 1.0f / src->RasterizerDensity; float recip_v = 1.0f / src->RasterizerDensity;
@@ -539,19 +574,19 @@ bool ImGui_ImplFreeType_FontAddGlyph(ImFontAtlas* atlas, ImFont* font, ImFontCon
glyph.Visible = true; glyph.Visible = true;
glyph.Colored = (ft_bitmap->pixel_mode == FT_PIXEL_MODE_BGRA); glyph.Colored = (ft_bitmap->pixel_mode == FT_PIXEL_MODE_BGRA);
glyph.PackId = pack_id; glyph.PackId = pack_id;
ImFontAtlasBuildAddFontGlyph(atlas, font, src, &glyph); ImFontAtlasBakedAddFontGlyph(atlas, baked, src, &glyph);
// Copy to texture, post-process and queue update for backend // Copy to texture, post-process and queue update for backend
ImTextureData* tex = atlas->TexData; ImTextureData* tex = atlas->TexData;
IM_ASSERT(r->x + r->w <= tex->Width && r->y + r->h <= tex->Height); IM_ASSERT(r->x + r->w <= tex->Width && r->y + r->h <= tex->Height);
ImFontAtlasTextureBlockConvert(temp_buffer, ImTextureFormat_RGBA32, w * 4, tex->GetPixelsAt(r->x, r->y), tex->Format, tex->GetPitch(), w, h); ImFontAtlasTextureBlockConvert(temp_buffer, ImTextureFormat_RGBA32, w * 4, tex->GetPixelsAt(r->x, r->y), tex->Format, tex->GetPitch(), w, h);
ImFontAtlasPostProcessData pp_data = { atlas, font, src, &font->Glyphs.back(), tex->GetPixelsAt(r->x, r->y), tex->Format, tex->GetPitch(), w, h }; ImFontAtlasPostProcessData pp_data = { atlas, baked->ContainerFont, src, baked, &baked->Glyphs.back(), tex->GetPixelsAt(r->x, r->y), tex->Format, tex->GetPitch(), w, h };
ImFontAtlasTextureBlockPostProcess(&pp_data); ImFontAtlasTextureBlockPostProcess(&pp_data);
ImFontAtlasTextureBlockQueueUpload(atlas, tex, r->x, r->y, r->w, r->h); ImFontAtlasTextureBlockQueueUpload(atlas, tex, r->x, r->y, r->w, r->h);
} }
else else
{ {
ImFontAtlasBuildAddFontGlyph(atlas, font, src, &glyph); ImFontAtlasBakedAddFontGlyph(atlas, baked, src, &glyph);
} }
return true; return true;
} }
@@ -573,7 +608,9 @@ const ImFontLoader* ImGuiFreeType::GetFontLoader()
loader.FontSrcInit = ImGui_ImplFreeType_FontSrcInit; loader.FontSrcInit = ImGui_ImplFreeType_FontSrcInit;
loader.FontSrcDestroy = ImGui_ImplFreeType_FontSrcDestroy; loader.FontSrcDestroy = ImGui_ImplFreeType_FontSrcDestroy;
loader.FontSrcContainsGlyph = ImGui_ImplFreetype_FontSrcContainsGlyph; loader.FontSrcContainsGlyph = ImGui_ImplFreetype_FontSrcContainsGlyph;
loader.FontAddGlyph = ImGui_ImplFreeType_FontAddGlyph; loader.FontBakedInit = ImGui_ImplFreeType_FontBakedInit;
loader.FontBakedDestroy = ImGui_ImplFreeType_FontBakedDestroy;
loader.FontBakedAddGlyph = ImGui_ImplFreeType_FontBakedAddGlyph;
return &loader; return &loader;
} }