Merge branch 'master' into docking

This commit is contained in:
ocornut
2025-09-08 13:35:24 +02:00
14 changed files with 407 additions and 201 deletions

View File

@@ -48,7 +48,7 @@ Index of this file:
#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff)
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
#pragma warning (disable: 26451) // [Static Analyzer] Arithmetic overflow : Using operator 'xxx' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator 'xxx' to avoid overflow(io.2).
#pragma warning (disable: 26812) // [Static Analyzer] The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3). [MSVC Static Analyzer)
#pragma warning (disable: 26812) // [Static Analyzer] The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3).
#endif
// Clang/GCC warnings with -Weverything
@@ -1724,7 +1724,7 @@ void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32
clip_rect.z = ImMin(clip_rect.z, cpu_fine_clip_rect->z);
clip_rect.w = ImMin(clip_rect.w, cpu_fine_clip_rect->w);
}
font->RenderText(this, font_size, pos, col, clip_rect, text_begin, text_end, wrap_width, cpu_fine_clip_rect != NULL);
font->RenderText(this, font_size, pos, col, clip_rect, text_begin, text_end, wrap_width, (cpu_fine_clip_rect != NULL) ? ImDrawTextFlags_CpuFineClip : ImDrawTextFlags_None);
}
void ImDrawList::AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end)
@@ -5346,10 +5346,11 @@ ImFontBaked* ImFontAtlasBakedGetOrAdd(ImFontAtlas* atlas, ImFont* font, float fo
}
// Trim trailing space and find beginning of next line
static inline const char* CalcWordWrapNextLineStartA(const char* text, const char* text_end)
const char* ImTextCalcWordWrapNextLineStart(const char* text, const char* text_end, ImDrawTextFlags flags)
{
while (text < text_end && ImCharIsBlankA(*text))
text++;
if ((flags & ImDrawTextFlags_WrapKeepBlanks) == 0)
while (text < text_end && ImCharIsBlankA(*text))
text++;
if (*text == '\n')
text++;
return text;
@@ -5358,7 +5359,7 @@ static inline const char* CalcWordWrapNextLineStartA(const char* text, const cha
// Simple word-wrapping for English, not full-featured. Please submit failing cases!
// This will return the next location to wrap from. If no wrapping if necessary, this will fast-forward to e.g. text_end.
// FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.)
const char* ImFont::CalcWordWrapPosition(float size, const char* text, const char* text_end, float wrap_width)
const char* ImFontCalcWordWrapPositionEx(ImFont* font, float size, const char* text, const char* text_end, float wrap_width, ImDrawTextFlags flags)
{
// For references, possible wrap point marked with ^
// "aaa bbb, ccc,ddd. eee fff. ggg!"
@@ -5372,7 +5373,7 @@ const char* ImFont::CalcWordWrapPosition(float size, const char* text, const cha
// Cut words that cannot possibly fit within one line.
// e.g.: "The tropical fish" with ~5 characters worth of width --> "The tr" "opical" "fish"
ImFontBaked* baked = GetFontBaked(size);
ImFontBaked* baked = font->GetFontBaked(size);
const float scale = size / baked->Size;
float line_width = 0.0f;
@@ -5398,12 +5399,7 @@ const char* ImFont::CalcWordWrapPosition(float size, const char* text, const cha
if (c < 32)
{
if (c == '\n')
{
line_width = word_width = blank_width = 0.0f;
inside_word = true;
s = next_s;
continue;
}
return s; // Direct return, skip "Wrap_width is too small to fit anything" path.
if (c == '\r')
{
s = next_s;
@@ -5438,6 +5434,8 @@ const char* ImFont::CalcWordWrapPosition(float size, const char* text, const cha
{
prev_word_end = word_end;
line_width += word_width + blank_width;
if ((flags & ImDrawTextFlags_WrapKeepBlanks) && line_width <= wrap_width)
prev_word_end = s;
word_width = blank_width = 0.0f;
}
@@ -5464,14 +5462,21 @@ const char* ImFont::CalcWordWrapPosition(float size, const char* text, const cha
return s;
}
ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** out_remaining)
const char* ImFont::CalcWordWrapPosition(float size, const char* text, const char* text_end, float wrap_width)
{
return ImFontCalcWordWrapPositionEx(this, size, text, text_end, wrap_width, ImDrawTextFlags_None);
}
ImVec2 ImFontCalcTextSizeEx(ImFont* font, float size, float max_width, float wrap_width, const char* text_begin, const char* text_end_display, const char* text_end, const char** out_remaining, ImVec2* out_offset, ImDrawTextFlags flags)
{
if (!text_end)
text_end = text_begin + ImStrlen(text_begin); // FIXME-OPT: Need to avoid this.
if (!text_end_display)
text_end_display = text_end;
ImFontBaked* baked = font->GetFontBaked(size);
const float line_height = size;
ImFontBaked* baked = GetFontBaked(size);
const float scale = size / baked->Size;
const float scale = line_height / baked->Size;
ImVec2 text_size = ImVec2(0, 0);
float line_width = 0.0f;
@@ -5480,13 +5485,14 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
const char* word_wrap_eol = NULL;
const char* s = text_begin;
while (s < text_end)
while (s < text_end_display)
{
// Word-wrapping
if (word_wrap_enabled)
{
// Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
if (!word_wrap_eol)
word_wrap_eol = CalcWordWrapPosition(size, s, text_end, wrap_width - line_width);
word_wrap_eol = ImFontCalcWordWrapPositionEx(font, size, s, text_end, wrap_width - line_width, flags);
if (s >= word_wrap_eol)
{
@@ -5494,8 +5500,10 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
text_size.x = line_width;
text_size.y += line_height;
line_width = 0.0f;
s = ImTextCalcWordWrapNextLineStart(s, text_end, flags); // Wrapping skips upcoming blanks
if (flags & ImDrawTextFlags_StopOnNewLine)
break;
word_wrap_eol = NULL;
s = CalcWordWrapNextLineStartA(s, text_end); // Wrapping skips upcoming blanks
continue;
}
}
@@ -5508,18 +5516,17 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
else
s += ImTextCharFromUtf8(&c, s, text_end);
if (c < 32)
if (c == '\n')
{
if (c == '\n')
{
text_size.x = ImMax(text_size.x, line_width);
text_size.y += line_height;
line_width = 0.0f;
continue;
}
if (c == '\r')
continue;
text_size.x = ImMax(text_size.x, line_width);
text_size.y += line_height;
line_width = 0.0f;
if (flags & ImDrawTextFlags_StopOnNewLine)
break;
continue;
}
if (c == '\r')
continue;
// Optimized inline version of 'float char_width = GetCharAdvance((ImWchar)c);'
float char_width = (c < (unsigned int)baked->IndexAdvanceX.Size) ? baked->IndexAdvanceX.Data[c] : -1.0f;
@@ -5539,7 +5546,10 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
if (text_size.x < line_width)
text_size.x = line_width;
if (line_width > 0 || text_size.y == 0.0f)
if (out_offset != NULL)
*out_offset = ImVec2(line_width, text_size.y + line_height); // offset allow for the possibility of sitting after a trailing \n
if (line_width > 0 || text_size.y == 0.0f) // whereas size.y will ignore the trailing \n
text_size.y += line_height;
if (out_remaining != NULL)
@@ -5548,6 +5558,11 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
return text_size;
}
ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** out_remaining)
{
return ImFontCalcTextSizeEx(this, size, max_width, wrap_width, text_begin, text_end, text_end, out_remaining, NULL, ImDrawTextFlags_None);
}
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c, const ImVec4* cpu_fine_clip)
{
@@ -5588,7 +5603,8 @@ 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)
// DO NOT CALL DIRECTLY THIS WILL CHANGE WIDLY IN 2025-2025. Use ImDrawList::AddText().
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, ImDrawTextFlags flags)
{
// Align to be pixel perfect
begin:
@@ -5618,8 +5634,8 @@ begin:
// FIXME-OPT: This is not optimal as do first do a search for \n before calling CalcWordWrapPosition().
// If the specs for CalcWordWrapPosition() were reworked to optionally return on \n we could combine both.
// However it is still better than nothing performing the fast-forward!
s = CalcWordWrapPosition(size, s, line_end ? line_end : text_end, wrap_width);
s = CalcWordWrapNextLineStartA(s, text_end);
s = ImFontCalcWordWrapPositionEx(this, size, s, line_end ? line_end : text_end, wrap_width, flags);
s = ImTextCalcWordWrapNextLineStart(s, text_end, flags);
}
else
{
@@ -5654,6 +5670,7 @@ begin:
ImDrawIdx* idx_write = draw_list->_IdxWritePtr;
unsigned int vtx_index = draw_list->_VtxCurrentIdx;
const int cmd_count = draw_list->CmdBuffer.Size;
const bool cpu_fine_clip = (flags & ImDrawTextFlags_CpuFineClip) != 0;
const ImU32 col_untinted = col | ~IM_COL32_A_MASK;
const char* word_wrap_eol = NULL;
@@ -5664,7 +5681,7 @@ begin:
{
// Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
if (!word_wrap_eol)
word_wrap_eol = CalcWordWrapPosition(size, s, text_end, wrap_width - (x - origin_x));
word_wrap_eol = ImFontCalcWordWrapPositionEx(this, size, s, text_end, wrap_width - (x - origin_x), flags);
if (s >= word_wrap_eol)
{
@@ -5673,7 +5690,7 @@ begin:
if (y > clip_rect.w)
break; // break out of main loop
word_wrap_eol = NULL;
s = CalcWordWrapNextLineStartA(s, text_end); // Wrapping skips upcoming blanks
s = ImTextCalcWordWrapNextLineStart(s, text_end, flags); // Wrapping skips upcoming blanks
continue;
}
}