1
0
Fork 0
mirror of https://github.com/ocornut/imgui.git synced 2026-01-11 00:04:24 +00:00

Internals: added ImStrlen/ImMemchr #define to facilitate experimenting with variations. (#8421)

This commit is contained in:
ocornut 2025-03-07 11:09:02 +01:00
parent 377a387a42
commit 1ec99f4fd3
5 changed files with 56 additions and 53 deletions

View file

@ -1986,15 +1986,15 @@ void ImStrncpy(char* dst, const char* src, size_t count)
char* ImStrdup(const char* str) char* ImStrdup(const char* str)
{ {
size_t len = strlen(str); size_t len = ImStrlen(str);
void* buf = IM_ALLOC(len + 1); void* buf = IM_ALLOC(len + 1);
return (char*)memcpy(buf, (const void*)str, len + 1); return (char*)memcpy(buf, (const void*)str, len + 1);
} }
char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* src) char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* src)
{ {
size_t dst_buf_size = p_dst_size ? *p_dst_size : strlen(dst) + 1; size_t dst_buf_size = p_dst_size ? *p_dst_size : ImStrlen(dst) + 1;
size_t src_size = strlen(src) + 1; size_t src_size = ImStrlen(src) + 1;
if (dst_buf_size < src_size) if (dst_buf_size < src_size)
{ {
IM_FREE(dst); IM_FREE(dst);
@ -2007,7 +2007,7 @@ char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* src)
const char* ImStrchrRange(const char* str, const char* str_end, char c) const char* ImStrchrRange(const char* str, const char* str_end, char c)
{ {
const char* p = (const char*)memchr(str, (int)c, str_end - str); const char* p = (const char*)ImMemchr(str, (int)c, str_end - str);
return p; return p;
} }
@ -2022,13 +2022,13 @@ int ImStrlenW(const ImWchar* str)
// Find end-of-line. Return pointer will point to either first \n, either str_end. // 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* ImStreolRange(const char* str, const char* str_end)
{ {
const char* p = (const char*)memchr(str, '\n', str_end - str); const char* p = (const char*)ImMemchr(str, '\n', str_end - str);
return p ? p : str_end; return p ? p : str_end;
} }
const char* ImStrbol(const char* buf_mid_line, const char* buf_begin) // find beginning-of-line const char* ImStrbol(const char* buf_mid_line, const char* buf_begin) // find beginning-of-line
{ {
IM_ASSERT_PARANOID(buf_mid_line >= buf_begin && buf_mid_line <= buf_begin + strlen(buf_begin)); IM_ASSERT_PARANOID(buf_mid_line >= buf_begin && buf_mid_line <= buf_begin + ImStrlen(buf_begin));
while (buf_mid_line > buf_begin && buf_mid_line[-1] != '\n') while (buf_mid_line > buf_begin && buf_mid_line[-1] != '\n')
buf_mid_line--; buf_mid_line--;
return buf_mid_line; return buf_mid_line;
@ -2037,7 +2037,7 @@ const char* ImStrbol(const char* buf_mid_line, const char* buf_begin) // find be
const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end) const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end)
{ {
if (!needle_end) if (!needle_end)
needle_end = needle + strlen(needle); needle_end = needle + ImStrlen(needle);
const char un0 = (char)ImToUpper(*needle); const char un0 = (char)ImToUpper(*needle);
while ((!haystack_end && *haystack) || (haystack_end && haystack < haystack_end)) while ((!haystack_end && *haystack) || (haystack_end && haystack < haystack_end))
@ -2158,7 +2158,7 @@ void ImFormatStringToTempBufferV(const char** out_buf, const char** out_buf_end,
if (buf == NULL) if (buf == NULL)
buf = "(null)"; buf = "(null)";
*out_buf = buf; *out_buf = buf;
if (out_buf_end) { *out_buf_end = buf + strlen(buf); } if (out_buf_end) { *out_buf_end = buf + ImStrlen(buf); }
} }
else if (fmt[0] == '%' && fmt[1] == '.' && fmt[2] == '*' && fmt[3] == 's' && fmt[4] == 0) else if (fmt[0] == '%' && fmt[1] == '.' && fmt[2] == '*' && fmt[3] == 's' && fmt[4] == 0)
{ {
@ -2567,11 +2567,11 @@ const char* ImTextFindPreviousUtf8Codepoint(const char* in_text_start, const cha
int ImTextCountLines(const char* in_text, const char* in_text_end) int ImTextCountLines(const char* in_text, const char* in_text_end)
{ {
if (in_text_end == NULL) if (in_text_end == NULL)
in_text_end = in_text + strlen(in_text); // FIXME-OPT: Not optimal approach, discourage use for now. in_text_end = in_text + ImStrlen(in_text); // FIXME-OPT: Not optimal approach, discourage use for now.
int count = 0; int count = 0;
while (in_text < in_text_end) while (in_text < in_text_end)
{ {
const char* line_end = (const char*)memchr(in_text, '\n', in_text_end - in_text); const char* line_end = (const char*)ImMemchr(in_text, '\n', in_text_end - in_text);
in_text = line_end ? line_end + 1 : in_text_end; in_text = line_end ? line_end + 1 : in_text_end;
count++; count++;
} }
@ -2852,7 +2852,7 @@ void ImGuiTextFilter::ImGuiTextRange::split(char separator, ImVector<ImGuiTextRa
void ImGuiTextFilter::Build() void ImGuiTextFilter::Build()
{ {
Filters.resize(0); Filters.resize(0);
ImGuiTextRange input_range(InputBuf, InputBuf + strlen(InputBuf)); ImGuiTextRange input_range(InputBuf, InputBuf + ImStrlen(InputBuf));
input_range.split(',', &Filters); input_range.split(',', &Filters);
CountGrep = 0; CountGrep = 0;
@ -2920,7 +2920,7 @@ char ImGuiTextBuffer::EmptyString[1] = { 0 };
void ImGuiTextBuffer::append(const char* str, const char* str_end) void ImGuiTextBuffer::append(const char* str, const char* str_end)
{ {
int len = str_end ? (int)(str_end - str) : (int)strlen(str); int len = str_end ? (int)(str_end - str) : (int)ImStrlen(str);
// Add zero-terminator the first time // Add zero-terminator the first time
const int write_off = (Buf.Size != 0) ? Buf.Size : 1; const int write_off = (Buf.Size != 0) ? Buf.Size : 1;
@ -2979,7 +2979,7 @@ void ImGuiTextIndex::append(const char* base, int old_size, int new_size)
if (EndOffset == 0 || base[EndOffset - 1] == '\n') if (EndOffset == 0 || base[EndOffset - 1] == '\n')
LineOffsets.push_back(EndOffset); LineOffsets.push_back(EndOffset);
const char* base_end = base + new_size; const char* base_end = base + new_size;
for (const char* p = base + old_size; (p = (const char*)memchr(p, '\n', base_end - p)) != 0; ) for (const char* p = base + old_size; (p = (const char*)ImMemchr(p, '\n', base_end - p)) != 0; )
if (++p < base_end) // Don't push a trailing offset on last \n if (++p < base_end) // Don't push a trailing offset on last \n
LineOffsets.push_back((int)(intptr_t)(p - base)); LineOffsets.push_back((int)(intptr_t)(p - base));
EndOffset = ImMax(EndOffset, new_size); EndOffset = ImMax(EndOffset, new_size);
@ -3603,7 +3603,7 @@ void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool
else else
{ {
if (!text_end) if (!text_end)
text_end = text + strlen(text); // FIXME-OPT text_end = text + ImStrlen(text); // FIXME-OPT
text_display_end = text_end; text_display_end = text_end;
} }
@ -3621,7 +3621,7 @@ void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
if (!text_end) if (!text_end)
text_end = text + strlen(text); // FIXME-OPT text_end = text + ImStrlen(text); // FIXME-OPT
if (text != text_end) if (text != text_end)
{ {
@ -4294,7 +4294,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* ctx, const char* name) : DrawListInst(NUL
memset(this, 0, sizeof(*this)); memset(this, 0, sizeof(*this));
Ctx = ctx; Ctx = ctx;
Name = ImStrdup(name); Name = ImStrdup(name);
NameBufLen = (int)strlen(name) + 1; NameBufLen = (int)ImStrlen(name) + 1;
ID = ImHashStr(name); ID = ImHashStr(name);
IDStack.push_back(ID); IDStack.push_back(ID);
MoveId = GetID("#MOVE"); MoveId = GetID("#MOVE");
@ -8829,7 +8829,7 @@ const char* ImGui::GetKeyChordName(ImGuiKeyChord key_chord)
(key != ImGuiKey_None || key_chord == ImGuiKey_None) ? GetKeyName(key) : ""); (key != ImGuiKey_None || key_chord == ImGuiKey_None) ? GetKeyName(key) : "");
size_t len; size_t len;
if (key == ImGuiKey_None && key_chord != 0) if (key == ImGuiKey_None && key_chord != 0)
if ((len = strlen(g.TempKeychordName)) != 0) // Remove trailing '+' if ((len = ImStrlen(g.TempKeychordName)) != 0) // Remove trailing '+'
g.TempKeychordName[len - 1] = 0; g.TempKeychordName[len - 1] = 0;
return g.TempKeychordName; return g.TempKeychordName;
} }
@ -14134,7 +14134,7 @@ bool ImGui::SetDragDropPayload(const char* type, const void* data, size_t data_s
cond = ImGuiCond_Always; cond = ImGuiCond_Always;
IM_ASSERT(type != NULL); IM_ASSERT(type != NULL);
IM_ASSERT(strlen(type) < IM_ARRAYSIZE(payload.DataType) && "Payload type can be at most 32 characters long"); IM_ASSERT(ImStrlen(type) < IM_ARRAYSIZE(payload.DataType) && "Payload type can be at most 32 characters long");
IM_ASSERT((data != NULL && data_size > 0) || (data == NULL && data_size == 0)); IM_ASSERT((data != NULL && data_size > 0) || (data == NULL && data_size == 0));
IM_ASSERT(cond == ImGuiCond_Always || cond == ImGuiCond_Once); IM_ASSERT(cond == ImGuiCond_Always || cond == ImGuiCond_Once);
IM_ASSERT(payload.SourceId != 0); // Not called between BeginDragDropSource() and EndDragDropSource() IM_ASSERT(payload.SourceId != 0); // Not called between BeginDragDropSource() and EndDragDropSource()
@ -14378,7 +14378,7 @@ void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char*
} }
if (prefix) if (prefix)
LogRenderedText(ref_pos, prefix, prefix + strlen(prefix)); // Calculate end ourself to ensure "##" are included here. LogRenderedText(ref_pos, prefix, prefix + ImStrlen(prefix)); // Calculate end ourself to ensure "##" are included here.
// Re-adjust padding if we have popped out of our starting depth // Re-adjust padding if we have popped out of our starting depth
if (g.LogDepthRef > window->DC.TreeDepth) if (g.LogDepthRef > window->DC.TreeDepth)
@ -14411,7 +14411,7 @@ void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char*
} }
if (suffix) if (suffix)
LogRenderedText(ref_pos, suffix, suffix + strlen(suffix)); LogRenderedText(ref_pos, suffix, suffix + ImStrlen(suffix));
} }
// Start logging/capturing text output // Start logging/capturing text output
@ -14677,7 +14677,7 @@ void ImGui::LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size)
// For user convenience, we allow passing a non zero-terminated string (hence the ini_size parameter). // For user convenience, we allow passing a non zero-terminated string (hence the ini_size parameter).
// For our convenience and to make the code simpler, we'll also write zero-terminators within the buffer. So let's create a writable copy.. // For our convenience and to make the code simpler, we'll also write zero-terminators within the buffer. So let's create a writable copy..
if (ini_size == 0) if (ini_size == 0)
ini_size = strlen(ini_data); ini_size = ImStrlen(ini_data);
g.SettingsIniData.Buf.resize((int)ini_size + 1); g.SettingsIniData.Buf.resize((int)ini_size + 1);
char* const buf = g.SettingsIniData.Buf.Data; char* const buf = g.SettingsIniData.Buf.Data;
char* const buf_end = buf + ini_size; char* const buf_end = buf + ini_size;
@ -14778,7 +14778,7 @@ ImGuiWindowSettings* ImGui::CreateNewWindowSettings(const char* name)
if (const char* p = strstr(name, "###")) if (const char* p = strstr(name, "###"))
name = p; name = p;
} }
const size_t name_len = strlen(name); const size_t name_len = ImStrlen(name);
// Allocate chunk // Allocate chunk
const size_t chunk_size = sizeof(ImGuiWindowSettings) + name_len + 1; const size_t chunk_size = sizeof(ImGuiWindowSettings) + name_len + 1;
@ -15070,7 +15070,7 @@ static void Platform_SetClipboardTextFn_DefaultImpl(ImGuiContext*, const char* t
if (!main_clipboard) if (!main_clipboard)
PasteboardCreate(kPasteboardClipboard, &main_clipboard); PasteboardCreate(kPasteboardClipboard, &main_clipboard);
PasteboardClear(main_clipboard); PasteboardClear(main_clipboard);
CFDataRef cf_data = CFDataCreate(kCFAllocatorDefault, (const UInt8*)text, strlen(text)); CFDataRef cf_data = CFDataCreate(kCFAllocatorDefault, (const UInt8*)text, ImStrlen(text));
if (cf_data) if (cf_data)
{ {
PasteboardPutItemFlavor(main_clipboard, (PasteboardItemID)1, CFSTR("public.utf8-plain-text"), cf_data, 0); PasteboardPutItemFlavor(main_clipboard, (PasteboardItemID)1, CFSTR("public.utf8-plain-text"), cf_data, 0);
@ -15124,7 +15124,7 @@ static void Platform_SetClipboardTextFn_DefaultImpl(ImGuiContext* ctx, const cha
{ {
ImGuiContext& g = *ctx; ImGuiContext& g = *ctx;
g.ClipboardHandlerData.clear(); g.ClipboardHandlerData.clear();
const char* text_end = text + strlen(text); const char* text_end = text + ImStrlen(text);
g.ClipboardHandlerData.resize((int)(text_end - text) + 1); g.ClipboardHandlerData.resize((int)(text_end - text) + 1);
memcpy(&g.ClipboardHandlerData[0], text, (size_t)(text_end - text)); memcpy(&g.ClipboardHandlerData[0], text, (size_t)(text_end - text));
g.ClipboardHandlerData[(int)(text_end - text)] = 0; g.ClipboardHandlerData[(int)(text_end - text)] = 0;
@ -16894,7 +16894,7 @@ void ImGui::DebugHookIdInfo(ImGuiID id, ImGuiDataType data_type, const void* dat
ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "%d", (int)(intptr_t)data_id); ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "%d", (int)(intptr_t)data_id);
break; break;
case ImGuiDataType_String: case ImGuiDataType_String:
ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "%.*s", data_id_end ? (int)((const char*)data_id_end - (const char*)data_id) : (int)strlen((const char*)data_id), (const char*)data_id); ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "%.*s", data_id_end ? (int)((const char*)data_id_end - (const char*)data_id) : (int)ImStrlen((const char*)data_id), (const char*)data_id);
break; break;
case ImGuiDataType_Pointer: case ImGuiDataType_Pointer:
ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "(void*)0x%p", data_id); ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "(void*)0x%p", data_id);

View file

@ -143,6 +143,7 @@ namespace IMGUI_STB_NAMESPACE
#define STBTT_fabs(x) ImFabs(x) #define STBTT_fabs(x) ImFabs(x)
#define STBTT_ifloor(x) ((int)ImFloor(x)) #define STBTT_ifloor(x) ((int)ImFloor(x))
#define STBTT_iceil(x) ((int)ImCeil(x)) #define STBTT_iceil(x) ((int)ImCeil(x))
#define STBTT_strlen(x) ImStrlen(x)
#define STBTT_STATIC #define STBTT_STATIC
#define STB_TRUETYPE_IMPLEMENTATION #define STB_TRUETYPE_IMPLEMENTATION
#else #else
@ -2672,7 +2673,7 @@ ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels,
{ {
// Store a short copy of filename into into the font name for convenience // Store a short copy of filename into into the font name for convenience
const char* p; const char* p;
for (p = filename + strlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) {} for (p = filename + ImStrlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) {}
ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "%s, %.0fpx", p, size_pixels); ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "%s, %.0fpx", p, size_pixels);
} }
return AddFontFromMemoryTTF(data, (int)data_size, size_pixels, &font_cfg, glyph_ranges); return AddFontFromMemoryTTF(data, (int)data_size, size_pixels, &font_cfg, glyph_ranges);
@ -2707,7 +2708,7 @@ ImFont* ImFontAtlas::AddFontFromMemoryCompressedTTF(const void* compressed_ttf_d
ImFont* ImFontAtlas::AddFontFromMemoryCompressedBase85TTF(const char* compressed_ttf_data_base85, float size_pixels, const ImFontConfig* font_cfg, const ImWchar* glyph_ranges) ImFont* ImFontAtlas::AddFontFromMemoryCompressedBase85TTF(const char* compressed_ttf_data_base85, float size_pixels, const ImFontConfig* font_cfg, const ImWchar* glyph_ranges)
{ {
int compressed_ttf_size = (((int)strlen(compressed_ttf_data_base85) + 4) / 5) * 4; int compressed_ttf_size = (((int)ImStrlen(compressed_ttf_data_base85) + 4) / 5) * 4;
void* compressed_ttf = IM_ALLOC((size_t)compressed_ttf_size); void* compressed_ttf = IM_ALLOC((size_t)compressed_ttf_size);
Decode85((const unsigned char*)compressed_ttf_data_base85, (unsigned char*)compressed_ttf); Decode85((const unsigned char*)compressed_ttf_data_base85, (unsigned char*)compressed_ttf);
ImFont* font = AddFontFromMemoryCompressedTTF(compressed_ttf, compressed_ttf_size, size_pixels, font_cfg, glyph_ranges); ImFont* font = AddFontFromMemoryCompressedTTF(compressed_ttf, compressed_ttf_size, size_pixels, font_cfg, glyph_ranges);
@ -4029,7 +4030,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining) ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining)
{ {
if (!text_end) if (!text_end)
text_end = text_begin + strlen(text_begin); // FIXME-OPT: Need to avoid this. text_end = text_begin + ImStrlen(text_begin); // FIXME-OPT: Need to avoid this.
const float line_height = size; const float line_height = size;
const float scale = size / FontSize; const float scale = size / FontSize;
@ -4129,7 +4130,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
return; return;
if (!text_end) if (!text_end)
text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls. text_end = text_begin + ImStrlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
const float scale = size / FontSize; const float scale = size / FontSize;
const float line_height = FontSize * scale; const float line_height = FontSize * scale;
@ -4141,7 +4142,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
if (y + line_height < clip_rect.y) if (y + line_height < clip_rect.y)
while (y + line_height < clip_rect.y && s < text_end) while (y + line_height < clip_rect.y && s < text_end)
{ {
const char* line_end = (const char*)memchr(s, '\n', text_end - s); const char* line_end = (const char*)ImMemchr(s, '\n', text_end - s);
if (word_wrap_enabled) if (word_wrap_enabled)
{ {
// FIXME-OPT: This is not optimal as do first do a search for \n before calling CalcWordWrapPositionA(). // FIXME-OPT: This is not optimal as do first do a search for \n before calling CalcWordWrapPositionA().
@ -4165,7 +4166,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
float y_end = y; float y_end = y;
while (y_end < clip_rect.w && s_end < text_end) while (y_end < clip_rect.w && s_end < text_end)
{ {
s_end = (const char*)memchr(s_end, '\n', text_end - s_end); s_end = (const char*)ImMemchr(s_end, '\n', text_end - s_end);
s_end = s_end ? s_end + 1 : text_end; s_end = s_end ? s_end + 1 : text_end;
y_end += line_height; y_end += line_height;
} }

View file

@ -372,6 +372,8 @@ static inline bool ImIsPowerOfTwo(ImU64 v) { return v != 0 && (v &
static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; } static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; }
// Helpers: String // Helpers: String
#define ImStrlen strlen
#define ImMemchr memchr
IMGUI_API int ImStricmp(const char* str1, const char* str2); // Case insensitive compare. IMGUI_API int ImStricmp(const char* str1, const char* str2); // Case insensitive compare.
IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count); // Case insensitive compare to a certain count. IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count); // Case insensitive compare to a certain count.
IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count); // Copy to a certain count and always zero terminate (strncpy doesn't). IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count); // Copy to a certain count and always zero terminate (strncpy doesn't).

View file

@ -1648,7 +1648,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
if (label != NULL && label[0] != 0) if (label != NULL && label[0] != 0)
{ {
column->NameOffset = (ImS16)table->ColumnsNames.size(); column->NameOffset = (ImS16)table->ColumnsNames.size();
table->ColumnsNames.append(label, label + strlen(label) + 1); table->ColumnsNames.append(label, label + ImStrlen(label) + 1);
} }
} }

View file

@ -169,7 +169,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
// Calculate length // Calculate length
const char* text_begin = text; const char* text_begin = text;
if (text_end == NULL) if (text_end == NULL)
text_end = text + strlen(text); // FIXME-OPT text_end = text + ImStrlen(text); // FIXME-OPT
const ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset); const ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
const float wrap_pos_x = window->DC.TextWrapPos; const float wrap_pos_x = window->DC.TextWrapPos;
@ -209,7 +209,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
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 = (const char*)memchr(line, '\n', text_end - line); const char* line_end = (const char*)ImMemchr(line, '\n', text_end - line);
if (!line_end) if (!line_end)
line_end = text_end; line_end = text_end;
if ((flags & ImGuiTextFlags_NoWidthForLargeClippedText) == 0) if ((flags & ImGuiTextFlags_NoWidthForLargeClippedText) == 0)
@ -230,7 +230,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
if (IsClippedEx(line_rect, 0)) if (IsClippedEx(line_rect, 0))
break; break;
const char* line_end = (const char*)memchr(line, '\n', text_end - line); const char* line_end = (const char*)ImMemchr(line, '\n', text_end - line);
if (!line_end) if (!line_end)
line_end = text_end; line_end = text_end;
text_size.x = ImMax(text_size.x, CalcTextSize(line, line_end).x); text_size.x = ImMax(text_size.x, CalcTextSize(line, line_end).x);
@ -245,7 +245,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
int lines_skipped = 0; int lines_skipped = 0;
while (line < text_end) while (line < text_end)
{ {
const char* line_end = (const char*)memchr(line, '\n', text_end - line); const char* line_end = (const char*)ImMemchr(line, '\n', text_end - line);
if (!line_end) if (!line_end)
line_end = text_end; line_end = text_end;
if ((flags & ImGuiTextFlags_NoWidthForLargeClippedText) == 0) if ((flags & ImGuiTextFlags_NoWidthForLargeClippedText) == 0)
@ -2064,7 +2064,7 @@ static const char* Items_SingleStringGetter(void* data, int idx)
{ {
if (idx == items_count) if (idx == items_count)
break; break;
p += strlen(p) + 1; p += ImStrlen(p) + 1;
items_count++; items_count++;
} }
return *p ? p : NULL; return *p ? p : NULL;
@ -2132,7 +2132,7 @@ bool ImGui::Combo(const char* label, int* current_item, const char* items_separa
const char* p = items_separated_by_zeros; // FIXME-OPT: Avoid computing this, or at least only when combo is open const char* p = items_separated_by_zeros; // FIXME-OPT: Avoid computing this, or at least only when combo is open
while (*p) while (*p)
{ {
p += strlen(p) + 1; p += ImStrlen(p) + 1;
items_count++; items_count++;
} }
bool value_changed = Combo(label, current_item, Items_SingleStringGetter, (void*)items_separated_by_zeros, items_count, height_in_items); bool value_changed = Combo(label, current_item, Items_SingleStringGetter, (void*)items_separated_by_zeros, items_count, height_in_items);
@ -3899,7 +3899,7 @@ static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char**
line_count++; line_count++;
if (s_eol == NULL) if (s_eol == NULL)
{ {
s = s + strlen(s); s = s + ImStrlen(s);
break; break;
} }
s = s_eol + 1; s = s_eol + 1;
@ -4187,7 +4187,7 @@ void ImGuiInputTextState::OnCharPressed(unsigned int c)
// The changes we had to make to stb_textedit_key made it very much UTF-8 specific which is not too great. // The changes we had to make to stb_textedit_key made it very much UTF-8 specific which is not too great.
char utf8[5]; char utf8[5];
ImTextCharToUtf8(utf8, c); ImTextCharToUtf8(utf8, c);
stb_textedit_text(this, Stb, utf8, (int)strlen(utf8)); stb_textedit_text(this, Stb, utf8, (int)ImStrlen(utf8));
CursorFollow = true; CursorFollow = true;
CursorAnimReset(); CursorAnimReset();
} }
@ -4238,7 +4238,7 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons
// Grow internal buffer if needed // Grow internal buffer if needed
const bool is_resizable = (Flags & ImGuiInputTextFlags_CallbackResize) != 0; const bool is_resizable = (Flags & ImGuiInputTextFlags_CallbackResize) != 0;
const int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)strlen(new_text); const int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)ImStrlen(new_text);
if (new_text_len + BufTextLen >= BufSize) if (new_text_len + BufTextLen >= BufSize)
{ {
if (!is_resizable) if (!is_resizable)
@ -4560,7 +4560,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
const bool init_state = (init_make_active || user_scroll_active); const bool init_state = (init_make_active || user_scroll_active);
if (init_reload_from_user_buf) if (init_reload_from_user_buf)
{ {
int new_len = (int)strlen(buf); int new_len = (int)ImStrlen(buf);
IM_ASSERT(new_len + 1 <= buf_size && "Is your input buffer properly zero-terminated?"); IM_ASSERT(new_len + 1 <= buf_size && "Is your input buffer properly zero-terminated?");
state->WantReloadUserBuf = false; state->WantReloadUserBuf = false;
InputTextReconcileUndoState(state, state->TextA.Data, state->TextLen, buf, new_len); InputTextReconcileUndoState(state, state->TextA.Data, state->TextLen, buf, new_len);
@ -4582,7 +4582,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// Take a copy of the initial buffer value. // Take a copy of the initial buffer value.
// From the moment we focused we are normally ignoring the content of 'buf' (unless we are in read-only mode) // From the moment we focused we are normally ignoring the content of 'buf' (unless we are in read-only mode)
const int buf_len = (int)strlen(buf); const int buf_len = (int)ImStrlen(buf);
IM_ASSERT(buf_len + 1 <= buf_size && "Is your input buffer properly zero-terminated?"); IM_ASSERT(buf_len + 1 <= buf_size && "Is your input buffer properly zero-terminated?");
state->TextToRevertTo.resize(buf_len + 1); // UTF-8. we use +1 to make sure that .Data is always pointing to at least an empty string. state->TextToRevertTo.resize(buf_len + 1); // UTF-8. we use +1 to make sure that .Data is always pointing to at least an empty string.
memcpy(state->TextToRevertTo.Data, buf, buf_len + 1); memcpy(state->TextToRevertTo.Data, buf, buf_len + 1);
@ -4667,7 +4667,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// Read-only mode always ever read from source buffer. Refresh TextLen when active. // Read-only mode always ever read from source buffer. Refresh TextLen when active.
if (is_readonly && state != NULL) if (is_readonly && state != NULL)
state->TextLen = (int)strlen(buf); state->TextLen = (int)ImStrlen(buf);
//if (is_readonly && state != NULL) //if (is_readonly && state != NULL)
// state->TextA.clear(); // Uncomment to facilitate debugging, but we otherwise prefer to keep/amortize th allocation. // state->TextA.clear(); // Uncomment to facilitate debugging, but we otherwise prefer to keep/amortize th allocation.
} }
@ -4946,7 +4946,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if (const char* clipboard = GetClipboardText()) if (const char* clipboard = GetClipboardText())
{ {
// Filter pasted buffer // Filter pasted buffer
const int clipboard_len = (int)strlen(clipboard); const int clipboard_len = (int)ImStrlen(clipboard);
ImVector<char> clipboard_filtered; ImVector<char> clipboard_filtered;
clipboard_filtered.reserve(clipboard_len + 1); clipboard_filtered.reserve(clipboard_len + 1);
for (const char* s = clipboard; *s != 0; ) for (const char* s = clipboard; *s != 0; )
@ -4958,7 +4958,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
continue; continue;
char c_utf8[5]; char c_utf8[5];
ImTextCharToUtf8(c_utf8, c); ImTextCharToUtf8(c_utf8, c);
int out_len = (int)strlen(c_utf8); int out_len = (int)ImStrlen(c_utf8);
clipboard_filtered.resize(clipboard_filtered.Size + out_len); clipboard_filtered.resize(clipboard_filtered.Size + out_len);
memcpy(clipboard_filtered.Data + clipboard_filtered.Size - out_len, c_utf8, out_len); memcpy(clipboard_filtered.Data + clipboard_filtered.Size - out_len, c_utf8, out_len);
} }
@ -5088,7 +5088,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if (buf_dirty) if (buf_dirty)
{ {
// Callback may update buffer and thus set buf_dirty even in read-only mode. // Callback may update buffer and thus set buf_dirty even in read-only mode.
IM_ASSERT(callback_data.BufTextLen == (int)strlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text! IM_ASSERT(callback_data.BufTextLen == (int)ImStrlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text!
InputTextReconcileUndoState(state, state->CallbackTextBackup.Data, state->CallbackTextBackup.Size - 1, callback_data.Buf, callback_data.BufTextLen); InputTextReconcileUndoState(state, state->CallbackTextBackup.Data, state->CallbackTextBackup.Size - 1, callback_data.Buf, callback_data.BufTextLen);
state->TextLen = callback_data.BufTextLen; // Assume correct length and valid UTF-8 from user, saves us an extra strlen() state->TextLen = callback_data.BufTextLen; // Assume correct length and valid UTF-8 from user, saves us an extra strlen()
state->CursorAnimReset(); state->CursorAnimReset();
@ -5187,7 +5187,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if (is_displaying_hint) if (is_displaying_hint)
{ {
buf_display = hint; buf_display = hint;
buf_display_end = hint + strlen(hint); buf_display_end = hint + ImStrlen(hint);
} }
// Render text. We currently only render selection when the widget is active or while scrolling. // Render text. We currently only render selection when the widget is active or while scrolling.
@ -5220,7 +5220,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
int line_count = 1; int line_count = 1;
if (is_multiline) if (is_multiline)
{ {
for (const char* s = text_begin; (s = (const char*)memchr(s, '\n', (size_t)(text_end - s))) != NULL; s++) for (const char* s = text_begin; (s = (const char*)ImMemchr(s, '\n', (size_t)(text_end - s))) != NULL; s++)
{ {
if (cursor_line_no == -1 && s >= cursor_ptr) { cursor_line_no = line_count; } if (cursor_line_no == -1 && s >= cursor_ptr) { cursor_line_no = line_count; }
if (selmin_line_no == -1 && s >= selmin_ptr) { selmin_line_no = line_count; } if (selmin_line_no == -1 && s >= selmin_ptr) { selmin_line_no = line_count; }
@ -5298,7 +5298,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
break; break;
if (rect_pos.y < clip_rect.y) if (rect_pos.y < clip_rect.y)
{ {
p = (const char*)memchr((void*)p, '\n', text_selected_end - p); p = (const char*)ImMemchr((void*)p, '\n', text_selected_end - p);
p = p ? p + 1 : text_selected_end; p = p ? p + 1 : text_selected_end;
} }
else else
@ -5350,7 +5350,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
else if (!is_displaying_hint && g.ActiveId == id) else if (!is_displaying_hint && g.ActiveId == id)
buf_display_end = buf_display + state->TextLen; buf_display_end = buf_display + state->TextLen;
else if (!is_displaying_hint) else if (!is_displaying_hint)
buf_display_end = buf_display + strlen(buf_display); buf_display_end = buf_display + ImStrlen(buf_display);
if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length) if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length)
{ {
@ -7184,7 +7184,7 @@ ImGuiTypingSelectRequest* ImGui::GetTypingSelectRequest(ImGuiTypingSelectFlags f
// Append to buffer // Append to buffer
const int buffer_max_len = IM_ARRAYSIZE(data->SearchBuffer) - 1; const int buffer_max_len = IM_ARRAYSIZE(data->SearchBuffer) - 1;
int buffer_len = (int)strlen(data->SearchBuffer); int buffer_len = (int)ImStrlen(data->SearchBuffer);
bool select_request = false; bool select_request = false;
for (ImWchar w : g.IO.InputQueueCharacters) for (ImWchar w : g.IO.InputQueueCharacters)
{ {
@ -10111,7 +10111,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
else else
{ {
tab->NameOffset = (ImS32)tab_bar->TabsNames.size(); tab->NameOffset = (ImS32)tab_bar->TabsNames.size();
tab_bar->TabsNames.append(label, label + strlen(label) + 1); tab_bar->TabsNames.append(label, label + ImStrlen(label) + 1);
} }
// Update selected tab // Update selected tab