mirror of
				https://github.com/ocornut/imgui.git
				synced 2025-11-04 01:34:32 +00:00 
			
		
		
		
	RenderText(), InputTextMultiline(): Optimization for large text by using memchr, wmemchr, wcschr when appropriate.
This commit is contained in:
		@@ -59,6 +59,7 @@ Other Changes:
 | 
				
			|||||||
  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
 | 
					- 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!) 
 | 
					  on the position of new lines in the buffer (it wasn't affecting the output but still not the right thing to do!) 
 | 
				
			||||||
 | 
					- InputTextMultiline(), RenderText(): Some optimization for very large text buffers, useful for non-optimized builds.
 | 
				
			||||||
- 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)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -850,6 +850,7 @@ CODE
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <ctype.h>      // toupper, isprint
 | 
					#include <ctype.h>      // toupper, isprint
 | 
				
			||||||
#include <stdio.h>      // vsnprintf, sscanf, printf
 | 
					#include <stdio.h>      // vsnprintf, sscanf, printf
 | 
				
			||||||
 | 
					#include <wchar.h>      // wcslen
 | 
				
			||||||
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
 | 
					#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
 | 
				
			||||||
#include <stddef.h>     // intptr_t
 | 
					#include <stddef.h>     // intptr_t
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
@@ -1210,9 +1211,7 @@ const char* ImStrchrRange(const char* str, const char* str_end, char c)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int ImStrlenW(const ImWchar* str)
 | 
					int ImStrlenW(const ImWchar* str)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int n = 0;
 | 
					    return (int)wcslen((const wchar_t*)str);
 | 
				
			||||||
    while (*str++) n++;
 | 
					 | 
				
			||||||
    return n;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 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.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2646,11 +2646,11 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
 | 
				
			|||||||
    // Fast-forward to first visible line
 | 
					    // Fast-forward to first visible line
 | 
				
			||||||
    const char* s = text_begin;
 | 
					    const char* s = text_begin;
 | 
				
			||||||
    if (y + line_height < clip_rect.y && !word_wrap_enabled)
 | 
					    if (y + line_height < clip_rect.y && !word_wrap_enabled)
 | 
				
			||||||
        while (y + line_height < clip_rect.y)
 | 
					        while (y + line_height < clip_rect.y && s < text_end)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            while (s < text_end)
 | 
					            s = (const char*)memchr(s, '\n', text_end - s) + 1;
 | 
				
			||||||
                if (*s++ == '\n')
 | 
					            if (s == NULL)
 | 
				
			||||||
                    break;
 | 
					                s = text_end;
 | 
				
			||||||
            y += line_height;
 | 
					            y += line_height;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2660,15 +2660,15 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        const char* s_end = s;
 | 
					        const char* s_end = s;
 | 
				
			||||||
        float y_end = y;
 | 
					        float y_end = y;
 | 
				
			||||||
        while (y_end < clip_rect.w)
 | 
					        while (y_end < clip_rect.w && s_end < text_end)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            while (s_end < text_end)
 | 
					            s_end = (const char*)memchr(s_end, '\n', text_end - s_end) + 1;
 | 
				
			||||||
                if (*s_end++ == '\n')
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
            y_end += line_height;
 | 
					            y_end += line_height;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        text_end = s_end;
 | 
					        text_end = s_end;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (s == text_end)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Reserve vertices for remaining worse case (over-reserving is useful and easily amortized)
 | 
					    // Reserve vertices for remaining worse case (over-reserving is useful and easily amortized)
 | 
				
			||||||
    const int vtx_count_max = (int)(text_end - s) * 4;
 | 
					    const int vtx_count_max = (int)(text_end - s) * 4;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,6 +36,7 @@ Index of this file:
 | 
				
			|||||||
#include "imgui_internal.h"
 | 
					#include "imgui_internal.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <ctype.h>      // toupper, isprint
 | 
					#include <ctype.h>      // toupper, isprint
 | 
				
			||||||
 | 
					#include <wchar.h>      // wmemchr
 | 
				
			||||||
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
 | 
					#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
 | 
				
			||||||
