diff options
author | Bartosz Taudul <wolf@nereid.pl> | 2021-12-23 16:17:01 +0300 |
---|---|---|
committer | Bartosz Taudul <wolf@nereid.pl> | 2021-12-23 16:17:01 +0300 |
commit | e822dde7e13d228ddb69592659a7c42d4b862825 (patch) | |
tree | b46e0c5fd1cc8e264c0664d11e4bedf20d3bd193 /imgui/imgui.cpp | |
parent | b83cda575a3f650752e3d35cd8263c8ae8552e1a (diff) |
Merge thedmd/feature/font-line-spacing into ImGui.
Diffstat (limited to 'imgui/imgui.cpp')
-rw-r--r-- | imgui/imgui.cpp | 79 |
1 files changed, 51 insertions, 28 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(); |