mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-02-16 20:15:38 +00:00
Added support for vertical abbreviations of multiline text entries.
This commit is contained in:
parent
67488467c3
commit
ce217c48a4
|
@ -480,8 +480,10 @@ float Font::getLetterHeight()
|
||||||
return glyph->texSize.y * glyph->texture->textureSize.y;
|
return glyph->texSize.y * glyph->texture->textureSize.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Font::wrapText(std::string text, float xLen)
|
std::string Font::wrapText(std::string text, float maxLength, float maxHeight, float lineSpacing)
|
||||||
{
|
{
|
||||||
|
assert(maxLength != 0.0f);
|
||||||
|
|
||||||
std::string out;
|
std::string out;
|
||||||
std::string line;
|
std::string line;
|
||||||
std::string word;
|
std::string word;
|
||||||
|
@ -490,13 +492,26 @@ std::string Font::wrapText(std::string text, float xLen)
|
||||||
|
|
||||||
size_t space {0};
|
size_t space {0};
|
||||||
glm::vec2 textSize {0.0f, 0.0f};
|
glm::vec2 textSize {0.0f, 0.0f};
|
||||||
float dotsSize {sizeText("...").x};
|
const float dotsSize {sizeText("...").x};
|
||||||
|
const float lineHeight {getHeight(lineSpacing)};
|
||||||
|
float accumHeight {0.0f};
|
||||||
|
const bool restrictHeight {maxHeight > 0.0f};
|
||||||
|
bool skipLastLine {false};
|
||||||
|
|
||||||
// While there's text or we still have text to render.
|
// While there's text or we still have text to render.
|
||||||
while (text.length() > 0) {
|
while (text.length() > 0) {
|
||||||
|
if (restrictHeight && accumHeight > maxHeight)
|
||||||
|
break;
|
||||||
|
|
||||||
space = text.find_first_of(" \t\n");
|
space = text.find_first_of(" \t\n");
|
||||||
if (space == std::string::npos)
|
|
||||||
|
if (space == std::string::npos) {
|
||||||
space = text.length() - 1;
|
space = text.length() - 1;
|
||||||
|
}
|
||||||
|
else if (restrictHeight) {
|
||||||
|
if (text.at(space) == '\n')
|
||||||
|
accumHeight += lineHeight;
|
||||||
|
}
|
||||||
|
|
||||||
word = text.substr(0, space + 1);
|
word = text.substr(0, space + 1);
|
||||||
text.erase(0, space + 1);
|
text.erase(0, space + 1);
|
||||||
|
@ -505,33 +520,71 @@ std::string Font::wrapText(std::string text, float xLen)
|
||||||
|
|
||||||
textSize = sizeText(temp);
|
textSize = sizeText(temp);
|
||||||
|
|
||||||
// If the word will fit on the line, add it to our line, and continue.
|
// If the word will fit on the line, add it to our line and continue.
|
||||||
if (textSize.x <= xLen) {
|
if (textSize.x <= maxLength) {
|
||||||
line = temp;
|
line = temp;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// The next word won't fit, so break here.
|
// If the word is too long to fit within maxLength then abbreviate it.
|
||||||
|
if (sizeText(word).x > maxLength) {
|
||||||
|
|
||||||
// If the word is too long to fit within xLen, then abbreviate it.
|
if (line != "") {
|
||||||
if (xLen > 0 && sizeText(word).x > xLen) {
|
if (restrictHeight) {
|
||||||
float length {xLen - dotsSize};
|
if (accumHeight + lineHeight > maxHeight)
|
||||||
if (length < 0)
|
continue;
|
||||||
length = 0;
|
accumHeight += lineHeight;
|
||||||
abbreviatedWord = getTextMaxWidth(word, length);
|
}
|
||||||
abbreviatedWord += "...";
|
line.append("\n");
|
||||||
word = abbreviatedWord;
|
}
|
||||||
out += line;
|
|
||||||
|
float lineLength {sizeText(word).x};
|
||||||
|
float cutTarget {lineLength - maxLength + dotsSize};
|
||||||
|
float cutSize {0.0f};
|
||||||
|
|
||||||
|
while (word != "" && cutSize < cutTarget) {
|
||||||
|
cutSize += sizeText(word.substr(word.size() - 1)).x;
|
||||||
|
word.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
word.append("...");
|
||||||
|
line = line + word;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
out += line + '\n';
|
out += line + '\n';
|
||||||
|
if (restrictHeight)
|
||||||
|
accumHeight += lineHeight;
|
||||||
|
|
||||||
|
if (restrictHeight && accumHeight > maxHeight) {
|
||||||
|
out.pop_back();
|
||||||
|
skipLastLine = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
line = word;
|
line = word;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Whatever's left should fit.
|
// Whatever's left should fit.
|
||||||
out += line;
|
if (!skipLastLine)
|
||||||
|
out.append(line);
|
||||||
|
|
||||||
|
if (restrictHeight && out.back() == '\n')
|
||||||
|
out.pop_back();
|
||||||
|
|
||||||
|
// If the text has been abbreviated vertically then add "..." at the end of the string.
|
||||||
|
if (restrictHeight && accumHeight > maxHeight) {
|
||||||
|
if (out.back() != '\n') {
|
||||||
|
float cutSize {0.0f};
|
||||||
|
float cutTarget {sizeText(line).x - maxLength + dotsSize};
|
||||||
|
while (cutSize < cutTarget) {
|
||||||
|
cutSize += sizeText(out.substr(out.size() - 1)).x;
|
||||||
|
out.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.append("...");
|
||||||
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,10 @@ public:
|
||||||
void renderTextCache(TextCache* cache);
|
void renderTextCache(TextCache* cache);
|
||||||
|
|
||||||
// Inserts newlines into text to make it wrap properly.
|
// Inserts newlines into text to make it wrap properly.
|
||||||
std::string wrapText(std::string text, float xLen);
|
std::string wrapText(std::string text,
|
||||||
|
float maxLength,
|
||||||
|
float maxHeight = 0.0f,
|
||||||
|
float lineSpacing = 1.5f);
|
||||||
|
|
||||||
// Returns the expected size of a string after wrapping is applied.
|
// Returns the expected size of a string after wrapping is applied.
|
||||||
glm::vec2 sizeWrappedText(std::string text, float xLen, float lineSpacing = 1.5f);
|
glm::vec2 sizeWrappedText(std::string text, float xLen, float lineSpacing = 1.5f);
|
||||||
|
|
Loading…
Reference in a new issue