aboutsummaryrefslogtreecommitdiff
path: root/src/Text.cpp
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2020-11-21 18:20:00 +0100
committerdec05eba <dec05eba@protonmail.com>2020-11-21 18:20:00 +0100
commit44e66882f6e517b06522cb1e510ed9dea7574273 (patch)
treec25095570a1a9438d267b724236fefd22e68aeed /src/Text.cpp
parent9d36cfb599490888fa54110c796e14b542c402df (diff)
Render emoji in text, do not show notification count for cache sync, lazy load 4chan board
Diffstat (limited to 'src/Text.cpp')
-rw-r--r--src/Text.cpp71
1 files changed, 62 insertions, 9 deletions
diff --git a/src/Text.cpp b/src/Text.cpp
index b463f92..539f211 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -1,5 +1,6 @@
#include "../include/Text.hpp"
-#include "../include/FontLoader.hpp"
+#include "../include/ResourceLoader.hpp"
+#include "../generated/Emoji.hpp"
#include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Window/Clipboard.hpp>
#include <SFML/Window/Event.hpp>
@@ -46,6 +47,7 @@ namespace QuickMedia
{
vertices[0].setPrimitiveType(sf::PrimitiveType::Quads);
vertices[1].setPrimitiveType(sf::PrimitiveType::Quads);
+ vertices[2].setPrimitiveType(sf::PrimitiveType::Quads);
setString(std::move(_str));
}
@@ -226,9 +228,17 @@ namespace QuickMedia
return size;
}
- static size_t find_end_of_non_cjk(const sf::Uint32 *str, size_t size) {
+ static size_t find_end_of_emoji(const sf::Uint32 *str, size_t size) {
for(size_t i = 0; i < size; ++i) {
- if(is_cjk_codepoint(str[i]))
+ if(!codepoint_is_emoji(str[i]))
+ return i;
+ }
+ return size;
+ }
+
+ static size_t find_end_of_non_cjk_and_non_emoji(const sf::Uint32 *str, size_t size) {
+ for(size_t i = 0; i < size; ++i) {
+ if(is_cjk_codepoint(str[i]) || codepoint_is_emoji(str[i]))
return i;
}
return size;
@@ -240,13 +250,18 @@ namespace QuickMedia
size_t size = str.getSize();
while(index < size) {
size_t offset;
- bool is_cjk = is_cjk_codepoint(str[index]);
- if(is_cjk)
+ TextElement::TextType text_type = TextElement::TextType::LATIN;
+ if(is_cjk_codepoint(str[index])) {
+ text_type = TextElement::TextType::CJK;
offset = find_end_of_cjk(str.getData() + index + 1, size - index - 1);
- else
- offset = find_end_of_non_cjk(str.getData() + index + 1, size - index - 1);
+ } else if(codepoint_is_emoji(str[index])) {
+ text_type = TextElement::TextType::EMOJI;
+ offset = find_end_of_emoji(str.getData() + index + 1, size - index - 1);
+ } else {
+ offset = find_end_of_non_cjk_and_non_emoji(str.getData() + index + 1, size - index - 1);
+ }
textElements.push_back({ StringViewUtf32(str.getData() + index, offset + 1), TextElement::Type::TEXT });
- textElements.back().text_type = is_cjk ? TextElement::TextType::CJK : TextElement::TextType::LATIN;
+ textElements.back().text_type = text_type;
index += 1 + offset;
}
}
@@ -317,6 +332,7 @@ namespace QuickMedia
vertices_linear.clear();
vertices[0].clear();
vertices[1].clear();
+ vertices[2].clear();
boundingBox = sf::FloatRect();
sf::Font *latin_font;
@@ -325,7 +341,8 @@ namespace QuickMedia
else
latin_font = FontLoader::get_font(FontLoader::FontType::LATIN);
- float hspace = latin_font->getGlyph(' ', characterSize, false).advance + characterSpacing;
+ float latin_font_height = latin_font->getGlyph(' ', characterSize, false).advance;
+ float hspace = latin_font_height + characterSpacing;
float vspace = latin_font->getLineSpacing(characterSize); // TODO: What about japanese font???
sf::Vector2f glyphPos;
@@ -338,6 +355,35 @@ namespace QuickMedia
if(textElement.text_type == TextElement::TextType::CJK) {
ff = FontLoader::get_font(FontLoader::FontType::CJK);
vertices_index = 1;
+ } else if(textElement.text_type == TextElement::TextType::EMOJI) {
+ vertices_index = 2;
+ textElement.position = glyphPos;
+ for(size_t i = 0; i < textElement.text.size; ++i)
+ {
+ sf::Uint32 codePoint = textElement.text[i];
+ int vertexStart = vertices[vertices_index].getVertexCount();
+ EmojiRectangle emoji_rec = emoji_get_extents(codePoint);
+
+ const float font_height_offset = -latin_font_height * 1.0f;
+ sf::Vector2f vertexTopLeft(glyphPos.x, glyphPos.y + font_height_offset - emoji_rec.height * 0.5f);
+ sf::Vector2f vertexTopRight(glyphPos.x + emoji_rec.width, glyphPos.y + font_height_offset - emoji_rec.height * 0.5f);
+ sf::Vector2f vertexBottomLeft(glyphPos.x, glyphPos.y + font_height_offset + emoji_rec.height * 0.5f);
+ sf::Vector2f vertexBottomRight(glyphPos.x + emoji_rec.width, glyphPos.y + font_height_offset + emoji_rec.height * 0.5f);
+
+ sf::Vector2f textureTopLeft(emoji_rec.x, emoji_rec.y);
+ sf::Vector2f textureTopRight(emoji_rec.x + emoji_rec.width, emoji_rec.y);
+ sf::Vector2f textureBottomLeft(emoji_rec.x, emoji_rec.y + emoji_rec.height);
+ sf::Vector2f textureBottomRight(emoji_rec.x + emoji_rec.width, emoji_rec.y + emoji_rec.height);
+
+ vertices[vertices_index].append({ vertexTopLeft, sf::Color::White, textureTopLeft });
+ vertices[vertices_index].append({ vertexTopRight, sf::Color::White, textureTopRight });
+ vertices[vertices_index].append({ vertexBottomRight, sf::Color::White, textureBottomRight });
+ vertices[vertices_index].append({ vertexBottomLeft, sf::Color::White, textureBottomLeft });
+
+ glyphPos.x += emoji_rec.width + characterSpacing;
+ vertices_linear.push_back({vertices_index, vertexStart, 0, codePoint});
+ }
+ continue;
}
//vertices[vertices_index].resize(vertices[vertices_index].getVertexCount() + 4 * textElement.text.size); // TODO: Precalculate
@@ -818,6 +864,13 @@ namespace QuickMedia
states.texture = &font->getTexture(characterSize);
target.draw(vertices[i], states);
}
+
+ if(vertices[2].getVertexCount() > 0) {
+ sf::RenderStates states;
+ states.transform.translate(pos);
+ states.texture = TextureLoader::get_texture("images/emoji.png");
+ target.draw(vertices[2], states);
+ }
if(!editable) return true;
pos.y -= floor(vspace * 2.0f);