Internals: added IM_LIKELY(), IM_UNLIKELY() helper macros (yet unused). Added ImFontGetCharAdvanceX() macro.

This commit is contained in:
ocornut 2024-11-07 16:58:50 +01:00
parent 419a9ada16
commit 01d27a4acd
2 changed files with 18 additions and 7 deletions

View File

@ -3847,7 +3847,7 @@ const ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c)
return &Glyphs.Data[i]; return &Glyphs.Data[i];
} }
// Wrapping skips upcoming blanks // Trim trailing space and find beginning of next line
static inline const char* CalcWordWrapNextLineStartA(const char* text, const char* text_end) static inline const char* CalcWordWrapNextLineStartA(const char* text, const char* text_end)
{ {
while (text < text_end && ImCharIsBlankA(*text)) while (text < text_end && ImCharIsBlankA(*text))
@ -3857,6 +3857,8 @@ static inline const char* CalcWordWrapNextLineStartA(const char* text, const cha
return text; return text;
} }
#define ImFontGetCharAdvanceX(_FONT, _CH) ((int)(_CH) < (_FONT)->IndexAdvanceX.Size ? (_FONT)->IndexAdvanceX.Data[_CH] : (_FONT)->FallbackAdvanceX)
// Simple word-wrapping for English, not full-featured. Please submit failing cases! // 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. // 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.) // 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.)
@ -3909,7 +3911,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
} }
} }
const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX.Data[c] : FallbackAdvanceX); const float char_width = ImFontGetCharAdvanceX(this, c);
if (ImCharIsBlankW(c)) if (ImCharIsBlankW(c))
{ {
if (inside_word) if (inside_word)
@ -4014,7 +4016,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
continue; continue;
} }
const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX.Data[c] : FallbackAdvanceX) * scale; const float char_width = ImFontGetCharAdvanceX(this, c);
if (line_width + char_width >= max_width) if (line_width + char_width >= max_width)
{ {
s = prev_s; s = prev_s;
@ -4063,9 +4065,9 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
if (y > clip_rect.w) if (y > clip_rect.w)
return; return;
const float start_x = x;
const float scale = size / FontSize; const float scale = size / FontSize;
const float line_height = FontSize * scale; const float line_height = FontSize * scale;
const float origin_x = x;
const bool word_wrap_enabled = (wrap_width > 0.0f); const bool word_wrap_enabled = (wrap_width > 0.0f);
// Fast-forward to first visible line // Fast-forward to first visible line
@ -4124,11 +4126,11 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
{ {
// 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. // 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) if (!word_wrap_eol)
word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - (x - start_x)); word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - (x - origin_x));
if (s >= word_wrap_eol) if (s >= word_wrap_eol)
{ {
x = start_x; x = origin_x;
y += line_height; y += line_height;
if (y > clip_rect.w) if (y > clip_rect.w)
break; // break out of main loop break; // break out of main loop
@ -4149,7 +4151,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
{ {
if (c == '\n') if (c == '\n')
{ {
x = start_x; x = origin_x;
y += line_height; y += line_height;
if (y > clip_rect.w) if (y > clip_rect.w)
break; // break out of main loop break; // break out of main loop

View File

@ -260,6 +260,15 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
#define IM_FLOOR IM_TRUNC #define IM_FLOOR IM_TRUNC
#endif #endif
// Hint for branch prediction
#if (defined(__cplusplus) && (__cplusplus >= 202002L)) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 202002L))
#define IM_LIKELY [[likely]]
#define IM_UNLIKELY [[unlikely]]
#else
#define IM_LIKELY
#define IM_UNLIKELY
#endif
// Enforce cdecl calling convention for functions called by the standard library, in case compilation settings changed the default to e.g. __vectorcall // Enforce cdecl calling convention for functions called by the standard library, in case compilation settings changed the default to e.g. __vectorcall
#ifdef _MSC_VER #ifdef _MSC_VER
#define IMGUI_CDECL __cdecl #define IMGUI_CDECL __cdecl