Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/wolfpld/tracy.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/imgui
diff options
context:
space:
mode:
authorBartosz Taudul <wolf@nereid.pl>2021-12-23 16:17:01 +0300
committerBartosz Taudul <wolf@nereid.pl>2021-12-23 16:17:01 +0300
commite822dde7e13d228ddb69592659a7c42d4b862825 (patch)
treeb46e0c5fd1cc8e264c0664d11e4bedf20d3bd193 /imgui
parentb83cda575a3f650752e3d35cd8263c8ae8552e1a (diff)
Merge thedmd/feature/font-line-spacing into ImGui.
Diffstat (limited to 'imgui')
-rw-r--r--imgui/imgui.cpp79
-rw-r--r--imgui/imgui.h12
-rw-r--r--imgui/imgui_draw.cpp40
-rw-r--r--imgui/imgui_internal.h18
-rw-r--r--imgui/imgui_tables.cpp2
-rw-r--r--imgui/imgui_widgets.cpp103
6 files changed, 155 insertions, 99 deletions
diff --git a/imgui/imgui.cpp b/imgui/imgui.cpp
index eb5c7101..b9b835f1 100644
--- a/imgui/imgui.cpp
+++ b/imgui/imgui.cpp
@@ -2860,7 +2860,7 @@ void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool
if (text != text_display_end)
{
- window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end);
+ window->DrawList->AddText(g.Font, g.FontSize, g.FontLineHeight, g.FontBaselineOffset, pos, GetColorU32(ImGuiCol_Text), text, text_display_end);
if (g.LogEnabled)
LogRenderedText(&pos, text, text_display_end);
}
@@ -2876,7 +2876,7 @@ void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end
if (text != text_end)
{
- window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_end, wrap_width);
+ window->DrawList->AddText(g.Font, g.FontSize, g.FontLineHeight, g.FontBaselineOffset, pos, GetColorU32(ImGuiCol_Text), text, text_end, wrap_width);
if (g.LogEnabled)
LogRenderedText(&pos, text, text_end);
}
@@ -2951,6 +2951,7 @@ void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, con
const ImFont* font = draw_list->_Data->Font;
const float font_size = draw_list->_Data->FontSize;
+ const float font_line_height = draw_list->_Data->FontLineHeight;
const char* text_end_ellipsis = NULL;
ImWchar ellipsis_char = font->EllipsisChar;
@@ -2975,18 +2976,18 @@ void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, con
// We can now claim the space between pos_max.x and ellipsis_max.x
const float text_avail_width = ImMax((ImMax(pos_max.x, ellipsis_max_x) - ellipsis_total_width) - pos_min.x, 1.0f);
- float text_size_clipped_x = font->CalcTextSizeA(font_size, text_avail_width, 0.0f, text, text_end_full, &text_end_ellipsis).x;
+ float text_size_clipped_x = font->CalcTextSizeA(font_size, font_line_height, text_avail_width, 0.0f, text, text_end_full, &text_end_ellipsis).x;
if (text == text_end_ellipsis && text_end_ellipsis < text_end_full)
{
// Always display at least 1 character if there's no room for character + ellipsis
text_end_ellipsis = text + ImTextCountUtf8BytesFromChar(text, text_end_full);
- text_size_clipped_x = font->CalcTextSizeA(font_size, FLT_MAX, 0.0f, text, text_end_ellipsis).x;
+ text_size_clipped_x = font->CalcTextSizeA(font_size, font_line_height, FLT_MAX, 0.0f, text, text_end_ellipsis).x;
}
while (text_end_ellipsis > text && ImCharIsBlankA(text_end_ellipsis[-1]))
{
// Trim trailing space before ellipsis (FIXME: Supporting non-ascii blanks would be nice, for this we need a function to backtrack in UTF-8 text)
text_end_ellipsis--;
- text_size_clipped_x -= font->CalcTextSizeA(font_size, FLT_MAX, 0.0f, text_end_ellipsis, text_end_ellipsis + 1).x; // Ascii blanks are always 1 byte
+ text_size_clipped_x -= font->CalcTextSizeA(font_size, font_line_height, FLT_MAX, 0.0f, text_end_ellipsis, text_end_ellipsis + 1).x; // Ascii blanks are always 1 byte
}
// Render text, render ellipsis
@@ -2995,7 +2996,7 @@ void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, con
if (ellipsis_x + ellipsis_total_width <= ellipsis_max_x)
for (int i = 0; i < ellipsis_char_count; i++)
{
- font->RenderChar(draw_list, font_size, ImVec2(ellipsis_x, pos_min.y), GetColorU32(ImGuiCol_Text), ellipsis_char);
+ font->RenderChar(draw_list, font_size, font_line_height, ImVec2(ellipsis_x, pos_min.y), GetColorU32(ImGuiCol_Text), ellipsis_char);
ellipsis_x += ellipsis_glyph_width;
}
}
@@ -3185,7 +3186,7 @@ static void SetCurrentWindow(ImGuiWindow* window)
g.CurrentWindow = window;
g.CurrentTable = window && window->DC.CurrentTableIdx != -1 ? g.Tables.GetByIndex(window->DC.CurrentTableIdx) : NULL;
if (window)
- g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize();
+ ImGui::SetCurrentFont(g.Font);
}
void ImGui::GcCompactTransientMiscBuffers()
@@ -4008,7 +4009,7 @@ void ImGui::UpdateMouseWheel()
if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs))
{
float max_step = window->InnerRect.GetHeight() * 0.67f;
- float scroll_step = ImFloor(ImMin(5 * window->CalcFontSize(), max_step));
+ float scroll_step = ImFloor(ImMin(5 * window->CalcFontHeight(), max_step));
SetScrollY(window, window->Scroll.y - wheel_y * scroll_step);
}
}
@@ -4022,7 +4023,7 @@ void ImGui::UpdateMouseWheel()
if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs))
{
float max_step = window->InnerRect.GetWidth() * 0.67f;
- float scroll_step = ImFloor(ImMin(2 * window->CalcFontSize(), max_step));
+ float scroll_step = ImFloor(ImMin(2 * window->CalcFontWidth(), max_step));
SetScrollX(window, window->Scroll.x - wheel_x * scroll_step);
}
}
@@ -4919,9 +4920,10 @@ ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_tex
ImFont* font = g.Font;
const float font_size = g.FontSize;
+ const float font_line_height = g.FontLineHeight;
if (text == text_display_end)
- return ImVec2(0.0f, font_size);
- ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL);
+ return ImVec2(0.0f, font_line_height);
+ ImVec2 text_size = font->CalcTextSizeA(font_size, font_line_height, FLT_MAX, wrap_width, text, text_display_end, NULL);
// Round
// FIXME: This has been here since Dec 2015 (7b0bf230) but down the line we want this out.
@@ -6159,7 +6161,7 @@ void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& titl
// FIXME: Would be nice to generalize the subtleties expressed here into reusable code.
float pad_l = style.FramePadding.x;
float pad_r = style.FramePadding.x;
- float button_sz = g.FontSize;
+ float button_sz = g.FontLineHeight;
ImVec2 close_button_pos;
ImVec2 collapse_button_pos;
if (has_close_button)
@@ -7315,14 +7317,19 @@ void ImGui::SetCurrentFont(ImFont* font)
IM_ASSERT(font && font->IsLoaded()); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ?
IM_ASSERT(font->Scale > 0.0f);
g.Font = font;
- g.FontBaseSize = ImMax(1.0f, g.IO.FontGlobalScale * g.Font->FontSize * g.Font->Scale);
- g.FontSize = g.CurrentWindow ? g.CurrentWindow->CalcFontSize() : 0.0f;
+ g.FontBaseScale = ImMax(0.01f, g.IO.FontGlobalScale * g.Font->Scale);
+ const float font_scale = g.FontBaseScale * (g.CurrentWindow ? g.CurrentWindow->CalcFontScale() : 1.0f);
+ g.FontSize = IM_ROUND(g.Font->FontSize * font_scale);
+ g.FontLineHeight = IM_ROUND((g.Font->FontSize + g.Font->ExtraLineHeight) * font_scale);
+ g.FontBaselineOffset = g.Font->BaselineOffset * font_scale;
ImFontAtlas* atlas = g.Font->ContainerAtlas;
g.DrawListSharedData.TexUvWhitePixel = atlas->TexUvWhitePixel;
g.DrawListSharedData.TexUvLines = atlas->TexUvLines;
g.DrawListSharedData.Font = g.Font;
g.DrawListSharedData.FontSize = g.FontSize;
+ g.DrawListSharedData.FontLineHeight = g.FontLineHeight;
+ g.DrawListSharedData.FontBaselineOffset = g.FontBaselineOffset;
}
void ImGui::PushFont(ImFont* font)
@@ -7852,6 +7859,16 @@ float ImGui::GetFontSize()
return GImGui->FontSize;
}
+float ImGui::GetFontLineHeight()
+{
+ return GImGui->FontLineHeight;
+}
+
+float ImGui::GetFontBaselineOffset()
+{
+ return GImGui->FontBaselineOffset;
+}
+
ImVec2 ImGui::GetFontTexUvWhitePixel()
{
return GImGui->DrawListSharedData.TexUvWhitePixel;
@@ -7863,7 +7880,7 @@ void ImGui::SetWindowFontScale(float scale)
ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
window->FontWindowScale = scale;
- g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize();
+ SetCurrentFont(g.Font);
}
void ImGui::ActivateItem(ImGuiID id)
@@ -8631,25 +8648,25 @@ ImVec2 ImGui::CalcItemSize(ImVec2 size, float default_w, float default_h)
float ImGui::GetTextLineHeight()
{
ImGuiContext& g = *GImGui;
- return g.FontSize;
+ return g.FontLineHeight;
}
float ImGui::GetTextLineHeightWithSpacing()
{
ImGuiContext& g = *GImGui;
- return g.FontSize + g.Style.ItemSpacing.y;
+ return g.FontLineHeight + g.Style.ItemSpacing.y;
}
float ImGui::GetFrameHeight()
{
ImGuiContext& g = *GImGui;
- return g.FontSize + g.Style.FramePadding.y * 2.0f;
+ return g.FontLineHeight + g.Style.FramePadding.y * 2.0f;
}
float ImGui::GetFrameHeightWithSpacing()
{
ImGuiContext& g = *GImGui;
- return g.FontSize + g.Style.FramePadding.y * 2.0f + g.Style.ItemSpacing.y;
+ return g.FontLineHeight + g.Style.FramePadding.y * 2.0f + g.Style.ItemSpacing.y;
}
// FIXME: All the Contents Region function are messy or misleading. WE WILL AIM TO OBSOLETE ALL OF THEM WITH A NEW "WORK RECT" API. Thanks for your patience!
@@ -10333,23 +10350,24 @@ static void ImGui::NavUpdate()
{
// *Fallback* manual-scroll with Nav directional keys when window has no navigable item
ImGuiWindow* window = g.NavWindow;
- const float scroll_speed = IM_ROUND(window->CalcFontSize() * 100 * io.DeltaTime); // We need round the scrolling speed because sub-pixel scroll isn't reliably supported.
+ const float scroll_speed_x = IM_ROUND(window->CalcFontWidth() * 100 * io.DeltaTime); // We need round the scrolling speed because sub-pixel scroll isn't reliably supported.
+ const float scroll_speed_y = IM_ROUND(window->CalcFontHeight() * 100 * io.DeltaTime); // We need round the scrolling speed because sub-pixel scroll isn't reliably supported.
const ImGuiDir move_dir = g.NavMoveDir;
if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll && move_dir != ImGuiDir_None)
{
if (move_dir == ImGuiDir_Left || move_dir == ImGuiDir_Right)
- SetScrollX(window, ImFloor(window->Scroll.x + ((move_dir == ImGuiDir_Left) ? -1.0f : +1.0f) * scroll_speed));
+ SetScrollX(window, ImFloor(window->Scroll.x + ((move_dir == ImGuiDir_Left) ? -1.0f : +1.0f) * scroll_speed_x));
if (move_dir == ImGuiDir_Up || move_dir == ImGuiDir_Down)
- SetScrollY(window, ImFloor(window->Scroll.y + ((move_dir == ImGuiDir_Up) ? -1.0f : +1.0f) * scroll_speed));
+ SetScrollY(window, ImFloor(window->Scroll.y + ((move_dir == ImGuiDir_Up) ? -1.0f : +1.0f) * scroll_speed_y));
}
// *Normal* Manual scroll with NavScrollXXX keys
// Next movement request will clamp the NavId reference rectangle to the visible area, so navigation will resume within those bounds.
ImVec2 scroll_dir = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadLStick, ImGuiInputReadMode_Down, 1.0f / 10.0f, 10.0f);
if (scroll_dir.x != 0.0f && window->ScrollbarX)
- SetScrollX(window, ImFloor(window->Scroll.x + scroll_dir.x * scroll_speed));
+ SetScrollX(window, ImFloor(window->Scroll.x + scroll_dir.x * scroll_speed_x));
if (scroll_dir.y != 0.0f)
- SetScrollY(window, ImFloor(window->Scroll.y + scroll_dir.y * scroll_speed));
+ SetScrollY(window, ImFloor(window->Scroll.y + scroll_dir.y * scroll_speed_y));
}
// Always prioritize mouse highlight if navigation is disabled
@@ -10474,7 +10492,7 @@ void ImGui::NavUpdateCreateMoveRequest()
if (!window_rect_rel.Contains(window->NavRectRel[g.NavLayer]))
{
IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: clamp NavRectRel\n");
- float pad = window->CalcFontSize() * 0.5f;
+ float pad = window->CalcFontWidth() * 0.5f;
window_rect_rel.Expand(ImVec2(-ImMin(window_rect_rel.GetWidth(), pad), -ImMin(window_rect_rel.GetHeight(), pad))); // Terrible approximation for the intent of starting navigation from first fully visible item
window->NavRectRel[g.NavLayer].ClipWithFull(window_rect_rel);
g.NavId = g.NavFocusScopeId = 0;
@@ -10698,7 +10716,7 @@ static float ImGui::NavUpdatePageUpPageDown()
else
{
ImRect& nav_rect_rel = window->NavRectRel[g.NavLayer];
- const float page_offset_y = ImMax(0.0f, window->InnerRect.GetHeight() - window->CalcFontSize() * 1.0f + nav_rect_rel.GetHeight());
+ const float page_offset_y = ImMax(0.0f, window->InnerRect.GetHeight() - window->CalcFontHeight() * 1.0f + nav_rect_rel.GetHeight());
float nav_scoring_rect_offset_y = 0.0f;
if (IsKeyPressed(io.KeyMap[ImGuiKey_PageUp], true))
{
@@ -16943,7 +16961,7 @@ void ImGui::DebugRenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP*
window->DrawList->AddRectFilled(thumb_r.Min, thumb_r.Max, GetColorU32(ImGuiCol_WindowBg, alpha_mul));
window->DrawList->AddRectFilled(title_r.Min, title_r.Max, GetColorU32(window_is_focused ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg, alpha_mul));
window->DrawList->AddRect(thumb_r.Min, thumb_r.Max, GetColorU32(ImGuiCol_Border, alpha_mul));
- window->DrawList->AddText(g.Font, g.FontSize * 1.0f, title_r.Min, GetColorU32(ImGuiCol_Text, alpha_mul), thumb_window->Name, FindRenderedTextEnd(thumb_window->Name));
+ window->DrawList->AddText(g.Font, g.FontSize, g.FontLineHeight, g.FontBaselineOffset, title_r.Min, GetColorU32(ImGuiCol_Text, alpha_mul), thumb_window->Name, FindRenderedTextEnd(thumb_window->Name));
}
draw_list->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_Border, alpha_mul));
}
@@ -17740,7 +17758,12 @@ void ImGui::DebugNodeFont(ImFont* font)
"You may oversample them to get some flexibility with scaling. "
"You can also render at multiple sizes and select which one to use at runtime.\n\n"
"(Glimmer of hope: the atlas system will be rewritten in the future to make scaling more flexible.)");
+ SetNextItemWidth(GetFontSize() * 8);
+ DragFloat("Extra line height", &font->ExtraLineHeight, 1.0f, -font->FontSize, FLT_MAX, "%g");
+ SetNextItemWidth(GetFontSize() * 8);
+ DragFloat("Baseline offset", &font->BaselineOffset, 0.1f, -FLT_MAX, FLT_MAX, "%g");
Text("Ascent: %f, Descent: %f, Height: %f", font->Ascent, font->Descent, font->Ascent - font->Descent);
+ Text("Line Height: %f", font->FontSize + font->ExtraLineHeight);
char c_str[5];
Text("Fallback character: '%s' (U+%04X)", ImTextCharToUtf8(c_str, font->FallbackChar), font->FallbackChar);
Text("Ellipsis character: '%s' (U+%04X)", ImTextCharToUtf8(c_str, font->EllipsisChar), font->EllipsisChar);
@@ -17790,7 +17813,7 @@ void ImGui::DebugNodeFont(ImFont* font)
const ImFontGlyph* glyph = font->FindGlyphNoFallback((ImWchar)(base + n));
draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255, 255, 255, 100) : IM_COL32(255, 255, 255, 50));
if (glyph)
- font->RenderChar(draw_list, cell_size, cell_p1, glyph_col, (ImWchar)(base + n));
+ font->RenderChar(draw_list, cell_size, cell_size, cell_p1, glyph_col, (ImWchar)(base + n));
if (glyph && IsMouseHoveringRect(cell_p1, cell_p2))
{
BeginTooltip();
diff --git a/imgui/imgui.h b/imgui/imgui.h
index ceb3b086..d21f44bc 100644
--- a/imgui/imgui.h
+++ b/imgui/imgui.h
@@ -433,7 +433,9 @@ namespace ImGui
// Style read access
// - Use the style editor (ShowStyleEditor() function) to interactively see what the colors are)
IMGUI_API ImFont* GetFont(); // get current font
- IMGUI_API float GetFontSize(); // get current font size (= height in pixels) of current font with current scale applied
+ IMGUI_API float GetFontSize(); // get current font size, mostly used in context where width should be determined (= size in pixels) of current font with current scale applied
+ IMGUI_API float GetFontLineHeight(); // get current font line height (in pixels) of current font with current scale applied
+ IMGUI_API float GetFontBaselineOffset(); // get current font baseline offset (in pixels) of current font with current scale applied
IMGUI_API ImVec2 GetFontTexUvWhitePixel(); // get UV coordinate for a while pixel, useful to draw custom shapes via the ImDrawList API
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
@@ -2551,6 +2553,7 @@ struct ImDrawList
IMGUI_API void AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments);
IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL);
IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL);
+ IMGUI_API void AddText(const ImFont* font, float font_size, float font_line_height, float font_baseline_offset, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL);
IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness);
IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col); // Note: Anti-aliased filling requires points to be in clockwise order.
IMGUI_API void AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0); // Cubic Bezier (4 control points)
@@ -2864,6 +2867,8 @@ struct ImFont
ImWchar DotChar; // 2 // out // = '.' // Character used for ellipsis rendering (if a single '...' character isn't found)
bool DirtyLookupTables; // 1 // out //
float Scale; // 4 // in // = 1.f // Base font scale, multiplied by the per-window font scale which you can adjust with SetWindowFontScale()
+ float ExtraLineHeight; // 4 // in // // Amount of space to be added to line height. Using negative values are allowed. (You need to call ImGui::SetCurrentFont() to populate these values when you're expecting immediate response.)
+ float BaselineOffset; // 4 // in // // Font baseline will be modified by this value while drawing. (You need to call ImGui::SetCurrentFont() to populate these values when you're expecting immediate response.)
float Ascent, Descent; // 4+4 // out // // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize]
int MetricsTotalSurface;// 4 // out // // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs)
ImU8 Used4kPagesMap[(IM_UNICODE_CODEPOINT_MAX+1)/4096/8]; // 2 bytes if ImWchar=ImWchar16, 34 bytes if ImWchar==ImWchar32. Store 1-bit for each block of 4K codepoints that has one active glyph. This is mainly used to facilitate iterations across all used codepoints.
@@ -2879,10 +2884,11 @@ struct ImFont
// 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
// 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.
- IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8
+ IMGUI_API ImVec2 CalcTextSizeA(float size, float line_height, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8
IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const;
- IMGUI_API void RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, ImWchar c) const;
+ IMGUI_API void RenderChar(ImDrawList* draw_list, float size, float line_height, ImVec2 pos, ImU32 col, ImWchar c) const;
IMGUI_API void RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const;
+ IMGUI_API void RenderText(ImDrawList* draw_list, float size, float line_height, float baseline_offset, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const;
// [Internal] Don't use!
IMGUI_API void BuildLookupTable();
diff --git a/imgui/imgui_draw.cpp b/imgui/imgui_draw.cpp
index 80ef77d3..f7dc4faa 100644
--- a/imgui/imgui_draw.cpp
+++ b/imgui/imgui_draw.cpp
@@ -1583,6 +1583,21 @@ void ImDrawList::AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const Im
void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec4* cpu_fine_clip_rect)
{
+ // Pull default font/size from the shared ImDrawListSharedData instance
+ if (font == NULL)
+ font = _Data->Font;
+ if (font_size == 0.0f)
+ font_size = _Data->FontSize;
+
+ const float scale = font_size / font->FontSize;
+ const float line_height = (font->FontSize + font->ExtraLineHeight) * scale;
+ const float baseline_offset = font->BaselineOffset * scale;
+
+ AddText(font, font_size, line_height, baseline_offset, pos, col, text_begin, text_end, wrap_width, cpu_fine_clip_rect);
+}
+
+void ImDrawList::AddText(const ImFont* font, float font_size, float font_line_height, float font_baseline_offset, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec4* cpu_fine_clip_rect)
+{
if ((col & IM_COL32_A_MASK) == 0)
return;
@@ -1607,7 +1622,7 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos,
clip_rect.z = ImMin(clip_rect.z, cpu_fine_clip_rect->z);
clip_rect.w = ImMin(clip_rect.w, cpu_fine_clip_rect->w);
}
- font->RenderText(this, font_size, pos, col, clip_rect, text_begin, text_end, wrap_width, cpu_fine_clip_rect != NULL);
+ font->RenderText(this, font_size, font_line_height, font_baseline_offset, pos, col, clip_rect, text_begin, text_end, wrap_width, cpu_fine_clip_rect != NULL);
}
void ImDrawList::AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end)
@@ -3113,6 +3128,8 @@ void ImFontGlyphRangesBuilder::BuildRanges(ImVector<ImWchar>* out_ranges)
ImFont::ImFont()
{
FontSize = 0.0f;
+ ExtraLineHeight = 0.0f;
+ BaselineOffset = 0.0f;
FallbackAdvanceX = 0.0f;
FallbackChar = (ImWchar)-1;
EllipsisChar = (ImWchar)-1;
@@ -3436,12 +3453,11 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
return s;
}
-ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining) const
+ImVec2 ImFont::CalcTextSizeA(float size, float line_height, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining) const
{
if (!text_end)
text_end = text_begin + strlen(text_begin); // FIXME-OPT: Need to avoid this.
- const float line_height = size;
const float scale = size / FontSize;
ImVec2 text_size = ImVec2(0, 0);
@@ -3531,7 +3547,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
}
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
-void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, ImWchar c) const
+void ImFont::RenderChar(ImDrawList* draw_list, float size, float line_height, ImVec2 pos, ImU32 col, ImWchar c) const
{
const ImFontGlyph* glyph = FindGlyph(c);
if (!glyph || !glyph->Visible)
@@ -3540,7 +3556,7 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
col |= ~IM_COL32_A_MASK;
float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f;
pos.x = IM_FLOOR(pos.x);
- pos.y = IM_FLOOR(pos.y);
+ pos.y = IM_FLOOR(pos.y + (line_height - size) * 0.5f);
draw_list->PrimReserve(6, 4);
draw_list->PrimRectUV(ImVec2(pos.x + glyph->X0 * scale, pos.y + glyph->Y0 * scale), ImVec2(pos.x + glyph->X1 * scale, pos.y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col);
}
@@ -3548,19 +3564,27 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip) const
{
+ const float scale = size / FontSize;
+ const float line_height = (FontSize + ExtraLineHeight) * scale;
+ const float baseline_offset = BaselineOffset * scale;
+
+ RenderText(draw_list, size, line_height, baseline_offset, pos, col, clip_rect, text_begin, text_end, wrap_width, cpu_fine_clip);
+}
+
+void ImFont::RenderText(ImDrawList* draw_list, float size, float line_height, float baseline_offset, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip) const
+{
if (!text_end)
text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
// Align to be pixel perfect
pos.x = IM_FLOOR(pos.x);
- pos.y = IM_FLOOR(pos.y);
+ pos.y = IM_FLOOR(pos.y + (line_height - size) * 0.5f + baseline_offset);
float x = pos.x;
float y = pos.y;
if (y > clip_rect.w)
return;
const float scale = size / FontSize;
- const float line_height = FontSize * scale;
const bool word_wrap_enabled = (wrap_width > 0.0f);
const char* word_wrap_eol = NULL;
@@ -3757,7 +3781,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
// Render an arrow aimed to be aligned with text (p_min is a position in the same space text would be positioned). To e.g. denote expanded/collapsed state
void ImGui::RenderArrow(ImDrawList* draw_list, ImVec2 pos, ImU32 col, ImGuiDir dir, float scale)
{
- const float h = draw_list->_Data->FontSize * 1.00f;
+ const float h = draw_list->_Data->FontLineHeight * 1.00f;
float r = h * 0.40f * scale;
ImVec2 center = pos + ImVec2(h * 0.50f, h * 0.50f * scale);
diff --git a/imgui/imgui_internal.h b/imgui/imgui_internal.h
index 398c69dc..422b11b8 100644
--- a/imgui/imgui_internal.h
+++ b/imgui/imgui_internal.h
@@ -725,6 +725,8 @@ struct IMGUI_API ImDrawListSharedData
ImVec2 TexUvWhitePixel; // UV of white pixel in the atlas
ImFont* Font; // Current/default font (optional, for simplified AddText overload)
float FontSize; // Current/default font size (optional, for simplified AddText overload)
+ float FontLineHeight; // Current/default font line height (optional, for simplified AddText overload)
+ float FontBaselineOffset; // Current/default font baseline offset (optional, for simplified AddText overload)
float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo()
float CircleSegmentMaxError; // Number of circle segments to use per pixel of radius for AddCircle() etc
ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen()
@@ -1677,8 +1679,10 @@ struct ImGuiContext
ImGuiConfigFlags ConfigFlagsCurrFrame; // = g.IO.ConfigFlags at the time of NewFrame()
ImGuiConfigFlags ConfigFlagsLastFrame;
ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back()
- float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window.
- float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height.
+ float FontSize; // (Shortcut) == FontBaseScale * g.CurrentWindow->FontWindowScale * Font->FontSize == window->FontSize(). Text height for current window.
+ float FontLineHeight; // (Shortcut) == FontBaseScale * g.CurrentWindow->FontWindowScale * (Font->FontSize + Font->ExtraLineHeight) (optional, for simplified AddText overload)
+ float FontBaselineOffset; // (Shortcut) == FontBaseScale * g.CurrentWindow->FontWindowScale * Font->BaselineOffset (optional, for simplified AddText overload)
+ float FontBaseScale; // (Shortcut) == IO.FontGlobalScale * Font->Scale. Base text scale.
ImDrawListSharedData DrawListSharedData;
double Time;
int FrameCount;
@@ -1944,7 +1948,7 @@ struct ImGuiContext
ConfigFlagsCurrFrame = ConfigFlagsLastFrame = ImGuiConfigFlags_None;
FontAtlasOwnedByContext = shared_font_atlas ? false : true;
Font = NULL;
- FontSize = FontBaseSize = 0.0f;
+ FontSize = FontBaseScale = FontLineHeight = FontBaselineOffset = 0.0f;
IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)();
Time = 0.0f;
FrameCount = 0;
@@ -2282,10 +2286,12 @@ public:
// We don't use g.FontSize because the window may be != g.CurrentWidow.
ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
- float CalcFontSize() const { ImGuiContext& g = *GImGui; float scale = g.FontBaseSize * FontWindowScale * FontDpiScale; if (ParentWindow) scale *= ParentWindow->FontWindowScale; return scale; }
- float TitleBarHeight() const { ImGuiContext& g = *GImGui; return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontSize() + g.Style.FramePadding.y * 2.0f; }
+ float CalcFontScale() const { float scale = FontWindowScale; if (ParentWindow) scale *= ParentWindow->FontWindowScale; return scale; }
+ float CalcFontWidth() const { ImGuiContext& g = *GImGui; return CalcFontScale() * g.FontSize; }
+ float CalcFontHeight() const { ImGuiContext& g = *GImGui; return CalcFontScale() * g.FontLineHeight; }
+ float TitleBarHeight() const { ImGuiContext& g = *GImGui; return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontHeight() + g.Style.FramePadding.y * 2.0f; }
ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight())); }
- float MenuBarHeight() const { ImGuiContext& g = *GImGui; return (Flags & ImGuiWindowFlags_MenuBar) ? DC.MenuBarOffset.y + CalcFontSize() + g.Style.FramePadding.y * 2.0f : 0.0f; }
+ float MenuBarHeight() const { ImGuiContext& g = *GImGui; return (Flags & ImGuiWindowFlags_MenuBar) ? DC.MenuBarOffset.y + CalcFontHeight() + g.Style.FramePadding.y * 2.0f : 0.0f; }
ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight(); return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight()); }
};
diff --git a/imgui/imgui_tables.cpp b/imgui/imgui_tables.cpp
index 8a3fe93c..d6470a8c 100644
--- a/imgui/imgui_tables.cpp
+++ b/imgui/imgui_tables.cpp
@@ -533,7 +533,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
// It will also react to changing fonts with mixed results. It doesn't need to be perfect but merely provide a decent transition.
// FIXME-DPI: Provide consistent standards for reference size. Perhaps using g.CurrentDpiScale would be more self explanatory.
// This is will lead us to non-rounded WidthRequest in columns, which should work but is a poorly tested path.
- const float new_ref_scale_unit = g.FontSize; // g.Font->GetCharAdvance('A') ?
+ const float new_ref_scale_unit = g.FontLineHeight; // g.Font->GetCharAdvance('A') ?
if (table->RefScale != 0.0f && table->RefScale != new_ref_scale_unit)
{
const float scale_factor = new_ref_scale_unit / table->RefScale;
diff --git a/imgui/imgui_widgets.cpp b/imgui/imgui_widgets.cpp
index 89e3681e..2650d4d2 100644
--- a/imgui/imgui_widgets.cpp
+++ b/imgui/imgui_widgets.cpp
@@ -396,7 +396,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args)
const char* text_begin = g.TempBuffer;
const char* text_end = text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
const ImVec2 label_size = CalcTextSize(text_begin, text_end, false);
- const ImVec2 total_size = ImVec2(g.FontSize + (label_size.x > 0.0f ? (label_size.x + style.FramePadding.x * 2) : 0.0f), label_size.y); // Empty text doesn't add padding
+ const ImVec2 total_size = ImVec2(g.FontLineHeight + (label_size.x > 0.0f ? (label_size.x + style.FramePadding.x * 2) : 0.0f), label_size.y); // Empty text doesn't add padding
ImVec2 pos = window->DC.CursorPos;
pos.y += window->DC.CurrLineTextBaseOffset;
ItemSize(total_size, 0.0f);
@@ -406,7 +406,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args)
// Render
ImU32 text_col = GetColorU32(ImGuiCol_Text);
- RenderBullet(window->DrawList, bb.Min + ImVec2(style.FramePadding.x + g.FontSize * 0.5f, g.FontSize * 0.5f), text_col);
+ RenderBullet(window->DrawList, bb.Min + ImVec2(style.FramePadding.x + g.FontSize * 0.5f, g.FontLineHeight * 0.5f), text_col);
RenderText(bb.Min + ImVec2(g.FontSize + style.FramePadding.x * 2, 0.0f), text_begin, text_end, false);
}
@@ -776,7 +776,7 @@ bool ImGui::ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size, ImGuiBu
const ImU32 text_col = GetColorU32(ImGuiCol_Text);
RenderNavHighlight(bb, id);
RenderFrame(bb.Min, bb.Max, bg_col, true, g.Style.FrameRounding);
- RenderArrow(window->DrawList, bb.Min + ImVec2(ImMax(0.0f, (size.x - g.FontSize) * 0.5f), ImMax(0.0f, (size.y - g.FontSize) * 0.5f)), text_col, dir);
+ RenderArrow(window->DrawList, bb.Min + ImVec2(ImMax(0.0f, (size.x - g.FontLineHeight) * 0.5f), ImMax(0.0f, (size.y - g.FontLineHeight) * 0.5f)), text_col, dir);
return pressed;
}
@@ -795,7 +795,7 @@ bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos)
// Tweak 1: Shrink hit-testing area if button covers an abnormally large proportion of the visible region. That's in order to facilitate moving the window away. (#3825)
// This may better be applied as a general hit-rect reduction mechanism for all widgets to ensure the area to move window is always accessible?
- const ImRect bb(pos, pos + ImVec2(g.FontSize, g.FontSize) + g.Style.FramePadding * 2.0f);
+ const ImRect bb(pos, pos + ImVec2(g.FontLineHeight, g.FontLineHeight) + g.Style.FramePadding * 2.0f);
ImRect bb_interact = bb;
const float area_to_visible_ratio = window->OuterRectClipped.GetArea() / bb.GetArea();
if (area_to_visible_ratio < 1.5f)
@@ -832,7 +832,7 @@ bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos, ImGuiDockNode* dock_no
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
- ImRect bb(pos, pos + ImVec2(g.FontSize, g.FontSize) + g.Style.FramePadding * 2.0f);
+ ImRect bb(pos, pos + ImVec2(g.FontSize, g.FontLineHeight) + g.Style.FramePadding * 2.0f);
ItemAdd(bb, id);
bool hovered, held;
bool pressed = ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_None);
@@ -927,8 +927,8 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
// When we are too small, start hiding and disabling the grab (this reduce visual noise on very small window and facilitate using the window resize grab)
float alpha = 1.0f;
- if ((axis == ImGuiAxis_Y) && bb_frame_height < g.FontSize + g.Style.FramePadding.y * 2.0f)
- alpha = ImSaturate((bb_frame_height - g.FontSize) / (g.Style.FramePadding.y * 2.0f));
+ if ((axis == ImGuiAxis_Y) && bb_frame_height < g.FontLineHeight + g.Style.FramePadding.y * 2.0f)
+ alpha = ImSaturate((bb_frame_height - g.FontLineHeight) / (g.Style.FramePadding.y * 2.0f));
if (alpha <= 0.0f)
return false;
@@ -1254,7 +1254,7 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* over
const ImGuiStyle& style = g.Style;
ImVec2 pos = window->DC.CursorPos;
- ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), g.FontSize + style.FramePadding.y * 2.0f);
+ ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), g.FontLineHeight + style.FramePadding.y * 2.0f);
ImRect bb(pos, pos + size);
ItemSize(size, style.FramePadding.y);
if (!ItemAdd(bb, 0))
@@ -1288,7 +1288,7 @@ void ImGui::Bullet()
ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
- const float line_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + g.Style.FramePadding.y * 2), g.FontSize);
+ const float line_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontLineHeight + g.Style.FramePadding.y * 2), g.FontLineHeight);
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize, line_height));
ItemSize(bb);
if (!ItemAdd(bb, 0))
@@ -1347,7 +1347,7 @@ void ImGui::NewLine()
if (window->DC.CurrLineSize.y > 0.0f) // In the event that we are on a line with items that is smaller that FontSize high, we will preserve its height.
ItemSize(ImVec2(0, 0));
else
- ItemSize(ImVec2(0.0f, g.FontSize));
+ ItemSize(ImVec2(0.0f, g.FontLineHeight));
window->DC.LayoutType = backup_layout_type;
}
@@ -1358,7 +1358,7 @@ void ImGui::AlignTextToFramePadding()
return;
ImGuiContext& g = *GImGui;
- window->DC.CurrLineSize.y = ImMax(window->DC.CurrLineSize.y, g.FontSize + g.Style.FramePadding.y * 2);
+ window->DC.CurrLineSize.y = ImMax(window->DC.CurrLineSize.y, g.FontLineHeight + g.Style.FramePadding.y * 2);
window->DC.CurrLineTextBaseOffset = ImMax(window->DC.CurrLineTextBaseOffset, g.Style.FramePadding.y);
}
@@ -1573,7 +1573,7 @@ static float CalcMaxPopupHeightFromItemCount(int items_count)
ImGuiContext& g = *GImGui;
if (items_count <= 0)
return FLT_MAX;
- return (g.FontSize + g.Style.ItemSpacing.y) * items_count - g.Style.ItemSpacing.y + (g.Style.WindowPadding.y * 2);
+ return (g.FontLineHeight + g.Style.ItemSpacing.y) * items_count - g.Style.ItemSpacing.y + (g.Style.WindowPadding.y * 2);
}
bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags)
@@ -3634,8 +3634,8 @@ static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* t
{
ImGuiContext& g = *GImGui;
ImFont* font = g.Font;
- const float line_height = g.FontSize;
- const float scale = line_height / font->FontSize;
+ const float line_height = g.FontLineHeight;
+ const float scale = g.FontSize / font->FontSize;
ImVec2 text_size = ImVec2(0, 0);
float line_width = 0.0f;
@@ -3989,7 +3989,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
BeginGroup();
const ImGuiID id = window->GetID(label);
const ImVec2 label_size = CalcTextSize(label, NULL, true);
- const ImVec2 frame_size = CalcItemSize(size_arg, CalcItemWidth(), (is_multiline ? g.FontSize * 8.0f : label_size.y) + style.FramePadding.y * 2.0f); // Arbitrary default of 8 lines high for multi-line
+ const ImVec2 frame_size = CalcItemSize(size_arg, CalcItemWidth(), (is_multiline ? g.FontLineHeight * 8.0f : label_size.y) + style.FramePadding.y * 2.0f); // Arbitrary default of 8 lines high for multi-line
const ImVec2 total_size = ImVec2(frame_size.x + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), frame_size.y);
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size);
@@ -4195,7 +4195,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// Edit in progress
const float mouse_x = (io.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + state->ScrollX;
- const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y) : (g.FontSize * 0.5f));
+ const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y) : (g.FontLineHeight * 0.5f));
const bool is_osx = io.ConfigMacOSXBehaviors;
if (select_all)
@@ -4294,7 +4294,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
IM_ASSERT(state != NULL);
IM_ASSERT(io.KeyMods == GetMergedKeyModFlags() && "Mismatching io.KeyCtrl/io.KeyShift/io.KeyAlt/io.KeySuper vs io.KeyMods"); // We rarely do this check, but if anything let's do it here.
- const int row_count_per_page = ImMax((int)((inner_size.y - style.FramePadding.y) / g.FontSize), 1);
+ const int row_count_per_page = ImMax((int)((inner_size.y - style.FramePadding.y) / g.FontLineHeight), 1);
state->Stb.row_count_per_page = row_count_per_page;
const int k_mask = (io.KeyShift ? STB_TEXTEDIT_K_SHIFT : 0);
@@ -4319,10 +4319,10 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); }
- else if (IsKeyPressedMap(ImGuiKey_UpArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); }
- else if (IsKeyPressedMap(ImGuiKey_DownArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); }
- else if (IsKeyPressedMap(ImGuiKey_PageUp) && is_multiline) { state->OnKeyPressed(STB_TEXTEDIT_K_PGUP | k_mask); scroll_y -= row_count_per_page * g.FontSize; }
- else if (IsKeyPressedMap(ImGuiKey_PageDown) && is_multiline) { state->OnKeyPressed(STB_TEXTEDIT_K_PGDOWN | k_mask); scroll_y += row_count_per_page * g.FontSize; }
+ else if (IsKeyPressedMap(ImGuiKey_UpArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontLineHeight, 0.0f)); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); }
+ else if (IsKeyPressedMap(ImGuiKey_DownArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontLineHeight, GetScrollMaxY())); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); }
+ else if (IsKeyPressedMap(ImGuiKey_PageUp) && is_multiline) { state->OnKeyPressed(STB_TEXTEDIT_K_PGUP | k_mask); scroll_y -= row_count_per_page * g.FontLineHeight; }
+ else if (IsKeyPressedMap(ImGuiKey_PageDown) && is_multiline) { state->OnKeyPressed(STB_TEXTEDIT_K_PGDOWN | k_mask); scroll_y += row_count_per_page * g.FontLineHeight; }
else if (IsKeyPressedMap(ImGuiKey_Home)) { state->OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_End)) { state->OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Delete) && !is_readonly && !is_cut) { state->OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); }
@@ -4665,16 +4665,16 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// Calculate 2d position by finding the beginning of the line and measuring distance
cursor_offset.x = InputTextCalcTextSizeW(ImStrbolW(searches_input_ptr[0], text_begin), searches_input_ptr[0]).x;
- cursor_offset.y = searches_result_line_no[0] * g.FontSize;
+ cursor_offset.y = searches_result_line_no[0] * g.FontLineHeight;
if (searches_result_line_no[1] >= 0)
{
select_start_offset.x = InputTextCalcTextSizeW(ImStrbolW(searches_input_ptr[1], text_begin), searches_input_ptr[1]).x;
- select_start_offset.y = searches_result_line_no[1] * g.FontSize;
+ select_start_offset.y = searches_result_line_no[1] * g.FontLineHeight;
}
// Store text height (note that we haven't calculated text width at all, see GitHub issues #383, #1224)
if (is_multiline)
- text_size = ImVec2(inner_size.x, line_count * g.FontSize);
+ text_size = ImVec2(inner_size.x, line_count * g.FontLineHeight);
}
// Scroll
@@ -4699,8 +4699,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if (is_multiline)
{
// Test if cursor is vertically visible
- if (cursor_offset.y - g.FontSize < scroll_y)
- scroll_y = ImMax(0.0f, cursor_offset.y - g.FontSize);
+ if (cursor_offset.y - g.FontLineHeight < scroll_y)
+ scroll_y = ImMax(0.0f, cursor_offset.y - g.FontLineHeight);
else if (cursor_offset.y - (inner_size.y - style.FramePadding.y * 2.0f) >= scroll_y)
scroll_y = cursor_offset.y - inner_size.y + style.FramePadding.y * 2.0f;
const float scroll_max_y = ImMax((text_size.y + style.FramePadding.y * 2.0f) - inner_size.y, 0.0f);
@@ -4725,7 +4725,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
ImVec2 rect_pos = draw_pos + select_start_offset - draw_scroll;
for (const ImWchar* p = text_selected_begin; p < text_selected_end; )
{
- if (rect_pos.y > clip_rect.w + g.FontSize)
+ if (rect_pos.y > clip_rect.w + g.FontLineHeight)
break;
if (rect_pos.y < clip_rect.y)
{
@@ -4739,13 +4739,13 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
{
ImVec2 rect_size = InputTextCalcTextSizeW(p, text_selected_end, &p, NULL, true);
if (rect_size.x <= 0.0f) rect_size.x = IM_FLOOR(g.Font->GetCharAdvance((ImWchar)' ') * 0.50f); // So we can see selected empty lines
- ImRect rect(rect_pos + ImVec2(0.0f, bg_offy_up - g.FontSize), rect_pos + ImVec2(rect_size.x, bg_offy_dn));
+ ImRect rect(rect_pos + ImVec2(0.0f, bg_offy_up - g.FontLineHeight), rect_pos + ImVec2(rect_size.x, bg_offy_dn));
rect.ClipWith(clip_rect);
if (rect.Overlaps(clip_rect))
draw_window->DrawList->AddRectFilled(rect.Min, rect.Max, bg_color);
}
rect_pos.x = draw_pos.x - draw_scroll.x;
- rect_pos.y += g.FontSize;
+ rect_pos.y += g.FontLineHeight;
}
}
@@ -4753,7 +4753,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length)
{
ImU32 col = GetColorU32(is_displaying_hint ? ImGuiCol_TextDisabled : ImGuiCol_Text);
- draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos - draw_scroll, col, buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect);
+ draw_window->DrawList->AddText(g.Font, g.FontSize, g.FontLineHeight, g.FontBaselineOffset, draw_pos - draw_scroll, col, buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect);
}
// Draw blinking cursor
@@ -4762,23 +4762,20 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
state->CursorAnim += io.DeltaTime;
bool cursor_is_visible = (!g.IO.ConfigInputTextCursorBlink) || (state->CursorAnim <= 0.0f) || ImFmod(state->CursorAnim, 1.20f) <= 0.80f;
ImVec2 cursor_screen_pos = ImFloor(draw_pos + cursor_offset - draw_scroll);
- ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y - g.FontSize + 0.5f, cursor_screen_pos.x + 1.0f, cursor_screen_pos.y - 1.5f);
+ ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y - g.FontLineHeight + 0.5f, cursor_screen_pos.x + 1.0f, cursor_screen_pos.y - g.FontLineHeight+ g.FontLineHeight - 1.5f);
if (cursor_is_visible && cursor_screen_rect.Overlaps(clip_rect))
draw_window->DrawList->AddLine(cursor_screen_rect.Min, cursor_screen_rect.GetBL(), GetColorU32(ImGuiCol_Text));
// Notify OS of text input position for advanced IME (-1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.)
if (!is_readonly)
- {
- g.PlatformImePos = ImVec2(cursor_screen_pos.x - 1, cursor_screen_pos.y - g.FontSize);
- g.PlatformImePosViewport = window->Viewport;
- }
+ g.PlatformImePos = ImVec2(cursor_screen_pos.x - 1.0f, cursor_screen_pos.y - g.FontLineHeight);
}
}
else
{
// Render text only (no selection, no cursor)
if (is_multiline)
- text_size = ImVec2(inner_size.x, InputTextCalcTextLenAndLineCount(buf_display, &buf_display_end) * g.FontSize); // We don't need width
+ text_size = ImVec2(inner_size.x, InputTextCalcTextLenAndLineCount(buf_display, &buf_display_end) * g.FontLineHeight); // We don't need width
else if (!is_displaying_hint && g.ActiveId == id)
buf_display_end = buf_display + state->CurLenA;
else if (!is_displaying_hint)
@@ -4787,7 +4784,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length)
{
ImU32 col = GetColorU32(is_displaying_hint ? ImGuiCol_TextDisabled : ImGuiCol_Text);
- draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos, col, buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect);
+ draw_window->DrawList->AddText(g.Font, g.FontSize, g.FontLineHeight, g.FontBaselineOffset, draw_pos, col, buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect);
}
}
@@ -5625,7 +5622,7 @@ void ImGui::ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags
Separator();
}
- ImVec2 sz(g.FontSize * 3 + g.Style.FramePadding.y * 2, g.FontSize * 3 + g.Style.FramePadding.y * 2);
+ ImVec2 sz(g.FontSize * 3 + g.Style.FramePadding.y * 2, g.FontLineHeight * 3 + g.Style.FramePadding.y * 2);
ImVec4 cf(col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]);
int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]);
ColorButton("##preview", cf, (flags & (ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf)) | ImGuiColorEditFlags_NoTooltip, sz);
@@ -5707,7 +5704,7 @@ void ImGui::ColorPickerOptionsPopup(const float* ref_col, ImGuiColorEditFlags fl
ImGuiContext& g = *GImGui;
if (allow_opt_picker)
{
- ImVec2 picker_size(g.FontSize * 8, ImMax(g.FontSize * 8 - (GetFrameHeight() + g.Style.ItemInnerSpacing.x), 1.0f)); // FIXME: Picker size copied from main picker function
+ ImVec2 picker_size(g.FontSize * 8, ImMax(g.FontLineHeight * 8 - (GetFrameHeight() + g.Style.ItemInnerSpacing.x), 1.0f)); // FIXME: Picker size copied from main picker function
PushItemWidth(picker_size.x);
for (int picker_type = 0; picker_type < 2; picker_type++)
{
@@ -5898,7 +5895,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
const ImVec2 label_size = CalcTextSize(label, label_end, false);
// We vertically grow up to current line height up the typical widget height.
- const float frame_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + style.FramePadding.y * 2), label_size.y + padding.y * 2);
+ const float frame_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontLineHeight + style.FramePadding.y * 2), label_size.y + padding.y * 2);
ImRect frame_bb;
frame_bb.Min.x = (flags & ImGuiTreeNodeFlags_SpanFullWidth) ? window->WorkRect.Min.x : window->DC.CursorPos.x;
frame_bb.Min.y = window->DC.CursorPos.y;
@@ -5912,9 +5909,9 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
frame_bb.Max.x += IM_FLOOR(window->WindowPadding.x * 0.5f);
}
- const float text_offset_x = g.FontSize + (display_frame ? padding.x * 3 : padding.x * 2); // Collapser arrow width + Spacing
+ const float text_offset_x = g.FontLineHeight + (display_frame ? padding.x * 3 : padding.x * 2); // Collapser arrow width + Spacing
const float text_offset_y = ImMax(padding.y, window->DC.CurrLineTextBaseOffset); // Latch before ItemSize changes it
- const float text_width = g.FontSize + (label_size.x > 0.0f ? label_size.x + padding.x * 2 : 0.0f); // Include collapser
+ const float text_width = g.FontLineHeight + (label_size.x > 0.0f ? label_size.x + padding.x * 2 : 0.0f); // Include collapser
ImVec2 text_pos(window->DC.CursorPos.x + text_offset_x, window->DC.CursorPos.y + text_offset_y);
ItemSize(ImVec2(text_width, frame_height), padding.y);
@@ -6033,7 +6030,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
RenderFrame(frame_bb.Min, frame_bb.Max, bg_col, true, style.FrameRounding);
RenderNavHighlight(frame_bb, id, nav_highlight_flags);
if (flags & ImGuiTreeNodeFlags_Bullet)
- RenderBullet(window->DrawList, ImVec2(text_pos.x - text_offset_x * 0.60f, text_pos.y + g.FontSize * 0.5f), text_col);
+ RenderBullet(window->DrawList, ImVec2(text_pos.x - text_offset_x * 0.60f, text_pos.y + g.FontLineHeight * 0.5f), text_col);
else if (!is_leaf)
RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y), text_col, is_open ? ImGuiDir_Down : ImGuiDir_Right, 1.0f);
else // Leaf without bullet, left-adjusted text
@@ -6055,9 +6052,9 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
}
RenderNavHighlight(frame_bb, id, nav_highlight_flags);
if (flags & ImGuiTreeNodeFlags_Bullet)
- RenderBullet(window->DrawList, ImVec2(text_pos.x - text_offset_x * 0.5f, text_pos.y + g.FontSize * 0.5f), text_col);
+ RenderBullet(window->DrawList, ImVec2(text_pos.x - text_offset_x * 0.5f, text_pos.y + g.FontLineHeight * 0.5f), text_col);
else if (!is_leaf)
- RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y + g.FontSize * 0.15f), text_col, is_open ? ImGuiDir_Down : ImGuiDir_Right, 0.70f);
+ RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y + g.FontLineHeight * 0.15f), text_col, is_open ? ImGuiDir_Down : ImGuiDir_Right, 0.70f);
if (g.LogEnabled)
LogSetNextTextDecoration(">", NULL);
RenderText(text_pos, label, label_end, false);
@@ -6170,7 +6167,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFl
// FIXME: CloseButton can overlap into text, need find a way to clip the text somehow.
ImGuiContext& g = *GImGui;
ImGuiLastItemData last_item_backup = g.LastItemData;
- float button_size = g.FontSize;
+ float button_size = g.FontLineHeight;
float button_x = ImMax(g.LastItemData.Rect.Min.x, g.LastItemData.Rect.Max.x - g.Style.FramePadding.x * 2.0f - button_size);
float button_y = g.LastItemData.Rect.Min.y;
ImGuiID close_button_id = GetIDWithSeed("#CLOSE", NULL, id);
@@ -6998,7 +6995,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
ImGuiWindow* child_menu_window = (g.BeginPopupStack.Size < g.OpenPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].SourceWindow == window) ? g.OpenPopupStack[g.BeginPopupStack.Size].Window : NULL;
if (g.HoveredWindow == window && child_menu_window != NULL && !(window->Flags & ImGuiWindowFlags_MenuBar))
{
- float ref_unit = g.FontSize; // FIXME-DPI
+ float ref_unit = g.FontLineHeight; // FIXME-DPI
ImRect next_window_rect = child_menu_window->Rect();
ImVec2 ta = (g.IO.MousePos - g.IO.MouseDelta);
ImVec2 tb = (window->Pos.x < child_menu_window->Pos.x) ? next_window_rect.GetTL() : next_window_rect.GetTR();
@@ -7158,7 +7155,7 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut
PopStyleColor();
}
if (selected)
- RenderCheckMark(window->DrawList, pos + ImVec2(offsets->OffsetMark + stretch_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f), GetColorU32(ImGuiCol_Text), g.FontSize * 0.866f);
+ RenderCheckMark(window->DrawList, pos + ImVec2(offsets->OffsetMark + stretch_w + g.FontSize * 0.40f, g.FontLineHeight * 0.134f * 0.5f), GetColorU32(ImGuiCol_Text), g.FontSize * 0.866f);
}
IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (selected ? ImGuiItemStatusFlags_Checked : 0));
if (!enabled)
@@ -7279,7 +7276,7 @@ bool ImGui::BeginTabBar(const char* str_id, ImGuiTabBarFlags flags)
ImGuiID id = window->GetID(str_id);
ImGuiTabBar* tab_bar = g.TabBars.GetOrAddByKey(id);
- ImRect tab_bar_bb = ImRect(window->DC.CursorPos.x, window->DC.CursorPos.y, window->WorkRect.Max.x, window->DC.CursorPos.y + g.FontSize + g.Style.FramePadding.y * 2);
+ ImRect tab_bar_bb = ImRect(window->DC.CursorPos.x, window->DC.CursorPos.y, window->WorkRect.Max.x, window->DC.CursorPos.y + g.FontLineHeight + g.Style.FramePadding.y * 2);
tab_bar->ID = id;
return BeginTabBarEx(tab_bar, tab_bar_bb, flags | ImGuiTabBarFlags_IsFocused, NULL);
}
@@ -7605,9 +7602,9 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
{
// Scrolling speed adjust itself so we can always reach our target in 1/3 seconds.
// Teleport if we are aiming far off the visible line
- tab_bar->ScrollingSpeed = ImMax(tab_bar->ScrollingSpeed, 70.0f * g.FontSize);
+ tab_bar->ScrollingSpeed = ImMax(tab_bar->ScrollingSpeed, 70.0f * g.FontLineHeight);
tab_bar->ScrollingSpeed = ImMax(tab_bar->ScrollingSpeed, ImFabs(tab_bar->ScrollingTarget - tab_bar->ScrollingAnim) / 0.3f);
- const bool teleport = (tab_bar->PrevFrameVisible + 1 < g.FrameCount) || (tab_bar->ScrollingTargetDistToVisibility > 10.0f * g.FontSize);
+ const bool teleport = (tab_bar->PrevFrameVisible + 1 < g.FrameCount) || (tab_bar->ScrollingTargetDistToVisibility > 10.0f * g.FontLineHeight);
tab_bar->ScrollingAnim = teleport ? tab_bar->ScrollingTarget : ImLinearSweep(tab_bar->ScrollingAnim, tab_bar->ScrollingTarget, g.IO.DeltaTime * tab_bar->ScrollingSpeed);
}
else
@@ -7846,7 +7843,7 @@ static ImGuiTabItem* ImGui::TabBarScrollingButtons(ImGuiTabBar* tab_bar)
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
- const ImVec2 arrow_button_size(g.FontSize - 2.0f, g.FontSize + g.Style.FramePadding.y * 2.0f);
+ const ImVec2 arrow_button_size(g.FontSize - 2.0f, g.FontLineHeight + g.Style.FramePadding.y * 2.0f);
const float scrolling_buttons_width = arrow_button_size.x * 2.0f;
const ImVec2 backup_cursor_pos = window->DC.CursorPos;
@@ -7908,7 +7905,7 @@ static ImGuiTabItem* ImGui::TabBarTabListPopupButton(ImGuiTabBar* tab_bar)
ImGuiWindow* window = g.CurrentWindow;
// We use g.Style.FramePadding.y to match the square ArrowButton size
- const float tab_list_popup_button_width = g.FontSize + g.Style.FramePadding.y;
+ const float tab_list_popup_button_width = g.FontLineHeight + g.Style.FramePadding.y;
const ImVec2 backup_cursor_pos = window->DC.CursorPos;
window->DC.CursorPos = ImVec2(tab_bar->BarRect.Min.x - g.Style.FramePadding.y, tab_bar->BarRect.Min.y);
tab_bar->BarRect.Min.x += tab_list_popup_button_width;