diff --git a/src/engine/client/text.cpp b/src/engine/client/text.cpp index 681dbd04e..3288198c6 100644 --- a/src/engine/client/text.cpp +++ b/src/engine/client/text.cpp @@ -1058,6 +1058,10 @@ public: const char *pCurrent = (char *)pText; const char *pEnd = pCurrent + Length; + const char *pEllipsis = "…"; + SFontSizeChar *pEllipsisChr = nullptr; + if(pCursor->m_Flags & TEXTFLAG_ELLIPSIS_AT_END) + pEllipsisChr = GetChar(TextContainer.m_pFont, pSizeData, 0x2026); // … int RenderFlags = TextContainer.m_RenderFlags; @@ -1164,7 +1168,7 @@ public: pCursor->m_CursorCharacter = -1; } - while(pCurrent < pEnd && (pCursor->m_MaxLines < 1 || LineCount <= pCursor->m_MaxLines)) + while(pCurrent != pEllipsis && pCurrent < pEnd && (pCursor->m_MaxLines < 1 || LineCount <= pCursor->m_MaxLines)) { int NewLine = 0; const char *pBatchEnd = pEnd; @@ -1213,11 +1217,11 @@ public: const char *pTmp = pCurrent; int NextCharacter = str_utf8_decode(&pTmp); - while(pCurrent < pBatchEnd) + while(pCurrent < pBatchEnd && pCurrent != pEllipsis) { pCursor->m_CharCount += pTmp - pCurrent; - int Character = NextCharacter; pCurrent = pTmp; + int Character = NextCharacter; NextCharacter = str_utf8_decode(&pTmp); if(Character == '\n') @@ -1243,7 +1247,32 @@ public: CharKerning = Kerning(TextContainer.m_pFont, LastCharGlyphIndex, pChr->m_GlyphIndex) * Scale * Size; LastCharGlyphIndex = pChr->m_GlyphIndex; - if(pCursor->m_Flags & TEXTFLAG_STOP_AT_END && (DrawX + CharKerning) + Advance - pCursor->m_StartX > pCursor->m_LineWidth) + if(pCursor->m_Flags & TEXTFLAG_ELLIPSIS_AT_END && pCurrent < pBatchEnd && pCurrent != pEllipsis) + { + if(pEllipsisChr) + { + float AdvanceEllipsis = ((((RenderFlags & TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH) != 0) ? (pEllipsisChr->m_Width) : (pEllipsisChr->m_AdvanceX + ((!ApplyBearingX) ? (-pEllipsisChr->m_OffsetX) : 0.f)))) * Scale * Size; + float CharKerningEllipsis = 0.f; + if((RenderFlags & TEXT_RENDER_FLAG_KERNING) != 0) + CharKerningEllipsis = Kerning(TextContainer.m_pFont, pChr->m_GlyphIndex, pEllipsisChr->m_GlyphIndex) * Scale * Size; + + if(DrawX + CharKerning + Advance + CharKerningEllipsis + AdvanceEllipsis - pCursor->m_StartX > pCursor->m_LineWidth) + { + // we hit the end, only render ellipsis and finish + pTmp = pEllipsis; + NextCharacter = 0x2026; + continue; + } + } + else + { + // no ellipsis char in font, just stop + pCurrent = pEnd; + break; + } + } + + if(pCursor->m_Flags & TEXTFLAG_STOP_AT_END && DrawX + CharKerning + Advance - pCursor->m_StartX > pCursor->m_LineWidth) { // we hit the end of the line, no more to render or count pCurrent = pEnd; diff --git a/src/engine/textrender.h b/src/engine/textrender.h index e1d04e706..9608c7002 100644 --- a/src/engine/textrender.h +++ b/src/engine/textrender.h @@ -12,7 +12,8 @@ enum { TEXTFLAG_RENDER = 1, TEXTFLAG_ALLOW_NEWLINE = 2, - TEXTFLAG_STOP_AT_END = 4 + TEXTFLAG_STOP_AT_END = 4, + TEXTFLAG_ELLIPSIS_AT_END = 8, }; enum ETextAlignment diff --git a/src/game/client/components/hud.cpp b/src/game/client/components/hud.cpp index 5a8a58d71..401980a6d 100644 --- a/src/game/client/components/hud.cpp +++ b/src/game/client/components/hud.cpp @@ -441,10 +441,8 @@ void CHud::RenderScoreHud() if(m_aScoreInfo[t].m_OptionalNameTextContainerIndex != -1) TextRender()->DeleteTextContainer(m_aScoreInfo[t].m_OptionalNameTextContainerIndex); - float w = TextRender()->TextWidth(0, 8.0f, pName, -1, -1.0f); - CTextCursor Cursor; - TextRender()->SetCursor(&Cursor, minimum(m_Width - w - 1.0f, m_Width - ScoreWidthMax - ImageSize - 2 * Split - PosSize), StartY + (t + 1) * 20.0f - 2.0f, 8.0f, TEXTFLAG_RENDER); + TextRender()->SetCursor(&Cursor, minimum(m_Width - 1.0f, m_Width - ScoreWidthMax - ImageSize - 2 * Split - PosSize), StartY + (t + 1) * 20.0f - 2.0f, 8.0f, TEXTFLAG_RENDER); Cursor.m_LineWidth = -1; m_aScoreInfo[t].m_OptionalNameTextContainerIndex = TextRender()->CreateTextContainer(&Cursor, pName); } diff --git a/src/game/client/components/scoreboard.cpp b/src/game/client/components/scoreboard.cpp index 16ec086c5..45354a5bf 100644 --- a/src/game/client/components/scoreboard.cpp +++ b/src/game/client/components/scoreboard.cpp @@ -470,7 +470,7 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch RenderTools()->RenderTee(pIdleState, &TeeInfo, EMOTE_NORMAL, vec2(1.0f, 0.0f), TeeRenderPos); // name - TextRender()->SetCursor(&Cursor, NameOffset, y + (LineHeight - FontSize) / 2.f, FontSize, TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END); + TextRender()->SetCursor(&Cursor, NameOffset, y + (LineHeight - FontSize) / 2.f, FontSize, TEXTFLAG_RENDER | TEXTFLAG_ELLIPSIS_AT_END); if(m_pClient->m_aClients[pInfo->m_ClientID].m_AuthLevel) { ColorRGBA Color = color_cast(ColorHSLA(g_Config.m_ClAuthedPlayerColor)); @@ -508,7 +508,7 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f); tw = minimum(TextRender()->TextWidth(nullptr, FontSize, m_pClient->m_aClients[pInfo->m_ClientID].m_aClan, -1, -1.0f), ClanLength); - TextRender()->SetCursor(&Cursor, ClanOffset + (ClanLength - tw) / 2, y + (LineHeight - FontSize) / 2.f, FontSize, TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END); + TextRender()->SetCursor(&Cursor, ClanOffset + (ClanLength - tw) / 2, y + (LineHeight - FontSize) / 2.f, FontSize, TEXTFLAG_RENDER | TEXTFLAG_ELLIPSIS_AT_END); Cursor.m_LineWidth = ClanLength; TextRender()->TextEx(&Cursor, m_pClient->m_aClients[pInfo->m_ClientID].m_aClan, -1);