dep/imgui: Sync to 5ee9c2a

And fix a bunch of local bugs, including random large-font-size glyphs.
This commit is contained in:
Stenzek 2025-06-27 17:02:25 +10:00
parent 280c0036eb
commit ebf97c26b8
No known key found for this signature in database
17 changed files with 375 additions and 328 deletions

View File

@ -13,6 +13,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\imgui.cpp" /> <ClCompile Include="src\imgui.cpp" />
<ClCompile Include="src\imgui_demo.cpp" />
<ClCompile Include="src\imgui_draw.cpp" /> <ClCompile Include="src\imgui_draw.cpp" />
<ClCompile Include="src\imgui_freetype.cpp" /> <ClCompile Include="src\imgui_freetype.cpp" />
<ClCompile Include="src\imgui_stdlib.cpp" /> <ClCompile Include="src\imgui_stdlib.cpp" />

View File

@ -17,6 +17,7 @@
<ClCompile Include="src\imgui_stdlib.cpp" /> <ClCompile Include="src\imgui_stdlib.cpp" />
<ClCompile Include="src\imgui_tables.cpp" /> <ClCompile Include="src\imgui_tables.cpp" />
<ClCompile Include="src\imgui_freetype.cpp" /> <ClCompile Include="src\imgui_freetype.cpp" />
<ClCompile Include="src\imgui_demo.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Natvis Include="imgui.natvis" /> <Natvis Include="imgui.natvis" />

View File

@ -28,13 +28,13 @@
//#define IMGUI_API __attribute__((visibility("default"))) // GCC/Clang: override visibility when set is hidden //#define IMGUI_API __attribute__((visibility("default"))) // GCC/Clang: override visibility when set is hidden
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names. //---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names.
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS #define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
//---- Disable all of Dear ImGui or don't implement standard windows/tools. //---- Disable all of Dear ImGui or don't implement standard windows/tools.
// It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp. // It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp.
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty. //#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. //#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty.
#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowIDStackToolWindow() will be empty. //#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowIDStackToolWindow() will be empty.
//---- Don't implement some functions to reduce linkage requirements. //---- Don't implement some functions to reduce linkage requirements.
#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a) #define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
@ -139,3 +139,7 @@ namespace ImGui
void MyFunction(const char* name, MyMatrix44* mtx); void MyFunction(const char* name, MyMatrix44* mtx);
} }
*/ */
// Use our texture type
class GPUTexture;
#define ImTextureID GPUTexture*

View File

