mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-24 05:19:02 +08:00
TextUnformatted: Using memchr(), fixed not properly testing for text_end bound + comments.
Internals: Added ImStreolRange() + used in LogRenderedText() + comments.
This commit is contained in:
parent
d02b11dfbd
commit
cf0afb48ac
@ -56,6 +56,8 @@ Other Changes:
|
|||||||
- BeginChild(): Fixed BeginChild(const char*, ...) variation erroneously not applying the ID stack
|
- BeginChild(): Fixed BeginChild(const char*, ...) variation erroneously not applying the ID stack
|
||||||
to the provided string to uniquely identify the child window. This was undoing an intentional change
|
to the provided string to uniquely identify the child window. This was undoing an intentional change
|
||||||
introduced in 1.50 and broken in 1.60. (#1698, #894, #713).
|
introduced in 1.50 and broken in 1.60. (#1698, #894, #713).
|
||||||
|
- TextUnformatted(): Fixed a case where large-text path would read bytes past the text_end marker depending
|
||||||
|
on the position of new lines in the buffer (it wasn't affecting the output but still not the right thing to do!)
|
||||||
- BeginMenu(): Fixed menu popup horizontal offset being off the item in the menu bar when WindowPadding=0.0f.
|
- BeginMenu(): Fixed menu popup horizontal offset being off the item in the menu bar when WindowPadding=0.0f.
|
||||||
- ArrowButton(): Fixed arrow shape being horizontally misaligned by (FramePadding.y-FramePadding.x) if they are different.
|
- ArrowButton(): Fixed arrow shape being horizontally misaligned by (FramePadding.y-FramePadding.x) if they are different.
|
||||||
- Drag and Drop: Added GetDragDropPayload() to peek directly into the payload (if any) from anywhere. (#143)
|
- Drag and Drop: Added GetDragDropPayload() to peek directly into the payload (if any) from anywhere. (#143)
|
||||||
|
41
imgui.cpp
41
imgui.cpp
@ -1203,10 +1203,8 @@ char* ImStrdup(const char *str)
|
|||||||
|
|
||||||
const char* ImStrchrRange(const char* str, const char* str_end, char c)
|
const char* ImStrchrRange(const char* str, const char* str_end, char c)
|
||||||
{
|
{
|
||||||
for ( ; str < str_end; str++)
|
const char* p = (const char*)memchr(str, (int)c, str_end - str);
|
||||||
if (*str == c)
|
return p;
|
||||||
return str;
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ImStrlenW(const ImWchar* str)
|
int ImStrlenW(const ImWchar* str)
|
||||||
@ -1216,6 +1214,13 @@ int ImStrlenW(const ImWchar* str)
|
|||||||
return n;
|
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
|
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')
|
while (buf_mid_line > buf_begin && buf_mid_line[-1] != '\n')
|
||||||
@ -8343,29 +8348,17 @@ void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char*
|
|||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
// Split the string. Each new line (after a '\n') is followed by spacing corresponding to the current depth of our log entry.
|
// 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;
|
const char* line_start = text_remaining;
|
||||||
while (line_end < text_end)
|
const char* line_end = ImStreolRange(line_start, text_end);
|
||||||
if (*line_end == '\n')
|
const bool is_first_line = (line_start == text);
|
||||||
break;
|
const bool is_last_line = (line_end == text_end);
|
||||||
else
|
if (!is_last_line || (line_start != line_end))
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
is_last_line = true;
|
const int char_count = (int)(line_end - line_start);
|
||||||
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);
|
|
||||||
if (log_new_line || !is_first_line)
|
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
|
else
|
||||||
LogText(" %.*s", char_count, text_remaining);
|
LogText(" %.*s", char_count, line_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_last_line)
|
if (is_last_line)
|
||||||
|
@ -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 char* ImStrdup(const char* str);
|
||||||
IMGUI_API const char* ImStrchrRange(const char* str_begin, const char* str_end, char c);
|
IMGUI_API const char* ImStrchrRange(const char* str_begin, const char* str_end, char c);
|
||||||
IMGUI_API int ImStrlenW(const ImWchar* str);
|
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 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 void ImStrTrimBlanks(char* str);
|
||||||
IMGUI_API int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) IM_FMTARGS(3);
|
IMGUI_API int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) IM_FMTARGS(3);
|
||||||
|
@ -133,8 +133,9 @@ void ImGui::TextUnformatted(const char* text, const char* text_end)
|
|||||||
{
|
{
|
||||||
// Long text!
|
// Long text!
|
||||||
// Perform manual coarse clipping to optimize for long multi-line 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.
|
// - 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 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 char* line = text;
|
||||||
const float line_height = GetTextLineHeight();
|
const float line_height = GetTextLineHeight();
|
||||||
const ImRect clip_rect = window->ClipRect;
|
const ImRect clip_rect = window->ClipRect;
|
||||||
@ -153,7 +154,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end)
|
|||||||
int lines_skipped = 0;
|
int lines_skipped = 0;
|
||||||
while (line < text_end && lines_skipped < lines_skippable)
|
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)
|
if (!line_end)
|
||||||
line_end = text_end;
|
line_end = text_end;
|
||||||
line = line_end + 1;
|
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));
|
ImRect line_rect(pos, pos + ImVec2(FLT_MAX, line_height));
|
||||||
while (line < text_end)
|
while (line < text_end)
|
||||||
{
|
{
|
||||||
const char* line_end = strchr(line, '\n');
|
|
||||||
if (IsClippedEx(line_rect, 0, false))
|
if (IsClippedEx(line_rect, 0, false))
|
||||||
break;
|
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);
|
const ImVec2 line_size = CalcTextSize(line, line_end, false);
|
||||||
text_size.x = ImMax(text_size.x, line_size.x);
|
text_size.x = ImMax(text_size.x, line_size.x);
|
||||||
RenderText(pos, line, line_end, false);
|
RenderText(pos, line, line_end, false);
|
||||||
if (!line_end)
|
|
||||||
line_end = text_end;
|
|
||||||
line = line_end + 1;
|
line = line_end + 1;
|
||||||
line_rect.Min.y += line_height;
|
line_rect.Min.y += line_height;
|
||||||
line_rect.Max.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;
|
int lines_skipped = 0;
|
||||||
while (line < text_end)
|
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)
|
if (!line_end)
|
||||||
line_end = text_end;
|
line_end = text_end;
|
||||||
line = line_end + 1;
|
line = line_end + 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user