From f51a76e6febb27923e3ca8e853974a24465c4739 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 13 Jun 2021 04:21:35 +0200 Subject: Support braille, temporary disable video cache to support seeking in long videos on youtube... --- src/Text.cpp | 62 ++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 20 deletions(-) (limited to 'src/Text.cpp') diff --git a/src/Text.cpp b/src/Text.cpp index 138cd9d..32aae2e 100644 --- a/src/Text.cpp +++ b/src/Text.cpp @@ -16,6 +16,12 @@ namespace QuickMedia static const float WORD_WRAP_MIN_SIZE = 80.0f; static const sf::Color URL_COLOR(35, 140, 245); + static const size_t FONT_INDEX_LATIN = 0; + static const size_t FONT_INDEX_CJK = 1; + static const size_t FONT_INDEX_SYMBOLS = 2; + static const size_t FONT_INDEX_EMOJI = 3; + static const size_t FONT_ARRAY_SIZE = 4; + size_t StringViewUtf32::find(const StringViewUtf32 &other, size_t offset) const { if(offset >= size) return -1; @@ -46,10 +52,8 @@ namespace QuickMedia caretIndex(0), caret_offset_x(0.0f) { - vertices[0].setPrimitiveType(sf::PrimitiveType::Triangles); - vertices[1].setPrimitiveType(sf::PrimitiveType::Triangles); - vertices[2].setPrimitiveType(sf::PrimitiveType::Triangles); - for(int i = 0; i < 3; ++i) { + for(size_t i = 0; i < FONT_ARRAY_SIZE; ++i) { + vertices[i].setPrimitiveType(sf::PrimitiveType::Triangles); vertex_buffers[i] = sf::VertexBuffer(sf::PrimitiveType::Triangles, sf::VertexBuffer::Static); } setString(std::move(_str)); @@ -240,6 +244,12 @@ namespace QuickMedia return is_chinese_codepoint(codepoint) || is_japanese_codepoint(codepoint) || is_korean_codepoint(codepoint); } + static bool is_symbol_codepoint(sf::Uint32 codepoint) { + // TODO: Add the remaining NotoSansSymbols2-Regular.ttf codepoints as well. + // See codepoint ranges with: fc-query --format='%{charset}\n' /usr/share/fonts/noto/NotoSansSymbols2-Regular.ttf. + return codepoint >= 0x2800 && codepoint <= 0x28FF; // Braille + } + static size_t find_end_of_cjk(const sf::Uint32 *str, size_t size) { for(size_t i = 0; i < size; ++i) { if(!is_cjk_codepoint(str[i])) @@ -256,9 +266,17 @@ namespace QuickMedia return size; } - static size_t find_end_of_non_cjk_and_non_emoji(const sf::Uint32 *str, size_t size) { + static size_t find_end_of_symbol(const sf::Uint32 *str, size_t size) { + for(size_t i = 0; i < size; ++i) { + if(!is_symbol_codepoint(str[i])) + return i; + } + return size; + } + + static size_t find_end_latin(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])) + if(is_cjk_codepoint(str[i]) || codepoint_is_emoji(str[i]) || is_symbol_codepoint(str[i])) return i; } return size; @@ -271,14 +289,17 @@ namespace QuickMedia while(index < size) { size_t offset; TextElement::TextType text_type = TextElement::TextType::LATIN; - if(is_cjk_codepoint(str[index])) { + if(is_symbol_codepoint(str[index])) { + text_type = TextElement::TextType::SYMBOL; + offset = find_end_of_symbol(str.getData() + index + 1, size - index - 1); + } else if(is_cjk_codepoint(str[index])) { text_type = TextElement::TextType::CJK; offset = find_end_of_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); + offset = find_end_latin(str.getData() + index + 1, size - index - 1); } textElements.push_back({ StringViewUtf32(str.getData() + index, offset + 1), TextElement::Type::TEXT }); textElements.back().text_type = text_type; @@ -359,7 +380,7 @@ namespace QuickMedia dirty = false; vertices_linear.clear(); - for(int i = 0; i < 3; ++i) { + for(size_t i = 0; i < FONT_ARRAY_SIZE; ++i) { vertices[i].clear(); vertices[i].resize(0); } @@ -384,13 +405,16 @@ namespace QuickMedia { TextElement &textElement = textElements[textElementIndex]; const sf::Font *ff = latin_font; - int vertices_index = 0; + int vertices_index = FONT_INDEX_LATIN; prevCodePoint = 0; if(textElement.text_type == TextElement::TextType::CJK) { ff = FontLoader::get_font(FontLoader::FontType::CJK); - vertices_index = 1; + vertices_index = FONT_INDEX_CJK; + } else if(textElement.text_type == TextElement::TextType::SYMBOL) { + ff = FontLoader::get_font(FontLoader::FontType::SYMBOLS); + vertices_index = FONT_INDEX_SYMBOLS; } else if(textElement.text_type == TextElement::TextType::EMOJI) { - vertices_index = 2; + vertices_index = FONT_INDEX_EMOJI; textElement.position = glyphPos; sf::Color emoji_color(255, 255, 255, color.a); for(size_t i = 0; i < textElement.text.size; ++i) @@ -599,14 +623,14 @@ namespace QuickMedia boundingBox.height = num_lines * line_height; // TODO: Clear |vertices| somehow even with editable text - for(int i = 0; i < 3; ++i) { + for(size_t i = 0; i < FONT_ARRAY_SIZE; ++i) { vertex_buffers[i].create(vertices[i].getVertexCount()); vertex_buffers[i].update(&vertices[i][0], vertices[i].getVertexCount(), 0); } //url_ranges.clear(); if(!editable) { - for(int i = 0; i < 3; ++i) { + for(size_t i = 0; i < FONT_ARRAY_SIZE; ++i) { vertices[i].clear(); vertices[i].resize(0); } @@ -911,8 +935,8 @@ namespace QuickMedia const float vspace = latin_font->getLineSpacing(characterSize); pos.y += floor(vspace); // Origin is at bottom left, we want it to be at top left - const FontLoader::FontType font_types[] = { latin_font_type, FontLoader::FontType::CJK }; - for(size_t i = 0; i < 2; ++i) { + const FontLoader::FontType font_types[] = { latin_font_type, FontLoader::FontType::CJK, FontLoader::FontType::SYMBOLS }; + for(size_t i = 0; i < FONT_INDEX_EMOJI; ++i) { if(vertex_buffers[i].getVertexCount() == 0) continue; @@ -921,15 +945,13 @@ namespace QuickMedia states.transform.translate(pos); states.texture = &font->getTexture(characterSize); target.draw(vertex_buffers[i], states); - //target.draw(vertices[i], states); } - if(vertex_buffers[2].getVertexCount() > 0) { + if(vertex_buffers[FONT_INDEX_EMOJI].getVertexCount() > 0) { sf::RenderStates states; states.transform.translate(pos); states.texture = TextureLoader::get_texture("images/emoji.png"); - target.draw(vertex_buffers[2], states); - //target.draw(vertices[2], states); + target.draw(vertex_buffers[FONT_INDEX_EMOJI], states); } if(!editable) return true; -- cgit v1.2.3