1
0
mirror of https://github.com/ocornut/imgui.git synced 2024-09-24 11:38:34 +02:00

Merge branch 'master' into 2016-07-navigation

This commit is contained in:
ocornut 2016-11-09 15:21:36 +01:00
commit 941cf1b436
7 changed files with 103 additions and 44 deletions

View File

@ -103,6 +103,7 @@ The library started its life and is best known as "ImGui" only due to the fact t
<br><b>How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.</b>
<br><b>How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?</b>
<br><b>How can I load a different font than the default?</b>
<br><b>How can I easily use icons in my application?</b>
<br><b>How can I load multiple fonts?</b>
<br><b>How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?</b>
<br><b>How can I use the drawing facilities without an ImGui window? (using ImDrawList API)</b>

View File

@ -4,12 +4,27 @@
Fonts are rasterized in a single texture at the time of calling either of io.Fonts.GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build().
If you want to use icons in ImGui, a good idea is to merge an icon font within your main font, and refer to icons directly in your strings.
You can use headers files with definitions for popular icon fonts codepoints, by Juliette Foucaut, at https://github.com/juliettef/IconFontCppHeaders
---------------------------------
USING ICONS
---------------------------------
Using an icon font (such as FontAwesome: http://fontawesome.io) is an easy and practical way to use icons in your ImGui application.
A common pattern is to merge the icon font within your main font, so you can refer to the icons directly from your strings without having to change fonts back and forth.
To refer to the icon from your C++ code, you can use headers files created by Juliette Foucaut, at https://github.com/juliettef/IconFontCppHeaders
// Merge icons into default tool font
#include "IconsFontAwesome.h"
ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontDefault();
ImFontConfig config;
config.MergeMode = true;
const ImWchar icon_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
io.Fonts->AddFontFromFileTTF("fonts/fontawesome-webfont.ttf", 13.0f, &config, icon_ranges);
// Usage, e.g.
ImGui::Text("%s Search", ICON_FA_SEARCH);
---------------------------------
LOADING INSTRUCTIONS
FONTS LOADING INSTRUCTIONS
---------------------------------
Load default font with:
@ -69,7 +84,7 @@
---------------------------------
REMAP CODEPOINTS
REMAPPING CODEPOINTS
---------------------------------
All your strings needs to use UTF-8 encoding. Specifying literal in your source code using a local code page (such as CP-923 for Japanese CP-1251 for Cyrillic) will not work.
@ -78,7 +93,7 @@
---------------------------------
EMBED A FONT IN SOURCE CODE
EMBEDDING FONT IN SOURCE CODE
---------------------------------
Compile and use 'binary_to_compressed_c.cpp' to create a compressed C style array. Then load the font with:
@ -94,9 +109,16 @@
FONT FILES INCLUDED IN THIS FOLDER
---------------------------------
Roboto-Medium.ttf
Apache License 2.0
by Christian Robertson
https://fonts.google.com/specimen/Roboto
Cousine-Regular.ttf
by Steve Matteson
Digitized data copyright (c) 2010 Google Corporation.
Licensed under the SIL Open Font License, Version 1.1
Licensed under the SIL Open Font License, Version 1.1
https://fonts.google.com/specimen/Cousine
DroidSans.ttf
Copyright (c) Steve Matteson
@ -107,13 +129,15 @@
Copyright (c) 2004, 2005 Tristan Grimmer
MIT License
recommended loading setting in ImGui: Size = 13.0, DisplayOffset.Y = +1
http://www.proggyfonts.net/
ProggyTiny.ttf
Copyright (c) 2004, 2005 Tristan Grimmer
MIT License
recommended loading setting in ImGui: Size = 10.0, DisplayOffset.Y = +1
http://www.proggyfonts.net/
Karla-Regular
Karla-Regular.ttf
Copyright (c) 2012, Jonathan Pinhorn
SIL OPEN FONT LICENSE Version 1.1

Binary file not shown.

View File

@ -31,6 +31,7 @@
- How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
- How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
- How can I load a different font than the default?
- How can I easily use icons in my application?
- How can I load multiple fonts?
- How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
- How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
@ -191,6 +192,7 @@
Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code.
Also read releases logs https://github.com/ocornut/imgui/releases for more details.
- 2016/11/06 (1.50) - BeginChild(const char*) now applies the stack id to the provided label, consistently with other functions as it should always have been. It shouldn't affect you unless (extremely unlikely) you were appending multiple times to a same child from different locations of the stack id. If that's the case, generate an id with GetId() and use it instead of passing string to BeginChild().
- 2016/10/15 (1.50) - avoid 'void* user_data' parameter to io.SetClipboardTextFn/io.GetClipboardTextFn pointers. We pass io.ClipboardUserData to it.
- 2016/09/25 (1.50) - style.WindowTitleAlign is now a ImVec2 (ImGuiAlign enum was removed). set to (0.5f,0.5f) for horizontal+vertical centering, (0.0f,0.0f) for upper-left, etc.
- 2016/07/30 (1.50) - SameLine(x) with x>0.0f is now relative to left of column/group if any, and not always to left of window. This was sort of always the intent and hopefully breakage should be minimal.
@ -449,6 +451,10 @@
io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels);
io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8()
Q: How can I easily use icons in my application?
A: The most convenient and practical way is to merge an icon font such as FontAwesome inside you main font. Then you can refer to icons within your strings.
Read 'How can I load multiple fonts?' and the file 'extra_fonts/README.txt' for instructions.
Q: How can I load multiple fonts?
A: Use the font atlas to pack them into a single texture:
(Read extra_fonts/README.txt and the code in ImFontAtlas for more details.)
@ -468,13 +474,13 @@
config.GlyphExtraSpacing.x = 1.0f;
io.Fonts->LoadFromFileTTF("myfontfile.ttf", size_pixels, &config);
// Combine multiple fonts into one
// Combine multiple fonts into one (e.g. for icon fonts)
ImWchar ranges[] = { 0xf000, 0xf3ff, 0 };
ImFontConfig config;
config.MergeMode = true;
io.Fonts->AddFontDefault();
io.Fonts->LoadFromFileTTF("fontawesome-webfont.ttf", 16.0f, &config, ranges);
io.Fonts->LoadFromFileTTF("myfontfile.ttf", size_pixels, NULL, &config, io.Fonts->GetGlyphRangesJapanese());
io.Fonts->LoadFromFileTTF("fontawesome-webfont.ttf", 16.0f, &config, ranges); // Merge icon font
io.Fonts->LoadFromFileTTF("myfontfile.ttf", size_pixels, NULL, &config, io.Fonts->GetGlyphRangesJapanese()); // Merge japanese glyphs
Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic?
A: When loading a font, pass custom Unicode ranges to specify the glyphs to load.
@ -700,6 +706,7 @@ static float GetDraggedColumnOffset(int column_index);
static bool IsKeyPressedMap(ImGuiKey key, bool repeat = true);
static ImFont* GetDefaultFont();
static void SetCurrentFont(ImFont* font);
static void SetCurrentWindow(ImGuiWindow* window);
static void SetWindowScrollX(ImGuiWindow* window, float new_scroll_x);
@ -865,6 +872,7 @@ ImGuiIO::ImGuiIO()
Fonts = &GImDefaultFontAtlas;
FontGlobalScale = 1.0f;
FontDefault = NULL;
FontAllowUserScaling = false;
DisplayFramebufferScale = ImVec2(1.0f, 1.0f);
DisplayVisibleMin = DisplayVisibleMax = ImVec2(0.0f, 0.0f);
@ -2776,7 +2784,8 @@ void ImGui::NewFrame()
g.Initialized = true;
}
SetCurrentFont(g.IO.Fonts->Fonts[0]);
SetCurrentFont(GetDefaultFont());
IM_ASSERT(g.Font->IsLoaded());
g.Time += g.IO.DeltaTime;
g.FrameCount += 1;
@ -4324,12 +4333,12 @@ bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button)
return BeginPopup(str_id);
}
bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags)
static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags)
{
ImGuiWindow* parent_window = GetCurrentWindow();
ImGuiWindow* parent_window = ImGui::GetCurrentWindow();
ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_ChildWindow;
const ImVec2 content_avail = GetContentRegionAvail();
const ImVec2 content_avail = ImGui::GetContentRegionAvail();
ImVec2 size = ImFloor(size_arg);
const int auto_fit_axises = ((size.x == 0.0f) ? 0x01 : 0x00) | ((size.y == 0.0f) ? 0x02 : 0x00);
if (size.x <= 0.0f)
@ -4341,33 +4350,39 @@ bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border,
flags |= extra_flags;
char title[256];
ImFormatString(title, IM_ARRAYSIZE(title), "%s.%s", parent_window->Name, str_id);
if (name)
ImFormatString(title, IM_ARRAYSIZE(title), "%s.%s.%08X", parent_window->Name, name, id);
else
ImFormatString(title, IM_ARRAYSIZE(title), "%s.%08X", parent_window->Name, id);
bool ret = ImGui::Begin(title, NULL, size, -1.0f, flags);
ImGuiWindow* child_window = GetCurrentWindow();
ImGuiWindow* child_window = ImGui::GetCurrentWindow();
child_window->AutoFitChildAxises = auto_fit_axises;
if (!(parent_window->Flags & ImGuiWindowFlags_ShowBorders))
child_window->Flags &= ~ImGuiWindowFlags_ShowBorders;
// Process navigation-in immediately so NavInit can run on first frame
const ImGuiID id = parent_window->GetChildID(child_window);
//const ImGuiID id = parent_window->GetChildID(child_window);
if (/*!(flags & ImGuiWindowFlags_NavFlattened) &&*/ (child_window->DC.NavLayerActiveFlags != 0 || child_window->DC.NavHasScroll) && GImGui->NavActivateId == id)
{
FocusWindow(child_window);
ImGui::FocusWindow(child_window);
NavInitWindow(child_window, false);
SetActiveIDNoNav(id+1, child_window); // Steal ActiveId with a dummy id so that key-press won't activate child item
ImGui::SetActiveIDNoNav(id+1, child_window); // Steal ActiveId with a dummy id so that key-press won't activate child item
GImGui->ActiveIdSource = ImGuiInputSource_Nav;
}
return ret;
}
bool ImGui::BeginChild(ImGuiID id, const ImVec2& size, bool border, ImGuiWindowFlags extra_flags)
bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags)
{
char str_id[32];
ImFormatString(str_id, IM_ARRAYSIZE(str_id), "child_%08x", id);
bool ret = ImGui::BeginChild(str_id, size, border, extra_flags);
return ret;
ImGuiWindow* window = GetCurrentWindow();
return BeginChildEx(str_id, window->GetID(str_id), size_arg, border, extra_flags);
}
bool ImGui::BeginChild(ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags)
{
return BeginChildEx(NULL, id, size_arg, border, extra_flags);
}
void ImGui::EndChild()
@ -5141,8 +5156,8 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
ImVec2 text_max = window->Pos + ImVec2(window->Size.x, style.FramePadding.y*2 + text_size.y);
ImRect clip_rect;
clip_rect.Max = ImVec2(window->Pos.x + window->Size.x - (p_open ? title_bar_rect.GetHeight() - 3 : style.FramePadding.x), text_max.y); // Match the size of CloseWindowButton()
float pad_left = (flags & ImGuiWindowFlags_NoCollapse) == 0 ? (style.FramePadding.x + g.FontSize + style.ItemInnerSpacing.x) : 0.0f;
float pad_right = (p_open != NULL) ? (style.FramePadding.x + g.FontSize + style.ItemInnerSpacing.x) : 0.0f;
float pad_left = (flags & ImGuiWindowFlags_NoCollapse) == 0 ? (style.FramePadding.x + g.FontSize + style.ItemInnerSpacing.x) : style.FramePadding.x;
float pad_right = (p_open != NULL) ? (style.FramePadding.x + g.FontSize + style.ItemInnerSpacing.x) : style.FramePadding.x;
if (style.WindowTitleAlign.x > 0.0f) pad_right = ImLerp(pad_right, pad_left, style.WindowTitleAlign.x);
text_min.x += pad_left;
text_max.x -= pad_right;
@ -5418,6 +5433,12 @@ float ImGui::CalcItemWidth()
return w;
}
static ImFont* GetDefaultFont()
{
ImGuiContext& g = *GImGui;
return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0];
}
static void SetCurrentFont(ImFont* font)
{
ImGuiContext& g = *GImGui;
@ -5433,7 +5454,7 @@ void ImGui::PushFont(ImFont* font)
{
ImGuiContext& g = *GImGui;
if (!font)
font = g.IO.Fonts->Fonts[0];
font = GetDefaultFont();
SetCurrentFont(font);
g.FontStack.push_back(font);
g.CurrentWindow->DrawList->PushTextureID(font->ContainerAtlas->TexID);
@ -5444,7 +5465,7 @@ void ImGui::PopFont()
ImGuiContext& g = *GImGui;
g.CurrentWindow->DrawList->PopTextureID();
g.FontStack.pop_back();
SetCurrentFont(g.FontStack.empty() ? g.IO.Fonts->Fonts[0] : g.FontStack.back());
SetCurrentFont(g.FontStack.empty() ? GetDefaultFont() : g.FontStack.back());
}
void ImGui::PushItemFlag(ImGuiItemFlags option, bool enabled)

View File

@ -779,6 +779,7 @@ struct ImGuiIO
ImFontAtlas* Fonts; // <auto> // Load and assemble one or more fonts into a single tightly packed texture. Output to Fonts array.
float FontGlobalScale; // = 1.0f // Global scale all fonts
bool FontAllowUserScaling; // = false // Allow user scaling text of individual window with CTRL+Wheel.
ImFont* FontDefault; // = NULL // Font to use on NewFrame(). Use NULL to uses Fonts->Fonts[0].
ImVec2 DisplayFramebufferScale; // = (1.0f,1.0f) // For retina display or other situations where window coordinates are different from framebuffer coordinates. User storage only, presently not used by ImGui.
ImVec2 DisplayVisibleMin; // <unset> (0.0f,0.0f) // If you use DisplaySize as a virtual space larger than your screen, set DisplayVisibleMin/Max to the visible area.
ImVec2 DisplayVisibleMax; // <unset> (0.0f,0.0f) // If the values are the same, we defaults to Min=(0.0f) and Max=DisplaySize

View File

@ -1592,7 +1592,7 @@ void ImGui::ShowTestWindow(bool* p_open)
if (ImGui::TreeNode("Dragging"))
{
ImGui::TextWrapped("You can use ImGui::GetItemActiveDragDelta() to query for the dragged amount on any widget.");
ImGui::TextWrapped("You can use ImGui::GetMouseDragDelta(0) to query for the dragged amount on any widget.");
ImGui::Button("Drag Me");
if (ImGui::IsItemActive())
{
@ -1751,7 +1751,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
ImFont* font = atlas->Fonts[i];
ImGui::BulletText("Font %d: \'%s\', %.2f px, %d glyphs", i, font->ConfigData ? font->ConfigData[0].Name : "", font->FontSize, font->Glyphs.Size);
ImGui::TreePush((void*)(intptr_t)i);
if (i > 0) { ImGui::SameLine(); if (ImGui::SmallButton("Set as default")) { atlas->Fonts[i] = atlas->Fonts[0]; atlas->Fonts[0] = font; } }
ImGui::SameLine(); if (ImGui::SmallButton("Set as default")) ImGui::GetIO().FontDefault = font;
ImGui::PushFont(font);
ImGui::Text("The quick brown fox jumps over the lazy dog");
ImGui::PopFont();
@ -1822,6 +1822,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
ImGui::PopItemWidth();
}
// Demonstrate creating a fullscreen menu bar and populating it.
static void ShowExampleAppMainMenuBar()
{
if (ImGui::BeginMainMenuBar())
@ -1902,6 +1903,7 @@ static void ShowExampleMenuFile()
if (ImGui::MenuItem("Quit", "Alt+F4")) {}
}
// Demonstrate creating a window which gets auto-resized according to its content.
static void ShowExampleAppAutoResize(bool* p_open)
{
if (!ImGui::Begin("Example: Auto-resizing window", p_open, ImGuiWindowFlags_AlwaysAutoResize))
@ -1918,6 +1920,7 @@ static void ShowExampleAppAutoResize(bool* p_open)
ImGui::End();
}
// Demonstrate creating a window with custom resize constraints.
static void ShowExampleAppConstrainedResize(bool* p_open)
{
struct CustomConstraints // Helper functions to demonstrate programmatic constraints
@ -1955,6 +1958,7 @@ static void ShowExampleAppConstrainedResize(bool* p_open)
ImGui::End();
}
// Demonstrate creating a simple static window with no decoration.
static void ShowExampleAppFixedOverlay(bool* p_open)
{
ImGui::SetNextWindowPos(ImVec2(10,10));
@ -1969,10 +1973,12 @@ static void ShowExampleAppFixedOverlay(bool* p_open)
ImGui::End();
}
// Demonstrate using "##" and "###" in identifiers to manipulate ID generation.
// Read section "How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs." about ID.
static void ShowExampleAppManipulatingWindowTitle(bool*)
{
// By default, Windows are uniquely identified by their title.
// You can use the "##" and "###" markers to manipulate the display/ID. Read FAQ at the top of this file!
// You can use the "##" and "###" markers to manipulate the display/ID.
// Using "##" to display same title but have unique identifier.
ImGui::SetNextWindowPos(ImVec2(100,100), ImGuiSetCond_FirstUseEver);
@ -1994,6 +2000,7 @@ static void ShowExampleAppManipulatingWindowTitle(bool*)
ImGui::End();
}
// Demonstrate using the low-level ImDrawList to draw custom shapes.
static void ShowExampleAppCustomRendering(bool* p_open)
{
ImGui::SetNextWindowSize(ImVec2(350,560), ImGuiSetCond_FirstUseEver);
@ -2061,21 +2068,21 @@ static void ShowExampleAppCustomRendering(bool* p_open)
bool adding_preview = false;
ImGui::InvisibleButton("canvas", canvas_size);
ImVec2 mouse_pos_in_canvas = ImVec2(ImGui::GetIO().MousePos.x - canvas_pos.x, ImGui::GetIO().MousePos.y - canvas_pos.y);
if (adding_line)
{
adding_preview = true;
points.push_back(mouse_pos_in_canvas);
if (!ImGui::GetIO().MouseDown[0])
adding_line = adding_preview = false;
}
if (ImGui::IsItemHovered())
{
ImVec2 mouse_pos_in_canvas = ImVec2(ImGui::GetIO().MousePos.x - canvas_pos.x, ImGui::GetIO().MousePos.y - canvas_pos.y);
if (!adding_line && ImGui::IsMouseClicked(0))
{
points.push_back(mouse_pos_in_canvas);
adding_line = true;
}
if (adding_line)
{
adding_preview = true;
points.push_back(mouse_pos_in_canvas);
if (!ImGui::GetIO().MouseDown[0])
adding_line = adding_preview = false;
}
if (ImGui::IsMouseClicked(1) && !points.empty())
{
adding_line = adding_preview = false;
@ -2093,6 +2100,7 @@ static void ShowExampleAppCustomRendering(bool* p_open)
ImGui::End();
}
// Demonstrating creating a simple console window, with scrolling, filtering, completion and history.
// For the console example, here we are using a more C++ like approach of declaring a class to hold the data and the functions.
struct ExampleAppConsole
{
@ -2445,6 +2453,7 @@ struct ExampleAppLog
}
};
// Demonstrate creating a simple log window with basic filtering.
static void ShowExampleAppLog(bool* p_open)
{
static ExampleAppLog log;
@ -2462,6 +2471,7 @@ static void ShowExampleAppLog(bool* p_open)
log.Draw("Example: Log", p_open);
}
// Demonstrate create a window with multiple child windows.
static void ShowExampleAppLayout(bool* p_open)
{
ImGui::SetNextWindowSize(ImVec2(500, 440), ImGuiSetCond_FirstUseEver);
@ -2507,6 +2517,7 @@ static void ShowExampleAppLayout(bool* p_open)
ImGui::End();
}
// Demonstrate create a simple property editor.
static void ShowExampleAppPropertyEditor(bool* p_open)
{
ImGui::SetNextWindowSize(ImVec2(430,450), ImGuiSetCond_FirstUseEver);
@ -2579,6 +2590,7 @@ static void ShowExampleAppPropertyEditor(bool* p_open)
ImGui::End();
}
// Demonstrate/test rendering huge amount of text, and the incidence of clipping.
static void ShowExampleAppLongText(bool* p_open)
{
ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiSetCond_FirstUseEver);

View File

@ -1184,7 +1184,7 @@ ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg_template)
font_cfg.OversampleH = font_cfg.OversampleV = 1;
font_cfg.PixelSnapH = true;
}
if (font_cfg.Name[0] == '\0') strcpy(font_cfg.Name, "<default>");
if (font_cfg.Name[0] == '\0') strcpy(font_cfg.Name, "ProggyClean.ttf, 13px");
const char* ttf_compressed_base85 = GetDefaultCompressedFontDataTTFBase85();
ImFont* font = AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, 13.0f, &font_cfg, GetGlyphRangesDefault());
@ -1206,7 +1206,7 @@ ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels,
// Store a short copy of filename into into the font name for convenience
const char* p;
for (p = filename + strlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) {}
snprintf(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "%s", p);
snprintf(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "%s, %.0fpx", p, size_pixels);
}
return AddFontFromMemoryTTF(data, data_size, size_pixels, &font_cfg, glyph_ranges);
}
@ -1942,7 +1942,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
else
{
s += ImTextCharFromUtf8(&c, s, text_end);
if (c == 0)
if (c == 0) // Malformed UTF-8?
break;
}
@ -2000,7 +2000,7 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip) const
{
if (!text_end)
text_end = text_begin + strlen(text_begin);
text_end = text_begin + strlen(text_begin); // ImGui functions generally already provides a valid text_end, so this is merely to handle direct calls.
// Align to be pixel perfect
pos.x = (float)(int)pos.x + DisplayOffset.x;
@ -2068,7 +2068,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
else
{
s += ImTextCharFromUtf8(&c, s, text_end);
if (c == 0)
if (c == 0) // Malformed UTF-8?
break;
}