From 837bec3ebdd87c185c12e0c150ddb75d1c210c0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Thu, 11 Oct 2018 20:51:30 -0700 Subject: [PATCH] Updated ImGui. --- 3rdparty/dear-imgui/imgui.cpp | 46 ++++++++++++--------------- 3rdparty/dear-imgui/imgui.h | 24 +++++++------- 3rdparty/dear-imgui/imgui_internal.h | 3 +- 3rdparty/dear-imgui/imgui_widgets.cpp | 15 +++++---- 4 files changed, 44 insertions(+), 44 deletions(-) diff --git a/3rdparty/dear-imgui/imgui.cpp b/3rdparty/dear-imgui/imgui.cpp index 9cd9c35f0..0d4739a32 100644 --- a/3rdparty/dear-imgui/imgui.cpp +++ b/3rdparty/dear-imgui/imgui.cpp @@ -1207,10 +1207,8 @@ char* ImStrdup(const char *str) const char* ImStrchrRange(const char* str, const char* str_end, char c) { - for ( ; str < str_end; str++) - if (*str == c) - return str; - return NULL; + const char* p = (const char*)memchr(str, (int)c, str_end - str); + return p; } int ImStrlenW(const ImWchar* str) @@ -1220,6 +1218,13 @@ int ImStrlenW(const ImWchar* str) return n; } +// Find end-of-line. Return pointer will point to either first \n, either str_end. +const char* ImStreolRange(const char* str, const char* str_end) +{ + const char* p = (const char*)memchr(str, '\n', str_end - str); + return p ? p : str_end; +} + const ImWchar* ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin) // find beginning-of-line { while (buf_mid_line > buf_begin && buf_mid_line[-1] != '\n') @@ -1960,6 +1965,8 @@ bool ImGuiTextFilter::PassFilter(const char* text, const char* text_end) const #endif #endif +char ImGuiTextBuffer::EmptyString[1] = { 0 }; + // Helper: Text buffer for logging/accumulating text void ImGuiTextBuffer::appendfv(const char* fmt, va_list args) { @@ -1973,7 +1980,8 @@ void ImGuiTextBuffer::appendfv(const char* fmt, va_list args) return; } - const int write_off = Buf.Size; + // Add zero-terminator the first time + const int write_off = (Buf.Size != 0) ? Buf.Size : 1; const int needed_sz = write_off + len; if (write_off + len >= Buf.Capacity) { @@ -8344,29 +8352,17 @@ void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char* for (;;) { // Split the string. Each new line (after a '\n') is followed by spacing corresponding to the current depth of our log entry. - const char* line_end = text_remaining; - while (line_end < text_end) - if (*line_end == '\n') - break; - else - line_end++; - if (line_end >= text_end) - line_end = NULL; - - const bool is_first_line = (text == text_remaining); - bool is_last_line = false; - if (line_end == NULL) + const char* line_start = text_remaining; + const char* line_end = ImStreolRange(line_start, text_end); + const bool is_first_line = (line_start == text); + const bool is_last_line = (line_end == text_end); + if (!is_last_line || (line_start != line_end)) { - is_last_line = true; - line_end = text_end; - } - if (line_end != NULL && !(is_last_line && (line_end - text_remaining)==0)) - { - const int char_count = (int)(line_end - text_remaining); + const int char_count = (int)(line_end - line_start); if (log_new_line || !is_first_line) - LogText(IM_NEWLINE "%*s%.*s", tree_depth*4, "", char_count, text_remaining); + LogText(IM_NEWLINE "%*s%.*s", tree_depth*4, "", char_count, line_start); else - LogText(" %.*s", char_count, text_remaining); + LogText(" %.*s", char_count, line_start); } if (is_last_line) diff --git a/3rdparty/dear-imgui/imgui.h b/3rdparty/dear-imgui/imgui.h index 7e44489b1..107f8d210 100644 --- a/3rdparty/dear-imgui/imgui.h +++ b/3rdparty/dear-imgui/imgui.h @@ -1367,25 +1367,27 @@ struct ImGuiTextFilter int CountGrep; }; -// Helper: Text buffer for logging/accumulating text +// Helper: Growable text buffer for logging/accumulating text +// (this could be called 'ImGuiTextBuilder' / 'ImGuiStringBuilder') struct ImGuiTextBuffer { ImVector Buf; + static char EmptyString[1]; - ImGuiTextBuffer() { Buf.push_back(0); } - inline char operator[](int i) { return Buf.Data[i]; } - const char* begin() const { return &Buf.front(); } - const char* end() const { return &Buf.back(); } // Buf is zero-terminated, so end() will point on the zero-terminator - int size() const { return Buf.Size - 1; } - bool empty() { return Buf.Size <= 1; } - void clear() { Buf.clear(); Buf.push_back(0); } - void reserve(int capacity) { Buf.reserve(capacity); } - const char* c_str() const { return Buf.Data; } + ImGuiTextBuffer() { } + inline char operator[](int i) { IM_ASSERT(Buf.Data != NULL); return Buf.Data[i]; } + const char* begin() const { return Buf.Data ? &Buf.front() : EmptyString; } + const char* end() const { return Buf.Data ? &Buf.back() : EmptyString; } // Buf is zero-terminated, so end() will point on the zero-terminator + int size() const { return Buf.Data ? Buf.Size - 1 : 0; } + bool empty() { return Buf.Size <= 1; } + void clear() { Buf.clear(); } + void reserve(int capacity) { Buf.reserve(capacity); } + const char* c_str() const { return Buf.Data ? Buf.Data : EmptyString; } IMGUI_API void appendf(const char* fmt, ...) IM_FMTARGS(2); IMGUI_API void appendfv(const char* fmt, va_list args) IM_FMTLIST(2); }; -// Helper: key->value storage +// Helper: Key->Value storage // Typically you don't have to worry about this since a storage is held within each Window. // We use it to e.g. store collapse state for a tree (Int 0/1) // This is optimized for efficient lookup (dichotomy into a contiguous buffer) and rare insertion (typically tied to user interactions aka max once a frame) diff --git a/3rdparty/dear-imgui/imgui_internal.h b/3rdparty/dear-imgui/imgui_internal.h index 124f08757..9ebcdd782 100644 --- a/3rdparty/dear-imgui/imgui_internal.h +++ b/3rdparty/dear-imgui/imgui_internal.h @@ -141,7 +141,8 @@ IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count); IMGUI_API char* ImStrdup(const char* str); IMGUI_API const char* ImStrchrRange(const char* str_begin, const char* str_end, char c); IMGUI_API int ImStrlenW(const ImWchar* str); -IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line +IMGUI_API const char* ImStreolRange(const char* str, const char* str_end); // End end-of-line +IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end); IMGUI_API void ImStrTrimBlanks(char* str); IMGUI_API int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) IM_FMTARGS(3); diff --git a/3rdparty/dear-imgui/imgui_widgets.cpp b/3rdparty/dear-imgui/imgui_widgets.cpp index 121fa78db..7351b93d0 100644 --- a/3rdparty/dear-imgui/imgui_widgets.cpp +++ b/3rdparty/dear-imgui/imgui_widgets.cpp @@ -133,8 +133,9 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) { // Long text! // Perform manual coarse clipping to optimize for long multi-line text - // From this point we will only compute the width of lines that are visible. Optimization only available when word-wrapping is disabled. - // We also don't vertically center the text within the line full height, which is unlikely to matter because we are likely the biggest and only item on the line. + // - From this point we will only compute the width of lines that are visible. Optimization only available when word-wrapping is disabled. + // - We also don't vertically center the text within the line full height, which is unlikely to matter because we are likely the biggest and only item on the line. + // - We use memchr(), pay attention that well optimized versions of those str/mem functions are much faster than a casually written loop. const char* line = text; const float line_height = GetTextLineHeight(); const ImRect clip_rect = window->ClipRect; @@ -153,7 +154,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) int lines_skipped = 0; while (line < text_end && lines_skipped < lines_skippable) { - const char* line_end = strchr(line, '\n'); + const char* line_end = (const char*)memchr(line, '\n', text_end - line); if (!line_end) line_end = text_end; line = line_end + 1; @@ -169,15 +170,15 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) ImRect line_rect(pos, pos + ImVec2(FLT_MAX, line_height)); while (line < text_end) { - const char* line_end = strchr(line, '\n'); if (IsClippedEx(line_rect, 0, false)) break; + const char* line_end = (const char*)memchr(line, '\n', text_end - line); + if (!line_end) + line_end = text_end; const ImVec2 line_size = CalcTextSize(line, line_end, false); text_size.x = ImMax(text_size.x, line_size.x); RenderText(pos, line, line_end, false); - if (!line_end) - line_end = text_end; line = line_end + 1; line_rect.Min.y += line_height; line_rect.Max.y += line_height; @@ -188,7 +189,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) int lines_skipped = 0; while (line < text_end) { - const char* line_end = strchr(line, '\n'); + const char* line_end = (const char*)memchr(line, '\n', text_end - line); if (!line_end) line_end = text_end; line = line_end + 1;