From 44e66882f6e517b06522cb1e510ed9dea7574273 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 21 Nov 2020 18:20:00 +0100 Subject: Render emoji in text, do not show notification count for cache sync, lazy load 4chan board --- src/Text.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 9 deletions(-) (limited to 'src/Text.cpp') 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 #include #include @@ -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); -- cgit v1.2.3