mirror of
https://github.com/ocornut/imgui.git
synced 2025-12-25 15:48:57 +00:00
InputText: optimize inactive path by avoiding an early ImStrlen().
This commit is contained in:
@@ -4536,30 +4536,44 @@ static int* ImLowerBound(int* in_begin, int* in_end, int v)
|
||||
|
||||
// FIXME-WORDWRAP: Bundle some of this into ImGuiTextIndex and/or extract as a different tool?
|
||||
// 'max_output_buffer_size' happens to be a meaningful optimization to avoid writing the full line_index when not necessarily needed (e.g. very large buffer, scrolled up, inactive)
|
||||
static int InputTextLineIndexBuild(ImGuiInputTextFlags flags, ImGuiTextIndex* line_index, const char* buf, const char* buf_end, float wrap_width, int max_output_buffer_size)
|
||||
static int InputTextLineIndexBuild(ImGuiInputTextFlags flags, ImGuiTextIndex* line_index, const char* buf, const char* buf_end, float wrap_width, int max_output_buffer_size, const char** out_buf_end)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
int size = 0;
|
||||
const char* s;
|
||||
if (flags & ImGuiInputTextFlags_WordWrap)
|
||||
{
|
||||
for (const char* s = buf; s < buf_end; )
|
||||
for (s = buf; s < buf_end; s = (*s == '\n') ? s + 1 : s)
|
||||
{
|
||||
if (size++ <= max_output_buffer_size)
|
||||
line_index->Offsets.push_back((int)(s - buf));
|
||||
s = ImFontCalcWordWrapPositionEx(g.Font, g.FontSize, s, buf_end, wrap_width, ImDrawTextFlags_WrapKeepBlanks);
|
||||
s = (*s == '\n') ? s + 1 : s;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (buf_end != NULL)
|
||||
{
|
||||
for (const char* s = buf; s < buf_end; )
|
||||
for (s = buf; s < buf_end; s = s ? s + 1 : buf_end)
|
||||
{
|
||||
if (size++ <= max_output_buffer_size)
|
||||
line_index->Offsets.push_back((int)(s - buf));
|
||||
s = (const char*)ImMemchr(s, '\n', buf_end - s);
|
||||
s = s ? s + 1 : buf_end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* s_eol;
|
||||
for (s = buf; ; s = s_eol + 1)
|
||||
{
|
||||
if (size++ <= max_output_buffer_size)
|
||||
line_index->Offsets.push_back((int)(s - buf));
|
||||
if ((s_eol = strchr(s, '\n')) != NULL)
|
||||
continue;
|
||||
s += strlen(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (out_buf_end != NULL)
|
||||
*out_buf_end = buf_end = s;
|
||||
if (size == 0)
|
||||
{
|
||||
line_index->Offsets.push_back(0);
|
||||
@@ -5367,8 +5381,10 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
{
|
||||
if (render_cursor || render_selection || g.ActiveId == id)
|
||||
buf_display_end = buf_display + state->TextLen; //-V595
|
||||
else if (is_multiline && !is_wordwrap)
|
||||
buf_display_end = NULL; // Inactive multi-line: end of buffer will be output by InputTextLineIndexBuild() special strchr() path.
|
||||
else
|
||||
buf_display_end = buf_display + ImStrlen(buf_display); // FIXME-OPT: For multi-line path this would optimally be folded into the InputTextLineIndex build below.
|
||||
buf_display_end = buf_display + ImStrlen(buf_display);
|
||||
}
|
||||
|
||||
// Calculate visibility
|
||||
@@ -5379,10 +5395,10 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
// Build line index for easy data access (makes code below simpler and faster)
|
||||
ImGuiTextIndex* line_index = &g.InputTextLineIndex;
|
||||
line_index->Offsets.resize(0);
|
||||
line_index->EndOffset = (int)(buf_display_end - buf_display);
|
||||
int line_count = 1;
|
||||
if (is_multiline)
|
||||
line_count = InputTextLineIndexBuild(flags, line_index, buf_display, buf_display_end, wrap_width, (render_cursor && state && state->CursorFollow) ? INT_MAX : line_visible_n1 + 1);
|
||||
line_count = InputTextLineIndexBuild(flags, line_index, buf_display, buf_display_end, wrap_width, (render_cursor && state && state->CursorFollow) ? INT_MAX : line_visible_n1 + 1, buf_display_end ? NULL : &buf_display_end);
|
||||
line_index->EndOffset = (int)(buf_display_end - buf_display);
|
||||
line_visible_n1 = ImMin(line_visible_n1, line_count);
|
||||
|
||||
// Store text height (we don't need width)
|
||||
|
||||
Reference in New Issue
Block a user