aboutsummaryrefslogtreecommitdiff
path: root/src/Text.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Text.cpp')
-rw-r--r--src/Text.cpp157
1 files changed, 131 insertions, 26 deletions
diff --git a/src/Text.cpp b/src/Text.cpp
index 02ea6fa..c433ddc 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -11,11 +11,14 @@ namespace dchat
const float EMOJI_SCALE_WITH_TEXT = 1.7f;
const float EMOJI_SCALE_STANDALONE = 5.0f;
+ const sf::Color URL_COLOR(15, 192, 252);
+
Text::Text(const sf::Font *_font) :
font(_font),
characterSize(0),
maxWidth(0.0f),
color(sf::Color::White),
+ urlColor(URL_COLOR),
dirty(false),
plainText(false),
totalHeight(0.0f)
@@ -29,6 +32,7 @@ namespace dchat
vertices(sf::PrimitiveType::Quads),
maxWidth(_maxWidth),
color(sf::Color::White),
+ urlColor(URL_COLOR),
dirty(true),
plainText(_plainText),
totalHeight(0.0f),
@@ -109,43 +113,142 @@ namespace dchat
return totalHeight;
}
+ size_t stringSplitUrl(const StringViewUtf32 textElementStr, const sf::String &urlStr, size_t offset, std::vector<TextElement> &newTextElements)
+ {
+ size_t stringStart = offset;
+ size_t urlStart = textElementStr.find(StringViewUtf32(urlStr.getData(), urlStr.getSize()), offset);
+ if(urlStart != -1)
+ {
+ offset = urlStart + urlStr.getSize();
+ while(offset < textElementStr.size)
+ {
+ if(isspace(textElementStr[offset]))
+ break;
+ ++offset;
+ }
+
+ StringViewUtf32 beforeUrlStr(textElementStr.data + stringStart, urlStart - stringStart);
+ newTextElements.push_back({ beforeUrlStr, TextElement::Type::TEXT });
+
+ StringViewUtf32 url(textElementStr.data + urlStart, offset - urlStart);
+ newTextElements.push_back({ url, TextElement::Type::URL });
+ return offset;
+ }
+ return -1;
+ }
+
void Text::stringSplitElements(sf::String &stringToSplit, usize startIndex)
{
+ StringViewUtf32 wholeStr(&stringToSplit[startIndex], stringToSplit.getSize() - startIndex);
+ textElements.push_back({ wholeStr, TextElement::Type::TEXT });
if(plainText)
- {
- StringViewUtf32 wholeStr(&stringToSplit[startIndex], stringToSplit.getSize() - startIndex);
- textElements.push_back({ wholeStr, TextElement::Type::TEXT });
return;
+
+ const char *httpStrRaw = "http://";
+ const sf::String httpStr = sf::String::fromUtf8(httpStrRaw, httpStrRaw + 7);
+
+ const char *httpsStrRaw = "https://";
+ const sf::String httpsStr = sf::String::fromUtf8(httpsStrRaw, httpsStrRaw + 8);
+
+ const char *emojiStrRaw = "[emoji](";
+ const sf::String emojiStr = sf::String::fromUtf8(emojiStrRaw, emojiStrRaw + 8);
+
+ const char *parentheseStrRaw = ")";
+ const sf::String parentheseStr = sf::String::fromUtf8(parentheseStrRaw, parentheseStrRaw + 1);
+ static_assert(sizeof(*parentheseStr.getData()) == sizeof(u32), "sf::String size has changed...");
+
+ std::vector<TextElement> newTextElements;
+ for(size_t i = 0; i < textElements.size(); ++i)
+ {
+ TextElement textElement = textElements[i];
+ if(textElement.type != TextElement::Type::TEXT)
+ {
+ newTextElements.push_back(textElement);
+ continue;
+ }
+
+ size_t offset = 0;
+ while(offset < textElement.text.size)
+ {
+ size_t stringStart = offset;
+ size_t foundStartIndex = textElement.text.find(StringViewUtf32(emojiStr.getData(), emojiStr.getSize()), offset);
+ size_t foundEndIndex = -1;
+ if(foundStartIndex != -1)
+ {
+ offset = foundStartIndex + 8;
+ foundEndIndex = textElement.text.find(StringViewUtf32(parentheseStr.getData(), parentheseStr.getSize()), offset);
+ }
+
+ if(foundEndIndex != -1)
+ {
+ StringViewUtf32 beforeEmojiStr(textElement.text.data + stringStart, foundStartIndex - stringStart);
+ newTextElements.push_back({ beforeEmojiStr, TextElement::Type::TEXT });
+
+ StringViewUtf32 url(textElement.text.data + offset, foundEndIndex - offset);
+ newTextElements.push_back({ url, TextElement::Type::EMOJI });
+ offset = foundEndIndex + 1;
+ }
+ else
+ {
+ StringViewUtf32 strToEnd(textElement.text.data + stringStart, textElement.text.size - stringStart);
+ newTextElements.push_back({ strToEnd, TextElement::Type::TEXT });
+ offset = textElement.text.size;
+ }
+ }
}
+ textElements = newTextElements;
- size_t offset = startIndex;
- while(offset < stringToSplit.getSize())
+ newTextElements.clear();
+ for(size_t i = 0; i < textElements.size(); ++i)
{
- size_t stringStart = offset;
- size_t foundStartIndex = stringToSplit.find("[emoji](", offset);
- size_t foundEndIndex = -1;
- if(foundStartIndex != -1)
+ TextElement textElement = textElements[i];
+ if(textElement.type != TextElement::Type::TEXT)
{
- offset += (foundStartIndex + 8);
- foundEndIndex = stringToSplit.find(")", offset);
+ newTextElements.push_back(textElement);
+ continue;
}
- if(foundEndIndex != -1)
+ size_t offset = 0;
+ while(offset < textElement.text.size)
{
- StringViewUtf32 beforeEmojiStr(&stringToSplit[stringStart], foundStartIndex - stringStart);
- textElements.push_back({ beforeEmojiStr, TextElement::Type::TEXT });
-
- StringViewUtf32 url(&stringToSplit[offset], foundEndIndex - offset);
- textElements.push_back({ url, TextElement::Type::EMOJI });
- offset = foundEndIndex + 1;
+ size_t urlEnd = stringSplitUrl(textElement.text, httpStr, offset, newTextElements);
+ if(urlEnd == -1)
+ {
+ StringViewUtf32 strToEnd(textElement.text.data + offset, textElement.text.size - offset);
+ newTextElements.push_back({ strToEnd, TextElement::Type::TEXT });
+ offset = textElement.text.size;
+ }
+ else
+ offset = urlEnd;
}
- else
+ }
+ textElements = newTextElements;
+
+ newTextElements.clear();
+ for(size_t i = 0; i < textElements.size(); ++i)
+ {
+ TextElement textElement = textElements[i];
+ if(textElement.type != TextElement::Type::TEXT)
+ {
+ newTextElements.push_back(textElement);
+ continue;
+ }
+
+ size_t offset = 0;
+ while(offset < textElement.text.size)
{
- StringViewUtf32 strToEnd(&stringToSplit[stringStart], stringToSplit.getSize() - stringStart);
- textElements.push_back({ strToEnd, TextElement::Type::TEXT });
- offset = stringToSplit.getSize();
+ size_t urlEnd = stringSplitUrl(textElement.text, httpsStr, offset, newTextElements);
+ if(urlEnd == -1)
+ {
+ StringViewUtf32 strToEnd(textElement.text.data + offset, textElement.text.size - offset);
+ newTextElements.push_back({ strToEnd, TextElement::Type::TEXT });
+ offset = textElement.text.size;
+ }
+ else
+ offset = urlEnd;
}
}
+ textElements = newTextElements;
for(std::vector<TextElement>::iterator it = textElements.begin(); it != textElements.end();)
{
@@ -302,10 +405,12 @@ namespace dchat
sf::Vector2f textureBottomLeft(glyph.textureRect.left, glyph.textureRect.top + glyph.textureRect.height);
sf::Vector2f textureBottomRight(glyph.textureRect.left + glyph.textureRect.width, glyph.textureRect.top + glyph.textureRect.height);
- vertices[vertexOffset + i * 4 + 0] = { vertexTopLeft, color, textureTopLeft };
- vertices[vertexOffset + i * 4 + 1] = { vertexTopRight, color, textureTopRight };
- vertices[vertexOffset + i * 4 + 2] = { vertexBottomRight, color, textureBottomRight };
- vertices[vertexOffset + i * 4 + 3] = { vertexBottomLeft, color, textureBottomLeft };
+ sf::Color fontColor = (textElement.type == TextElement::Type::TEXT ? color : urlColor);
+
+ vertices[vertexOffset + i * 4 + 0] = { vertexTopLeft, fontColor, textureTopLeft };
+ vertices[vertexOffset + i * 4 + 1] = { vertexTopRight, fontColor, textureTopRight };
+ vertices[vertexOffset + i * 4 + 2] = { vertexBottomRight, fontColor, textureBottomRight };
+ vertices[vertexOffset + i * 4 + 3] = { vertexBottomLeft, fontColor, textureBottomLeft };
glyphPos.x += glyph.advance;
}