update Dear ImGui to 1.91.8

This commit is contained in:
tildearrow 2025-08-11 16:28:38 -05:00
parent 2052fb31ef
commit 1a0d8dc52e
23 changed files with 664 additions and 487 deletions

View file

@ -1,4 +1,4 @@
// dear imgui, v1.91.7
// dear imgui, v1.91.8
// (drawing and font code)
/*
@ -1733,8 +1733,7 @@ void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32
// Accept null ranges
if (text_begin == text_end || text_begin[0] == 0)
return;
if (text_end == NULL)
text_end = text_begin + strlen(text_begin);
// No need to strlen() here: font->RenderText() will do it and may early out.
text_end = FindTextEnd(text_begin, text_end); //hides everything after ##
@ -1759,7 +1758,7 @@ void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32
void ImDrawList::AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end)
{
AddText(NULL, 0.0f, pos, col, text_begin, text_end);
AddText(_Data->Font, _Data->FontSize, pos, col, text_begin, text_end);
}
void ImDrawList::AddTextNoHashHide(ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec4* cpu_fine_clip_rect)
@ -2477,8 +2476,8 @@ ImFontConfig::ImFontConfig()
{
memset(this, 0, sizeof(*this));
FontDataOwnedByAtlas = true;
OversampleH = 2;
OversampleV = 1;
OversampleH = 0; // Auto == 1 or 2 depending on size
OversampleV = 0; // Auto == 1
GlyphMaxAdvanceX = FLT_MAX;
RasterizerMultiply = 1.0f;
RasterizerDensity = 1.0f;
@ -2623,6 +2622,7 @@ void ImFontAtlas::ClearTexData()
void ImFontAtlas::ClearFonts()
{
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!");
ClearInputData();
Fonts.clear_delete();
TexReady = false;
}
@ -2675,8 +2675,7 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!");
IM_ASSERT(font_cfg->FontData != NULL && font_cfg->FontDataSize > 0);
IM_ASSERT(font_cfg->SizePixels > 0.0f && "Is ImFontConfig struct correctly initialized?");
IM_ASSERT(font_cfg->OversampleH > 0 && font_cfg->OversampleV > 0 && "Is ImFontConfig struct correctly initialized?");
IM_ASSERT(font_cfg->RasterizerDensity > 0.0f);
IM_ASSERT(font_cfg->RasterizerDensity > 0.0f && "Is ImFontConfig struct correctly initialized?");
// Create new font
if (!font_cfg->MergeMode)
@ -2922,6 +2921,13 @@ void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsig
*data = table[*data];
}
void ImFontAtlasBuildGetOversampleFactors(const ImFontConfig* cfg, int* out_oversample_h, int* out_oversample_v)
{
// Automatically disable horizontal oversampling over size 36
*out_oversample_h = (cfg->OversampleH != 0) ? cfg->OversampleH : (cfg->SizePixels * cfg->RasterizerDensity > 36.0f || cfg->PixelSnapH) ? 1 : 2;
*out_oversample_v = (cfg->OversampleV != 0) ? cfg->OversampleV : 1;
}
#ifdef IMGUI_ENABLE_STB_TRUETYPE
// Temporary data for one source font (multiple source fonts can be merged into one destination ImFont)
// (C++03 doesn't allow instancing ImVector<> with function-local types so we declare the type here.)
@ -3087,15 +3093,19 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
buf_rects_out_n += src_tmp.GlyphsCount;
buf_packedchars_out_n += src_tmp.GlyphsCount;
// Convert our ranges in the format stb_truetype wants
// Automatic selection of oversampling parameters
ImFontConfig& cfg = atlas->ConfigData[src_i];
int oversample_h, oversample_v;
ImFontAtlasBuildGetOversampleFactors(&cfg, &oversample_h, &oversample_v);
// Convert our ranges in the format stb_truetype wants
src_tmp.PackRange.font_size = cfg.SizePixels * cfg.RasterizerDensity;
src_tmp.PackRange.first_unicode_codepoint_in_range = 0;
src_tmp.PackRange.array_of_unicode_codepoints = src_tmp.GlyphsList.Data;
src_tmp.PackRange.num_chars = src_tmp.GlyphsList.Size;
src_tmp.PackRange.chardata_for_range = src_tmp.PackedChars;
src_tmp.PackRange.h_oversample = (unsigned char)cfg.OversampleH;
src_tmp.PackRange.v_oversample = (unsigned char)cfg.OversampleV;
src_tmp.PackRange.h_oversample = (unsigned char)oversample_h;
src_tmp.PackRange.v_oversample = (unsigned char)oversample_v;
// Gather the sizes of all rectangles we will need to pack (this loop is based on stbtt_PackFontRangesGatherRects)
const float scale = (cfg.SizePixels > 0.0f) ? stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels * cfg.RasterizerDensity) : stbtt_ScaleForMappingEmToPixels(&src_tmp.FontInfo, -cfg.SizePixels * cfg.RasterizerDensity);
@ -3104,9 +3114,9 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
int x0, y0, x1, y1;
const int glyph_index_in_font = stbtt_FindGlyphIndex(&src_tmp.FontInfo, src_tmp.GlyphsList[glyph_i]);
IM_ASSERT(glyph_index_in_font != 0);
stbtt_GetGlyphBitmapBoxSubpixel(&src_tmp.FontInfo, glyph_index_in_font, scale * cfg.OversampleH, scale * cfg.OversampleV, 0, 0, &x0, &y0, &x1, &y1);
src_tmp.Rects[glyph_i].w = (stbrp_coord)(x1 - x0 + pack_padding + cfg.OversampleH - 1);
src_tmp.Rects[glyph_i].h = (stbrp_coord)(y1 - y0 + pack_padding + cfg.OversampleV - 1);
stbtt_GetGlyphBitmapBoxSubpixel(&src_tmp.FontInfo, glyph_index_in_font, scale * oversample_h, scale * oversample_v, 0, 0, &x0, &y0, &x1, &y1);
src_tmp.Rects[glyph_i].w = (stbrp_coord)(x1 - x0 + pack_padding + oversample_h - 1);
src_tmp.Rects[glyph_i].h = (stbrp_coord)(y1 - y0 + pack_padding + oversample_v - 1);
total_surface += src_tmp.Rects[glyph_i].w * src_tmp.Rects[glyph_i].h;
}
}
@ -3800,7 +3810,7 @@ ImFont::ImFont()
Scale = 1.0f;
Ascent = Descent = 0.0f;
MetricsTotalSurface = 0;
memset(Used4kPagesMap, 0, sizeof(Used4kPagesMap));
memset(Used8kPagesMap, 0, sizeof(Used8kPagesMap));
}
ImFont::~ImFont()
@ -3820,7 +3830,7 @@ void ImFont::ClearOutputData()
DirtyLookupTables = true;
Ascent = Descent = 0.0f;
MetricsTotalSurface = 0;
memset(Used4kPagesMap, 0, sizeof(Used4kPagesMap));
memset(Used8kPagesMap, 0, sizeof(Used8kPagesMap));
}
static ImWchar FindFirstExistingGlyph(ImFont* font, const ImWchar* candidate_chars, int candidate_chars_count)
@ -3843,17 +3853,17 @@ void ImFont::BuildLookupTable()
IndexAdvanceX.clear();
IndexLookup.clear();
DirtyLookupTables = false;
memset(Used4kPagesMap, 0, sizeof(Used4kPagesMap));
memset(Used8kPagesMap, 0, sizeof(Used8kPagesMap));
GrowIndex(max_codepoint + 1);
for (int i = 0; i < Glyphs.Size; i++)
{
int codepoint = (int)Glyphs[i].Codepoint;
IndexAdvanceX[codepoint] = Glyphs[i].AdvanceX;
IndexLookup[codepoint] = (ImWchar)i;
IndexLookup[codepoint] = (ImU16)i;
// Mark 4K page as used
const int page_n = codepoint / 4096;
Used4kPagesMap[page_n >> 3] |= 1 << (page_n & 7);
const int page_n = codepoint / 8192;
Used8kPagesMap[page_n >> 3] |= 1 << (page_n & 7);
}
// Create a glyph to handle TAB
@ -3867,7 +3877,7 @@ void ImFont::BuildLookupTable()
tab_glyph.Codepoint = '\t';
tab_glyph.AdvanceX *= IM_TABSIZE;
IndexAdvanceX[(int)tab_glyph.Codepoint] = (float)tab_glyph.AdvanceX;
IndexLookup[(int)tab_glyph.Codepoint] = (ImWchar)(Glyphs.Size - 1);
IndexLookup[(int)tab_glyph.Codepoint] = (ImU16)(Glyphs.Size - 1);
}
// Mark special glyphs as not visible (note that AddGlyph already mark as non-visible glyphs with zero-size polygons)
@ -3915,15 +3925,15 @@ void ImFont::BuildLookupTable()
}
}
// API is designed this way to avoid exposing the 4K page size
// API is designed this way to avoid exposing the 8K page size
// e.g. use with IsGlyphRangeUnused(0, 255)
bool ImFont::IsGlyphRangeUnused(unsigned int c_begin, unsigned int c_last)
{
unsigned int page_begin = (c_begin / 4096);
unsigned int page_last = (c_last / 4096);
unsigned int page_begin = (c_begin / 8192);
unsigned int page_last = (c_last / 8192);
for (unsigned int page_n = page_begin; page_n <= page_last; page_n++)
if ((page_n >> 3) < sizeof(Used4kPagesMap))
if (Used4kPagesMap[page_n >> 3] & (1 << (page_n & 7)))
if ((page_n >> 3) < sizeof(Used8kPagesMap))
if (Used8kPagesMap[page_n >> 3] & (1 << (page_n & 7)))
return false;
return true;
}
@ -3940,7 +3950,7 @@ void ImFont::GrowIndex(int new_size)
if (new_size <= IndexLookup.Size)
return;
IndexAdvanceX.resize(new_size, -1.0f);
IndexLookup.resize(new_size, (ImWchar)-1);
IndexLookup.resize(new_size, (ImU16)-1);
}
// x0/y0/x1/y1 are offset from the character upper-left layout position, in pixels. Therefore x0/y0 are often fairly close to zero.
@ -3983,6 +3993,7 @@ void ImFont::AddGlyph(const ImFontConfig* cfg, ImWchar codepoint, float x0, floa
glyph.U1 = u1;
glyph.V1 = v1;
glyph.AdvanceX = advance_x;
IM_ASSERT(Glyphs.Size < 0xFFFF); // IndexLookup[] hold 16-bit values and -1 is reserved.
// Compute rough surface usage metrics (+1 to account for average padding, +0.99 to round)
// We use (U1-U0)*TexWidth instead of X1-X0 to account for oversampling.
@ -3996,13 +4007,13 @@ void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst)
IM_ASSERT(IndexLookup.Size > 0); // Currently this can only be called AFTER the font has been built, aka after calling ImFontAtlas::GetTexDataAs*() function.
unsigned int index_size = (unsigned int)IndexLookup.Size;
if (dst < index_size && IndexLookup.Data[dst] == (ImWchar)-1 && !overwrite_dst) // 'dst' already exists
if (dst < index_size && IndexLookup.Data[dst] == (ImU16)-1 && !overwrite_dst) // 'dst' already exists
return;
if (src >= index_size && dst >= index_size) // both 'dst' and 'src' don't exist -> no-op
return;
GrowIndex(dst + 1);
IndexLookup[dst] = (src < index_size) ? IndexLookup.Data[src] : (ImWchar)-1;
IndexLookup[dst] = (src < index_size) ? IndexLookup.Data[src] : (ImU16)-1;
IndexAdvanceX[dst] = (src < index_size) ? IndexAdvanceX.Data[src] : 1.0f;
}
@ -4011,8 +4022,8 @@ const ImFontGlyph* ImFont::FindGlyph(ImWchar c)
{
if (c >= (size_t)IndexLookup.Size)
return FallbackGlyph;
const ImWchar i = IndexLookup.Data[c];
if (i == (ImWchar)-1)
const ImU16 i = IndexLookup.Data[c];
if (i == (ImU16)-1)
return FallbackGlyph;
return &Glyphs.Data[i];
}
@ -4021,8 +4032,8 @@ const ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c)
{
if (c >= (size_t)IndexLookup.Size)
return NULL;
const ImWchar i = IndexLookup.Data[c];
if (i == (ImWchar)-1)
const ImU16 i = IndexLookup.Data[c];
if (i == (ImU16)-1)
return NULL;
return &Glyphs.Data[i];
}
@ -4236,15 +4247,15 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, Im
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
void ImFont::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, bool cpu_fine_clip)
{
if (!text_end)
text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
// Align to be pixel perfect
float x = IM_TRUNC(pos.x);
float y = IM_TRUNC(pos.y);
if (y > clip_rect.w)
return;
if (!text_end)
text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
const float scale = size / FontSize;
const float line_height = FontSize * scale;
const float origin_x = x;