From 9693d4beaca66204c8b9da77b378236b12708ccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Sun, 9 Apr 2023 17:28:58 +0200 Subject: [PATCH] Fix vertical centering of multi-line UI labels Also calculate text height in `TextWidth`. Use calculated text height to verically center UI labels. The text cursor flags (in particular, the `TEXTFLAG_STOP_AT_END` flag) must also be passed to `TextWidth`. Otherwise, for example, when `TEXTFLAG_STOP_AT_END` is missing, the wrong text height is calculated, as text is rendered over multiple lines instead of stopping at the end of the first line. Closes #5396. --- src/engine/client/text.cpp | 10 +++++---- src/engine/textrender.h | 2 +- src/game/client/components/menus_settings.cpp | 3 +-- src/game/client/ui.cpp | 22 ++++++++++--------- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/engine/client/text.cpp b/src/engine/client/text.cpp index d75f9d1c1..6572c30fa 100644 --- a/src/engine/client/text.cpp +++ b/src/engine/client/text.cpp @@ -831,18 +831,20 @@ public: SetRenderFlags(OldRenderFlags); } - float TextWidth(float Size, const char *pText, int StrLength, float LineWidth, float *pAlignedHeight = nullptr, float *pMaxCharacterHeightInLine = nullptr) override + float TextWidth(float Size, const char *pText, int StrLength, float LineWidth, int Flags = 0, float *pHeight = nullptr, float *pAlignedFontSize = nullptr, float *pMaxCharacterHeightInLine = nullptr) override { CTextCursor Cursor; - SetCursor(&Cursor, 0, 0, Size, 0); + SetCursor(&Cursor, 0, 0, Size, Flags); Cursor.m_LineWidth = LineWidth; const unsigned OldRenderFlags = m_RenderFlags; if(LineWidth <= 0) SetRenderFlags(OldRenderFlags | ETextRenderFlags::TEXT_RENDER_FLAG_NO_FIRST_CHARACTER_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_LAST_CHARACTER_ADVANCE); TextEx(&Cursor, pText, StrLength); SetRenderFlags(OldRenderFlags); - if(pAlignedHeight != nullptr) - *pAlignedHeight = Cursor.m_AlignedFontSize; + if(pHeight != nullptr) + *pHeight = Cursor.Height(); + if(pAlignedFontSize != nullptr) + *pAlignedFontSize = Cursor.m_AlignedFontSize; if(pMaxCharacterHeightInLine != nullptr) *pMaxCharacterHeightInLine = Cursor.m_MaxCharacterHeight; return Cursor.m_LongestLineWidth; diff --git a/src/engine/textrender.h b/src/engine/textrender.h index ebfddc33a..956d3d2a5 100644 --- a/src/engine/textrender.h +++ b/src/engine/textrender.h @@ -229,7 +229,7 @@ public: virtual void TextSelectionColor(float r, float g, float b, float a) = 0; virtual void TextSelectionColor(ColorRGBA rgb) = 0; virtual void Text(float x, float y, float Size, const char *pText, float LineWidth) = 0; - virtual float TextWidth(float Size, const char *pText, int StrLength, float LineWidth, float *pAlignedHeight = nullptr, float *pMaxCharacterHeightInLine = nullptr) = 0; + virtual float TextWidth(float Size, const char *pText, int StrLength, float LineWidth, int Flags = 0, float *pHeight = nullptr, float *pAlignedFontSize = nullptr, float *pMaxCharacterHeightInLine = nullptr) = 0; virtual int TextLineCount(float Size, const char *pText, float LineWidth) = 0; virtual ColorRGBA GetTextColor() const = 0; diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index 08a003301..e61f756c3 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -862,8 +862,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView) OriginalRect.VSplitLeft(60.0f, 0, &Label); { SLabelProperties Props; - Props.m_MaxWidth = Label.w; - Props.m_AlignVertically = 0; + Props.m_MaxWidth = Label.w - 5.0f; UI()->DoLabel(&Label, pSkinToBeDraw->GetName(), 12.0f, TEXTALIGN_LEFT, Props); } if(g_Config.m_Debug) diff --git a/src/game/client/ui.cpp b/src/game/client/ui.cpp index 427e6c2d7..4344df349 100644 --- a/src/game/client/ui.cpp +++ b/src/game/client/ui.cpp @@ -519,10 +519,12 @@ void CUI::DoSmoothScrollLogic(float *pScrollOffset, float *pScrollOffsetChange, void CUI::DoLabel(const CUIRect *pRect, const char *pText, float Size, int Align, const SLabelProperties &LabelProps) { + int Flags = LabelProps.m_StopAtEnd ? TEXTFLAG_STOP_AT_END : 0; + float TextHeight = 0.0f; float AlignedFontSize = 0.0f; float MaxCharacterHeightInLine = 0.0f; float MaxTextWidth = LabelProps.m_MaxWidth != -1 ? LabelProps.m_MaxWidth : pRect->w; - float TextWidth = TextRender()->TextWidth(Size, pText, -1, LabelProps.m_MaxWidth, &AlignedFontSize, &MaxCharacterHeightInLine); + float TextWidth = TextRender()->TextWidth(Size, pText, -1, LabelProps.m_MaxWidth, Flags, &TextHeight, &AlignedFontSize, &MaxCharacterHeightInLine); while(TextWidth > MaxTextWidth + 0.001f) { if(!LabelProps.m_EnableWidthCheck) @@ -530,7 +532,7 @@ void CUI::DoLabel(const CUIRect *pRect, const char *pText, float Size, int Align if(Size < 4.0f) break; Size -= 1.0f; - TextWidth = TextRender()->TextWidth(Size, pText, -1, LabelProps.m_MaxWidth, &AlignedFontSize, &MaxCharacterHeightInLine); + TextWidth = TextRender()->TextWidth(Size, pText, -1, LabelProps.m_MaxWidth, Flags, &TextHeight, &AlignedFontSize, &MaxCharacterHeightInLine); } float CursorX = 0.0f; @@ -547,15 +549,14 @@ void CUI::DoLabel(const CUIRect *pRect, const char *pText, float Size, int Align CursorX = pRect->x + pRect->w - TextWidth; } - float CursorY = pRect->y + (pRect->h - AlignedFontSize) / 2.f; + float CursorY = pRect->y + (pRect->h - TextHeight) / 2.f; if(LabelProps.m_AlignVertically == 0) { CursorY = pRect->y + (pRect->h - AlignedFontSize) / 2.f - (AlignedFontSize - MaxCharacterHeightInLine) / 2.f; } CTextCursor Cursor; - int Flags = TEXTFLAG_RENDER | (LabelProps.m_StopAtEnd ? TEXTFLAG_STOP_AT_END : 0); - TextRender()->SetCursor(&Cursor, AlignmentHori, AlignmentVert, Size, Flags); + TextRender()->SetCursor(&Cursor, CursorX, CursorY, Size, TEXTFLAG_RENDER | Flags); Cursor.m_LineWidth = (float)LabelProps.m_MaxWidth; if(LabelProps.m_pSelCursor) { @@ -581,10 +582,12 @@ void CUI::DoLabel(const CUIRect *pRect, const char *pText, float Size, int Align void CUI::DoLabel(CUIElement::SUIElementRect &RectEl, const CUIRect *pRect, const char *pText, float Size, int Align, const SLabelProperties &LabelProps, int StrLen, const CTextCursor *pReadCursor) { + int Flags = pReadCursor ? (pReadCursor->m_Flags & ~TEXTFLAG_RENDER) : LabelProps.m_StopAtEnd ? TEXTFLAG_STOP_AT_END : 0; + float TextHeight = 0.0f; float AlignedFontSize = 0.0f; float MaxCharacterHeightInLine = 0.0f; float MaxTextWidth = LabelProps.m_MaxWidth != -1 ? LabelProps.m_MaxWidth : pRect->w; - float TextWidth = TextRender()->TextWidth(Size, pText, -1, LabelProps.m_MaxWidth, &AlignedFontSize, &MaxCharacterHeightInLine); + float TextWidth = TextRender()->TextWidth(Size, pText, -1, LabelProps.m_MaxWidth, Flags, &TextHeight, &AlignedFontSize, &MaxCharacterHeightInLine); while(TextWidth > MaxTextWidth + 0.001f) { if(!LabelProps.m_EnableWidthCheck) @@ -592,7 +595,7 @@ void CUI::DoLabel(CUIElement::SUIElementRect &RectEl, const CUIRect *pRect, cons if(Size < 4.0f) break; Size -= 1.0f; - TextWidth = TextRender()->TextWidth(Size, pText, -1, LabelProps.m_MaxWidth, &AlignedFontSize, &MaxCharacterHeightInLine); + TextWidth = TextRender()->TextWidth(Size, pText, -1, LabelProps.m_MaxWidth, Flags, &TextHeight, &AlignedFontSize, &MaxCharacterHeightInLine); } float CursorX = 0; @@ -609,7 +612,7 @@ void CUI::DoLabel(CUIElement::SUIElementRect &RectEl, const CUIRect *pRect, cons CursorX = pRect->x + pRect->w - TextWidth; } - float CursorY = pRect->y + (pRect->h - AlignedFontSize) / 2.f; + float CursorY = pRect->y + (pRect->h - TextHeight) / 2.f; if(LabelProps.m_AlignVertically == 0) { CursorY = pRect->y + (pRect->h - AlignedFontSize) / 2.f - (AlignedFontSize - MaxCharacterHeightInLine) / 2.f; @@ -622,8 +625,7 @@ void CUI::DoLabel(CUIElement::SUIElementRect &RectEl, const CUIRect *pRect, cons } else { - int Flags = TEXTFLAG_RENDER | (LabelProps.m_StopAtEnd ? TEXTFLAG_STOP_AT_END : 0); - TextRender()->SetCursor(&Cursor, CursorX, CursorY, Size, Flags); + TextRender()->SetCursor(&Cursor, CursorX, CursorY, Size, TEXTFLAG_RENDER | Flags); } Cursor.m_LineWidth = LabelProps.m_MaxWidth;