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/ResourceLoader.cpp | 8 ++++++- src/Text.cpp | 62 ++++++++++++++++++++++++++++++++++---------------- src/VideoPlayer.cpp | 4 ++-- 3 files changed, 51 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/ResourceLoader.cpp b/src/ResourceLoader.cpp index 3100c7f..fbcbe39 100644 --- a/src/ResourceLoader.cpp +++ b/src/ResourceLoader.cpp @@ -7,7 +7,7 @@ #include static std::string resource_root; -static std::array, 3> font_cache; +static std::array, 4> font_cache; static std::unordered_map> texture_cache; namespace QuickMedia { @@ -46,6 +46,12 @@ namespace QuickMedia::FontLoader { font_file_name = "NotoSansCJK-Regular.ttc"; break; } + case FontType::SYMBOLS: { + noto_directories.push_back("/usr/share/fonts/noto"); + noto_directories.push_back("/usr/share/fonts/truetype/noto"); + font_file_name = "NotoSansSymbols2-Regular.ttf"; + break; + } } bool successfully_loaded_font = false; 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; diff --git a/src/VideoPlayer.cpp b/src/VideoPlayer.cpp index 490ce82..0df4108 100644 --- a/src/VideoPlayer.cpp +++ b/src/VideoPlayer.cpp @@ -116,7 +116,7 @@ namespace QuickMedia { ytdl_format.c_str(), // TODO: Disable hr seek on low power devices? "--hr-seek=yes", - "--cache-pause=no", + "--cache=no", "--cookies", cookies_file_arg.c_str(), input_conf.c_str(), @@ -138,7 +138,7 @@ namespace QuickMedia { if(!use_system_mpv_config) { args.insert(args.end(), { - "--no-config", /*"--demuxer-max-bytes=40M", "--demuxer-max-back-bytes=20M",*/ + "--no-config", "--profile=gpu-hq", "--vo=gpu,vdpau,x11", "--hwdec=auto" -- cgit v1.2.3