From a1aa5cbb2d3073289aefa1655fd74f5e3bd0a2dc Mon Sep 17 00:00:00 2001 From: 4DBug <4DBug@github.com> Date: Thu, 15 Oct 2026 10:54:56 -0500 Subject: [PATCH] Fix: long TextUnformatted (>2000 bytes) rendered each visible line to the end of the text (RenderText end was nil, upstream passes line_end); PushFont() saved the new font instead of the current one, so PopFont() never restored it (font preview leaked into all later text); t_fixes covers both --- build/ImGui.luau | 4 ++-- build/imgui_love.lua | 4 ++-- imgui.lua | 2 +- imgui_widgets.lua | 2 +- tools/test/scripts/t_fixes.luau | 24 ++++++++++++++++++++++-- 5 files changed, 28 insertions(+), 8 deletions(-) diff --git a/build/ImGui.luau b/build/ImGui.luau index db5fcb8..8634ffa 100644 --- a/build/ImGui.luau +++ b/build/ImGui.luau @@ -5512,7 +5512,7 @@ function ImGui.PushFont(font, font_size_base) assert(font ~= nil) assert(font_size_base >= 0.0) - g.FontStack:push_back(ImFontStackData(font, g.FontSizeBase, g.FontSize)) + g.FontStack:push_back(ImFontStackData(g.Font, g.FontSizeBase, g.FontSize)) if font_size_base == 0.0 then font_size_base = g.FontSizeBase -- Keep current font size @@ -63145,7 +63145,7 @@ function ImGui.TextEx(text, text_end, flags) local line_size = ImGui.CalcTextSizeEx(text, line, line_end) text_size.x = ImMax(text_size.x, line_size.x) - ImGui.RenderText(pos, text, line, nil, false) + ImGui.RenderText(pos, text, line, line_end, false) line = line_end + 1 line_rect.Min.y = line_rect.Min.y + line_height line_rect.Max.y = line_rect.Max.y + line_height diff --git a/build/imgui_love.lua b/build/imgui_love.lua index 814517d..a8ddc32 100644 --- a/build/imgui_love.lua +++ b/build/imgui_love.lua @@ -5649,7 +5649,7 @@ function ImGui.PushFont(font, font_size_base) assert(font ~= nil) assert(font_size_base >= 0.0) - g.FontStack:push_back(ImFontStackData(font, g.FontSizeBase, g.FontSize)) + g.FontStack:push_back(ImFontStackData(g.Font, g.FontSizeBase, g.FontSize)) if font_size_base == 0.0 then font_size_base = g.FontSizeBase -- Keep current font size @@ -55771,7 +55771,7 @@ function ImGui.TextEx(text, text_end, flags) local line_size = ImGui.CalcTextSizeEx(text, line, line_end) text_size.x = ImMax(text_size.x, line_size.x) - ImGui.RenderText(pos, text, line, nil, false) + ImGui.RenderText(pos, text, line, line_end, false) line = line_end + 1 line_rect.Min.y = line_rect.Min.y + line_height line_rect.Max.y = line_rect.Max.y + line_height diff --git a/imgui.lua b/imgui.lua index 1fbb1b2..f0ffc1e 100644 --- a/imgui.lua +++ b/imgui.lua @@ -5467,7 +5467,7 @@ function ImGui.PushFont(font, font_size_base) IM_ASSERT(font ~= nil) IM_ASSERT(font_size_base >= 0.0) - g.FontStack:push_back(ImFontStackData(font, g.FontSizeBase, g.FontSize)) + g.FontStack:push_back(ImFontStackData(g.Font, g.FontSizeBase, g.FontSize)) if font_size_base == 0.0 then font_size_base = g.FontSizeBase -- Keep current font size diff --git a/imgui_widgets.lua b/imgui_widgets.lua index 318f54d..c7f4a45 100644 --- a/imgui_widgets.lua +++ b/imgui_widgets.lua @@ -170,7 +170,7 @@ function ImGui.TextEx(text, text_end, flags) local line_size = ImGui.CalcTextSizeEx(text, line, line_end) text_size.x = ImMax(text_size.x, line_size.x) - ImGui.RenderText(pos, text, line, nil, false) + ImGui.RenderText(pos, text, line, line_end, false) line = line_end + 1 line_rect.Min.y = line_rect.Min.y + line_height line_rect.Max.y = line_rect.Max.y + line_height diff --git a/tools/test/scripts/t_fixes.luau b/tools/test/scripts/t_fixes.luau index 4b492de..724779b 100644 --- a/tools/test/scripts/t_fixes.luau +++ b/tools/test/scripts/t_fixes.luau @@ -1,9 +1,12 @@ -- Regressions vs upstream: clipboard paste filter (InputTextEx), ImParseFormatTrimDecorations (Ctrl+click temp input), ShrinkWidths tie order, --- CalcItemSize by value, PushClipRectFullScreen (drop target outside clip rect), InputTextMultiline line index (render/scroll/edit), Shortcut() default +-- CalcItemSize by value, PushClipRectFullScreen (drop target outside clip rect), long TextUnformatted, PushFont/PopFont, InputTextMultiline line index (render/scroll/edit), Shortcut() default -- args, IsWindowAppearing() on frame 1 (FrameCount starts at 0), ColorButton -> ColorEdit4 drag and drop local G = require(game:GetService("ReplicatedStorage"):WaitForChild("ImGui")) local ImGui, ImVec2 = G.ImGui, G.ImVec2 -ImGui.CreateContext(); G.ImGui_ImplRoblox.Init() +ImGui.CreateContext() +ImGui.GetIO().Fonts:AddFontDefault() +local font2 = ImGui.GetIO().Fonts:AddFontDefault() -- second font for the PushFont/PopFont check +G.ImGui_ImplRoblox.Init() local io = ImGui.GetIO() local failed = {} local function check(ok, msg) if not ok then table.insert(failed, msg); print("FAIL " .. msg) end end @@ -18,6 +21,10 @@ check(w[3] == 100 and w[2] == 100 and w[1] == 99 and w[0] == 99, ("ShrinkWidths check(G.ImFloor(-1.5) == -2 and G.ImFloor(-0.2) == -1 and G.ImFloor(2.7) == 2, "ImFloor negative") +local long_text = {} +for i = 1, 300 do long_text[i] = string.format("line %04d", i) end +long_text = table.concat(long_text, "\n") -- 2999 bytes + local function edit_text() local st = ImGui.GetCurrentContext().InputTextState return G.ImGui._ByteArrayToString(st.TextA.Data, 1, st.TextLen + 1) @@ -110,6 +117,19 @@ game:GetService("RunService").Stepped:Connect(function() ImGui.ColorButton("cb", cb_col); rects.cb = rect() ImGui.ColorEdit4("##ce", ce_col); rects.ce = rect() ImGui.End() + -- TextUnformatted() > 2000 bytes (coarse-clipped long text path): each visible line renders only up to its '\n' + ImGui.SetNextWindowPos(ImVec2(320, 220)); ImGui.SetNextWindowSize(ImVec2(300, 150)) + ImGui.Begin("L") + local dl = ImGui.GetWindowDrawList() + local v0 = dl.VtxBuffer.Size + ImGui.TextUnformatted(long_text) + local nv = dl.VtxBuffer.Size - v0 + if f == 3 then check(nv > 0 and nv <= 14 * 9 * 4, "long TextUnformatted vertices " .. nv) end + -- PushFont() saves the CURRENT font: PopFont() must restore it + local font1 = ImGui.GetFont() + check(font2 ~= font1, "font2 is the default font"); ImGui.PushFont(font2, 0.0); ImGui.PopFont() + if f == 3 then check(ImGui.GetFont() == font1, "PopFont() did not restore the previous font") end + ImGui.End() ImGui.Render(); G.ImGui_ImplRoblox.RenderDrawData(ImGui.GetDrawData()) if f == 8 then check(edit_text() == "abc\u{e9}", "paste: '" .. edit_text() .. "'") end if f == 13 then check(edit_text() == "45", "SliderFloat temp input: '" .. edit_text() .. "'") end