#include <stddef.h>     // intptr_t
 | 
					#include <stddef.h>     // intptr_t
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
@@ -2906,7 +2907,7 @@ static void STB_TEXTEDIT_DELETECHARS(STB_TEXTEDIT_STRING* obj, int pos, int n)
 | 
				
			|||||||
    obj->CurLenA -= ImTextCountUtf8BytesFromStr(dst, dst + n);
 | 
					    obj->CurLenA -= ImTextCountUtf8BytesFromStr(dst, dst + n);
 | 
				
			||||||
    obj->CurLenW -= n;
 | 
					    obj->CurLenW -= n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Offset remaining text
 | 
					    // Offset remaining text (FIXME-OPT: Use memmove)
 | 
				
			||||||
    const ImWchar* src = obj->TextW.Data + pos + n;
 | 
					    const ImWchar* src = obj->TextW.Data + pos + n;
 | 
				
			||||||
    while (ImWchar c = *src++)
 | 
					    while (ImWchar c = *src++)
 | 
				
			||||||
        *dst++ = c;
 | 
					        *dst++ = c;
 | 
				
			||||||
@@ -3617,13 +3618,12 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
 | 
				
			|||||||
            // In multi-line mode, we never exit the loop until all lines are counted, so add one extra to the searches_remaining counter.
 | 
					            // In multi-line mode, we never exit the loop until all lines are counted, so add one extra to the searches_remaining counter.
 | 
				
			||||||
            searches_remaining += is_multiline ? 1 : 0;
 | 
					            searches_remaining += is_multiline ? 1 : 0;
 | 
				
			||||||
            int line_count = 0;
 | 
					            int line_count = 0;
 | 
				
			||||||
            for (const ImWchar* s = text_begin; *s != 0; s++)
 | 
					            for (const ImWchar* s = text_begin; (s = (const ImWchar*)wcschr((const wchar_t*)s, (wchar_t)'\n')) != NULL; s++)
 | 
				
			||||||
                if (*s == '\n')
 | 
					            {
 | 
				
			||||||
                {
 | 
					                line_count++;
 | 
				
			||||||
                    line_count++;
 | 
					                if (searches_result_line_number[0] == -1 && s >= searches_input_ptr[0]) { searches_result_line_number[0] = line_count; if (--searches_remaining <= 0) break; }
 | 
				
			||||||
                    if (searches_result_line_number[0] == -1 && s >= searches_input_ptr[0]) { searches_result_line_number[0] = line_count; if (--searches_remaining <= 0) break; }
 | 
					                if (searches_result_line_number[1] == -1 && s >= searches_input_ptr[1]) { searches_result_line_number[1] = line_count; if (--searches_remaining <= 0) break; }
 | 
				
			||||||
                    if (searches_result_line_number[1] == -1 && s >= searches_input_ptr[1]) { searches_result_line_number[1] = line_count; if (--searches_remaining <= 0) break; }
 | 
					            }
 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            line_count++;
 | 
					            line_count++;
 | 
				
			||||||
            if (searches_result_line_number[0] == -1) searches_result_line_number[0] = line_count;
 | 
					            if (searches_result_line_number[0] == -1) searches_result_line_number[0] = line_count;
 | 
				
			||||||
            if (searches_result_line_number[1] == -1) searches_result_line_number[1] = line_count;
 | 
					            if (searches_result_line_number[1] == -1) searches_result_line_number[1] = line_count;
 | 
				
			||||||
@@ -3691,9 +3691,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
 | 
				
			|||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                if (rect_pos.y < clip_rect.y)
 | 
					                if (rect_pos.y < clip_rect.y)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    while (p < text_selected_end)
 | 
					                    p = (const ImWchar*)wmemchr((const wchar_t*)p, '\n', text_selected_end - p) + 1;
 | 
				
			||||||
                        if (*p++ == '\n')
 | 
					 | 
				
			||||||
                            break;
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user