Created
August 13, 2021 11:01
-
-
Save Youlean/f3885098d95826e83d04bfb19c738265 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void IGraphics::DrawMultilineText(const IText& text, const char* str, const IRECT& bounds, float lineHeight, const IBlend* pBlend) | |
{ | |
auto CreateTextLinesVector = [&](const IText& textProps, const std::string& multiLineText, const IRECT& rect, std::vector<std::string> &textLines) | |
{ | |
IRECT textRect; | |
textLines.resize(0); | |
textLines.push_back(std::string()); | |
double stringSize = 0; | |
std::string tmpString; | |
double tmpStringSize = 0; | |
int nestedTabs = 0; | |
// Find space or new line or tab | |
for (int i = 0; i < multiLineText.size(); i++) | |
{ | |
std::string c; | |
c.reserve(multiLineText.size()); | |
c.push_back(multiLineText[i]); | |
if (c.back() == ' ') | |
{ | |
if (stringSize + tmpStringSize > rect.W()) | |
{ | |
textLines.push_back(std::string()); | |
stringSize = 0; | |
for (int j = 0; j < nestedTabs; j++) | |
{ | |
float textAdvance = MeasureText(textProps, " ", textRect); | |
stringSize += textAdvance; | |
textLines.back().append(" "); | |
} | |
} | |
textLines.back().append(tmpString); | |
stringSize += tmpStringSize; | |
tmpString.resize(0); | |
tmpStringSize = 0; | |
float textAdvance = MeasureText(textProps, c.c_str(), textRect); | |
stringSize += textAdvance; | |
if (stringSize <= rect.W()) | |
textLines.back().append(" "); | |
} | |
else if (c.back() == '\t') | |
{ | |
bool checkNestedTabs = false; | |
if (i == 0) | |
{ | |
checkNestedTabs = true; | |
} | |
else if (i > 0) | |
{ | |
if (multiLineText[i - 1] == '\n') | |
checkNestedTabs = true; | |
else | |
checkNestedTabs = false; | |
} | |
if (checkNestedTabs) | |
{ | |
for (int j = i; j < multiLineText.size(); j++) | |
{ | |
if (multiLineText[j] == '\t') nestedTabs++; | |
else break; | |
} | |
} | |
if (stringSize + tmpStringSize > rect.W()) | |
{ | |
textLines.push_back(std::string()); | |
stringSize = 0; | |
} | |
textLines.back().append(tmpString); | |
stringSize += tmpStringSize; | |
tmpString.resize(0); | |
tmpStringSize = 0; | |
float textAdvance = MeasureText(textProps, " ", textRect); | |
stringSize += textAdvance; | |
if (stringSize <= rect.W()) | |
textLines.back().append(" "); | |
} | |
else if (c.back() == '\n') | |
{ | |
nestedTabs = 0; | |
if (stringSize + tmpStringSize > rect.W()) | |
{ | |
textLines.push_back(std::string()); | |
stringSize = 0; | |
} | |
textLines.back().append(tmpString); | |
stringSize += tmpStringSize; | |
tmpString.resize(0); | |
tmpStringSize = 0; | |
textLines.push_back(std::string()); | |
stringSize = 0; | |
} | |
else | |
{ | |
if (stringSize > rect.W()) | |
{ | |
textLines.push_back(std::string()); | |
stringSize = 0; | |
for (int j = 0; j < nestedTabs; j++) | |
{ | |
float textAdvance = MeasureText(textProps, " ", textRect); | |
stringSize += textAdvance; | |
textLines.back().append(" "); | |
} | |
} | |
float textAdvance = MeasureText(textProps, c.c_str(), textRect); | |
tmpStringSize += textAdvance; | |
tmpString.append(c); | |
} | |
} | |
if (stringSize + tmpStringSize > rect.W()) | |
{ | |
textLines.push_back(std::string()); | |
stringSize = 0; | |
for (int j = 0; j < nestedTabs; j++) | |
{ | |
float textAdvance = MeasureText(textProps, " ", textRect); | |
stringSize += textAdvance; | |
textLines.back().append(" "); | |
} | |
} | |
textLines.back().append(tmpString); | |
}; | |
std::vector<std::string> textStringLines; | |
CreateTextLinesVector(text, str, bounds, textStringLines); | |
IRECT textRectMeasurement; | |
MeasureText(text, "TEXT", textRectMeasurement); | |
float fontHeight = textRectMeasurement.H() * lineHeight; | |
int lineNumber = (int)textStringLines.size(); | |
IText multilineTextProps = text; | |
multilineTextProps.mVAlign = EVAlign::Middle; | |
switch (text.mVAlign) | |
{ | |
case EVAlign::Top: | |
{ | |
for (int i = 0; i < lineNumber; i++) | |
{ | |
IRECT textRect = bounds; | |
textRect.B = bounds.T + (i + 1) * fontHeight; | |
textRect.T = textRect.B - fontHeight; | |
DrawText(multilineTextProps, textStringLines[i].c_str(), textRect, pBlend); | |
} | |
break; | |
} | |
case EVAlign::Bottom: | |
{ | |
for (int i = 0; i < lineNumber; i++) | |
{ | |
int indexInv = (lineNumber - 1) - i; | |
IRECT textRect = bounds; | |
textRect.T = bounds.B - (i + 1) * fontHeight; | |
textRect.B = textRect.T + fontHeight; | |
DrawText(multilineTextProps, textStringLines[indexInv].c_str(), textRect, pBlend); | |
} | |
break; | |
} | |
case EVAlign::Middle: | |
{ | |
for (int i = 0; i < lineNumber; i++) | |
{ | |
float top = (bounds.H() - lineNumber * fontHeight) / 2 + bounds.T; | |
IRECT textRect = bounds; | |
textRect.B = top + (i + 1) * fontHeight; | |
textRect.T = textRect.B - fontHeight; | |
DrawText(multilineTextProps, textStringLines[i].c_str(), textRect, pBlend); | |
} | |
break; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment