aboutsummaryrefslogtreecommitdiff
path: root/src/Text.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Text.cpp')
-rw-r--r--src/Text.cpp129
1 files changed, 106 insertions, 23 deletions
diff --git a/src/Text.cpp b/src/Text.cpp
index c433ddc..bc23235 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -1,6 +1,7 @@
#include "../include/Text.hpp"
#include "../include/Cache.hpp"
#include "../include/Gif.hpp"
+#include "../include/WebPagePreview.hpp"
#include <SFML/Graphics/RectangleShape.hpp>
#include <cmath>
@@ -10,6 +11,7 @@ namespace dchat
const float EMOJI_PADDING = 5.0f;
const float EMOJI_SCALE_WITH_TEXT = 1.7f;
const float EMOJI_SCALE_STANDALONE = 5.0f;
+ const float IMAGE_HEIGHT_SCALE = 15.0f;
const sf::Color URL_COLOR(15, 192, 252);
@@ -40,7 +42,6 @@ namespace dchat
{
setString(_str);
}
-
void Text::setString(const sf::String &str)
{
if(str != this->str)
@@ -101,7 +102,7 @@ namespace dchat
void Text::setLineSpacing(float lineSpacing)
{
- if(lineSpacing != this->lineSpacing)
+ if(fabs(lineSpacing - this->lineSpacing) > 0.001f)
{
this->lineSpacing = lineSpacing;
dirty = true;
@@ -414,8 +415,22 @@ namespace dchat
glyphPos.x += glyph.advance;
}
+
+ if(textElement.type != TextElement::Type::TEXT)
+ {
+ prevCodePoint = 0;
+ }
+
+ if(textElement.type == TextElement::Type::URL)
+ {
+ glyphPos.y += vspace + lineSpacing;
+ textElement.position.y = glyphPos.y;
+
+ glyphPos.x = 0.0f;
+ glyphPos.y += floor(vspace * IMAGE_HEIGHT_SCALE) + lineSpacing;
+ }
}
- totalHeight = glyphPos.y + lineSpacing + vspace;
+ totalHeight = glyphPos.y + vspace + lineSpacing;
}
void Text::draw(sf::RenderTarget &target, Cache &cache)
@@ -447,43 +462,111 @@ namespace dchat
{
if(textElement.type == TextElement::Type::EMOJI)
{
+ float emojiSize = vspace * (textElement.ownLine ? EMOJI_SCALE_STANDALONE : EMOJI_SCALE_WITH_TEXT);
+
sf::Vector2f pos = position;
pos += textElement.position;
pos.x = floor(pos.x);
pos.y = floor(pos.y);
- float emojiSize = vspace * (textElement.ownLine ? EMOJI_SCALE_STANDALONE : EMOJI_SCALE_WITH_TEXT);
sf::Vector2f size(emojiSize, emojiSize);
// TODO: Optimize this (add unordered_map that takes StringViewUtf32 as key)
auto u8Str = sf::String::fromUtf32(textElement.text.data, textElement.text.data + textElement.text.size).toUtf8();
const std::string &utf8Str = *(std::basic_string<char>*)&u8Str;
- const ImageByUrlResult imageByUrlResult = cache.getImageByUrl(utf8Str);
- if(imageByUrlResult.type == ImageByUrlResult::Type::CACHED)
+ const ContentByUrlResult contentByUrlResult = cache.getContentByUrl(utf8Str);
+ if(contentByUrlResult.type == ContentByUrlResult::Type::CACHED)
{
- if(imageByUrlResult.isGif)
+ switch(contentByUrlResult.cachedType)
{
- auto gifSize = imageByUrlResult.gif->getSize();
- float widthToHeightRatio = (float)gifSize.x / (float)gifSize.y;
-
- imageByUrlResult.gif->setPosition(pos);
- imageByUrlResult.gif->setScale(sf::Vector2f(size.x / (float)gifSize.x * widthToHeightRatio, size.y / (float)gifSize.y));
- imageByUrlResult.gif->draw(target);
+ case ContentByUrlResult::CachedType::GIF:
+ {
+ auto gifSize = contentByUrlResult.gif->getSize();
+ float widthToHeightRatio = (float)gifSize.x / (float)gifSize.y;
+
+ contentByUrlResult.gif->setPosition(pos);
+ contentByUrlResult.gif->setScale(sf::Vector2f(size.x / (float)gifSize.x * widthToHeightRatio, size.y / (float)gifSize.y));
+ contentByUrlResult.gif->draw(target);
+ break;
+ }
+ case ContentByUrlResult::CachedType::TEXTURE:
+ {
+ auto textureSize = contentByUrlResult.texture->getSize();
+ float widthToHeightRatio = (float)textureSize.x / (float)textureSize.y;
+
+ // TODO: Store this sprite somewhere, might not be efficient to create a new sprite object every frame
+ sf::Sprite sprite(*contentByUrlResult.texture);
+ sprite.setPosition(pos);
+ sprite.setScale(size.x / (float)textureSize.x * widthToHeightRatio, size.y / (float)textureSize.y);
+ target.draw(sprite);
+ break;
+ }
+ default:
+ // Ignore html in emoji....
+ break;
}
- else
+ }
+ else
+ {
+ sf::RectangleShape rect(size);
+ rect.setFillColor(sf::Color::White);
+ rect.setPosition(pos);
+ target.draw(rect);
+ }
+ }
+ else if(textElement.type == TextElement::Type::URL)
+ {
+ sf::Vector2f pos = position;
+ pos.y += floor(textElement.position.y);
+ float imageHeight = floor(vspace * IMAGE_HEIGHT_SCALE);
+
+ // TODO: Optimize this (add unordered_map that takes StringViewUtf32 as key)
+ auto u8Str = sf::String::fromUtf32(textElement.text.data, textElement.text.data + textElement.text.size).toUtf8();
+ const std::string &utf8Str = *(std::basic_string<char>*)&u8Str;
+ const ContentByUrlResult contentByUrlResult = cache.getContentByUrl(utf8Str);
+ if(contentByUrlResult.type == ContentByUrlResult::Type::CACHED)
+ {
+ switch(contentByUrlResult.cachedType)
{
- auto textureSize = imageByUrlResult.texture->getSize();
- float widthToHeightRatio = (float)textureSize.x / (float)textureSize.y;
-
- // TODO: Store this sprite somewhere, might not be efficient to create a new sprite object every frame
- sf::Sprite sprite(*imageByUrlResult.texture);
- sprite.setPosition(pos);
- sprite.setScale(size.x / (float)textureSize.x * widthToHeightRatio, size.y / (float)textureSize.y);
- target.draw(sprite);
+ case ContentByUrlResult::CachedType::GIF:
+ {
+ auto gifSize = contentByUrlResult.gif->getSize();
+ float widthToHeightRatio = (float)gifSize.x / (float)gifSize.y;
+
+ contentByUrlResult.gif->setPosition(pos);
+ contentByUrlResult.gif->setScale(sf::Vector2f(imageHeight / (float)gifSize.x * widthToHeightRatio, imageHeight / (float)gifSize.y));
+ contentByUrlResult.gif->draw(target);
+ break;
+ }
+ case ContentByUrlResult::CachedType::TEXTURE:
+ {
+ auto textureSize = contentByUrlResult.texture->getSize();
+ float widthToHeightRatio = (float)textureSize.x / (float)textureSize.y;
+
+ // TODO: Store this sprite somewhere, might not be efficient to create a new sprite object every frame
+ sf::Sprite sprite(*contentByUrlResult.texture);
+ sprite.setPosition(pos);
+ sprite.setScale(imageHeight / (float)textureSize.x * widthToHeightRatio, imageHeight / (float)textureSize.y);
+ target.draw(sprite);
+ break;
+ }
+ case ContentByUrlResult::CachedType::WEB_PAGE_PREVIEW:
+ {
+ const float previewWidth = floor(imageHeight * 1.77f);
+
+ // No need to perform culling here, that is done in @Text draw function
+ contentByUrlResult.webPagePreview->title.setCharacterSize(characterSize);
+ contentByUrlResult.webPagePreview->title.setMaxWidth(previewWidth);
+ contentByUrlResult.webPagePreview->title.setPosition(pos);
+ contentByUrlResult.webPagePreview->title.setLineSpacing(0.0f);
+ contentByUrlResult.webPagePreview->title.setFillColor(URL_COLOR);
+ contentByUrlResult.webPagePreview->title.draw(target, cache);
+ break;
+ }
}
}
else
{
- sf::RectangleShape rect(size);
+ sf::RectangleShape rect(sf::Vector2f(imageHeight, imageHeight));
rect.setFillColor(sf::Color::White);
rect.setPosition(pos);
target.draw(rect);