mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
Merge pull request #7711 from Robyt3/Textrender-Selection-Fix
Improve text line spacing and console text selection
This commit is contained in:
commit
03ce78f781
|
@ -1268,7 +1268,9 @@ public:
|
||||||
pCursor->m_GlyphCount = 0;
|
pCursor->m_GlyphCount = 0;
|
||||||
pCursor->m_CharCount = 0;
|
pCursor->m_CharCount = 0;
|
||||||
pCursor->m_MaxLines = 0;
|
pCursor->m_MaxLines = 0;
|
||||||
|
|
||||||
pCursor->m_LineSpacing = 0;
|
pCursor->m_LineSpacing = 0;
|
||||||
|
pCursor->m_AlignedLineSpacing = 0;
|
||||||
|
|
||||||
pCursor->m_StartX = x;
|
pCursor->m_StartX = x;
|
||||||
pCursor->m_StartY = y;
|
pCursor->m_StartY = y;
|
||||||
|
@ -1481,7 +1483,7 @@ public:
|
||||||
const float CursorY = round_to_int(pCursor->m_Y * FakeToScreen.y) / FakeToScreen.y;
|
const float CursorY = round_to_int(pCursor->m_Y * FakeToScreen.y) / FakeToScreen.y;
|
||||||
const int ActualSize = round_truncate(pCursor->m_FontSize * FakeToScreen.y);
|
const int ActualSize = round_truncate(pCursor->m_FontSize * FakeToScreen.y);
|
||||||
pCursor->m_AlignedFontSize = ActualSize / FakeToScreen.y;
|
pCursor->m_AlignedFontSize = ActualSize / FakeToScreen.y;
|
||||||
const float LineSpacing = pCursor->m_LineSpacing;
|
pCursor->m_AlignedLineSpacing = round_truncate(pCursor->m_LineSpacing * FakeToScreen.y) / FakeToScreen.y;
|
||||||
|
|
||||||
// string length
|
// string length
|
||||||
if(Length < 0)
|
if(Length < 0)
|
||||||
|
@ -1539,38 +1541,34 @@ public:
|
||||||
const auto &&CheckInsideChar = [&](bool CheckOuter, vec2 CursorPos, float LastCharX, float LastCharWidth, float CharX, float CharWidth, float CharY) -> bool {
|
const auto &&CheckInsideChar = [&](bool CheckOuter, vec2 CursorPos, float LastCharX, float LastCharWidth, float CharX, float CharWidth, float CharY) -> bool {
|
||||||
return (LastCharX - LastCharWidth / 2 <= CursorPos.x &&
|
return (LastCharX - LastCharWidth / 2 <= CursorPos.x &&
|
||||||
CharX + CharWidth / 2 > CursorPos.x &&
|
CharX + CharWidth / 2 > CursorPos.x &&
|
||||||
CharY - pCursor->m_AlignedFontSize - LineSpacing <= CursorPos.y &&
|
CursorPos.y >= CharY - pCursor->m_AlignedFontSize &&
|
||||||
CharY + LineSpacing > CursorPos.y) ||
|
CursorPos.y < CharY + pCursor->m_AlignedLineSpacing) ||
|
||||||
(CheckOuter &&
|
(CheckOuter &&
|
||||||
CharY - pCursor->m_AlignedFontSize + LineSpacing > CursorPos.y);
|
CursorPos.y <= CharY - pCursor->m_AlignedFontSize);
|
||||||
};
|
};
|
||||||
const auto &&CheckSelectionStart = [&](bool CheckOuter, vec2 CursorPos, int &SelectionChar, bool &SelectionUsedCase, float LastCharX, float LastCharWidth, float CharX, float CharWidth, float CharY) {
|
const auto &&CheckSelectionStart = [&](bool CheckOuter, vec2 CursorPos, int &SelectionChar, bool &SelectionUsedCase, float LastCharX, float LastCharWidth, float CharX, float CharWidth, float CharY) {
|
||||||
if(!SelectionStarted && !SelectionUsedCase)
|
if(!SelectionStarted && !SelectionUsedCase &&
|
||||||
|
CheckInsideChar(CheckOuter, CursorPos, LastCharX, LastCharWidth, CharX, CharWidth, CharY))
|
||||||
{
|
{
|
||||||
if(CheckInsideChar(CheckOuter, CursorPos, LastCharX, LastCharWidth, CharX, CharWidth, CharY))
|
SelectionChar = pCursor->m_GlyphCount;
|
||||||
{
|
SelectionStarted = !SelectionStarted;
|
||||||
SelectionChar = pCursor->m_GlyphCount;
|
SelectionUsedCase = true;
|
||||||
SelectionStarted = !SelectionStarted;
|
|
||||||
SelectionUsedCase = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const auto &&CheckOutsideChar = [&](bool CheckOuter, vec2 CursorPos, float CharX, float CharWidth, float CharY) -> bool {
|
const auto &&CheckOutsideChar = [&](bool CheckOuter, vec2 CursorPos, float CharX, float CharWidth, float CharY) -> bool {
|
||||||
return (CharX + CharWidth / 2 > CursorPos.x &&
|
return (CharX + CharWidth / 2 > CursorPos.x &&
|
||||||
CharY - pCursor->m_AlignedFontSize - LineSpacing <= CursorPos.y &&
|
CursorPos.y >= CharY - pCursor->m_AlignedFontSize &&
|
||||||
CharY + LineSpacing > CursorPos.y) ||
|
CursorPos.y < CharY + pCursor->m_AlignedLineSpacing) ||
|
||||||
(CheckOuter &&
|
(CheckOuter &&
|
||||||
CharY - LineSpacing <= CursorPos.y);
|
CursorPos.y >= CharY + pCursor->m_AlignedLineSpacing);
|
||||||
};
|
};
|
||||||
const auto &&CheckSelectionEnd = [&](bool CheckOuter, vec2 CursorPos, int &SelectionChar, bool &SelectionUsedCase, float CharX, float CharWidth, float CharY) {
|
const auto &&CheckSelectionEnd = [&](bool CheckOuter, vec2 CursorPos, int &SelectionChar, bool &SelectionUsedCase, float CharX, float CharWidth, float CharY) {
|
||||||
if(SelectionStarted && !SelectionUsedCase)
|
if(SelectionStarted && !SelectionUsedCase &&
|
||||||
|
CheckOutsideChar(CheckOuter, CursorPos, CharX, CharWidth, CharY))
|
||||||
{
|
{
|
||||||
if(CheckOutsideChar(CheckOuter, CursorPos, CharX, CharWidth, CharY))
|
SelectionChar = pCursor->m_GlyphCount;
|
||||||
{
|
SelectionStarted = !SelectionStarted;
|
||||||
SelectionChar = pCursor->m_GlyphCount;
|
SelectionUsedCase = true;
|
||||||
SelectionStarted = !SelectionStarted;
|
|
||||||
SelectionUsedCase = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1585,7 +1583,7 @@ public:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
DrawX = pCursor->m_StartX;
|
DrawX = pCursor->m_StartX;
|
||||||
DrawY += pCursor->m_AlignedFontSize + pCursor->m_LineSpacing;
|
DrawY += pCursor->m_AlignedFontSize + pCursor->m_AlignedLineSpacing;
|
||||||
if((RenderFlags & TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT) == 0)
|
if((RenderFlags & TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT) == 0)
|
||||||
{
|
{
|
||||||
DrawX = round_to_int(DrawX * FakeToScreen.x) / FakeToScreen.x; // realign
|
DrawX = round_to_int(DrawX * FakeToScreen.x) / FakeToScreen.x; // realign
|
||||||
|
@ -1868,7 +1866,8 @@ public:
|
||||||
|
|
||||||
if(SelectionStarted && IsRendered)
|
if(SelectionStarted && IsRendered)
|
||||||
{
|
{
|
||||||
vSelectionQuads.emplace_back(SelX, DrawY + (1.0f - pCursor->m_SelectionHeightFactor) * pCursor->m_AlignedFontSize, SelWidth, pCursor->m_SelectionHeightFactor * pCursor->m_AlignedFontSize);
|
const float SelectionHeight = pCursor->m_AlignedFontSize + pCursor->m_AlignedLineSpacing;
|
||||||
|
vSelectionQuads.emplace_back(SelX, DrawY + (1.0f - pCursor->m_SelectionHeightFactor) * SelectionHeight, SelWidth, pCursor->m_SelectionHeightFactor * SelectionHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
LastSelX = SelX;
|
LastSelX = SelX;
|
||||||
|
@ -1957,9 +1956,9 @@ public:
|
||||||
if(TextContainer.m_StringInfo.m_SelectionQuadContainerIndex == -1)
|
if(TextContainer.m_StringInfo.m_SelectionQuadContainerIndex == -1)
|
||||||
TextContainer.m_StringInfo.m_SelectionQuadContainerIndex = Graphics()->CreateQuadContainer(false);
|
TextContainer.m_StringInfo.m_SelectionQuadContainerIndex = Graphics()->CreateQuadContainer(false);
|
||||||
if(HasCursor)
|
if(HasCursor)
|
||||||
Graphics()->QuadContainerAddQuads(TextContainer.m_StringInfo.m_SelectionQuadContainerIndex, aCursorQuads, 2);
|
Graphics()->QuadContainerAddQuads(TextContainer.m_StringInfo.m_SelectionQuadContainerIndex, aCursorQuads, std::size(aCursorQuads));
|
||||||
if(HasSelection)
|
if(HasSelection)
|
||||||
Graphics()->QuadContainerAddQuads(TextContainer.m_StringInfo.m_SelectionQuadContainerIndex, vSelectionQuads.data(), (int)vSelectionQuads.size());
|
Graphics()->QuadContainerAddQuads(TextContainer.m_StringInfo.m_SelectionQuadContainerIndex, vSelectionQuads.data(), vSelectionQuads.size());
|
||||||
Graphics()->QuadContainerUpload(TextContainer.m_StringInfo.m_SelectionQuadContainerIndex);
|
Graphics()->QuadContainerUpload(TextContainer.m_StringInfo.m_SelectionQuadContainerIndex);
|
||||||
|
|
||||||
TextContainer.m_HasCursor = HasCursor;
|
TextContainer.m_HasCursor = HasCursor;
|
||||||
|
|
|
@ -212,6 +212,7 @@ public:
|
||||||
float m_FontSize;
|
float m_FontSize;
|
||||||
float m_AlignedFontSize;
|
float m_AlignedFontSize;
|
||||||
float m_LineSpacing;
|
float m_LineSpacing;
|
||||||
|
float m_AlignedLineSpacing;
|
||||||
|
|
||||||
ETextCursorSelectionMode m_CalculateSelectionMode;
|
ETextCursorSelectionMode m_CalculateSelectionMode;
|
||||||
float m_SelectionHeightFactor;
|
float m_SelectionHeightFactor;
|
||||||
|
@ -237,7 +238,7 @@ public:
|
||||||
|
|
||||||
float Height() const
|
float Height() const
|
||||||
{
|
{
|
||||||
return m_LineCount * m_AlignedFontSize + std::max(0, m_LineCount - 1) * m_LineSpacing;
|
return m_LineCount * (m_AlignedFontSize + m_AlignedLineSpacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
STextBoundingBox BoundingBox() const
|
STextBoundingBox BoundingBox() const
|
||||||
|
|
|
@ -575,7 +575,7 @@ void CGameConsole::CInstance::UpdateEntryTextAttributes(CBacklogEntry *pEntry) c
|
||||||
Cursor.m_MaxLines = 10;
|
Cursor.m_MaxLines = 10;
|
||||||
Cursor.m_LineSpacing = LINE_SPACING;
|
Cursor.m_LineSpacing = LINE_SPACING;
|
||||||
m_pGameConsole->TextRender()->TextEx(&Cursor, pEntry->m_aText, -1);
|
m_pGameConsole->TextRender()->TextEx(&Cursor, pEntry->m_aText, -1);
|
||||||
pEntry->m_YOffset = Cursor.Height() + LINE_SPACING;
|
pEntry->m_YOffset = Cursor.Height();
|
||||||
pEntry->m_LineCount = Cursor.m_LineCount;
|
pEntry->m_LineCount = Cursor.m_LineCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -909,9 +909,9 @@ void CGameConsole::OnRender()
|
||||||
|
|
||||||
{
|
{
|
||||||
// Get height of 1 line
|
// Get height of 1 line
|
||||||
float LineHeight = TextRender()->TextBoundingBox(FONT_SIZE, " ", -1, -1, LINE_SPACING).m_H + LINE_SPACING;
|
float LineHeight = TextRender()->TextBoundingBox(FONT_SIZE, " ", -1, -1, LINE_SPACING).m_H;
|
||||||
|
|
||||||
float RowHeight = FONT_SIZE * 1.25f;
|
float RowHeight = FONT_SIZE * 1.5f;
|
||||||
float x = 3;
|
float x = 3;
|
||||||
float y = ConsoleHeight - RowHeight - 5.0f;
|
float y = ConsoleHeight - RowHeight - 5.0f;
|
||||||
|
|
||||||
|
@ -1104,8 +1104,7 @@ void CGameConsole::OnRender()
|
||||||
|
|
||||||
if(First)
|
if(First)
|
||||||
{
|
{
|
||||||
int Diff = pConsole->m_BacklogLastActiveLine - SkippedLines;
|
OffsetY -= (pConsole->m_BacklogLastActiveLine - SkippedLines) * LineHeight;
|
||||||
OffsetY -= Diff * LineHeight - LINE_SPACING;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float LocalOffsetY = OffsetY + pEntry->m_YOffset / (float)pEntry->m_LineCount;
|
float LocalOffsetY = OffsetY + pEntry->m_YOffset / (float)pEntry->m_LineCount;
|
||||||
|
|
Loading…
Reference in a new issue