diff options
author | dec05eba <dec05eba@protonmail.com> | 2018-05-04 20:50:49 +0200 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2018-05-04 20:50:52 +0200 |
commit | 640d8df5277af4ac4b545cc6d4cf2830509e61b9 (patch) | |
tree | 3fdf9d2f0c78ecc6b869b0657989dfacbb0e6d33 /src | |
parent | 70d01f1f5699e265f79985b61136a62f9fa18a49 (diff) |
Add proper parsing of Text, add url
Diffstat (limited to 'src')
-rw-r--r-- | src/Channel.cpp | 26 | ||||
-rw-r--r-- | src/MessageBoard.cpp | 23 | ||||
-rw-r--r-- | src/Text.cpp | 157 |
3 files changed, 134 insertions, 72 deletions
diff --git a/src/Channel.cpp b/src/Channel.cpp index ae66e3c..e25057a 100644 --- a/src/Channel.cpp +++ b/src/Channel.cpp @@ -20,37 +20,17 @@ namespace dchat { addUserLocally(localUser); { - Message *message = new Message(&systemUser, u8"hello, worldåäö1![emoji](https://discordemoji.com/assets/emoji/playtime.png)"); + Message *message = new Message(&systemUser, u8"[emoji](https://discordemoji.com/assets/emoji/PepeDab.gif) deaf [emoji](https://discordemoji.com/assets/emoji/COGGERS.gif)"); messageBoard.addMessage(message); } { - Message *message = new Message(&systemUser, u8"hello, world2![emoji](https://discordemoji.com/assets/emoji/Feels3DMan.gif)"); + Message *message = new Message(&systemUser, u8"[emoji](https://discordemoji.com/assets/emoji/PepeDab.gif)[emoji](https://discordemoji.com/assets/emoji/COGGERS.gif)"); messageBoard.addMessage(message); } { - Message *message = new Message(&systemUser, u8"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."); - messageBoard.addMessage(message); - } - - { - Message *message = new Message(&systemUser, u8"Lorem ipsumdolorsitamet,consecteturadipiscingelit,seddoeiusmodtemporincididuntutaboreetdoloremagnaaliqua.Utenimadminimveniam"); - messageBoard.addMessage(message); - } - - { - Message *message = new Message(&systemUser, u8"xddd"); - messageBoard.addMessage(message); - } - - { - Message *message = new Message(&systemUser, u8"[emoji](https://discordemoji.com/assets/emoji/PepeDab.gif)[emoji](https://cdn.discordapp.com/emojis/398569871761473538.png?v=1)"); - messageBoard.addMessage(message); - } - - { - Message *message = new Message(&systemUser, u8"Message after big emoji"); + Message *message = new Message(&systemUser, u8"pepedab https://discordemoji.com/assets/emoji/PepeDab.gif coggers https://discordemoji.com/assets/emoji/COGGERS.gif"); messageBoard.addMessage(message); } diff --git a/src/MessageBoard.cpp b/src/MessageBoard.cpp index 71b622f..250f234 100644 --- a/src/MessageBoard.cpp +++ b/src/MessageBoard.cpp @@ -33,29 +33,6 @@ namespace dchat const float USERNAME_TIMESTAMP_SIDE_PADDING = 10.0f; const double SCROLL_MAX_SPEED = 20.0; - const LineColor LINE_COLOR - { - .sideColor = ColorScheme::getBackgroundColor() + sf::Color(10, 10, 10), - .centerColor = ColorScheme::getBackgroundColor() + sf::Color(10, 10, 10) - }; - - static void drawGradientLine(const sf::Vector2f &position, const sf::Vector2f &size, const LineColor &color, sf::RenderWindow &window) - { - sf::Vertex rectangle[] = - { - sf::Vertex(position, color.sideColor), - sf::Vertex(sf::Vector2f(position.x + size.x * 0.5f, position.y), color.centerColor), - sf::Vertex(sf::Vector2f(position.x + size.x * 0.5f, position.y + size.y), color.centerColor), - sf::Vertex(sf::Vector2f(position.x, position.y + size.y), color.sideColor), - - sf::Vertex(sf::Vector2f(position.x + size.x * 0.5f, position.y), color.centerColor), - sf::Vertex(sf::Vector2f(position.x + size.x, position.y), color.sideColor), - sf::Vertex(sf::Vector2f(position.x + size.x, position.y + size.y), color.sideColor), - sf::Vertex(sf::Vector2f(position.x + size.x * 0.5f, position.y + size.y), color.centerColor) - }; - window.draw(rectangle, 8, sf::Quads); - } - MessageBoard::MessageBoard(const sf::Vector2u &size) : selectingText(false), leftMouseButtonPressed(false), 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; } |