@ -1,4 +1,4 @@
// dear imgui, v1.92.0 WIP // dear imgui, v1.92.0
// (headers) // (headers)
// Help: // Help:
@ -28,8 +28,8 @@
// Library Version // Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
#define IMGUI_VERSION "1.92.0 WIP" #define IMGUI_VERSION "1.92.0"
#define IMGUI_VERSION_NUM 19198 #define IMGUI_VERSION_NUM 19200
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000 #define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198 #define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
@ -329,7 +329,7 @@ IM_MSVC_RUNTIME_CHECKS_RESTORE
// - In v1.91.4 (2024/10/08): the default type for ImTextureID was changed from 'void*' to 'ImU64'. This allowed backends requirig 64-bit worth of data to build on 32-bit architectures. Use intermediary intptr_t cast and read FAQ if you have casting warnings. // - In v1.91.4 (2024/10/08): the default type for ImTextureID was changed from 'void*' to 'ImU64'. This allowed backends requirig 64-bit worth of data to build on 32-bit architectures. Use intermediary intptr_t cast and read FAQ if you have casting warnings.
// - In v1.92.0 (2025/XX/XX): added ImTextureRef which carry either a ImTextureID either a pointer to internal texture atlas. All user facing functions taking ImTextureID changed to ImTextureRef // - In v1.92.0 (2025/XX/XX): added ImTextureRef which carry either a ImTextureID either a pointer to internal texture atlas. All user facing functions taking ImTextureID changed to ImTextureRef
#ifndef ImTextureID #ifndef ImTextureID
typedef void* ImTextureID; // Default: store a pointer or an integer fitting in a pointer (most renderer backends are ok with that) typedef ImU64 ImTextureID; // Default: store up to 64-bits (any pointer or integer). A majority of backends are ok with that.
#endif #endif
// Define this if you need 0 to be a valid ImTextureID for your backend. // Define this if you need 0 to be a valid ImTextureID for your backend.
@ -356,6 +356,9 @@ struct ImTextureRef
{ {
ImTextureRef() { _TexData = NULL; _TexID = ImTextureID_Invalid; } ImTextureRef() { _TexData = NULL; _TexID = ImTextureID_Invalid; }
ImTextureRef(ImTextureID tex_id) { _TexData = NULL; _TexID = tex_id; } ImTextureRef(ImTextureID tex_id) { _TexData = NULL; _TexID = tex_id; }
#if !defined(IMGUI_DISABLE_OBSOLETE_FUNCTIONS) && !defined(ImTextureID)
ImTextureRef(void* tex_id) { _TexData = NULL; _TexID = (ImTextureID)(size_t)tex_id; } // For legacy backends casting to ImTextureID
#endif
inline ImTextureID GetTexID() const; // == (_TexData ? _TexData->TexID : _TexID) // Implemented below in the file. inline ImTextureID GetTexID() const; // == (_TexData ? _TexData->TexID : _TexID) // Implemented below in the file.
@ -490,23 +493,27 @@ namespace ImGui
IMGUI_API void SetScrollFromPosY(float local_y, float center_y_ratio = 0.5f); // adjust scrolling amount to make given position visible. Generally GetCursorStartPos() + offset to compute a valid position. IMGUI_API void SetScrollFromPosY(float local_y, float center_y_ratio = 0.5f); // adjust scrolling amount to make given position visible. Generally GetCursorStartPos() + offset to compute a valid position.
// Parameters stacks (font) // Parameters stacks (font)
// - PushFont(font, 0.0f) // Change font and keep current size
// - PushFont(NULL, 20.0f) // Keep font and change current size
// - PushFont(font, 20.0f) // Change font and set size to 20.0f
// - PushFont(font, style.FontSizeBase * 2.0f) // Change font and set size to be twice bigger than current size.
// - PushFont(font, font->LegacySize) // Change font and set size to size passed to AddFontXXX() function. Same as pre-1.92 behavior.
// *IMPORTANT* before 1.92, fonts had a single size. They can now be dynamically be adjusted. // *IMPORTANT* before 1.92, fonts had a single size. They can now be dynamically be adjusted.
// - Before 1.92: PushFont() always used font default size. // - In 1.92 we have REMOVED the single parameter version of PushFont() because it seems like the easiest way to provide an error-proof transition.
// - Since 1.92: PushFont() preserve the current shared font size. // - PushFont(font) before 1.92 = PushFont(font, font->LegacySize) after 1.92 // Use default font size as passed to AddFontXXX() function.
// - To use old behavior (single size font, size specified in AddFontXXX() call: // *IMPORTANT* global scale factors are applied over the provided size.
// - Use 'PushFont(font, font->LegacySize)' at call site // - Global scale factors are: 'style.FontScaleMain', 'style.FontScaleDpi' and maybe more.
// - Or set 'ImFontConfig::Flags |= ImFontFlags_DefaultToLegacySize' before calling AddFont(), and then 'PushFont(font)' will use this size. // - If you want to apply a factor to the _current_ font size:
// - External scale factors are applied over the provided value. // - CORRECT: PushFont(NULL, style.FontSizeBase) // use current unscaled size == does nothing
// *IMPORTANT* If you want to scale an existing font size: // - CORRECT: PushFont(NULL, style.FontSizeBase * 2.0f) // use current unscaled size x2 == make text twice bigger
// - OK: PushFontSize(style.FontSizeBase * factor) (= value before external scale factors applied). // - INCORRECT: PushFont(NULL, GetFontSize()) // INCORRECT! using size after global factors already applied == GLOBAL SCALING FACTORS WILL APPLY TWICE!
// - KO: PushFontSize(GetFontSize() * factor) (= value after external scale factors applied. external scale factors are style.FontScaleMain + per-viewport scales.). // - INCORRECT: PushFont(NULL, GetFontSize() * 2.0f) // INCORRECT! using size after global factors already applied == GLOBAL SCALING FACTORS WILL APPLY TWICE!
IMGUI_API void PushFont(ImFont* font, float font_size_base = -1, float font_weight = -1); // use NULL as a shortcut to push default font. Use <0.0f to keep current font size. IMGUI_API void PushFont(ImFont* font, float font_size_base_unscaled, float font_weight); // Use NULL as a shortcut to keep current font. Use 0.0f to keep current size.
IMGUI_API void PopFont(); IMGUI_API void PopFont();
IMGUI_API void PushFontSize(float font_size_base); IMGUI_API ImFont* GetFont(); // get current font
IMGUI_API void PushFontSize(float font_size_base, float font_weight); IMGUI_API float GetFontSize(); // get current scaled font size (= height in pixels). AFTER global scale factors applied. *IMPORTANT* DO NOT PASS THIS VALUE TO PushFont()! Use ImGui::GetStyle().FontSizeBase to get value before global scale factors.
IMGUI_API void PopFontSize(); IMGUI_API float GetFontWeight(); // get current font weight
IMGUI_API void PushFontWeight(float font_weight); IMGUI_API ImFontBaked* GetFontBaked(); // get current font bound at current size // == GetFont()->GetFontBaked(GetFontSize())
IMGUI_API void PopFontWeight();
// Parameters stacks (shared) // Parameters stacks (shared)
IMGUI_API void PushStyleColor(ImGuiCol idx, ImU32 col); // modify a style color. always use this if you modify the style after NewFrame(). IMGUI_API void PushStyleColor(ImGuiCol idx, ImU32 col); // modify a style color. always use this if you modify the style after NewFrame().
@ -530,11 +537,7 @@ namespace ImGui
// Style read access // Style read access
// - Use the ShowStyleEditor() function to interactively see/edit the colors. // - Use the ShowStyleEditor() function to interactively see/edit the colors.
IMGUI_API ImFont* GetFont(); // get current font
IMGUI_API float GetFontSize(); // get current font size (= height in pixels) of current font with external scale factors applied. Use ImGui::GetStyle().FontSizeBase to get value before external scale factors.
IMGUI_API float GetFontWeight();
IMGUI_API ImVec2 GetFontTexUvWhitePixel(); // get UV coordinate for a white pixel, useful to draw custom shapes via the ImDrawList API IMGUI_API ImVec2 GetFontTexUvWhitePixel(); // get UV coordinate for a white pixel, useful to draw custom shapes via the ImDrawList API
IMGUI_API ImFontBaked* GetFontBaked(); // get current font bound at current size // == GetFont()->GetFontBaked(GetFontSize())
IMGUI_API ImU32 GetColorU32(ImGuiCol idx, float alpha_mul = 1.0f); // retrieve given style color with style alpha applied and optional extra alpha multiplier, packed as a 32-bit value suitable for ImDrawList IMGUI_API ImU32 GetColorU32(ImGuiCol idx, float alpha_mul = 1.0f); // retrieve given style color with style alpha applied and optional extra alpha multiplier, packed as a 32-bit value suitable for ImDrawList
IMGUI_API ImU32 GetColorU32(const ImVec4& col); // retrieve given color with style alpha applied, packed as a 32-bit value suitable for ImDrawList IMGUI_API ImU32 GetColorU32(const ImVec4& col); // retrieve given color with style alpha applied, packed as a 32-bit value suitable for ImDrawList
IMGUI_API ImU32 GetColorU32(ImU32 col, float alpha_mul = 1.0f); // retrieve given color with style alpha applied, packed as a 32-bit value suitable for ImDrawList IMGUI_API ImU32 GetColorU32(ImU32 col, float alpha_mul = 1.0f); // retrieve given color with style alpha applied, packed as a 32-bit value suitable for ImDrawList
@ -1531,7 +1534,7 @@ enum ImGuiKey : int
ImGuiKey_Space, ImGuiKey_Space,
ImGuiKey_Enter, ImGuiKey_Enter,
ImGuiKey_Escape, ImGuiKey_Escape,
ImGuiKey_LeftCtrl, ImGuiKey_LeftShift, ImGuiKey_LeftAlt, ImGuiKey_LeftSuper, ImGuiKey_LeftCtrl, ImGuiKey_LeftShift, ImGuiKey_LeftAlt, ImGuiKey_LeftSuper, // Also see ImGuiMod_Ctrl, ImGuiMod_Shift, ImGuiMod_Alt, ImGuiMod_Super below!
ImGuiKey_RightCtrl, ImGuiKey_RightShift, ImGuiKey_RightAlt, ImGuiKey_RightSuper, ImGuiKey_RightCtrl, ImGuiKey_RightShift, ImGuiKey_RightAlt, ImGuiKey_RightSuper,
ImGuiKey_Menu, ImGuiKey_Menu,
ImGuiKey_0, ImGuiKey_1, ImGuiKey_2, ImGuiKey_3, ImGuiKey_4, ImGuiKey_5, ImGuiKey_6, ImGuiKey_7, ImGuiKey_8, ImGuiKey_9, ImGuiKey_0, ImGuiKey_1, ImGuiKey_2, ImGuiKey_3, ImGuiKey_4, ImGuiKey_5, ImGuiKey_6, ImGuiKey_7, ImGuiKey_8, ImGuiKey_9,
@ -1571,32 +1574,34 @@ enum ImGuiKey : int
ImGuiKey_AppForward, ImGuiKey_AppForward,
ImGuiKey_Oem102, // Non-US backslash. ImGuiKey_Oem102, // Non-US backslash.
// Gamepad (some of those are analog values, 0.0f to 1.0f) // NAVIGATION ACTION // Gamepad
// (analog values are 0.0f to 1.0f)
// (download controller mapping PNG/PSD at http://dearimgui.com/controls_sheets) // (download controller mapping PNG/PSD at http://dearimgui.com/controls_sheets)
ImGuiKey_GamepadStart, // Menu (Xbox) + (Switch) Start/Options (PS) // // XBOX | SWITCH | PLAYSTA. | -> ACTION
ImGuiKey_GamepadBack, // View (Xbox) - (Switch) Share (PS) ImGuiKey_GamepadStart, // Menu | + | Options |
ImGuiKey_GamepadFaceLeft, // X (Xbox) Y (Switch) Square (PS) // Tap: Toggle Menu. Hold: Windowing mode (Focus/Move/Resize windows) ImGuiKey_GamepadBack, // View | - | Share |
ImGuiKey_GamepadFaceRight, // B (Xbox) A (Switch) Circle (PS) // Cancel / Close / Exit ImGuiKey_GamepadFaceLeft, // X | Y | Square | Tap: Toggle Menu. Hold: Windowing mode (Focus/Move/Resize windows)
ImGuiKey_GamepadFaceUp, // Y (Xbox) X (Switch) Triangle (PS) // Text Input / On-screen Keyboard ImGuiKey_GamepadFaceRight, // B | A | Circle | Cancel / Close / Exit
ImGuiKey_GamepadFaceDown, // A (Xbox) B (Switch) Cross (PS) // Activate / Open / Toggle / Tweak ImGuiKey_GamepadFaceUp, // Y | X | Triangle | Text Input / On-screen Keyboard
ImGuiKey_GamepadDpadLeft, // D-pad Left // Move / Tweak / Resize Window (in Windowing mode) ImGuiKey_GamepadFaceDown, // A | B | Cross | Activate / Open / Toggle / Tweak
ImGuiKey_GamepadDpadRight, // D-pad Right // Move / Tweak / Resize Window (in Windowing mode) ImGuiKey_GamepadDpadLeft, // D-pad Left | " | " | Move / Tweak / Resize Window (in Windowing mode)
ImGuiKey_GamepadDpadUp, // D-pad Up // Move / Tweak / Resize Window (in Windowing mode) ImGuiKey_GamepadDpadRight, // D-pad Right | " | " | Move / Tweak / Resize Window (in Windowing mode)
ImGuiKey_GamepadDpadDown, // D-pad Down // Move / Tweak / Resize Window (in Windowing mode) ImGuiKey_GamepadDpadUp, // D-pad Up | " | " | Move / Tweak / Resize Window (in Windowing mode)
ImGuiKey_GamepadL1, // L Bumper (Xbox) L (Switch) L1 (PS) // Tweak Slower / Focus Previous (in Windowing mode) ImGuiKey_GamepadDpadDown, // D-pad Down | " | " | Move / Tweak / Resize Window (in Windowing mode)
ImGuiKey_GamepadR1, // R Bumper (Xbox) R (Switch) R1 (PS) // Tweak Faster / Focus Next (in Windowing mode) ImGuiKey_GamepadL1, // L Bumper | L | L1 | Tweak Slower / Focus Previous (in Windowing mode)
ImGuiKey_GamepadL2, // L Trig. (Xbox) ZL (Switch) L2 (PS) [Analog] ImGuiKey_GamepadR1, // R Bumper | R | R1 | Tweak Faster / Focus Next (in Windowing mode)
ImGuiKey_GamepadR2, // R Trig. (Xbox) ZR (Switch) R2 (PS) [Analog] ImGuiKey_GamepadL2, // L Trigger | ZL | L2 | [Analog]
ImGuiKey_GamepadL3, // L Stick (Xbox) L3 (Switch) L3 (PS) ImGuiKey_GamepadR2, // R Trigger | ZR | R2 | [Analog]
ImGuiKey_GamepadR3, // R Stick (Xbox) R3 (Switch) R3 (PS) ImGuiKey_GamepadL3, // L Stick | L3 | L3 |
ImGuiKey_GamepadLStickLeft, // [Analog] // Move Window (in Windowing mode) ImGuiKey_GamepadR3, // R Stick | R3 | R3 |
ImGuiKey_GamepadLStickRight, // [Analog] // Move Window (in Windowing mode) ImGuiKey_GamepadLStickLeft, // | | | [Analog] Move Window (in Windowing mode)
ImGuiKey_GamepadLStickUp, // [Analog] // Move Window (in Windowing mode) ImGuiKey_GamepadLStickRight, // | | | [Analog] Move Window (in Windowing mode)
ImGuiKey_GamepadLStickDown, // [Analog] // Move Window (in Windowing mode) ImGuiKey_GamepadLStickUp, // | | | [Analog] Move Window (in Windowing mode)
ImGuiKey_GamepadRStickLeft, // [Analog] ImGuiKey_GamepadLStickDown, // | | | [Analog] Move Window (in Windowing mode)
ImGuiKey_GamepadRStickRight, // [Analog] ImGuiKey_GamepadRStickLeft, // | | | [Analog]
ImGuiKey_GamepadRStickUp, // [Analog] ImGuiKey_GamepadRStickRight, // | | | [Analog]
ImGuiKey_GamepadRStickDown, // [Analog] ImGuiKey_GamepadRStickUp, // | | | [Analog]
ImGuiKey_GamepadRStickDown, // | | | [Analog]
// Aliases: Mouse Buttons (auto-submitted from AddMouseButtonEvent() calls) // Aliases: Mouse Buttons (auto-submitted from AddMouseButtonEvent() calls)
// - This is mirroring the data also written to io.MouseDown[], io.MouseWheel, in a format allowing them to be accessed via standard key API. // - This is mirroring the data also written to io.MouseDown[], io.MouseWheel, in a format allowing them to be accessed via standard key API.
@ -1604,11 +1609,15 @@ enum ImGuiKey : int
// [Internal] Reserved for mod storage // [Internal] Reserved for mod storage
ImGuiKey_ReservedForModCtrl, ImGuiKey_ReservedForModShift, ImGuiKey_ReservedForModAlt, ImGuiKey_ReservedForModSuper, ImGuiKey_ReservedForModCtrl, ImGuiKey_ReservedForModShift, ImGuiKey_ReservedForModAlt, ImGuiKey_ReservedForModSuper,
// [Internal] If you need to iterate all keys (for e.g. an input mapper) you may use ImGuiKey_NamedKey_BEGIN..ImGuiKey_NamedKey_END.
ImGuiKey_NamedKey_END, ImGuiKey_NamedKey_END,
ImGuiKey_NamedKey_COUNT = ImGuiKey_NamedKey_END - ImGuiKey_NamedKey_BEGIN,
// Keyboard Modifiers (explicitly submitted by backend via AddKeyEvent() calls) // Keyboard Modifiers (explicitly submitted by backend via AddKeyEvent() calls)
// - This is mirroring the data also written to io.KeyCtrl, io.KeyShift, io.KeyAlt, io.KeySuper, in a format allowing // - Any functions taking a ImGuiKeyChord parameter can binary-or those with regular keys, e.g. Shortcut(ImGuiMod_Ctrl | ImGuiKey_S).
// them to be accessed via standard key API, allowing calls such as IsKeyPressed(), IsKeyReleased(), querying duration etc. // - Those are written back into io.KeyCtrl, io.KeyShift, io.KeyAlt, io.KeySuper for convenience,
// but may be accessed via standard key API such as IsKeyPressed(), IsKeyReleased(), querying duration etc.
// - Code polling every key (e.g. an interface to detect a key press for input mapping) might want to ignore those // - Code polling every key (e.g. an interface to detect a key press for input mapping) might want to ignore those
// and prefer using the real keys (e.g. ImGuiKey_LeftCtrl, ImGuiKey_RightCtrl instead of ImGuiMod_Ctrl). // and prefer using the real keys (e.g. ImGuiKey_LeftCtrl, ImGuiKey_RightCtrl instead of ImGuiMod_Ctrl).
// - In theory the value of keyboard modifiers should be roughly equivalent to a logical or of the equivalent left/right keys. // - In theory the value of keyboard modifiers should be roughly equivalent to a logical or of the equivalent left/right keys.
@ -1622,11 +1631,6 @@ enum ImGuiKey : int
ImGuiMod_Super = 1 << 15, // Windows/Super (non-macOS), Ctrl (macOS) ImGuiMod_Super = 1 << 15, // Windows/Super (non-macOS), Ctrl (macOS)
ImGuiMod_Mask_ = 0xF000, // 4-bits ImGuiMod_Mask_ = 0xF000, // 4-bits
// [Internal] If you need to iterate all keys (for e.g. an input mapper) you may use ImGuiKey_NamedKey_BEGIN..ImGuiKey_NamedKey_END.
ImGuiKey_NamedKey_COUNT = ImGuiKey_NamedKey_END - ImGuiKey_NamedKey_BEGIN,
//ImGuiKey_KeysData_SIZE = ImGuiKey_NamedKey_COUNT, // Size of KeysData[]: only hold named keys
//ImGuiKey_KeysData_OFFSET = ImGuiKey_NamedKey_BEGIN, // Accesses to io.KeysData[] must use (key - ImGuiKey_NamedKey_BEGIN) index.
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
ImGuiKey_COUNT = ImGuiKey_NamedKey_END, // Obsoleted in 1.91.5 because it was extremely misleading (since named keys don't start at 0 anymore) ImGuiKey_COUNT = ImGuiKey_NamedKey_END, // Obsoleted in 1.91.5 because it was extremely misleading (since named keys don't start at 0 anymore)
ImGuiMod_Shortcut = ImGuiMod_Ctrl, // Removed in 1.90.7, you can now simply use ImGuiMod_Ctrl ImGuiMod_Shortcut = ImGuiMod_Ctrl, // Removed in 1.90.7, you can now simply use ImGuiMod_Ctrl
@ -2229,10 +2233,11 @@ IM_MSVC_RUNTIME_CHECKS_RESTORE
struct ImGuiStyle struct ImGuiStyle
{ {
// ImGui::GetFontSize() == FontSizeBase * (FontScaleMain * FontScaleDpi * other_scaling_factors) // Font scaling
float FontSizeBase; // Current base font size before external scaling factors are applied. Use PushFont()/PushFontSize() to modify. Use ImGui::GetFontSize() to obtain scaled value. // - recap: ImGui::GetFontSize() == FontSizeBase * (FontScaleMain * FontScaleDpi * other_scaling_factors)
float FontScaleMain; // Main scale factor. May be set by application once, or exposed to end-user. float FontSizeBase; // Current base font size before external global factors are applied. Use PushFont(NULL, size) to modify. Use ImGui::GetFontSize() to obtain scaled value.
float FontScaleDpi; // Additional scale factor from viewport/monitor contents scale. When io.ConfigDpiScaleFonts is enabled, this is automatically overwritten when changing monitor DPI. float FontScaleMain; // Main global scale factor. May be set by application once, or exposed to end-user.
float FontScaleDpi; // Additional global scale factor from viewport/monitor contents scale. When io.ConfigDpiScaleFonts is enabled, this is automatically overwritten when changing monitor DPI.
float Alpha; // Global alpha applies to everything in Dear ImGui. float Alpha; // Global alpha applies to everything in Dear ImGui.
float DisabledAlpha; // Additional alpha multiplier applied by BeginDisabled(). Multiply over current value of Alpha. float DisabledAlpha; // Additional alpha multiplier applied by BeginDisabled(). Multiply over current value of Alpha.
@ -2281,6 +2286,8 @@ struct ImGuiStyle
ImVec2 SeparatorTextPadding; // Horizontal offset of text from each edge of the separator + spacing on other axis. Generally small values. .y is recommended to be == FramePadding.y. ImVec2 SeparatorTextPadding; // Horizontal offset of text from each edge of the separator + spacing on other axis. Generally small values. .y is recommended to be == FramePadding.y.
ImVec2 DisplayWindowPadding; // Apply to regular windows: amount which we enforce to keep visible when moving near edges of your screen. ImVec2 DisplayWindowPadding; // Apply to regular windows: amount which we enforce to keep visible when moving near edges of your screen.
ImVec2 DisplaySafeAreaPadding; // Apply to every windows, menus, popups, tooltips: amount where we avoid displaying contents. Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured). ImVec2 DisplaySafeAreaPadding; // Apply to every windows, menus, popups, tooltips: amount where we avoid displaying contents. Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured).
ImVec2 ScrollStepSize; // Step size for scrolling, 0.0f uses default ImGui behaviour.
float ScrollSmooth; // Smooth scrolling amount: 1.0f no smoothing. Anything above 1.0f will make the scroll delta more smooth.
float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). We apply per-monitor DPI scaling over this scale. May be removed later. float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). We apply per-monitor DPI scaling over this scale. May be removed later.
bool AntiAliasedLines; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList). bool AntiAliasedLines; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList).
bool AntiAliasedLinesUseTex; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering (NOT point/nearest filtering). Latched at the beginning of the frame (copied to ImDrawList). bool AntiAliasedLinesUseTex; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering (NOT point/nearest filtering). Latched at the beginning of the frame (copied to ImDrawList).
@ -2299,9 +2306,6 @@ struct ImGuiStyle
ImGuiHoveredFlags HoverFlagsForTooltipMouse;// Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using mouse. ImGuiHoveredFlags HoverFlagsForTooltipMouse;// Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using mouse.
ImGuiHoveredFlags HoverFlagsForTooltipNav; // Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using keyboard/gamepad. ImGuiHoveredFlags HoverFlagsForTooltipNav; // Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using keyboard/gamepad.
ImVec2 ScrollStepSize; // Step size for scrolling, 0.0f uses default ImGui behaviour.
float ScrollSmooth; // Smooth scrolling amount: 1.0f no smoothing. Anything above 1.0f will make the scroll delta more smooth.
// [Internal] // [Internal]
float _MainScale; // FIXME-WIP: Reference scale, as applied by ScaleAllSizes(). float _MainScale; // FIXME-WIP: Reference scale, as applied by ScaleAllSizes().
float _NextFrameFontSizeBase; // FIXME: Temporary hack until we finish remaining work. float _NextFrameFontSizeBase; // FIXME: Temporary hack until we finish remaining work.
@ -2520,7 +2524,7 @@ struct ImGuiIO
// Other state maintained from data above + IO function calls // Other state maintained from data above + IO function calls
ImGuiKeyChord KeyMods; // Key mods flags (any of ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Alt/ImGuiMod_Super flags, same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags. Read-only, updated by NewFrame() ImGuiKeyChord KeyMods; // Key mods flags (any of ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Alt/ImGuiMod_Super flags, same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags. Read-only, updated by NewFrame()
ImGuiKeyData KeysData[ImGuiKey_NamedKey_COUNT];// Key state for all known keys. Use IsKeyXXX() functions to access this. ImGuiKeyData KeysData[ImGuiKey_NamedKey_COUNT];// Key state for all known keys. MUST use 'key - ImGuiKey_NamedKey_BEGIN' as index. Use IsKeyXXX() functions to access this.
bool WantCaptureMouseUnlessPopupClose; // Alternative to WantCaptureMouse: (WantCaptureMouse == true && WantCaptureMouseUnlessPopupClose == false) when a click over void is expected to close a popup. bool WantCaptureMouseUnlessPopupClose; // Alternative to WantCaptureMouse: (WantCaptureMouse == true && WantCaptureMouseUnlessPopupClose == false) when a click over void is expected to close a popup.
ImVec2 MousePosPrev; // Previous mouse position (note that MouseDelta is not necessary == MousePos-MousePosPrev, in case either position is invalid) ImVec2 MousePosPrev; // Previous mouse position (note that MouseDelta is not necessary == MousePos-MousePosPrev, in case either position is invalid)
ImVec2 MouseClickedPos[5]; // Position at time of clicking ImVec2 MouseClickedPos[5]; // Position at time of clicking
@ -2833,31 +2837,31 @@ struct ImGuiListClipper
#define IMGUI_DEFINE_MATH_OPERATORS_IMPLEMENTED #define IMGUI_DEFINE_MATH_OPERATORS_IMPLEMENTED
IM_MSVC_RUNTIME_CHECKS_OFF IM_MSVC_RUNTIME_CHECKS_OFF
// ImVec2 operators // ImVec2 operators
static inline ImVec2 operator*(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x * rhs, lhs.y * rhs); } inline ImVec2 operator*(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x * rhs, lhs.y * rhs); }
static inline ImVec2 operator/(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x / rhs, lhs.y / rhs); } inline ImVec2 operator/(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x / rhs, lhs.y / rhs); }
static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x + rhs.x, lhs.y + rhs.y); } inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x + rhs.x, lhs.y + rhs.y); }
static inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x - rhs.x, lhs.y - rhs.y); } inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x - rhs.x, lhs.y - rhs.y); }
static inline ImVec2 operator*(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); } inline ImVec2 operator*(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
static inline ImVec2 operator/(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x / rhs.x, lhs.y / rhs.y); } inline ImVec2 operator/(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x / rhs.x, lhs.y / rhs.y); }
static inline ImVec2 operator-(const ImVec2& lhs) { return ImVec2(-lhs.x, -lhs.y); } inline ImVec2 operator-(const ImVec2& lhs) { return ImVec2(-lhs.x, -lhs.y); }
static inline ImVec2& operator*=(ImVec2& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; return lhs; } inline ImVec2& operator*=(ImVec2& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; return lhs; }
static inline ImVec2& operator/=(ImVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; } inline ImVec2& operator/=(ImVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; }
static inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; return lhs; } inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; return lhs; }
static inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; } inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; }
static inline ImVec2& operator*=(ImVec2& lhs, const ImVec2& rhs) { lhs.x *= rhs.x; lhs.y *= rhs.y; return lhs; } inline ImVec2& operator*=(ImVec2& lhs, const ImVec2& rhs) { lhs.x *= rhs.x; lhs.y *= rhs.y; return lhs; }
static inline ImVec2& operator/=(ImVec2& lhs, const ImVec2& rhs) { lhs.x /= rhs.x; lhs.y /= rhs.y; return lhs; } inline ImVec2& operator/=(ImVec2& lhs, const ImVec2& rhs) { lhs.x /= rhs.x; lhs.y /= rhs.y; return lhs; }
static inline bool operator==(const ImVec2& lhs, const ImVec2& rhs) { return lhs.x == rhs.x && lhs.y == rhs.y; } inline bool operator==(const ImVec2& lhs, const ImVec2& rhs) { return lhs.x == rhs.x && lhs.y == rhs.y; }
static inline bool operator!=(const ImVec2& lhs, const ImVec2& rhs) { return lhs.x != rhs.x || lhs.y != rhs.y; } inline bool operator!=(const ImVec2& lhs, const ImVec2& rhs) { return lhs.x != rhs.x || lhs.y != rhs.y; }
// ImVec4 operators // ImVec4 operators
static inline ImVec4 operator*(const ImVec4& lhs, const float rhs) { return ImVec4(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs); } inline ImVec4 operator*(const ImVec4& lhs, const float rhs) { return ImVec4(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs); }
static inline ImVec4 operator/(const ImVec4& lhs, const float rhs) { return ImVec4(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs, lhs.w / rhs); } inline ImVec4 operator/(const ImVec4& lhs, const float rhs) { return ImVec4(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs, lhs.w / rhs); }
static inline ImVec4 operator+(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w); } inline ImVec4 operator+(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w); }
static inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w); } inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w); }
static inline ImVec4 operator*(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w); } inline ImVec4 operator*(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w); }
static inline ImVec4 operator/(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z, lhs.w / rhs.w); } inline ImVec4 operator/(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z, lhs.w / rhs.w); }
static inline ImVec4 operator-(const ImVec4& lhs) { return ImVec4(-lhs.x, -lhs.y, -lhs.z, -lhs.w); } inline ImVec4 operator-(const ImVec4& lhs) { return ImVec4(-lhs.x, -lhs.y, -lhs.z, -lhs.w); }
static inline bool operator==(const ImVec4& lhs, const ImVec4& rhs) { return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.w == rhs.w; } inline bool operator==(const ImVec4& lhs, const ImVec4& rhs) { return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.w == rhs.w; }
static inline bool operator!=(const ImVec4& lhs, const ImVec4& rhs) { return lhs.x != rhs.x || lhs.y != rhs.y || lhs.z != rhs.z || lhs.w != rhs.w; } inline bool operator!=(const ImVec4& lhs, const ImVec4& rhs) { return lhs.x != rhs.x || lhs.y != rhs.y || lhs.z != rhs.z || lhs.w != rhs.w; }
IM_MSVC_RUNTIME_CHECKS_RESTORE IM_MSVC_RUNTIME_CHECKS_RESTORE
#endif #endif
@ -3330,8 +3334,8 @@ struct ImDrawList
// Obsolete names // Obsolete names
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
IMGUI_API void PushTextureID(ImTextureRef tex_ref) { PushTexture(tex_ref); } // RENAMED in 1.92.x inline void PushTextureID(ImTextureRef tex_ref) { PushTexture(tex_ref); } // RENAMED in 1.92.x
IMGUI_API void PopTextureID() { PopTexture(); } // RENAMED in 1.92.x inline void PopTextureID() { PopTexture(); } // RENAMED in 1.92.x
#endif #endif
//inline void AddEllipse(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0, float thickness = 1.0f) { AddEllipse(center, ImVec2(radius_x, radius_y), col, rot, num_segments, thickness); } // OBSOLETED in 1.90.5 (Mar 2024) //inline void AddEllipse(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0, float thickness = 1.0f) { AddEllipse(center, ImVec2(radius_x, radius_y), col, rot, num_segments, thickness); } // OBSOLETED in 1.90.5 (Mar 2024)
//inline void AddEllipseFilled(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0) { AddEllipseFilled(center, ImVec2(radius_x, radius_y), col, rot, num_segments); } // OBSOLETED in 1.90.5 (Mar 2024) //inline void AddEllipseFilled(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0) { AddEllipseFilled(center, ImVec2(radius_x, radius_y), col, rot, num_segments); } // OBSOLETED in 1.90.5 (Mar 2024)
@ -3445,8 +3449,8 @@ struct ImTextureData
~ImTextureData() { DestroyPixels(); } ~ImTextureData() { DestroyPixels(); }
IMGUI_API void Create(ImTextureFormat format, int w, int h); IMGUI_API void Create(ImTextureFormat format, int w, int h);
IMGUI_API void DestroyPixels(); IMGUI_API void DestroyPixels();
unsigned char* GetPixels() { IM_ASSERT(Pixels != NULL); return Pixels; } void* GetPixels() { IM_ASSERT(Pixels != NULL); return Pixels; }
unsigned char* GetPixelsAt(int x, int y) { IM_ASSERT(Pixels != NULL); return Pixels + (x + y * Width) * BytesPerPixel; } void* GetPixelsAt(int x, int y) { IM_ASSERT(Pixels != NULL); return Pixels + (x + y * Width) * BytesPerPixel; }
int GetSizeInBytes() const { return Width * Height * BytesPerPixel; } int GetSizeInBytes() const { return Width * Height * BytesPerPixel; }
int GetPitch() const { return Width * BytesPerPixel; } int GetPitch() const { return Width * BytesPerPixel; }
ImTextureRef GetTexRef() { ImTextureRef tex_ref; tex_ref._TexData = this; tex_ref._TexID = ImTextureID_Invalid; return tex_ref; } ImTextureRef GetTexRef() { ImTextureRef tex_ref; tex_ref._TexData = this; tex_ref._TexID = ImTextureID_Invalid; return tex_ref; }
@ -3480,7 +3484,7 @@ struct ImFontConfig
float SizePixels; // // Size in pixels for rasterizer (more or less maps to the resulting font height). float SizePixels; // // Size in pixels for rasterizer (more or less maps to the resulting font height).
float Weight; float Weight;
const ImWchar* GlyphRanges; // NULL // *LEGACY* THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). const ImWchar* GlyphRanges; // NULL // *LEGACY* THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list).
const ImWchar* GlyphExcludeRanges; // NULL // Pointer to a VERY SHORT user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). This is very close to GlyphRanges[] but designed to exclude ranges from a font source, when merging fonts with overlapping glyphs. Use "Input Glyphs Overlap Detection Tool" to find about your overlapping ranges. const ImWchar* GlyphExcludeRanges; // NULL // Pointer to a small user-provided list of Unicode ranges (2 value per range, values are inclusive, zero-terminated list). This is very close to GlyphRanges[] but designed to exclude ranges from a font source, when merging fonts with overlapping glyphs. Use "Input Glyphs Overlap Detection Tool" to find about your overlapping ranges.
//ImVec2 GlyphExtraSpacing; // 0, 0 // (REMOVED AT IT SEEMS LARGELY OBSOLETE. PLEASE REPORT IF YOU WERE USING THIS). Extra spacing (in pixels) between glyphs when rendered: essentially add to glyph->AdvanceX. Only X axis is supported for now. //ImVec2 GlyphExtraSpacing; // 0, 0 // (REMOVED AT IT SEEMS LARGELY OBSOLETE. PLEASE REPORT IF YOU WERE USING THIS). Extra spacing (in pixels) between glyphs when rendered: essentially add to glyph->AdvanceX. Only X axis is supported for now.
ImVec2 GlyphOffset; // 0, 0 // Offset (in pixels) all glyphs from this font input. Absolute value for default size, other sizes will scale this value. ImVec2 GlyphOffset; // 0, 0 // Offset (in pixels) all glyphs from this font input. Absolute value for default size, other sizes will scale this value.
float GlyphMinAdvanceX; // 0 // Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font. Absolute value for default size, other sizes will scale this value. float GlyphMinAdvanceX; // 0 // Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font. Absolute value for default size, other sizes will scale this value.
@ -3764,7 +3768,6 @@ struct ImFontBaked
enum ImFontFlags_ enum ImFontFlags_
{ {
ImFontFlags_None = 0, ImFontFlags_None = 0,
ImFontFlags_DefaultToLegacySize = 1 << 0, // Legacy compatibility: make PushFont() calls without explicit size use font->LegacySize instead of current font size.
ImFontFlags_NoLoadError = 1 << 1, // Disable throwing an error/assert when calling AddFontXXX() with missing file/data. Calling code is expected to check AddFontXXX() return value. ImFontFlags_NoLoadError = 1 << 1, // Disable throwing an error/assert when calling AddFontXXX() with missing file/data. Calling code is expected to check AddFontXXX() return value.
ImFontFlags_NoLoadGlyphs = 1 << 2, // [Internal] Disable loading new glyphs. ImFontFlags_NoLoadGlyphs = 1 << 2, // [Internal] Disable loading new glyphs.
ImFontFlags_LockBakedSizes = 1 << 3, // [Internal] Disable loading new baked sizes, disable garbage collecting current ones. e.g. if you want to lock a font to a single size. Important: if you use this to preload given sizes, consider the possibility of multiple font density used on Retina display. ImFontFlags_LockBakedSizes = 1 << 3, // [Internal] Disable loading new baked sizes, disable garbage collecting current ones. e.g. if you want to lock a font to a single size. Important: if you use this to preload given sizes, consider the possibility of multiple font density used on Retina display.
@ -3958,7 +3961,8 @@ struct ImGuiPlatformImeData
namespace ImGui namespace ImGui
{ {
// OBSOLETED in 1.92.0 (from June 2025) // OBSOLETED in 1.92.0 (from June 2025)
IMGUI_API void SetWindowFontScale(float scale); // Set font scale factor for current window. Prefer using PushFontSize(style.FontSizeBase * factor) or use style.FontScaleMain to scale all windows. static inline void PushFont(ImFont* font) { PushFont(font, font ? font->LegacySize : 0.0f, font ? font->DefaultWeight : -1.0f); }
IMGUI_API void SetWindowFontScale(float scale); // Set font scale factor for current window. Prefer using PushFont(NULL, style.FontSizeBase * factor) or use style.FontScaleMain to scale all windows.
// OBSOLETED in 1.91.9 (from February 2025) // OBSOLETED in 1.91.9 (from February 2025)
IMGUI_API void Image(ImTextureRef tex_ref, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col); // <-- 'border_col' was removed in favor of ImGuiCol_ImageBorder. If you use 'tint_col', use ImageWithBg() instead. IMGUI_API void Image(ImTextureRef tex_ref, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col); // <-- 'border_col' was removed in favor of ImGuiCol_ImageBorder. If you use 'tint_col', use ImageWithBg() instead.
// OBSOLETED in 1.91.0 (from July 2024) // OBSOLETED in 1.91.0 (from July 2024)

View File

@ -1,4 +1,4 @@
// dear imgui, v1.92.0 WIP // dear imgui, v1.92.0
// (internal structures/api) // (internal structures/api)
// You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility. // You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility.
@ -838,9 +838,10 @@ struct IMGUI_API ImDrawListSharedData
{ {
ImVec2 TexUvWhitePixel; // UV of white pixel in the atlas (== FontAtlas->TexUvWhitePixel) ImVec2 TexUvWhitePixel; // UV of white pixel in the atlas (== FontAtlas->TexUvWhitePixel)
const ImVec4* TexUvLines; // UV of anti-aliased lines in the atlas (== FontAtlas->TexUvLines) const ImVec4* TexUvLines; // UV of anti-aliased lines in the atlas (== FontAtlas->TexUvLines)
ImFont* Font; // Current/default font (optional, for simplified AddText overload) ImFontAtlas* FontAtlas; // Current font atlas
float FontSize; // Current/default font size (optional, for simplified AddText overload) ImFont* Font; // Current font (used for simplified AddText overload)
float FontScale; // Current/default font scale (== FontSize / Font->FontSize) float FontSize; // Current font size (used for for simplified AddText overload)
float FontScale; // Current font scale (== FontSize / Font->FontSize)
float FontWeight; // Current/default font weight float FontWeight; // Current/default font weight
float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo()
float CircleSegmentMaxError; // Number of circle segments to use per pixel of radius for AddCircle() etc float CircleSegmentMaxError; // Number of circle segments to use per pixel of radius for AddCircle() etc
@ -2144,7 +2145,7 @@ struct ImGuiContext
ImFont* Font; // Currently bound font. (== FontStack.back().Font) ImFont* Font; // Currently bound font. (== FontStack.back().Font)
ImFontBaked* FontBaked; // Currently bound font at currently bound size. (== Font->GetFontBaked(FontSize)) ImFontBaked* FontBaked; // Currently bound font at currently bound size. (== Font->GetFontBaked(FontSize))
float FontSize; // Currently bound font size == line height (== FontSizeBase + externals scales applied in the UpdateCurrentFontSize() function). float FontSize; // Currently bound font size == line height (== FontSizeBase + externals scales applied in the UpdateCurrentFontSize() function).
float FontSizeBase; // Font size before scaling == style.FontSizeBase == value passed to PushFont() / PushFontSize() when specified. float FontSizeBase; // Font size before scaling == style.FontSizeBase == value passed to PushFont() when specified.
float FontBakedScale; // == FontBaked->Size / FontSize. Scale factor over baked size. Rarely used nowadays, very often == 1.0f. float FontBakedScale; // == FontBaked->Size / FontSize. Scale factor over baked size. Rarely used nowadays, very often == 1.0f.
float FontRasterizerDensity; // Current font density. Used by all calls to GetFontBaked(). float FontRasterizerDensity; // Current font density. Used by all calls to GetFontBaked().
float FontWeight; float FontWeight;
@ -3718,8 +3719,8 @@ typedef ImFontLoader ImFontBuilderIO; // [renamed/changed in 1.92] The types are
// Helpers: ImTextureRef ==/!= operators provided as convenience // Helpers: ImTextureRef ==/!= operators provided as convenience
// (note that _TexID and _TexData are never set simultaneously) // (note that _TexID and _TexData are never set simultaneously)
static inline bool operator==(const ImTextureRef& lhs, const ImTextureRef& rhs) { return lhs._TexID == rhs._TexID && lhs._TexData == rhs._TexData; } inline bool operator==(const ImTextureRef& lhs, const ImTextureRef& rhs) { return lhs._TexID == rhs._TexID && lhs._TexData == rhs._TexData; }
static inline bool operator!=(const ImTextureRef& lhs, const ImTextureRef& rhs) { return lhs._TexID != rhs._TexID || lhs._TexData != rhs._TexData; } inline bool operator!=(const ImTextureRef& lhs, const ImTextureRef& rhs) { return lhs._TexID != rhs._TexID || lhs._TexData != rhs._TexData; }
// Refer to ImFontAtlasPackGetRect() to better understand how this works. // Refer to ImFontAtlasPackGetRect() to better understand how this works.
#define ImFontAtlasRectId_IndexMask_ (0x000FFFFF) // 20-bits: index to access builder->RectsIndex[]. #define ImFontAtlasRectId_IndexMask_ (0x000FFFFF) // 20-bits: index to access builder->RectsIndex[].
@ -3751,7 +3752,7 @@ struct ImFontAtlasPostProcessData
ImFontGlyph* Glyph; ImFontGlyph* Glyph;
// Pixel data // Pixel data
unsigned char* Pixels; void* Pixels;
ImTextureFormat Format; ImTextureFormat Format;
int Pitch; int Pitch;
int Width; int Width;

View File

@ -1,4 +1,4 @@
// dear imgui, v1.92.0 WIP // dear imgui, v1.92.0
// (main code and documentation) // (main code and documentation)
// Help: // Help:
@ -460,6 +460,14 @@ CODE
When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
You can read releases logs https://github.com/ocornut/imgui/releases for more details. You can read releases logs https://github.com/ocornut/imgui/releases for more details.
- 2025/06/25 (1.92.0) - layout: commented out legacy ErrorCheckUsingSetCursorPosToExtendParentBoundaries() fallback obsoleted in 1.89 (August 2022) which allowed a SetCursorPos()/SetCursorScreenPos() call WITHOUT AN ITEM
to extend parent window/cell boundaries. Replaced with assert/tooltip that would already happens if previously using IMGUI_DISABLE_OBSOLETE_FUNCTIONS. (#5548, #4510, #3355, #1760, #1490, #4152, #150)
- Incorrect way to make a window content size 200x200:
Begin(...) + SetCursorScreenPos(GetCursorScreenPos() + ImVec2(200,200)) + End();
- Correct ways to make a window content size 200x200:
Begin(...) + SetCursorScreenPos(GetCursorScreenPos() + ImVec2(200,200)) + Dummy(ImVec2(0,0)) + End();
Begin(...) + Dummy(ImVec2(200,200)) + End();
- TL;DR; if the assert triggers, you can add a Dummy({0,0}) call to validate extending parent boundaries.
- 2025/06/11 (1.92.0) - THIS VERSION CONTAINS THE LARGEST AMOUNT OF BREAKING CHANGES SINCE 2015! I TRIED REALLY HARD TO KEEP THEM TO A MINIMUM, REDUCE THE AMOUNT OF INTERFERENCES, BUT INEVITABLY SOME USERS WILL BE AFFECTED. - 2025/06/11 (1.92.0) - THIS VERSION CONTAINS THE LARGEST AMOUNT OF BREAKING CHANGES SINCE 2015! I TRIED REALLY HARD TO KEEP THEM TO A MINIMUM, REDUCE THE AMOUNT OF INTERFERENCES, BUT INEVITABLY SOME USERS WILL BE AFFECTED.
IN ORDER TO HELP US IMPROVE THE TRANSITION PROCESS, INCL. DOCUMENTATION AND COMMENTS, PLEASE REPORT **ANY** DOUBT, CONFUSION, QUESTIONS, FEEDBACK TO: https://github.com/ocornut/imgui/issues/ IN ORDER TO HELP US IMPROVE THE TRANSITION PROCESS, INCL. DOCUMENTATION AND COMMENTS, PLEASE REPORT **ANY** DOUBT, CONFUSION, QUESTIONS, FEEDBACK TO: https://github.com/ocornut/imgui/issues/
As part of the plan to reduce impact of API breaking changes, several unfinished changes/features/refactors related to font and text systems and scaling will be part of subsequent releases (1.92.1+). As part of the plan to reduce impact of API breaking changes, several unfinished changes/features/refactors related to font and text systems and scaling will be part of subsequent releases (1.92.1+).
@ -470,11 +478,27 @@ CODE
- With a legacy backend (< 1.92): Instead of setting io.FontGlobalScale = 1.0f/N -> set ImFontCfg::RasterizerDensity = N. This already worked before, but is now pretty much required. - With a legacy backend (< 1.92): Instead of setting io.FontGlobalScale = 1.0f/N -> set ImFontCfg::RasterizerDensity = N. This already worked before, but is now pretty much required.
- With a new backend (1.92+): This should be all automatic. FramebufferScale is automatically used to set current font RasterizerDensity. FramebufferScale is a per-viewport property provided by backend through the Platform_GetWindowFramebufferScale() handler in 'docking' branch. - With a new backend (1.92+): This should be all automatic. FramebufferScale is automatically used to set current font RasterizerDensity. FramebufferScale is a per-viewport property provided by backend through the Platform_GetWindowFramebufferScale() handler in 'docking' branch.
- Fonts: **IMPORTANT** on Font Sizing: Before 1.92, fonts were of a single size. They can now be dynamically sized. - Fonts: **IMPORTANT** on Font Sizing: Before 1.92, fonts were of a single size. They can now be dynamically sized.
- PushFont() API now has an optional size parameter. PushFontSize() was also added. - PushFont() API now has a REQUIRED size parameter.
- Before 1.92: ImGui::PushFont() always used font "default" size specified in AddFont() call. - Before 1.92: PushFont() always used font "default" size specified in AddFont() call. It is equivalent to calling PushFont(font, font->LegacySize).
- Since 1.92: ImGui::PushFont() preserve the current font size which is a shared value. - Since 1.92: PushFont(font, 0.0f) preserve the current font size which is a shared value.
- To use old behavior: (A) use 'ImGui::PushFont(font, font->LegacySize)' at call site (preferred). (B) Set 'ImFontConfig::Flags |= ImFontFlags_DefaultToLegacySize' in AddFont() call (not desirable as it requires e.g. third-party code to be aware of it). - To use old behavior: use 'ImGui::PushFont(font, font->LegacySize)' at call site.
- Kept inline single parameter function. Will obsolete.
- Fonts: **IMPORTANT** on Font Merging:
- When searching for a glyph in multiple merged fonts: font inputs are now scanned in orderfor the first font input which the desired glyph. This is technically a different behavior than before!
- e.g. If you are merging fonts you may have glyphs that you expected to load from Font Source 2 which exists in Font Source 1. After the update and when using a new backend, those glyphs may now loaded from Font Source 1!
- You can use `ImFontConfig::GlyphExcludeRanges[]` to specify ranges to ignore in given Input:
// Add Font Source 1 but ignore ICON_MIN_FA..ICON_MAX_FA range
static ImWchar exclude_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
ImFontConfig cfg1;
cfg1.GlyphExcludeRanges = exclude_ranges;
io.Fonts->AddFontFromFileTTF("segoeui.ttf", 0.0f, &cfg1);
// Add Font Source 2, which expects to use the range above
ImFontConfig cfg2;
cfg2.MergeMode = true;
io.Fonts->AddFontFromFileTTF("FontAwesome4.ttf", 0.0f, &cfg2);
- You can use `Metrics/Debugger->Fonts->Font->Input Glyphs Overlap Detection Tool` to see list of glyphs available in multiple font sources. This can facilitate unde
- Fonts: ImFont::FontSize was removed and does not make sense anymore. ImFont::LegacySize is the size passed to AddFont(). - Fonts: ImFont::FontSize was removed and does not make sense anymore. ImFont::LegacySize is the size passed to AddFont().
- Fonts: Removed support for PushFont(NULL) which was a shortcut for "default font".
- Fonts: Renamed/moved 'io.FontGlobalScale' to 'style.FontScaleMain'. - Fonts: Renamed/moved 'io.FontGlobalScale' to 'style.FontScaleMain'.
- Textures: all API functions taking a 'ImTextureID' parameter are now taking a 'ImTextureRef'. Affected functions are: ImGui::Image(), ImGui::ImageWithBg(), ImGui::ImageButton(), ImDrawList::AddImage(), ImDrawList::AddImageQuad(), ImDrawList::AddImageRounded(). - Textures: all API functions taking a 'ImTextureID' parameter are now taking a 'ImTextureRef'. Affected functions are: ImGui::Image(), ImGui::ImageWithBg(), ImGui::ImageButton(), ImDrawList::AddImage(), ImDrawList::AddImageQuad(), ImDrawList::AddImageRounded().
- Fonts: obsoleted ImFontAtlas::GetTexDataAsRGBA32(), GetTexDataAsAlpha8(), Build(), SetTexID(), IsBuilt() functions. The new protocol for backends to handle textures doesn't need them. Kept redirection functions (will obsolete). - Fonts: obsoleted ImFontAtlas::GetTexDataAsRGBA32(), GetTexDataAsAlpha8(), Build(), SetTexID(), IsBuilt() functions. The new protocol for backends to handle textures doesn't need them. Kept redirection functions (will obsolete).
@ -482,7 +506,7 @@ CODE
- Fonts: specifying glyph ranges is now unnecessary. The value of ImFontConfig::GlyphRanges[] is only useful for legacy backends. All GetGlyphRangesXXXX() functions are now marked obsolete: GetGlyphRangesDefault(), GetGlyphRangesGreek(), GetGlyphRangesKorean(), GetGlyphRangesJapanese(), GetGlyphRangesChineseSimplifiedCommon(), GetGlyphRangesChineseFull(), GetGlyphRangesCyrillic(), GetGlyphRangesThai(), GetGlyphRangesVietnamese(). - Fonts: specifying glyph ranges is now unnecessary. The value of ImFontConfig::GlyphRanges[] is only useful for legacy backends. All GetGlyphRangesXXXX() functions are now marked obsolete: GetGlyphRangesDefault(), GetGlyphRangesGreek(), GetGlyphRangesKorean(), GetGlyphRangesJapanese(), GetGlyphRangesChineseSimplifiedCommon(), GetGlyphRangesChineseFull(), GetGlyphRangesCyrillic(), GetGlyphRangesThai(), GetGlyphRangesVietnamese().
- Fonts: removed ImFontAtlas::TexDesiredWidth to enforce a texture width. (#327) - Fonts: removed ImFontAtlas::TexDesiredWidth to enforce a texture width. (#327)
- Fonts: if you create and manage ImFontAtlas instances yourself (instead of relying on ImGuiContext to create one, you'll need to call ImFontAtlasUpdateNewFrame() yourself. An assert will trigger if you don't. - Fonts: if you create and manage ImFontAtlas instances yourself (instead of relying on ImGuiContext to create one, you'll need to call ImFontAtlasUpdateNewFrame() yourself. An assert will trigger if you don't.
- Fonts: obsolete ImGui::SetWindowFontScale() which is not useful anymore. Prefer using 'PushFontSize(style.FontSizeBase * factor)' or to manipulate other scaling factors. - Fonts: obsolete ImGui::SetWindowFontScale() which is not useful anymore. Prefer using 'PushFont(NULL, style.FontSizeBase * factor)' or to manipulate other scaling factors.
- Fonts: obsoleted ImFont::Scale which is not useful anymore. - Fonts: obsoleted ImFont::Scale which is not useful anymore.
- Fonts: generally reworked Internals of ImFontAtlas and ImFont. While in theory a vast majority of users shouldn't be affected, some use cases or extensions might be. Among other things: - Fonts: generally reworked Internals of ImFontAtlas and ImFont. While in theory a vast majority of users shouldn't be affected, some use cases or extensions might be. Among other things:
- ImDrawCmd::TextureId has been changed to ImDrawCmd::TexRef. - ImDrawCmd::TextureId has been changed to ImDrawCmd::TexRef.
@ -3938,7 +3962,7 @@ void ImGui::RenderMouseCursor(ImVec2 base_pos, float base_scale, ImGuiMouseCurso
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
if (mouse_cursor <= ImGuiMouseCursor_None || mouse_cursor >= ImGuiMouseCursor_COUNT) // We intentionally accept out of bound values. if (mouse_cursor <= ImGuiMouseCursor_None || mouse_cursor >= ImGuiMouseCursor_COUNT) // We intentionally accept out of bound values.
mouse_cursor = ImGuiMouseCursor_Arrow; mouse_cursor = ImGuiMouseCursor_Arrow;
ImFontAtlas* font_atlas = g.DrawListSharedData.Font->ContainerAtlas; ImFontAtlas* font_atlas = g.DrawListSharedData.FontAtlas;
for (ImGuiViewportP* viewport : g.Viewports) for (ImGuiViewportP* viewport : g.Viewports)
{ {
// We scale cursor with current viewport/monitor, however Windows 10 for its own hardware cursor seems to be using a different scale factor. // We scale cursor with current viewport/monitor, however Windows 10 for its own hardware cursor seems to be using a different scale factor.
@ -6621,9 +6645,9 @@ static ImVec2 CalcWindowAutoFitSize(ImGuiWindow* window, const ImVec2& size_cont
// FIXME: CalcWindowAutoFitSize() doesn't take into account that only one axis may be auto-fit when calculating scrollbars, // FIXME: CalcWindowAutoFitSize() doesn't take into account that only one axis may be auto-fit when calculating scrollbars,
// we may need to compute/store three variants of size_auto_fit, for x/y/xy. // we may need to compute/store three variants of size_auto_fit, for x/y/xy.
// Here we implement a workaround for child windows only, but a full solution would apply to normal windows as well: // Here we implement a workaround for child windows only, but a full solution would apply to normal windows as well:
if ((window->ChildFlags & ImGuiChildFlags_ResizeX) && !(window->ChildFlags & ImGuiChildFlags_ResizeY)) if ((window->ChildFlags & ImGuiChildFlags_ResizeX) && !(window->ChildFlags & (ImGuiChildFlags_ResizeY | ImGuiChildFlags_AutoResizeY)))
size_auto_fit.y = window->SizeFull.y; size_auto_fit.y = window->SizeFull.y;
else if (!(window->ChildFlags & ImGuiChildFlags_ResizeX) && (window->ChildFlags & ImGuiChildFlags_ResizeY)) else if ((window->ChildFlags & ImGuiChildFlags_ResizeY) && !(window->ChildFlags & (ImGuiChildFlags_ResizeX | ImGuiChildFlags_AutoResizeX)))
size_auto_fit.x = window->SizeFull.x; size_auto_fit.x = window->SizeFull.x;
// When the window cannot fit all contents (either because of constraints, either because screen is too small), // When the window cannot fit all contents (either because of constraints, either because screen is too small),
@ -6743,7 +6767,9 @@ static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& si
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindowFlags flags = window->Flags; ImGuiWindowFlags flags = window->Flags;
if ((flags & ImGuiWindowFlags_NoResize) || (flags & ImGuiWindowFlags_AlwaysAutoResize) || window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) if ((flags & ImGuiWindowFlags_NoResize) || window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0)
return false;
if ((flags & ImGuiWindowFlags_AlwaysAutoResize) && (window->ChildFlags & (ImGuiChildFlags_ResizeX | ImGuiChildFlags_ResizeY)) == 0)
return false; return false;
if (window->WasActive == false) // Early out to avoid running this code for e.g. a hidden implicit/fallback Debug window. if (window->WasActive == false) // Early out to avoid running this code for e.g. a hidden implicit/fallback Debug window.
return false; return false;
@ -8532,7 +8558,9 @@ ImFontBaked* ImGui::GetFontBaked()
return GImGui->FontBaked; return GImGui->FontBaked;
} }
// Get current font size (= height in pixels) of current font, with external scale factors applied. Use ImGui::GetStyle().FontSizeBase to get value before external scale factors. // Get current font size (= height in pixels) of current font, with global scale factors applied.
// - Use style.FontSizeBase to get value before global scale factors.
// - recap: ImGui::GetFontSize() == style.FontSizeBase * (style.FontScaleMain * style.FontScaleDpi * other_scaling_factors)
float ImGui::GetFontSize() float ImGui::GetFontSize()
{ {
return GImGui->FontSize; return GImGui->FontSize;
@ -8548,7 +8576,7 @@ ImVec2 ImGui::GetFontTexUvWhitePixel()
return GImGui->DrawListSharedData.TexUvWhitePixel; return GImGui->DrawListSharedData.TexUvWhitePixel;
} }
// Prefer using PushFontSize(style.FontSizeBase * factor), or use style.FontScaleMain to scale all windows. // Prefer using PushFont(NULL, style.FontSizeBase * factor), or use style.FontScaleMain to scale all windows.
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
void ImGui::SetWindowFontScale(float scale) void ImGui::SetWindowFontScale(float scale)
{ {
@ -8729,8 +8757,6 @@ bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max)
// - SetFontRasterizerDensity() [Internal] // - SetFontRasterizerDensity() [Internal]
// - PushFont() // - PushFont()
// - PopFont() // - PopFont()
// - PushFontSize()
// - PopFontSize()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void ImGui::UpdateFontsNewFrame() void ImGui::UpdateFontsNewFrame()
@ -8830,10 +8856,12 @@ void ImGui::SetCurrentFont(ImFont* font, float font_size_before_scaling, float f
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
IM_ASSERT(font->Scale > 0.0f); IM_ASSERT(font->Scale > 0.0f);
#endif #endif
g.DrawListSharedData.Font = g.Font; ImFontAtlas* atlas = font->ContainerAtlas;
ImFontAtlasUpdateDrawListsSharedData(g.Font->ContainerAtlas); g.DrawListSharedData.FontAtlas = atlas;
g.DrawListSharedData.Font = font;
ImFontAtlasUpdateDrawListsSharedData(atlas);
if (g.CurrentWindow != NULL) if (g.CurrentWindow != NULL)
g.CurrentWindow->DrawList->_SetTexture(font->ContainerAtlas->TexRef); g.CurrentWindow->DrawList->_SetTexture(atlas->TexRef);
} }
} }
@ -8851,13 +8879,13 @@ void ImGui::UpdateCurrentFontSize(float restore_font_size_after_scaling)
if (g.CurrentTable == NULL || g.CurrentTable->CurrentColumn != -1) // See 8465#issuecomment-2951509561. Ideally the SkipItems=true in tables would be amended with extra data. if (g.CurrentTable == NULL || g.CurrentTable->CurrentColumn != -1) // See 8465#issuecomment-2951509561. Ideally the SkipItems=true in tables would be amended with extra data.
return; return;
// Restoring is pretty much only used by PopFont()/PopFontSize() // Restoring is pretty much only used by PopFont()
float final_size = (restore_font_size_after_scaling > 0.0f) ? restore_font_size_after_scaling : 0.0f; float final_size = (restore_font_size_after_scaling > 0.0f) ? restore_font_size_after_scaling : 0.0f;
if (final_size == 0.0f) if (final_size == 0.0f)
{ {
final_size = g.FontSizeBase; final_size = g.FontSizeBase;
// External scale factors // Global scale factors
final_size *= g.Style.FontScaleMain; // Main global scale factor final_size *= g.Style.FontScaleMain; // Main global scale factor
final_size *= g.Style.FontScaleDpi; // Per-monitor/viewport DPI scale factor, automatically updated when io.ConfigDpiScaleFonts is enabled. final_size *= g.Style.FontScaleDpi; // Per-monitor/viewport DPI scale factor, automatically updated when io.ConfigDpiScaleFonts is enabled.
@ -8899,24 +8927,20 @@ void ImGui::SetFontRasterizerDensity(float rasterizer_density)
UpdateCurrentFontSize(0.0f); UpdateCurrentFontSize(0.0f);
} }
// If you want to scale an existing font size: // If you want to scale an existing font size! Read comments in imgui.h!
// - Use e.g. PushFontSize(style.FontSizeBase * factor) (= value before external scale factors applied).
// - Do NOT use PushFontSize(GetFontSize() * factor) (= value after external scale factors applied).
void ImGui::PushFont(ImFont* font, float font_size_base, float font_weight) void ImGui::PushFont(ImFont* font, float font_size_base, float font_weight)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
if (font == NULL) // Before 1.92 (June 2025), PushFont(NULL) == PushFont(GetDefaultFont())
font = g.Font;
IM_ASSERT(font != NULL);
IM_ASSERT(font_size_base >= 0.0f);
g.FontStack.push_back({ g.Font, g.FontSizeBase, g.FontSize, g.FontWeight }); g.FontStack.push_back({ g.Font, g.FontSizeBase, g.FontSize, g.FontWeight });
if (font == NULL) if (font_size_base == 0.0f)
font = GetDefaultFont(); font_size_base = g.FontSizeBase; // Keep current font size
if (font_size_base <= 0.0f)
{
if (font->Flags & ImFontFlags_DefaultToLegacySize)
font_size_base = font->LegacySize; // Legacy: use AddFont() specified font size. Same as doing PushFont(font, font->LegacySize)
else
font_size_base = g.FontSizeBase; // Keep current font size
}
if (font_weight <= 0.0f) if (font_weight <= 0.0f)
font_weight = font->DefaultWeight; font_weight = (font_weight == 0.0f) ? font->DefaultWeight : g.FontWeight;
SetCurrentFont(font, font_size_base, 0.0f, font_weight); SetCurrentFont(font, font_size_base, 0.0f, font_weight);
} }
@ -8933,34 +8957,6 @@ void ImGui::PopFont()
g.FontStack.pop_back(); g.FontStack.pop_back();
} }
void ImGui::PushFontSize(float font_size_base)
{
ImGuiContext& g = *GImGui;
PushFont(g.Font, font_size_base, g.FontWeight);
}
void ImGui::PushFontSize(float font_size_base, float font_weight)
{
ImGuiContext& g = *GImGui;
PushFont(g.Font, font_size_base, font_weight);
}
void ImGui::PopFontSize()
{
PopFont();
}
void ImGui::PushFontWeight(float font_weight)
{
ImGuiContext& g = *GImGui;
PushFont(g.Font, g.FontSizeBase, font_weight);
}
void ImGui::PopFontWeight()
{
PopFont();
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] ID STACK // [SECTION] ID STACK
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -10612,36 +10608,44 @@ bool ImGui::DebugCheckVersionAndDataLayout(const char* version, size_t sz_io, si
return !error; return !error;
} }
// Until 1.89 (IMGUI_VERSION_NUM < 18814) it was legal to use SetCursorPos() to extend the boundary of a parent (e.g. window or table cell) // Until 1.89 (August 2022, IMGUI_VERSION_NUM < 18814) it was legal to use SetCursorPos()/SetCursorScreenPos()
// This is causing issues and ambiguity and we need to retire that. // to extend contents size of our parent container (e.g. window contents size, which is used for auto-resizing
// See https://github.com/ocornut/imgui/issues/5548 for more details. // windows, table column contents size used for auto-resizing columns, group size).
// [Scenario 1] // This was causing issues and ambiguities and we needed to retire that.
// From 1.89, extending contents size boundaries REQUIRES AN ITEM TO BE SUBMITTED.
//
// Previously this would make the window content size ~200x200: // Previously this would make the window content size ~200x200:
// Begin(...) + SetCursorScreenPos(GetCursorScreenPos() + ImVec2(200,200)) + End(); // NOT OK // Begin(...) + SetCursorScreenPos(GetCursorScreenPos() + ImVec2(200,200)) + End(); // NOT OK ANYMORE
// Instead, please submit an item: // Instead, please submit an item:
// Begin(...) + SetCursorScreenPos(GetCursorScreenPos() + ImVec2(200,200)) + Dummy(ImVec2(0,0)) + End(); // OK // Begin(...) + SetCursorScreenPos(GetCursorScreenPos() + ImVec2(200,200)) + Dummy(ImVec2(0,0)) + End(); // OK
// Alternative: // Alternative:
// Begin(...) + Dummy(ImVec2(200,200)) + End(); // OK // Begin(...) + Dummy(ImVec2(200,200)) + End(); // OK
// [Scenario 2] //
// For reference this is one of the issue what we aim to fix with this change: // The assert below detects when the _last_ call in a window was a SetCursorPos() not followed by an Item,
// BeginGroup() + SomeItem("foobar") + SetCursorScreenPos(GetCursorScreenPos()) + EndGroup() // and with a position that would grow the parent contents size.
// The previous logic made SetCursorScreenPos(GetCursorScreenPos()) have a side-effect! It would erroneously incorporate ItemSpacing.y after the item into content size, making the group taller! //
// While this code is a little twisted, no-one would expect SetXXX(GetXXX()) to have a side-effect. Using vertical alignment patterns could trigger this issue. // Advanced:
// - For reference, old logic was causing issues because it meant that SetCursorScreenPos(GetCursorScreenPos())
// had a side-effect on layout! In particular this caused problem to compute group boundaries.
// e.g. BeginGroup() + SomeItem() + SetCursorScreenPos(GetCursorScreenPos()) + EndGroup() would cause the
// group to be taller because auto-sizing generally adds padding on bottom and right side.
// - While this code is a little twisted, no-one would expect SetXXX(GetXXX()) to have a side-effect.
// Using vertical alignment patterns would frequently trigger this sorts of issue.
// - See https://github.com/ocornut/imgui/issues/5548 for more details.
void ImGui::ErrorCheckUsingSetCursorPosToExtendParentBoundaries() void ImGui::ErrorCheckUsingSetCursorPosToExtendParentBoundaries()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
IM_ASSERT(window->DC.IsSetPos); IM_ASSERT(window->DC.IsSetPos);
window->DC.IsSetPos = false; window->DC.IsSetPos = false;
#ifdef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
if (window->DC.CursorPos.x <= window->DC.CursorMaxPos.x && window->DC.CursorPos.y <= window->DC.CursorMaxPos.y) if (window->DC.CursorPos.x <= window->DC.CursorMaxPos.x && window->DC.CursorPos.y <= window->DC.CursorMaxPos.y)
return; return;
if (window->SkipItems) if (window->SkipItems)
return; return;
IM_ASSERT(0 && "Code uses SetCursorPos()/SetCursorScreenPos() to extend window/parent boundaries. Please submit an item e.g. Dummy() to validate extent."); IM_ASSERT_USER_ERROR(0, "Code uses SetCursorPos()/SetCursorScreenPos() to extend window/parent boundaries.\nPlease submit an item e.g. Dummy() afterwards in order to grow window/parent boundaries.");
#else
window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos); // For reference, the old behavior was essentially:
#endif //window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos);
} }
static void ImGui::ErrorCheckNewFrameSanityChecks() static void ImGui::ErrorCheckNewFrameSanityChecks()
@ -15993,7 +15997,8 @@ void ImGui::ShowFontAtlas(ImFontAtlas* atlas)
DragFloat("FontScaleDpi", &style.FontScaleDpi, 0.02f, 0.5f, 5.0f); DragFloat("FontScaleDpi", &style.FontScaleDpi, 0.02f, 0.5f, 5.0f);
//SetItemTooltip("When io.ConfigDpiScaleFonts is set, this value is automatically overwritten."); //SetItemTooltip("When io.ConfigDpiScaleFonts is set, this value is automatically overwritten.");
//EndDisabled(); //EndDisabled();
BulletText("Warning: Font scaling will NOT be smooth, because\nImGuiBackendFlags_RendererHasTextures is not set!"); if ((io.BackendFlags & ImGuiBackendFlags_RendererHasTextures) == 0)
BulletText("Warning: Font scaling will NOT be smooth, because\nImGuiBackendFlags_RendererHasTextures is not set!");
BulletText("Load a nice font for better results!"); BulletText("Load a nice font for better results!");
BulletText("Please submit feedback:"); BulletText("Please submit feedback:");
SameLine(); TextLinkOpenURL("#8465", "https://github.com/ocornut/imgui/issues/8465"); SameLine(); TextLinkOpenURL("#8465", "https://github.com/ocornut/imgui/issues/8465");
@ -16962,7 +16967,7 @@ void ImGui::DebugNodeFont(ImFont* font)
Indent(); Indent();
if (cfg->ShowFontPreview) if (cfg->ShowFontPreview)
{ {
PushFont(font); PushFont(font, 0.0f, -1.0f);
Text("The quick brown fox jumps over the lazy dog"); Text("The quick brown fox jumps over the lazy dog");
PopFont(); PopFont();
} }
@ -17028,7 +17033,8 @@ void ImGui::DebugNodeFont(ImFont* font)
} }
if (font->Sources.Size > 1 && TreeNode("Input Glyphs Overlap Detection Tool")) if (font->Sources.Size > 1 && TreeNode("Input Glyphs Overlap Detection Tool"))
{ {
TextWrapped("- First Input that contains the glyph is used.\n- Use ImFontConfig::GlyphExcludeRanges[] to specify ranges to ignore glyph in given Input.\n- This tool doesn't cache results and is slow, don't keep it open!"); TextWrapped("- First Input that contains the glyph is used.\n"
"- Use ImFontConfig::GlyphExcludeRanges[] to specify ranges to ignore glyph in given Input.\n- Prefer using a small number of ranges as the list is scanned every time a new glyph is loaded,\n - e.g. GlyphExcludeRanges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };\n- This tool doesn't cache results and is slow, don't keep it open!");
if (BeginTable("table", 2)) if (BeginTable("table", 2))
{ {
for (unsigned int c = 0; c < 0x10000; c++) for (unsigned int c = 0; c < 0x10000; c++)

View File

@ -1,4 +1,4 @@
// dear imgui, v1.92.0 WIP // dear imgui, v1.92.0
// (demo code) // (demo code)
// Help: // Help:
@ -842,6 +842,9 @@ static void DemoWindowWidgetsBasic()
ImGui::RadioButton("radio b", &e, 1); ImGui::SameLine(); ImGui::RadioButton("radio b", &e, 1); ImGui::SameLine();
ImGui::RadioButton("radio c", &e, 2); ImGui::RadioButton("radio c", &e, 2);
ImGui::AlignTextToFramePadding();
ImGui::TextLinkOpenURL("Hyperlink", "https://github.com/ocornut/imgui/wiki/Error-Handling");
// Color buttons, demonstrate using PushID() to add unique identifier in the ID stack, and changing style. // Color buttons, demonstrate using PushID() to add unique identifier in the ID stack, and changing style.
IMGUI_DEMO_MARKER("Widgets/Basic/Buttons (Colored)"); IMGUI_DEMO_MARKER("Widgets/Basic/Buttons (Colored)");
for (int i = 0; i < 7; i++) for (int i = 0; i < 7; i++)
@ -4444,11 +4447,11 @@ static void DemoWindowLayout()
ImGui::Text("SetNextItemWidth/PushItemWidth(-Min(GetContentRegionAvail().x * 0.40f, GetFontSize() * 12))"); ImGui::Text("SetNextItemWidth/PushItemWidth(-Min(GetContentRegionAvail().x * 0.40f, GetFontSize() * 12))");
ImGui::PushItemWidth(-IM_MIN(ImGui::GetFontSize() * 12, ImGui::GetContentRegionAvail().x * 0.40f)); ImGui::PushItemWidth(-IM_MIN(ImGui::GetFontSize() * 12, ImGui::GetContentRegionAvail().x * 0.40f));
ImGui::DragFloat("float##4a", &f); ImGui::DragFloat("float##5a", &f);
if (show_indented_items) if (show_indented_items)
{ {
ImGui::Indent(); ImGui::Indent();
ImGui::DragFloat("float (indented)##4b", &f); ImGui::DragFloat("float (indented)##5b", &f);
ImGui::Unindent(); ImGui::Unindent();
} }
ImGui::PopItemWidth(); ImGui::PopItemWidth();
@ -4458,11 +4461,11 @@ static void DemoWindowLayout()
ImGui::Text("SetNextItemWidth/PushItemWidth(-FLT_MIN)"); ImGui::Text("SetNextItemWidth/PushItemWidth(-FLT_MIN)");
ImGui::SameLine(); HelpMarker("Align to right edge"); ImGui::SameLine(); HelpMarker("Align to right edge");
ImGui::PushItemWidth(-FLT_MIN); ImGui::PushItemWidth(-FLT_MIN);
ImGui::DragFloat("##float5a", &f); ImGui::DragFloat("##float6a", &f);
if (show_indented_items) if (show_indented_items)
{ {
ImGui::Indent(); ImGui::Indent();
ImGui::DragFloat("float (indented)##5b", &f); ImGui::DragFloat("float (indented)##6b", &f);
ImGui::Unindent(); ImGui::Unindent();
} }
ImGui::PopItemWidth(); ImGui::PopItemWidth();
@ -8024,6 +8027,8 @@ void ImGui::ShowAboutWindow(bool* p_open)
ImGui::SameLine(); ImGui::SameLine();
ImGui::TextLinkOpenURL("Wiki", "https://github.com/ocornut/imgui/wiki"); ImGui::TextLinkOpenURL("Wiki", "https://github.com/ocornut/imgui/wiki");
ImGui::SameLine(); ImGui::SameLine();
ImGui::TextLinkOpenURL("Extensions", "https://github.com/ocornut/imgui/wiki/Useful-Extensions");
ImGui::SameLine();
ImGui::TextLinkOpenURL("Releases", "https://github.com/ocornut/imgui/releases"); ImGui::TextLinkOpenURL("Releases", "https://github.com/ocornut/imgui/releases");
ImGui::SameLine(); ImGui::SameLine();
ImGui::TextLinkOpenURL("Funding", "https://github.com/ocornut/imgui/wiki/Funding"); ImGui::TextLinkOpenURL("Funding", "https://github.com/ocornut/imgui/wiki/Funding");
@ -8146,7 +8151,7 @@ void ImGui::ShowAboutWindow(bool* p_open)
if (io.BackendFlags & ImGuiBackendFlags_RendererHasTextures) ImGui::Text(" RendererHasTextures"); if (io.BackendFlags & ImGuiBackendFlags_RendererHasTextures) ImGui::Text(" RendererHasTextures");
ImGui::Separator(); ImGui::Separator();
ImGui::Text("io.Fonts: %d fonts, Flags: 0x%08X, TexSize: %d,%d", io.Fonts->Fonts.Size, io.Fonts->Flags, io.Fonts->TexData->Width, io.Fonts->TexData->Height); ImGui::Text("io.Fonts: %d fonts, Flags: 0x%08X, TexSize: %d,%d", io.Fonts->Fonts.Size, io.Fonts->Flags, io.Fonts->TexData->Width, io.Fonts->TexData->Height);
ImGui::Text("io.Fonts->FontLoaderName: \"%s\"", io.Fonts->FontLoaderName ? io.Fonts->FontLoaderName : "NULL"); ImGui::Text("io.Fonts->FontLoaderName: %s", io.Fonts->FontLoaderName ? io.Fonts->FontLoaderName : "NULL");
ImGui::Text("io.DisplaySize: %.2f,%.2f", io.DisplaySize.x, io.DisplaySize.y); ImGui::Text("io.DisplaySize: %.2f,%.2f", io.DisplaySize.x, io.DisplaySize.y);
ImGui::Text("io.DisplayFramebufferScale: %.2f,%.2f", io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y); ImGui::Text("io.DisplayFramebufferScale: %.2f,%.2f", io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y);
ImGui::Separator(); ImGui::Separator();

View File

@ -1,4 +1,4 @@
// dear imgui, v1.92.0 WIP // dear imgui, v1.92.0
// (drawing and font code) // (drawing and font code)
/* /*
@ -695,6 +695,7 @@ void ImDrawList::_SetTexture(ImTextureRef tex_ref)
if (_CmdHeader.TexRef == tex_ref) if (_CmdHeader.TexRef == tex_ref)
return; return;
_CmdHeader.TexRef = tex_ref; _CmdHeader.TexRef = tex_ref;
_TextureStack.back() = tex_ref;
_OnChangedTexture(); _OnChangedTexture();
} }
@ -2696,10 +2697,11 @@ void ImFontAtlas::ClearFonts()
Fonts.clear_delete(); Fonts.clear_delete();
TexIsBuilt = false; TexIsBuilt = false;
for (ImDrawListSharedData* shared_data : DrawListSharedDatas) for (ImDrawListSharedData* shared_data : DrawListSharedDatas)
{ if (shared_data->FontAtlas == this)
shared_data->Font = NULL; {
shared_data->FontScale = shared_data->FontSize = 0.0f; shared_data->Font = NULL;
} shared_data->FontScale = shared_data->FontSize = 0.0f;
}
} }
static void ImFontAtlasBuildUpdateRendererHasTexturesFromContext(ImFontAtlas* atlas) static void ImFontAtlasBuildUpdateRendererHasTexturesFromContext(ImFontAtlas* atlas)
@ -2863,7 +2865,7 @@ void ImFontAtlasTextureBlockPostProcess(ImFontAtlasPostProcessData* data)
void ImFontAtlasTextureBlockPostProcessMultiply(ImFontAtlasPostProcessData* data, float multiply_factor) void ImFontAtlasTextureBlockPostProcessMultiply(ImFontAtlasPostProcessData* data, float multiply_factor)
{ {
unsigned char* pixels = data->Pixels; unsigned char* pixels = (unsigned char*)data->Pixels;
int pitch = data->Pitch; int pitch = data->Pitch;
if (data->Format == ImTextureFormat_Alpha8) if (data->Format == ImTextureFormat_Alpha8)
{ {
@ -3106,7 +3108,7 @@ ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg_template)
if (font_cfg.Name[0] == '\0') if (font_cfg.Name[0] == '\0')
ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "ProggyClean.ttf"); ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "ProggyClean.ttf");
font_cfg.EllipsisChar = (ImWchar)0x0085; font_cfg.EllipsisChar = (ImWchar)0x0085;
font_cfg.GlyphOffset.y = 1.0f * IM_TRUNC(font_cfg.SizePixels / 13.0f); // Add +1 offset per 13 units font_cfg.GlyphOffset.y += 1.0f * IM_TRUNC(font_cfg.SizePixels / 13.0f); // Add +1 offset per 13 units
int ttf_compressed_size = 0; int ttf_compressed_size = 0;
const char* ttf_compressed = GetDefaultCompressedFontDataTTF(&ttf_compressed_size); const char* ttf_compressed = GetDefaultCompressedFontDataTTF(&ttf_compressed_size);
@ -3454,7 +3456,7 @@ void ImFontAtlasBuildRenderBitmapFromString(ImFontAtlas* atlas, int x, int y, in
{ {
case ImTextureFormat_Alpha8: case ImTextureFormat_Alpha8:
{ {
ImU8* out_p = tex->GetPixelsAt(x, y); ImU8* out_p = (ImU8*)tex->GetPixelsAt(x, y);
for (int off_y = 0; off_y < h; off_y++, out_p += tex->Width, in_str += w) for (int off_y = 0; off_y < h; off_y++, out_p += tex->Width, in_str += w)
for (int off_x = 0; off_x < w; off_x++) for (int off_x = 0; off_x < w; off_x++)
out_p[off_x] = (in_str[off_x] == in_marker_char) ? 0xFF : 0x00; out_p[off_x] = (in_str[off_x] == in_marker_char) ? 0xFF : 0x00;
@ -3462,7 +3464,7 @@ void ImFontAtlasBuildRenderBitmapFromString(ImFontAtlas* atlas, int x, int y, in
} }
case ImTextureFormat_RGBA32: case ImTextureFormat_RGBA32:
{ {
ImU32* out_p = (ImU32*)(void*)tex->GetPixelsAt(x, y); ImU32* out_p = (ImU32*)tex->GetPixelsAt(x, y);
for (int off_y = 0; off_y < h; off_y++, out_p += tex->Width, in_str += w) for (int off_y = 0; off_y < h; off_y++, out_p += tex->Width, in_str += w)
for (int off_x = 0; off_x < w; off_x++) for (int off_x = 0; off_x < w; off_x++)
out_p[off_x] = (in_str[off_x] == in_marker_char) ? IM_COL32_WHITE : IM_COL32_BLACK_TRANS; out_p[off_x] = (in_str[off_x] == in_marker_char) ? IM_COL32_WHITE : IM_COL32_BLACK_TRANS;
@ -3768,7 +3770,7 @@ void ImFontAtlasBakedDiscardFontGlyph(ImFontAtlas* atlas, ImFont* font, ImFontBa
ImFontBaked* ImFontAtlasBakedAdd(ImFontAtlas* atlas, ImFont* font, float font_size, float font_weight, float font_rasterizer_density, ImGuiID baked_id) ImFontBaked* ImFontAtlasBakedAdd(ImFontAtlas* atlas, ImFont* font, float font_size, float font_weight, float font_rasterizer_density, ImGuiID baked_id)
{ {
IMGUI_DEBUG_LOG_FONT("[font] Created baked %.2fpx\n", font_size); IMGUI_DEBUG_LOG_FONT("[font] Created baked %.2fpx %.2f\n", font_size, font_weight);
ImFontBaked* baked = atlas->Builder->BakedPool.push_back(ImFontBaked()); ImFontBaked* baked = atlas->Builder->BakedPool.push_back(ImFontBaked());
baked->Size = font_size; baked->Size = font_size;
baked->RasterizerDensity = font_rasterizer_density; baked->RasterizerDensity = font_rasterizer_density;
@ -3832,7 +3834,7 @@ ImFontBaked* ImFontAtlasBakedGetClosestMatch(ImFontAtlas* atlas, ImFont* font, f
void ImFontAtlasBakedDiscard(ImFontAtlas* atlas, ImFont* font, ImFontBaked* baked) void ImFontAtlasBakedDiscard(ImFontAtlas* atlas, ImFont* font, ImFontBaked* baked)
{ {
ImFontAtlasBuilder* builder = atlas->Builder; ImFontAtlasBuilder* builder = atlas->Builder;
IMGUI_DEBUG_LOG_FONT("[font] Discard baked %.2f for \"%s\"\n", baked->Size, font->GetDebugName()); IMGUI_DEBUG_LOG_FONT("[font] Discard baked %.2f/%.2f for \"%s\"\n", baked->Size, baked->Weight, font->GetDebugName());
for (ImFontGlyph& glyph : baked->Glyphs) for (ImFontGlyph& glyph : baked->Glyphs)
if (glyph.PackId != ImFontAtlasRectId_Invalid) if (glyph.PackId != ImFontAtlasRectId_Invalid)
@ -3925,10 +3927,11 @@ void ImFontAtlasUpdateDrawListsTextures(ImFontAtlas* atlas, ImTextureRef old_tex
void ImFontAtlasUpdateDrawListsSharedData(ImFontAtlas* atlas) void ImFontAtlasUpdateDrawListsSharedData(ImFontAtlas* atlas)
{ {
for (ImDrawListSharedData* shared_data : atlas->DrawListSharedDatas) for (ImDrawListSharedData* shared_data : atlas->DrawListSharedDatas)
{ if (shared_data->FontAtlas == atlas)
shared_data->TexUvWhitePixel = atlas->TexUvWhitePixel; {
shared_data->TexUvLines = atlas->TexUvLines; shared_data->TexUvWhitePixel = atlas->TexUvWhitePixel;
} shared_data->TexUvLines = atlas->TexUvLines;
}
} }
// Set current texture. This is mostly called from AddTexture() + to handle a failed resize. // Set current texture. This is mostly called from AddTexture() + to handle a failed resize.
@ -5132,7 +5135,7 @@ void ImFontAtlasBakedSetFontGlyphBitmap(ImFontAtlas* atlas, ImFontBaked* baked,
{ {
ImTextureData* tex = atlas->TexData; ImTextureData* tex = atlas->TexData;
IM_ASSERT(r->x + r->w <= tex->Width && r->y + r->h <= tex->Height); IM_ASSERT(r->x + r->w <= tex->Width && r->y + r->h <= tex->Height);
ImFontAtlasTextureBlockConvert(src_pixels, src_fmt, src_pitch, tex->GetPixelsAt(r->x, r->y), tex->Format, tex->GetPitch(), r->w, r->h); ImFontAtlasTextureBlockConvert(src_pixels, src_fmt, src_pitch, (unsigned char*)tex->GetPixelsAt(r->x, r->y), tex->Format, tex->GetPitch(), r->w, r->h);
ImFontAtlasPostProcessData pp_data = { atlas, baked->ContainerFont, src, baked, glyph, tex->GetPixelsAt(r->x, r->y), tex->Format, tex->GetPitch(), r->w, r->h }; ImFontAtlasPostProcessData pp_data = { atlas, baked->ContainerFont, src, baked, glyph, tex->GetPixelsAt(r->x, r->y), tex->Format, tex->GetPitch(), r->w, r->h };
ImFontAtlasTextureBlockPostProcess(&pp_data); ImFontAtlasTextureBlockPostProcess(&pp_data);
ImFontAtlasTextureBlockQueueUpload(atlas, tex, r->x, r->y, r->w, r->h); ImFontAtlasTextureBlockQueueUpload(atlas, tex, r->x, r->y, r->w, r->h);
@ -5236,7 +5239,7 @@ ImFontBaked* ImFont::GetFontBaked(float size, float font_weight, float density)
ImFontBaked* baked = LastBaked; ImFontBaked* baked = LastBaked;
// Round font size // Round font size
// - ImGui::PushFontSize() will already round, but other paths calling GetFontBaked() directly also needs it (e.g. ImFontAtlasBuildPreloadAllGlyphRanges) // - ImGui::PushFont() will already round, but other paths calling GetFontBaked() directly also needs it (e.g. ImFontAtlasBuildPreloadAllGlyphRanges)
size = ImGui::GetRoundedFontSize(size); size = ImGui::GetRoundedFontSize(size);
font_weight = (font_weight > 0.0f) ? font_weight : DefaultWeight; font_weight = (font_weight > 0.0f) ? font_weight : DefaultWeight;
@ -5591,7 +5594,6 @@ begin:
return; 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 cmd_count = draw_list->CmdBuffer.Size;
const int vtx_count_max = (int)(text_end - s) * 4; const int vtx_count_max = (int)(text_end - s) * 4;
const int idx_count_max = (int)(text_end - s) * 6; const int idx_count_max = (int)(text_end - s) * 6;
const int idx_expected_size = draw_list->IdxBuffer.Size + idx_count_max; const int idx_expected_size = draw_list->IdxBuffer.Size + idx_count_max;
@ -5599,6 +5601,7 @@ begin:
ImDrawVert* vtx_write = draw_list->_VtxWritePtr; ImDrawVert* vtx_write = draw_list->_VtxWritePtr;
ImDrawIdx* idx_write = draw_list->_IdxWritePtr; ImDrawIdx* idx_write = draw_list->_IdxWritePtr;
unsigned int vtx_index = draw_list->_VtxCurrentIdx; unsigned int vtx_index = draw_list->_VtxCurrentIdx;
const int cmd_count = draw_list->CmdBuffer.Size;
const ImU32 col_untinted = col | ~IM_COL32_A_MASK; const ImU32 col_untinted = col | ~IM_COL32_A_MASK;
const char* word_wrap_eol = NULL; const char* word_wrap_eol = NULL;
@ -5715,12 +5718,14 @@ begin:
} }
// Edge case: calling RenderText() with unloaded glyphs triggering texture change. It doesn't happen via ImGui:: calls because CalcTextSize() is always used. // Edge case: calling RenderText() with unloaded glyphs triggering texture change. It doesn't happen via ImGui:: calls because CalcTextSize() is always used.
if (cmd_count != draw_list->CmdBuffer.Size) if (cmd_count != draw_list->CmdBuffer.Size) //-V547
{ {
IM_ASSERT(draw_list->CmdBuffer[draw_list->CmdBuffer.Size - 1].ElemCount == 0); IM_ASSERT(draw_list->CmdBuffer[draw_list->CmdBuffer.Size - 1].ElemCount == 0);
draw_list->CmdBuffer.pop_back(); draw_list->CmdBuffer.pop_back();
draw_list->PrimUnreserve(idx_count_max, vtx_count_max); draw_list->PrimUnreserve(idx_count_max, vtx_count_max);
draw_list->AddDrawCmd(); draw_list->AddDrawCmd();
//IMGUI_DEBUG_LOG("RenderText: cancel and retry to missing glyphs.\n"); // [DEBUG]
//draw_list->AddRectFilled(pos, pos + ImVec2(10, 10), IM_COL32(255, 0, 0, 255)); // [DEBUG]
goto begin; goto begin;
//RenderText(draw_list, size, pos, col, clip_rect, text_begin, text_end, wrap_width, cpu_fine_clip); // FIXME-OPT: Would a 'goto begin' be better for code-gen? //RenderText(draw_list, size, pos, col, clip_rect, text_begin, text_end, wrap_width, cpu_fine_clip); // FIXME-OPT: Would a 'goto begin' be better for code-gen?
//return; //return;

View File

@ -153,7 +153,7 @@ struct ImGui_ImplFreeType_FontSrcData
FT_Face FtFace; FT_Face FtFace;
ImGuiFreeTypeLoaderFlags UserFlags; // = ImFontConfig::FontLoaderFlags ImGuiFreeTypeLoaderFlags UserFlags; // = ImFontConfig::FontLoaderFlags
FT_Int32 LoadFlags; FT_Int32 LoadFlags;
ImFontBaked* BakedLastActivated; FT_Size LastSize;
FT_Fixed LastWeight; FT_Fixed LastWeight;
FT_Fixed* VarDesignCoords; FT_Fixed* VarDesignCoords;
FT_UInt VarDesignNumAxis; FT_UInt VarDesignNumAxis;
@ -373,7 +373,7 @@ static void* FreeType_Realloc(FT_Memory /*memory*/, long cur_size, long new_size
bool ImGui_ImplFreeType_LoaderInit(ImFontAtlas* atlas) bool ImGui_ImplFreeType_LoaderInit(ImFontAtlas* atlas)
{ {
IM_ASSERT(atlas->FontLoaderData == NULL); IM_ASSERT(atlas->FontLoaderData == nullptr);
ImGui_ImplFreeType_Data* bd = IM_NEW(ImGui_ImplFreeType_Data)(); ImGui_ImplFreeType_Data* bd = IM_NEW(ImGui_ImplFreeType_Data)();
// FreeType memory management: https://www.freetype.org/freetype2/docs/design/design-4.html // FreeType memory management: https://www.freetype.org/freetype2/docs/design/design-4.html
@ -407,23 +407,23 @@ bool ImGui_ImplFreeType_LoaderInit(ImFontAtlas* atlas)
void ImGui_ImplFreeType_LoaderShutdown(ImFontAtlas* atlas) void ImGui_ImplFreeType_LoaderShutdown(ImFontAtlas* atlas)
{ {
ImGui_ImplFreeType_Data* bd = (ImGui_ImplFreeType_Data*)atlas->FontLoaderData; ImGui_ImplFreeType_Data* bd = (ImGui_ImplFreeType_Data*)atlas->FontLoaderData;
IM_ASSERT(bd != NULL); IM_ASSERT(bd != nullptr);
FT_Done_Library(bd->Library); FT_Done_Library(bd->Library);
IM_DELETE(bd); IM_DELETE(bd);
atlas->FontLoaderData = NULL; atlas->FontLoaderData = nullptr;
} }
bool ImGui_ImplFreeType_FontSrcInit(ImFontAtlas* atlas, ImFontConfig* src) bool ImGui_ImplFreeType_FontSrcInit(ImFontAtlas* atlas, ImFontConfig* src)
{ {
ImGui_ImplFreeType_Data* bd = (ImGui_ImplFreeType_Data*)atlas->FontLoaderData; ImGui_ImplFreeType_Data* bd = (ImGui_ImplFreeType_Data*)atlas->FontLoaderData;
ImGui_ImplFreeType_FontSrcData* bd_font_data = IM_NEW(ImGui_ImplFreeType_FontSrcData); ImGui_ImplFreeType_FontSrcData* bd_font_data = IM_NEW(ImGui_ImplFreeType_FontSrcData);
IM_ASSERT(src->FontLoaderData == NULL); IM_ASSERT(src->FontLoaderData == nullptr);
src->FontLoaderData = bd_font_data; src->FontLoaderData = bd_font_data;
if (!bd_font_data->InitFont(bd->Library, src, (ImGuiFreeTypeLoaderFlags)atlas->FontLoaderFlags)) if (!bd_font_data->InitFont(bd->Library, src, (ImGuiFreeTypeLoaderFlags)atlas->FontLoaderFlags))
{ {
IM_DELETE(bd_font_data); IM_DELETE(bd_font_data);
src->FontLoaderData = NULL; src->FontLoaderData = nullptr;
return false; return false;
} }
@ -435,7 +435,7 @@ void ImGui_ImplFreeType_FontSrcDestroy(ImFontAtlas* atlas, ImFontConfig* src)
IM_UNUSED(atlas); IM_UNUSED(atlas);
ImGui_ImplFreeType_FontSrcData* bd_font_data = (ImGui_ImplFreeType_FontSrcData*)src->FontLoaderData; ImGui_ImplFreeType_FontSrcData* bd_font_data = (ImGui_ImplFreeType_FontSrcData*)src->FontLoaderData;
IM_DELETE(bd_font_data); IM_DELETE(bd_font_data);
src->FontLoaderData = NULL; src->FontLoaderData = nullptr;
} }
bool ImGui_ImplFreeType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src) bool ImGui_ImplFreeType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src)
@ -446,11 +446,10 @@ bool ImGui_ImplFreeType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* src, ImF
size *= (src->SizePixels / baked->ContainerFont->Sources[0]->SizePixels); size *= (src->SizePixels / baked->ContainerFont->Sources[0]->SizePixels);
ImGui_ImplFreeType_FontSrcData* bd_font_data = (ImGui_ImplFreeType_FontSrcData*)src->FontLoaderData; ImGui_ImplFreeType_FontSrcData* bd_font_data = (ImGui_ImplFreeType_FontSrcData*)src->FontLoaderData;
bd_font_data->BakedLastActivated = baked;
// We use one FT_Size per (source + baked) combination. // We use one FT_Size per (source + baked) combination.
ImGui_ImplFreeType_FontSrcBakedData* bd_baked_data = (ImGui_ImplFreeType_FontSrcBakedData*)loader_data_for_baked_src; ImGui_ImplFreeType_FontSrcBakedData* bd_baked_data = (ImGui_ImplFreeType_FontSrcBakedData*)loader_data_for_baked_src;
IM_ASSERT(bd_baked_data != NULL); IM_ASSERT(bd_baked_data != nullptr);
IM_PLACEMENT_NEW(bd_baked_data) ImGui_ImplFreeType_FontSrcBakedData(); IM_PLACEMENT_NEW(bd_baked_data) ImGui_ImplFreeType_FontSrcBakedData();
FT_New_Size(bd_font_data->FtFace, &bd_baked_data->FtSize); FT_New_Size(bd_font_data->FtFace, &bd_baked_data->FtSize);
@ -470,6 +469,10 @@ bool ImGui_ImplFreeType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* src, ImF
} }
} }
// Track last state to ensure the FT_Face and our baked data is synchronized.
bd_font_data->LastSize = bd_baked_data->FtSize;
bd_font_data->LastWeight = bd_baked_data->FtWeight;
// Vuhdo 2017: "I'm not sure how to deal with font sizes properly. As far as I understand, currently ImGui assumes that the 'pixel_height' // Vuhdo 2017: "I'm not sure how to deal with font sizes properly. As far as I understand, currently ImGui assumes that the 'pixel_height'
// is a maximum height of an any given glyph, i.e. it's the sum of font's ascender and descender. Seems strange to me. // is a maximum height of an any given glyph, i.e. it's the sum of font's ascender and descender. Seems strange to me.
// FT_Set_Pixel_Sizes() doesn't seem to get us the same result." // FT_Set_Pixel_Sizes() doesn't seem to get us the same result."
@ -502,9 +505,11 @@ void ImGui_ImplFreeType_FontBakedDestroy(ImFontAtlas* atlas, ImFontConfig* src,
{ {
IM_UNUSED(atlas); IM_UNUSED(atlas);
IM_UNUSED(baked); IM_UNUSED(baked);
IM_UNUSED(src); ImGui_ImplFreeType_FontSrcData* bd_font_data = (ImGui_ImplFreeType_FontSrcData*)src->FontLoaderData;
IM_ASSERT(bd_font_data != nullptr);
ImGui_ImplFreeType_FontSrcBakedData* bd_baked_data = (ImGui_ImplFreeType_FontSrcBakedData*)loader_data_for_baked_src; ImGui_ImplFreeType_FontSrcBakedData* bd_baked_data = (ImGui_ImplFreeType_FontSrcBakedData*)loader_data_for_baked_src;
IM_ASSERT(bd_baked_data != NULL); IM_ASSERT(bd_baked_data != nullptr);
bd_font_data->LastSize = (bd_font_data->LastSize == bd_baked_data->FtSize) ? nullptr : bd_font_data->LastSize;
FT_Done_Size(bd_baked_data->FtSize); FT_Done_Size(bd_baked_data->FtSize);
bd_baked_data->~ImGui_ImplFreeType_FontSrcBakedData(); // ~IM_PLACEMENT_DELETE() bd_baked_data->~ImGui_ImplFreeType_FontSrcBakedData(); // ~IM_PLACEMENT_DELETE()
} }
@ -517,32 +522,34 @@ bool ImGui_ImplFreeType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontConfig* src
return false; return false;
FT_Error error; FT_Error error;
if (bd_font_data->BakedLastActivated != baked) // <-- could use id
{
// Activate current size
ImGui_ImplFreeType_FontSrcBakedData* bd_baked_data = (ImGui_ImplFreeType_FontSrcBakedData*)loader_data_for_baked_src;
//if (!bd_font_data->BakedLastActivated || bd_font_data->BakedLastActivated->Size != baked->Size)
FT_Activate_Size(bd_baked_data->FtSize);
//if (bd_font_data->WeightCoordIndex >= 0 && (!bd_font_data->BakedLastActivated || bd_font_data->LastWeight != bd_baked_data->FtWeight))
if (bd_font_data->WeightCoordIndex >= 0)
{
if (bd_baked_data->FtWeight != 0)
{
bd_font_data->VarDesignCoords[bd_font_data->WeightCoordIndex] = bd_baked_data->FtWeight;
FT_Set_Var_Design_Coordinates(bd_font_data->FtFace, bd_font_data->VarDesignNumAxis, bd_font_data->VarDesignCoords);
}
else
{
FT_Set_Var_Design_Coordinates(bd_font_data->FtFace, 0, nullptr);
}
}
// Activate current weight // Activate current size
bd_font_data->BakedLastActivated = baked; ImGui_ImplFreeType_FontSrcBakedData* bd_baked_data = (ImGui_ImplFreeType_FontSrcBakedData*)loader_data_for_baked_src;
if ( bd_font_data->LastSize != bd_baked_data->FtSize)
{
bd_font_data->LastSize = bd_baked_data->FtSize;
FT_Activate_Size(bd_baked_data->FtSize);
}
if (bd_font_data->WeightCoordIndex >= 0 && bd_font_data->LastWeight != bd_baked_data->FtWeight)
{
bd_font_data->LastWeight = bd_baked_data->FtWeight;
if (bd_baked_data->FtWeight != 0)
{
bd_font_data->VarDesignCoords[bd_font_data->WeightCoordIndex] = bd_baked_data->FtWeight;
FT_Set_Var_Design_Coordinates(bd_font_data->FtFace, bd_font_data->VarDesignNumAxis, bd_font_data->VarDesignCoords);
}
else
{
FT_Set_Var_Design_Coordinates(bd_font_data->FtFace, 0, nullptr);
}
} }
// FT_Font state should be synchronized.
IM_ASSERT(bd_font_data->FtFace->size == bd_baked_data->FtSize);
IM_ASSERT(bd_font_data->WeightCoordIndex < 0 || bd_font_data->LastWeight == bd_baked_data->FtWeight);
const FT_Glyph_Metrics* metrics = ImGui_ImplFreeType_LoadGlyph(bd_font_data, codepoint); const FT_Glyph_Metrics* metrics = ImGui_ImplFreeType_LoadGlyph(bd_font_data, codepoint);
if (metrics == NULL) if (metrics == nullptr)
return false; return false;
// Render glyph into a bitmap (currently held by FreeType) // Render glyph into a bitmap (currently held by FreeType)
@ -552,7 +559,7 @@ bool ImGui_ImplFreeType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontConfig* src
error = FT_Render_Glyph(slot, render_mode); error = FT_Render_Glyph(slot, render_mode);
const FT_Bitmap* ft_bitmap = &slot->bitmap; const FT_Bitmap* ft_bitmap = &slot->bitmap;
if (error != 0 || ft_bitmap == nullptr) if (error != 0 || ft_bitmap == nullptr)
return NULL; return false;
const int w = (int)ft_bitmap->width; const int w = (int)ft_bitmap->width;
const int h = (int)ft_bitmap->rows; const int h = (int)ft_bitmap->rows;
@ -571,7 +578,7 @@ bool ImGui_ImplFreeType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontConfig* src
{ {
// Pathological out of memory case (TexMaxWidth/TexMaxHeight set too small?) // Pathological out of memory case (TexMaxWidth/TexMaxHeight set too small?)
IM_ASSERT(pack_id != ImFontAtlasRectId_Invalid && "Out of texture memory."); IM_ASSERT(pack_id != ImFontAtlasRectId_Invalid && "Out of texture memory.");
return NULL; return false;
} }
ImTextureRect* r = ImFontAtlasPackGetRect(atlas, pack_id); ImTextureRect* r = ImFontAtlasPackGetRect(atlas, pack_id);

View File

@ -1,4 +1,4 @@
// dear imgui, v1.92.0 WIP // dear imgui, v1.92.0
// (tables and columns code) // (tables and columns code)
/* /*

View File

@ -1,4 +1,4 @@
// dear imgui, v1.92.0 WIP // dear imgui, v1.92.0
// (widgets code) // (widgets code)
/* /*
@ -4283,23 +4283,24 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons
if (new_text == new_text_end) if (new_text == new_text_end)
return; return;
ImGuiContext& g = *Ctx;
ImGuiInputTextState* obj = &g.InputTextState;
IM_ASSERT(obj->ID != 0 && g.ActiveId == obj->ID);
// 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)ImStrlen(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 + 1 > obj->TextA.Size && (Flags & ImGuiInputTextFlags_ReadOnly) == 0)
{ {
if (!is_resizable) if (!is_resizable)
return; return;
ImGuiContext& g = *Ctx; IM_ASSERT(Buf == obj->TextA.Data);
ImGuiInputTextState* edit_state = &g.InputTextState;
IM_ASSERT(edit_state->ID != 0 && g.ActiveId == edit_state->ID);
IM_ASSERT(Buf == edit_state->TextA.Data);
int new_buf_size = BufTextLen + ImClamp(new_text_len * 4, 32, ImMax(256, new_text_len)) + 1; int new_buf_size = BufTextLen + ImClamp(new_text_len * 4, 32, ImMax(256, new_text_len)) + 1;
edit_state->TextA.resize(new_buf_size + 1); obj->TextA.resize(new_buf_size + 1);
edit_state->TextSrc = edit_state->TextA.Data; obj->TextSrc = obj->TextA.Data;
Buf = edit_state->TextA.Data; Buf = obj->TextA.Data;
BufSize = edit_state->BufCapacity = new_buf_size; BufSize = obj->BufCapacity = new_buf_size;
} }
if (BufTextLen != pos) if (BufTextLen != pos)
@ -5484,7 +5485,7 @@ void ImGui::DebugNodeInputTextState(ImGuiInputTextState* state)
Text("ID: 0x%08X, ActiveID: 0x%08X", state->ID, g.ActiveId); Text("ID: 0x%08X, ActiveID: 0x%08X", state->ID, g.ActiveId);
DebugLocateItemOnHover(state->ID); DebugLocateItemOnHover(state->ID);
Text("CurLenA: %d, Cursor: %d, Selection: %d..%d", state->TextLen, stb_state->cursor, stb_state->select_start, stb_state->select_end); Text("CurLenA: %d, Cursor: %d, Selection: %d..%d", state->TextLen, stb_state->cursor, stb_state->select_start, stb_state->select_end);
Text("BufCapacityA: %d", state->BufCapacity); Text("BufCapacity: %d", state->BufCapacity);
Text("(Internal Buffer: TextA Size: %d, Capacity: %d)", state->TextA.Size, state->TextA.Capacity); Text("(Internal Buffer: TextA Size: %d, Capacity: %d)", state->TextA.Size, state->TextA.Capacity);
Text("has_preferred_x: %d (%.2f)", stb_state->has_preferred_x, stb_state->preferred_x); Text("has_preferred_x: %d (%.2f)", stb_state->has_preferred_x, stb_state->preferred_x);
Text("undo_point: %d, redo_point: %d, undo_char_point: %d, redo_char_point: %d", undo_state->undo_point, undo_state->redo_point, undo_state->undo_char_point, undo_state->redo_char_point); Text("undo_point: %d, redo_point: %d, undo_char_point: %d, redo_char_point: %d", undo_state->undo_point, undo_state->redo_point, undo_state->undo_char_point, undo_state->redo_char_point);

View File

@ -4152,7 +4152,7 @@ void CDROM::DrawDebugWindow(float scale)
else else
{ {
const float end_y = ImGui::GetCursorPosY(); const float end_y = ImGui::GetCursorPosY();
ImGui::SetCursorPosX(ImGui::GetWindowWidth() - 120.0f * scale); ImGui::SetCursorPosX(ImGui::GetWindowWidth() - 140.0f * scale);
ImGui::SetCursorPosY(start_y); ImGui::SetCursorPosY(start_y);
if (ImGui::Button("Show Current File")) if (ImGui::Button("Show Current File"))
s_state.show_current_file = true; s_state.show_current_file = true;

View File

@ -2913,18 +2913,18 @@ void FullscreenUI::DrawIntRangeSetting(SettingsInterface* bsi, std::string_view
ImGui::PushFont(UIStyle.Font, UIStyle.MediumLargeFontSize, UIStyle.NormalFontWeight); ImGui::PushFont(UIStyle.Font, UIStyle.MediumLargeFontSize, UIStyle.NormalFontWeight);
ImGuiFullscreen::TextAlignedMultiLine(0.0f, IMSTR_START_END(summary)); ImGuiFullscreen::TextAlignedMultiLine(0.0f, IMSTR_START_END(summary));
ImGui::PushFontWeight(UIStyle.BoldFontWeight); ImGui::PushFont(UIStyle.Font, UIStyle.MediumLargeFontSize, UIStyle.BoldFontWeight);
ImGui::Text("%s: ", FSUI_CSTR("Value Range")); ImGui::Text("%s: ", FSUI_CSTR("Value Range"));
ImGui::PopFontWeight(); ImGui::PopFont();
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text(format, min_value); ImGui::Text(format, min_value);
ImGui::SameLine(); ImGui::SameLine();
ImGui::TextUnformatted(" - "); ImGui::TextUnformatted(" - ");
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text(format, max_value); ImGui::Text(format, max_value);
ImGui::PushFontWeight(UIStyle.BoldFontWeight); ImGui::PushFont(UIStyle.Font, UIStyle.MediumLargeFontSize, UIStyle.BoldFontWeight);
ImGui::Text("%s: ", FSUI_CSTR("Default Value")); ImGui::Text("%s: ", FSUI_CSTR("Default Value"));
ImGui::PopFontWeight(); ImGui::PopFont();
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text(format, default_value); ImGui::Text(format, default_value);
ImGui::PopFont(); ImGui::PopFont();
@ -2980,18 +2980,18 @@ void FullscreenUI::DrawFloatRangeSetting(SettingsInterface* bsi, std::string_vie
ImGui::PushFont(UIStyle.Font, UIStyle.MediumLargeFontSize, UIStyle.NormalFontWeight); ImGui::PushFont(UIStyle.Font, UIStyle.MediumLargeFontSize, UIStyle.NormalFontWeight);
ImGuiFullscreen::TextAlignedMultiLine(0.0f, IMSTR_START_END(summary)); ImGuiFullscreen::TextAlignedMultiLine(0.0f, IMSTR_START_END(summary));
ImGui::PushFontWeight(UIStyle.BoldFontWeight); ImGui::PushFont(UIStyle.Font, UIStyle.MediumLargeFontSize, UIStyle.BoldFontWeight);
ImGui::Text("%s: ", FSUI_CSTR("Value Range")); ImGui::Text("%s: ", FSUI_CSTR("Value Range"));
ImGui::PopFontWeight(); ImGui::PopFont();
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text(format, min_value * multiplier); ImGui::Text(format, min_value * multiplier);
ImGui::SameLine(); ImGui::SameLine();
ImGui::TextUnformatted(" - "); ImGui::TextUnformatted(" - ");
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text(format, max_value * multiplier); ImGui::Text(format, max_value * multiplier);
ImGui::PushFontWeight(UIStyle.BoldFontWeight); ImGui::PushFont(UIStyle.Font, UIStyle.MediumLargeFontSize, UIStyle.BoldFontWeight);
ImGui::Text("%s: ", FSUI_CSTR("Default Value")); ImGui::Text("%s: ", FSUI_CSTR("Default Value"));
ImGui::PopFontWeight(); ImGui::PopFont();
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text(format, default_value * multiplier); ImGui::Text(format, default_value * multiplier);
ImGui::PopFont(); ImGui::PopFont();
@ -3056,18 +3056,18 @@ void FullscreenUI::DrawFloatSpinBoxSetting(SettingsInterface* bsi, std::string_v
ImGui::PushFont(UIStyle.Font, UIStyle.MediumLargeFontSize, UIStyle.NormalFontWeight); ImGui::PushFont(UIStyle.Font, UIStyle.MediumLargeFontSize, UIStyle.NormalFontWeight);
ImGuiFullscreen::TextAlignedMultiLine(0.0f, IMSTR_START_END(summary)); ImGuiFullscreen::TextAlignedMultiLine(0.0f, IMSTR_START_END(summary));
ImGui::PushFontWeight(UIStyle.BoldFontWeight); ImGui::PushFont(UIStyle.Font, UIStyle.MediumLargeFontSize, UIStyle.BoldFontWeight);
ImGui::Text("%s: ", FSUI_CSTR("Value Range")); ImGui::Text("%s: ", FSUI_CSTR("Value Range"));
ImGui::PopFontWeight(); ImGui::PopFont();
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text(format, min_value * multiplier); ImGui::Text(format, min_value * multiplier);
ImGui::SameLine(); ImGui::SameLine();
ImGui::TextUnformatted(" - "); ImGui::TextUnformatted(" - ");
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text(format, max_value * multiplier); ImGui::Text(format, max_value * multiplier);
ImGui::PushFontWeight(UIStyle.BoldFontWeight); ImGui::PushFont(UIStyle.Font, UIStyle.MediumLargeFontSize, UIStyle.BoldFontWeight);
ImGui::Text("%s: ", FSUI_CSTR("Default Value")); ImGui::Text("%s: ", FSUI_CSTR("Default Value"));
ImGui::PopFontWeight(); ImGui::PopFont();
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text(format, default_value * multiplier); ImGui::Text(format, default_value * multiplier);
ImGui::PopFont(); ImGui::PopFont();
@ -3298,18 +3298,18 @@ void FullscreenUI::DrawIntSpinBoxSetting(SettingsInterface* bsi, std::string_vie
ImGui::PushFont(UIStyle.Font, UIStyle.MediumLargeFontSize, UIStyle.NormalFontWeight); ImGui::PushFont(UIStyle.Font, UIStyle.MediumLargeFontSize, UIStyle.NormalFontWeight);
ImGuiFullscreen::TextAlignedMultiLine(0.0f, IMSTR_START_END(summary)); ImGuiFullscreen::TextAlignedMultiLine(0.0f, IMSTR_START_END(summary));
ImGui::PushFontWeight(UIStyle.BoldFontWeight); ImGui::PushFont(UIStyle.Font, UIStyle.MediumLargeFontSize, UIStyle.BoldFontWeight);
ImGui::Text("%s: ", FSUI_CSTR("Value Range")); ImGui::Text("%s: ", FSUI_CSTR("Value Range"));
ImGui::PopFontWeight(); ImGui::PopFont();
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text(format, min_value); ImGui::Text(format, min_value);
ImGui::SameLine(); ImGui::SameLine();
ImGui::TextUnformatted(" - "); ImGui::TextUnformatted(" - ");
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text(format, max_value); ImGui::Text(format, max_value);
ImGui::PushFontWeight(UIStyle.BoldFontWeight); ImGui::PushFont(UIStyle.Font, UIStyle.MediumLargeFontSize, UIStyle.BoldFontWeight);
ImGui::Text("%s: ", FSUI_CSTR("Default Value")); ImGui::Text("%s: ", FSUI_CSTR("Default Value"));
ImGui::PopFontWeight(); ImGui::PopFont();
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text(format, default_value); ImGui::Text(format, default_value);
ImGui::PopFont(); ImGui::PopFont();
@ -7452,7 +7452,7 @@ void FullscreenUI::DrawSaveStateSelector()
u32 grid_x = 0; u32 grid_x = 0;
ImGui::SetCursorPosX(start_x); ImGui::SetCursorPosX(start_x);
for (u32 i = 0; i < s_state.save_state_selector_slots.size();) for (u32 i = 0;;)
{ {
SaveStateListEntry& entry = s_state.save_state_selector_slots[i]; SaveStateListEntry& entry = s_state.save_state_selector_slots[i];
@ -7584,6 +7584,11 @@ void FullscreenUI::DrawSaveStateSelector()
} }
} }
// avoid triggering imgui warning
i++;
if (i == s_state.save_state_selector_slots.size())
break;
grid_x++; grid_x++;
if (grid_x == grid_count_x) if (grid_x == grid_count_x)
{ {
@ -7596,7 +7601,6 @@ void FullscreenUI::DrawSaveStateSelector()
ImGui::SameLine(start_x + static_cast<float>(grid_x) * (item_width + item_spacing)); ImGui::SameLine(start_x + static_cast<float>(grid_x) * (item_width + item_spacing));
} }
i++;
} }
EndMenuButtons(); EndMenuButtons();
@ -7659,9 +7663,9 @@ void FullscreenUI::DrawResumeStateSelector()
SmallString sick; SmallString sick;
sick.format(FSUI_FSTR("Do you want to continue from the automatic save created at {:%c}?"), sick.format(FSUI_FSTR("Do you want to continue from the automatic save created at {:%c}?"),
fmt::localtime(entry.timestamp)); fmt::localtime(entry.timestamp));
ImGui::PushFontWeight(UIStyle.BoldFontWeight); ImGui::PushFont(nullptr, 0.0f, UIStyle.BoldFontWeight);
ImGuiFullscreen::TextAlignedMultiLine(0.5f, IMSTR_START_END(sick)); ImGuiFullscreen::TextAlignedMultiLine(0.5f, IMSTR_START_END(sick));
ImGui::PopFontWeight(); ImGui::PopFont();
const GPUTexture* image = entry.preview_texture ? entry.preview_texture.get() : GetPlaceholderTexture().get(); const GPUTexture* image = entry.preview_texture ? entry.preview_texture.get() : GetPlaceholderTexture().get();
const float image_height = LayoutScale(280.0f); const float image_height = LayoutScale(280.0f);
@ -8280,7 +8284,7 @@ void FullscreenUI::DrawGameList(const ImVec2& heading_size)
{ {
// title // title
const char* title = FSUI_CSTR("No Game Selected"); const char* title = FSUI_CSTR("No Game Selected");
ImGui::PushFont(UIStyle.Font, UIStyle.LargeFontSize); ImGui::PushFont(UIStyle.Font, UIStyle.LargeFontSize, UIStyle.BoldFontWeight);
text_width = ImGui::CalcTextSize(title, nullptr, false, work_width).x; text_width = ImGui::CalcTextSize(title, nullptr, false, work_width).x;
ImGui::SetCursorPosX((work_width - text_width) / 2.0f); ImGui::SetCursorPosX((work_width - text_width) / 2.0f);
ImGui::TextWrapped("%s", title); ImGui::TextWrapped("%s", title);
@ -8421,6 +8425,8 @@ void FullscreenUI::DrawGameGrid(const ImVec2& heading_size)
if (entry == s_state.game_list_sorted_entries.front()) if (entry == s_state.game_list_sorted_entries.front())
ImGui::SetItemDefaultFocus(); ImGui::SetItemDefaultFocus();
else if (entry == s_state.game_list_sorted_entries.back())
break;
grid_x++; grid_x++;
if (grid_x == grid_count_x) if (grid_x == grid_count_x)
@ -8851,9 +8857,9 @@ void FullscreenUI::DrawAboutWindow()
ImGui::GetWindowDrawList()->AddImage(s_state.app_icon_texture.get(), ImGui::GetCursorScreenPos(), ImGui::GetWindowDrawList()->AddImage(s_state.app_icon_texture.get(), ImGui::GetCursorScreenPos(),
ImGui::GetCursorScreenPos() + image_size); ImGui::GetCursorScreenPos() + image_size);
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + indent); ImGui::SetCursorPosX(ImGui::GetCursorPosX() + indent);
ImGui::PushFontWeight(UIStyle.BoldFontWeight); ImGui::PushFont(nullptr, 0.0f, UIStyle.BoldFontWeight);
ImGui::TextUnformatted("DuckStation"); ImGui::TextUnformatted("DuckStation");
ImGui::PopFontWeight(); ImGui::PopFont();
ImGui::PushStyleColor(ImGuiCol_Text, DarkerColor(UIStyle.BackgroundTextColor)); ImGui::PushStyleColor(ImGuiCol_Text, DarkerColor(UIStyle.BackgroundTextColor));
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + indent); ImGui::SetCursorPosX(ImGui::GetCursorPosX() + indent);
ImGui::TextUnformatted(g_scm_tag_str); ImGui::TextUnformatted(g_scm_tag_str);

View File

@ -1647,7 +1647,7 @@ void GTE::DrawFreecamWindow(float scale)
if (ImGui::CollapsingHeader("Settings", ImGuiTreeNodeFlags_DefaultOpen)) if (ImGui::CollapsingHeader("Settings", ImGuiTreeNodeFlags_DefaultOpen))
{ {
const float third_width = 50.0f * scale; const float third_width = 100.0f * scale;
const float second_width = item_width - third_width; const float second_width = item_width - third_width;
enabled_changed = ImGui::Checkbox("Enable Freecam", &freecam_enabled); enabled_changed = ImGui::Checkbox("Enable Freecam", &freecam_enabled);
@ -1666,7 +1666,7 @@ void GTE::DrawFreecamWindow(float scale)
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + style.ItemInnerSpacing.y); ImGui::SetCursorPosY(ImGui::GetCursorPosY() + style.ItemInnerSpacing.y);
ImGui::TextUnformatted("Movement Speed:"); ImGui::TextUnformatted("Movement Speed:");
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::SetNextItemWidth(second_width); ImGui::SetNextItemWidth(second_width - (style.FramePadding.x * 2.0f));
ImGui::DragFloat("##MovementSpeed", &s_config.freecam_move_speed, 1.0f, 0.0f, FREECAM_MAX_MOVE_SPEED); ImGui::DragFloat("##MovementSpeed", &s_config.freecam_move_speed, 1.0f, 0.0f, FREECAM_MAX_MOVE_SPEED);
ImGui::NextColumn(); ImGui::NextColumn();
if (ImGui::Button("Reset##ResetMovementSpeed")) if (ImGui::Button("Reset##ResetMovementSpeed"))
@ -1676,7 +1676,7 @@ void GTE::DrawFreecamWindow(float scale)
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + style.ItemInnerSpacing.y); ImGui::SetCursorPosY(ImGui::GetCursorPosY() + style.ItemInnerSpacing.y);
ImGui::TextUnformatted("Turning Speed:"); ImGui::TextUnformatted("Turning Speed:");
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::SetNextItemWidth(second_width); ImGui::SetNextItemWidth(second_width - (style.FramePadding.x * 2.0f));
ImGui::DragFloat("##TurnSpeed", &s_config.freecam_turn_speed, 1.0f, 0.0f, FREECAM_MAX_TURN_SPEED); ImGui::DragFloat("##TurnSpeed", &s_config.freecam_turn_speed, 1.0f, 0.0f, FREECAM_MAX_TURN_SPEED);
ImGui::NextColumn(); ImGui::NextColumn();
if (ImGui::Button("Reset##ResetTurnSpeed")) if (ImGui::Button("Reset##ResetTurnSpeed"))
@ -1691,7 +1691,7 @@ void GTE::DrawFreecamWindow(float scale)
{ {
ImGui::Columns(2, "Rotation", false); ImGui::Columns(2, "Rotation", false);
ImGui::SetColumnWidth(0, label_width); ImGui::SetColumnWidth(0, label_width);
ImGui::SetColumnWidth(1, item_width); ImGui::SetColumnWidth(1, item_width + (style.FramePadding.x * 2.0f));
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + style.ItemInnerSpacing.y); ImGui::SetCursorPosY(ImGui::GetCursorPosY() + style.ItemInnerSpacing.y);
ImGui::TextUnformatted("X Rotation (Pitch):"); ImGui::TextUnformatted("X Rotation (Pitch):");
@ -1729,7 +1729,7 @@ void GTE::DrawFreecamWindow(float scale)
{ {
ImGui::Columns(2, "Translation", false); ImGui::Columns(2, "Translation", false);
ImGui::SetColumnWidth(0, label_width); ImGui::SetColumnWidth(0, label_width);
ImGui::SetColumnWidth(1, item_width); ImGui::SetColumnWidth(1, item_width + (style.FramePadding.x * 2.0f));
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + style.ItemInnerSpacing.y); ImGui::SetCursorPosY(ImGui::GetCursorPosY() + style.ItemInnerSpacing.y);
ImGui::TextUnformatted("X Offset:"); ImGui::TextUnformatted("X Offset:");
@ -1762,8 +1762,6 @@ void GTE::DrawFreecamWindow(float scale)
s_config.freecam_translation = GSVector4::zero(); s_config.freecam_translation = GSVector4::zero();
changed = true; changed = true;
} }
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + padding_height);
} }
if (enabled_changed || (!freecam_enabled && changed)) if (enabled_changed || (!freecam_enabled && changed))

View File

@ -113,9 +113,9 @@ static void UpdateInputOverlay(void* buffer);
static constexpr size_t NUM_DEBUG_WINDOWS = 7; static constexpr size_t NUM_DEBUG_WINDOWS = 7;
static constexpr const char* DEBUG_WINDOW_CONFIG_SECTION = "DebugWindows"; static constexpr const char* DEBUG_WINDOW_CONFIG_SECTION = "DebugWindows";
static constexpr const std::array<DebugWindowInfo, NUM_DEBUG_WINDOWS> s_debug_window_info = {{ static constexpr const std::array<DebugWindowInfo, NUM_DEBUG_WINDOWS> s_debug_window_info = {{
{"Freecam", "Free Camera", ":icons/applications-system.png", &GTE::DrawFreecamWindow, 500, 425}, {"Freecam", "Free Camera", ":icons/applications-system.png", &GTE::DrawFreecamWindow, 510, 500},
{"SPU", "SPU State", ":icons/applications-system.png", &SPU::DrawDebugStateWindow, 800, 915}, {"SPU", "SPU State", ":icons/applications-system.png", &SPU::DrawDebugStateWindow, 820, 950},
{"CDROM", "CD-ROM State", ":icons/applications-system.png", &CDROM::DrawDebugWindow, 800, 540}, {"CDROM", "CD-ROM State", ":icons/applications-system.png", &CDROM::DrawDebugWindow, 820, 555},
{"GPU", "GPU State", ":icons/applications-system.png", [](float sc) { g_gpu.DrawDebugStateWindow(sc); }, 450, 550}, {"GPU", "GPU State", ":icons/applications-system.png", [](float sc) { g_gpu.DrawDebugStateWindow(sc); }, 450, 550},
{"DMA", "DMA State", ":icons/applications-system.png", &DMA::DrawDebugStateWindow, 860, 180}, {"DMA", "DMA State", ":icons/applications-system.png", &DMA::DrawDebugStateWindow, 860, 180},
{"MDEC", "MDEC State", ":icons/applications-system.png", &MDEC::DrawDebugStateWindow, 300, 350}, {"MDEC", "MDEC State", ":icons/applications-system.png", &MDEC::DrawDebugStateWindow, 300, 350},
@ -1216,7 +1216,7 @@ void SaveStateSelectorUI::Draw()
ImGui::PushStyleColor(ImGuiCol_ScrollbarBg, UIStyle.BackgroundColor); ImGui::PushStyleColor(ImGuiCol_ScrollbarBg, UIStyle.BackgroundColor);
ImGui::PushStyleColor(ImGuiCol_WindowBg, DarkerColor(UIStyle.PopupBackgroundColor)); ImGui::PushStyleColor(ImGuiCol_WindowBg, DarkerColor(UIStyle.PopupBackgroundColor));
ImGui::PushStyleColor(ImGuiCol_Text, UIStyle.BackgroundTextColor); ImGui::PushStyleColor(ImGuiCol_Text, UIStyle.BackgroundTextColor);
ImGui::PushFont(ImGuiManager::GetTextFont(), ImGuiManager::GetOSDFontSize()); ImGui::PushFont(ImGuiManager::GetTextFont(), ImGuiManager::GetOSDFontSize(), 0.0f);
ImGui::SetNextWindowSize(ImVec2(width, height), ImGuiCond_Always); ImGui::SetNextWindowSize(ImVec2(width, height), ImGuiCond_Always);
ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.5f), ImGuiCond_Always, ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.5f), ImGuiCond_Always,
ImVec2(0.5f, 0.5f)); ImVec2(0.5f, 0.5f));
@ -1304,7 +1304,7 @@ void SaveStateSelectorUI::Draw()
if (entry.global) if (entry.global)
ImGui::TextUnformatted(entry.game_details.c_str(), entry.game_details.c_str() + entry.game_details.length()); ImGui::TextUnformatted(entry.game_details.c_str(), entry.game_details.c_str() + entry.game_details.length());
ImGui::TextUnformatted(entry.summary.c_str(), entry.summary.c_str() + entry.summary.length()); ImGui::TextUnformatted(entry.summary.c_str(), entry.summary.c_str() + entry.summary.length());
ImGui::PushFont(ImGuiManager::GetFixedFont()); ImGui::PushFont(ImGuiManager::GetFixedFont(), 0.0f, 0.0f);
ImGui::TextUnformatted(entry.filename.data(), entry.filename.data() + entry.filename.length()); ImGui::TextUnformatted(entry.filename.data(), entry.filename.data() + entry.filename.length());
ImGui::PopFont(); ImGui::PopFont();

View File

@ -1008,10 +1008,10 @@ bool ImGuiFullscreen::BeginFullscreenColumns(const char* title, float pos_y, boo
bool clipped; bool clipped;
if (title) if (title)
{ {
ImGui::PushFontSize(UIStyle.LargeFontSize, UIStyle.BoldFontWeight); ImGui::PushFont(UIStyle.Font, UIStyle.LargeFontSize, UIStyle.BoldFontWeight);
clipped = ImGui::Begin(title, nullptr, clipped = ImGui::Begin(title, nullptr,
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBackground); ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBackground);
ImGui::PopFontSize(); ImGui::PopFont();
} }
else else
{ {
@ -1050,7 +1050,7 @@ bool ImGuiFullscreen::BeginFullscreenColumnWindow(float start, float end, const
return ImGui::BeginChild(name, size, return ImGui::BeginChild(name, size,
(padding.x != 0.0f || padding.y != 0.0f) ? ImGuiChildFlags_AlwaysUseWindowPadding : 0, (padding.x != 0.0f || padding.y != 0.0f) ? ImGuiChildFlags_AlwaysUseWindowPadding : 0,
ImGuiWindowFlags_NavFlattened); ImGuiChildFlags_NavFlattened);
} }
void ImGuiFullscreen::EndFullscreenColumnWindow() void ImGuiFullscreen::EndFullscreenColumnWindow()
@ -1389,7 +1389,7 @@ void ImGuiFullscreen::DrawWindowTitle(std::string_view title)
if (!ImGui::ItemAdd(rect, window->GetID("window_title"))) if (!ImGui::ItemAdd(rect, window->GetID("window_title")))
return; return;
ImGui::PushFont(UIStyle.Font, UIStyle.LargeFontSize); ImGui::PushFont(UIStyle.Font, UIStyle.LargeFontSize, UIStyle.BoldFontWeight);
ImGui::RenderTextClipped(rect.Min, rect.Max, IMSTR_START_END(title), nullptr, ImVec2(0.0f, 0.0f), &rect); ImGui::RenderTextClipped(rect.Min, rect.Max, IMSTR_START_END(title), nullptr, ImVec2(0.0f, 0.0f), &rect);
ImGui::PopFont(); ImGui::PopFont();
@ -3728,7 +3728,7 @@ void ImGuiFullscreen::DrawLoadingScreen(std::string_view image, std::string_view
ImGui::PushStyleColor(ImGuiCol_Text, UIStyle.BackgroundTextColor); ImGui::PushStyleColor(ImGuiCol_Text, UIStyle.BackgroundTextColor);
ImGui::PushStyleColor(ImGuiCol_FrameBg, UIStyle.BackgroundColor); ImGui::PushStyleColor(ImGuiCol_FrameBg, UIStyle.BackgroundColor);
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, UIStyle.SecondaryColor); ImGui::PushStyleColor(ImGuiCol_PlotHistogram, UIStyle.SecondaryColor);
ImGui::PushFont(ImGuiManager::GetTextFont(), ImGuiManager::GetOSDFontSize()); ImGui::PushFont(ImGuiManager::GetTextFont(), ImGuiManager::GetOSDFontSize(), UIStyle.BoldFontWeight);
ImGui::SetNextWindowSize(ImVec2(width, ((has_progress || is_persistent) ? 85.0f : 55.0f) * scale), ImGuiCond_Always); ImGui::SetNextWindowSize(ImVec2(width, ((has_progress || is_persistent) ? 85.0f : 55.0f) * scale), ImGuiCond_Always);
ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, (io.DisplaySize.y * 0.5f) + (100.0f * scale)), ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, (io.DisplaySize.y * 0.5f) + (100.0f * scale)),
ImGuiCond_Always, ImVec2(0.5f, 0.0f)); ImGuiCond_Always, ImVec2(0.5f, 0.0f));

View File

@ -35,16 +35,12 @@
#include <cmath> #include <cmath>
#include <deque> #include <deque>
#include <mutex> #include <mutex>
#include <limits>
#include <type_traits> #include <type_traits>
#include <unordered_map> #include <unordered_map>
LOG_CHANNEL(ImGuiManager); LOG_CHANNEL(ImGuiManager);
// TODO: for dynamic fonts
// max texture size
// lock/bake osd font
// gc fonts on scale change
namespace ImGuiManager { namespace ImGuiManager {
namespace { namespace {
@ -84,10 +80,10 @@ static bool CreateFontAtlas(Error* error);
static bool CompilePipelines(Error* error); static bool CompilePipelines(Error* error);
static void RenderDrawLists(u32 window_width, u32 window_height, WindowInfo::PreRotation prerotation); static void RenderDrawLists(u32 window_width, u32 window_height, WindowInfo::PreRotation prerotation);
static void UpdateTextures(); static void UpdateTextures();
static void SetCommonIOOptions(ImGuiIO& io); static void SetCommonIOOptions(ImGuiIO& io, ImGuiPlatformIO& pio);
static void SetImKeyState(ImGuiIO& io, ImGuiKey imkey, bool pressed); static void SetImKeyState(ImGuiIO& io, ImGuiKey imkey, bool pressed);
static const char* GetClipboardTextImpl(void* userdata); static const char* GetClipboardTextImpl(ImGuiContext* ctx);
static void SetClipboardTextImpl(void* userdata, const char* text); static void SetClipboardTextImpl(ImGuiContext* ctx, const char* text);
static void AddOSDMessage(std::string key, std::string message, float duration, bool is_warning); static void AddOSDMessage(std::string key, std::string message, float duration, bool is_warning);
static void RemoveKeyedOSDMessage(std::string key, bool is_warning); static void RemoveKeyedOSDMessage(std::string key, bool is_warning);
static void ClearOSDMessages(bool clear_warnings); static void ClearOSDMessages(bool clear_warnings);
@ -107,6 +103,10 @@ static constexpr std::array<const char*, static_cast<size_t>(TextFont::MaxCount)
"NotoSansJP-VariableFont_wght.ttf", // Japanese "NotoSansJP-VariableFont_wght.ttf", // Japanese
"NotoSansKR-VariableFont_wght.ttf", // Korean "NotoSansKR-VariableFont_wght.ttf", // Korean
}}; }};
static constexpr const char* FIXED_FONT_NAME = "RobotoMono-VariableFont_wght.ttf";
static constexpr const char* FA_FONT_NAME = "fa-solid-900.ttf";
static constexpr const char* PF_FONT_NAME = "promptfont.otf";
static constexpr const char* EMOJI_FONT_NAME = "TwitterColorEmoji-SVGinOT.ttf";
namespace { namespace {
@ -215,7 +215,7 @@ bool ImGuiManager::Initialize(float global_scale, float screen_margin, Error* er
#else #else
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard | ImGuiConfigFlags_NavEnableGamepad; io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard | ImGuiConfigFlags_NavEnableGamepad;
#endif #endif
SetCommonIOOptions(io); SetCommonIOOptions(io, s_state.imgui_context->PlatformIO);
s_state.last_render_time = Timer::GetCurrentValue(); s_state.last_render_time = Timer::GetCurrentValue();
s_state.window_format = main_swap_chain ? main_swap_chain->GetFormat() : GPUTexture::Format::RGBA8; s_state.window_format = main_swap_chain ? main_swap_chain->GetFormat() : GPUTexture::Format::RGBA8;
@ -582,6 +582,8 @@ void ImGuiManager::SetStyle(ImGuiStyle& style, float scale)
{ {
style = ImGuiStyle(); style = ImGuiStyle();
style.WindowMinSize = ImVec2(1.0f, 1.0f); style.WindowMinSize = ImVec2(1.0f, 1.0f);
style.FrameRounding = 8.0f;
style.FramePadding = ImVec2(8.0f, 6.0f);
ImVec4* colors = style.Colors; ImVec4* colors = style.Colors;
colors[ImGuiCol_Text] = ImVec4(0.95f, 0.96f, 0.98f, 1.00f); colors[ImGuiCol_Text] = ImVec4(0.95f, 0.96f, 0.98f, 1.00f);
@ -619,16 +621,16 @@ void ImGuiManager::SetStyle(ImGuiStyle& style, float scale)
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.27f, 0.32f, 0.38f, 1.00f); colors[ImGuiCol_ResizeGripActive] = ImVec4(0.27f, 0.32f, 0.38f, 1.00f);
colors[ImGuiCol_Tab] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f); colors[ImGuiCol_Tab] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
colors[ImGuiCol_TabHovered] = ImVec4(0.33f, 0.38f, 0.46f, 1.00f); colors[ImGuiCol_TabHovered] = ImVec4(0.33f, 0.38f, 0.46f, 1.00f);
colors[ImGuiCol_TabActive] = ImVec4(0.27f, 0.32f, 0.38f, 1.00f); colors[ImGuiCol_TabSelected] = ImVec4(0.27f, 0.32f, 0.38f, 1.00f);
colors[ImGuiCol_TabUnfocused] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f); colors[ImGuiCol_TabDimmed] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f); colors[ImGuiCol_TabDimmedSelected] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f);
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
colors[ImGuiCol_NavHighlight] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); colors[ImGuiCol_NavCursor] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f); colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f); colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f);
@ -769,6 +771,10 @@ bool ImGuiManager::LoadFontData(Error* error)
{ {
Timer load_timer; Timer load_timer;
static constexpr auto font_resource_name = [](const std::string_view font_name) {
return TinyString::from_format("fonts/{}", font_name);
};
// only load used text fonts, that way we don't waste memory on mini // only load used text fonts, that way we don't waste memory on mini
for (const TextFont text_font : s_state.text_font_order) for (const TextFont text_font : s_state.text_font_order)
{ {
@ -777,7 +783,7 @@ bool ImGuiManager::LoadFontData(Error* error)
continue; continue;
std::optional<DynamicHeapArray<u8>> font_data = std::optional<DynamicHeapArray<u8>> font_data =
Host::ReadResourceFile(TinyString::from_format("fonts/{}", TEXT_FONT_NAMES[index]), true, error); Host::ReadResourceFile(font_resource_name(TEXT_FONT_NAMES[index]), true, error);
if (!font_data.has_value()) if (!font_data.has_value())
return false; return false;
@ -787,7 +793,7 @@ bool ImGuiManager::LoadFontData(Error* error)
if (s_state.fixed_font_data.empty()) if (s_state.fixed_font_data.empty())
{ {
std::optional<DynamicHeapArray<u8>> font_data = std::optional<DynamicHeapArray<u8>> font_data =
Host::ReadResourceFile("fonts/RobotoMono-VariableFont_wght.ttf", true, error); Host::ReadResourceFile(font_resource_name(FIXED_FONT_NAME), true, error);
if (!font_data.has_value()) if (!font_data.has_value())
return false; return false;
@ -796,7 +802,8 @@ bool ImGuiManager::LoadFontData(Error* error)
if (s_state.icon_fa_font_data.empty()) if (s_state.icon_fa_font_data.empty())
{ {
std::optional<DynamicHeapArray<u8>> font_data = Host::ReadResourceFile("fonts/fa-solid-900.ttf", true, error); std::optional<DynamicHeapArray<u8>> font_data =
Host::ReadResourceFile(font_resource_name(FA_FONT_NAME), true, error);
if (!font_data.has_value()) if (!font_data.has_value())
return false; return false;
@ -805,7 +812,8 @@ bool ImGuiManager::LoadFontData(Error* error)
if (s_state.icon_pf_font_data.empty()) if (s_state.icon_pf_font_data.empty())
{ {
std::optional<DynamicHeapArray<u8>> font_data = Host::ReadResourceFile("fonts/promptfont.otf", true, error); std::optional<DynamicHeapArray<u8>> font_data =
Host::ReadResourceFile(font_resource_name(PF_FONT_NAME), true, error);
if (!font_data.has_value()) if (!font_data.has_value())
return false; return false;
@ -815,7 +823,7 @@ bool ImGuiManager::LoadFontData(Error* error)
if (s_state.emoji_font_data.empty()) if (s_state.emoji_font_data.empty())
{ {
std::optional<DynamicHeapArray<u8>> font_data = std::optional<DynamicHeapArray<u8>> font_data =
Host::ReadResourceFile("fonts/TwitterColorEmoji-SVGinOT.ttf", true, error); Host::ReadResourceFile(font_resource_name(EMOJI_FONT_NAME), true, error);
if (!font_data.has_value()) if (!font_data.has_value())
return false; return false;
@ -843,6 +851,7 @@ bool ImGuiManager::CreateFontAtlas(Error* error)
// First text font has to be added before the icon fonts. // First text font has to be added before the icon fonts.
// Remaining fonts are added after the icon font, otherwise the wrong glyphs will be used in the UI. // Remaining fonts are added after the icon font, otherwise the wrong glyphs will be used in the UI.
const TextFont first_font = s_state.text_font_order.front(); const TextFont first_font = s_state.text_font_order.front();
StringUtil::Strlcpy(text_cfg.Name, TEXT_FONT_NAMES[static_cast<size_t>(first_font)], std::size(text_cfg.Name));
auto& first_font_data = s_state.text_fonts_data[static_cast<size_t>(first_font)]; auto& first_font_data = s_state.text_fonts_data[static_cast<size_t>(first_font)];
Assert(!first_font_data.empty()); Assert(!first_font_data.empty());
s_state.text_font = s_state.text_font =
@ -856,6 +865,7 @@ bool ImGuiManager::CreateFontAtlas(Error* error)
// Add icon fonts. // Add icon fonts.
ImFontConfig icon_cfg; ImFontConfig icon_cfg;
StringUtil::Strlcpy(icon_cfg.Name, "PromptFont", std::size(icon_cfg.Name));
icon_cfg.MergeMode = true; icon_cfg.MergeMode = true;
icon_cfg.FontDataOwnedByAtlas = false; icon_cfg.FontDataOwnedByAtlas = false;
icon_cfg.PixelSnapH = true; icon_cfg.PixelSnapH = true;
@ -872,6 +882,7 @@ bool ImGuiManager::CreateFontAtlas(Error* error)
// Only for emoji font. // Only for emoji font.
icon_cfg.FontLoaderFlags = ImGuiFreeTypeLoaderFlags_LoadColor | ImGuiFreeTypeLoaderFlags_Bitmap; icon_cfg.FontLoaderFlags = ImGuiFreeTypeLoaderFlags_LoadColor | ImGuiFreeTypeLoaderFlags_Bitmap;
StringUtil::Strlcpy(icon_cfg.Name, "EmojiFont", std::size(icon_cfg.Name));
if (!ImGui::GetIO().Fonts->AddFontFromMemoryTTF(s_state.emoji_font_data.data(), if (!ImGui::GetIO().Fonts->AddFontFromMemoryTTF(s_state.emoji_font_data.data(),
static_cast<int>(s_state.emoji_font_data.size()), static_cast<int>(s_state.emoji_font_data.size()),
@ -881,6 +892,7 @@ bool ImGuiManager::CreateFontAtlas(Error* error)
return false; return false;
} }
StringUtil::Strlcpy(icon_cfg.Name, "FontAwesomeFont", std::size(icon_cfg.Name));
if (!ImGui::GetIO().Fonts->AddFontFromMemoryTTF(s_state.icon_fa_font_data.data(), if (!ImGui::GetIO().Fonts->AddFontFromMemoryTTF(s_state.icon_fa_font_data.data(),
static_cast<int>(s_state.icon_fa_font_data.size()), static_cast<int>(s_state.icon_fa_font_data.size()),
default_text_size * 0.75f, 0.0f, &icon_cfg)) [[unlikely]] default_text_size * 0.75f, 0.0f, &icon_cfg)) [[unlikely]]
@ -899,6 +911,7 @@ bool ImGuiManager::CreateFontAtlas(Error* error)
auto& font_data = s_state.text_fonts_data[static_cast<size_t>(text_font_idx)]; auto& font_data = s_state.text_fonts_data[static_cast<size_t>(text_font_idx)];
Assert(!font_data.empty()); Assert(!font_data.empty());
StringUtil::Strlcpy(text_cfg.Name, "TextFont-", std::size(text_cfg.Name));
if (!ImGui::GetIO().Fonts->AddFontFromMemoryTTF(font_data.data(), static_cast<int>(font_data.size()), if (!ImGui::GetIO().Fonts->AddFontFromMemoryTTF(font_data.data(), static_cast<int>(font_data.size()),
default_text_size, default_text_weight, &text_cfg)) default_text_size, default_text_weight, &text_cfg))
{ {
@ -909,6 +922,7 @@ bool ImGuiManager::CreateFontAtlas(Error* error)
// Add the fixed-width font separately last. // Add the fixed-width font separately last.
ImFontConfig fixed_cfg; ImFontConfig fixed_cfg;
StringUtil::Strlcpy(fixed_cfg.Name, "FixedFont", std::size(fixed_cfg.Name));
fixed_cfg.FontDataOwnedByAtlas = false; fixed_cfg.FontDataOwnedByAtlas = false;
s_state.fixed_font = ImGui::GetIO().Fonts->AddFontFromMemoryTTF(s_state.fixed_font_data.data(), s_state.fixed_font = ImGui::GetIO().Fonts->AddFontFromMemoryTTF(s_state.fixed_font_data.data(),
static_cast<int>(s_state.fixed_font_data.size()), static_cast<int>(s_state.fixed_font_data.size()),
@ -921,12 +935,6 @@ bool ImGuiManager::CreateFontAtlas(Error* error)
ImGuiFullscreen::SetFont(s_state.text_font); ImGuiFullscreen::SetFont(s_state.text_font);
if (!io.Fonts->Build())
{
Error::SetStringView(error, "Build() failed");
return false;
}
DEV_LOG("Creating font atlas took {} ms", load_timer.GetTimeMilliseconds()); DEV_LOG("Creating font atlas took {} ms", load_timer.GetTimeMilliseconds());
return true; return true;
} }
@ -1301,11 +1309,11 @@ void ImGuiManager::UpdateMousePosition(float x, float y)
std::atomic_thread_fence(std::memory_order_release); std::atomic_thread_fence(std::memory_order_release);
} }
void ImGuiManager::SetCommonIOOptions(ImGuiIO& io) void ImGuiManager::SetCommonIOOptions(ImGuiIO& io, ImGuiPlatformIO& pio)
{ {
io.KeyRepeatDelay = 0.5f; io.KeyRepeatDelay = 0.5f;
io.GetClipboardTextFn = GetClipboardTextImpl; pio.Platform_GetClipboardTextFn = GetClipboardTextImpl;
io.SetClipboardTextFn = SetClipboardTextImpl; pio.Platform_SetClipboardTextFn = SetClipboardTextImpl;
} }
bool ImGuiManager::ProcessPointerButtonEvent(InputBindingKey key, float value) bool ImGuiManager::ProcessPointerButtonEvent(InputBindingKey key, float value)
@ -1448,7 +1456,7 @@ bool ImGuiManager::ProcessGenericInputEvent(GenericInputBinding key, float value
return s_state.imgui_wants_keyboard.load(std::memory_order_acquire); return s_state.imgui_wants_keyboard.load(std::memory_order_acquire);
} }
const char* ImGuiManager::GetClipboardTextImpl(void* userdata) const char* ImGuiManager::GetClipboardTextImpl(ImGuiContext* ctx)
{ {
const std::string text = Host::GetClipboardText(); const std::string text = Host::GetClipboardText();
if (text.empty() || text.length() >= std::numeric_limits<int>::max()) if (text.empty() || text.length() >= std::numeric_limits<int>::max())
@ -1461,7 +1469,7 @@ const char* ImGuiManager::GetClipboardTextImpl(void* userdata)
return GImGui->ClipboardHandlerData.Data; return GImGui->ClipboardHandlerData.Data;
} }
void ImGuiManager::SetClipboardTextImpl(void* userdata, const char* text) void ImGuiManager::SetClipboardTextImpl(ImGuiContext* ctx, const char* text)
{ {
const size_t length = std::strlen(text); const size_t length = std::strlen(text);
if (length == 0) if (length == 0)
@ -1655,7 +1663,7 @@ bool ImGuiManager::CreateAuxiliaryRenderWindow(AuxiliaryRenderWindowState* state
state->imgui_context->IO.BackendFlags |= state->imgui_context->IO.BackendFlags |=
ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures; ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures;
state->imgui_context->IO.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange; state->imgui_context->IO.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange;
SetCommonIOOptions(state->imgui_context->IO); SetCommonIOOptions(state->imgui_context->IO, state->imgui_context->PlatformIO);
SetStyle(state->imgui_context->Style, state->swap_chain->GetScale()); SetStyle(state->imgui_context->Style, state->swap_chain->GetScale());
state->imgui_context->Style.WindowBorderSize = 0.0f; state->imgui_context->Style.WindowBorderSize = 0.0f;
@ -1720,7 +1728,7 @@ bool ImGuiManager::RenderAuxiliaryRenderWindow(AuxiliaryRenderWindowState* state
const float window_scale = state->swap_chain->GetScale(); const float window_scale = state->swap_chain->GetScale();
ImGui::NewFrame(); ImGui::NewFrame();
ImGui::PushFont(s_state.text_font, GetDebugFontSize(window_scale)); ImGui::PushFont(s_state.text_font, GetDebugFontSize(window_scale), 0.0f);
ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f), ImGuiCond_Always); ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f), ImGuiCond_Always);
ImGui::SetNextWindowSize(state->imgui_context->IO.DisplaySize, ImGuiCond_Always); ImGui::SetNextWindowSize(state->imgui_context->IO.DisplaySize, ImGuiCond_Always);
if (ImGui::Begin("AuxRenderWindowMain", nullptr, if (ImGui::Begin("AuxRenderWindowMain", nullptr,