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... --- TODO | 6 ++-- include/ResourceLoader.hpp | 3 +- include/Text.hpp | 8 ++---- shaders/rounded_rectangle.glsl | 2 +- src/ResourceLoader.cpp | 8 +++++- src/Text.cpp | 62 ++++++++++++++++++++++++++++-------------- src/VideoPlayer.cpp | 4 +-- 7 files changed, 61 insertions(+), 32 deletions(-) diff --git a/TODO b/TODO index f8677fb..f97cbd1 100644 --- a/TODO +++ b/TODO @@ -163,7 +163,9 @@ Update item height when it switches from not being merged with previous to being Reload youtube video url if the video is idle for too long. The video url is only valid for a specific amount of time (the valid duration is in the json). Improve live stream startup time by downloading the video formats in parts instead of the hls manifest? Add youtube chapters. -Faster seeking for long youtube videos. Disable drop shadow on pinephone. --resume-playback doesn't seem to work with the new youtube code. Or maybe --save-position-on-quit fails? -Create drop shadow with shader instead of quads. \ No newline at end of file +Load the next page in chapter list when reaching the bottom (when going to previous chapters in image view). +Seeking too much breaks mpv when playing youtube. It takes 30 seconds or something to resume! +Re-enable video cache which was disabled because youtube seeking freezes for up to 20 seconds when its used! +Loading image background should be rounded. \ No newline at end of file diff --git a/include/ResourceLoader.hpp b/include/ResourceLoader.hpp index a778f18..29efa91 100644 --- a/include/ResourceLoader.hpp +++ b/include/ResourceLoader.hpp @@ -14,7 +14,8 @@ namespace QuickMedia::FontLoader { enum class FontType { LATIN, LATIN_BOLD, - CJK + CJK, + SYMBOLS }; // Note: not thread-safe diff --git a/include/Text.hpp b/include/Text.hpp index a39b2ba..72fdd66 100644 --- a/include/Text.hpp +++ b/include/Text.hpp @@ -42,6 +42,7 @@ namespace QuickMedia enum class TextType { LATIN, CJK, + SYMBOL, EMOJI }; @@ -146,11 +147,8 @@ namespace QuickMedia sf::String str; // TODO: Remove this for non-editable text??? also replace with std::string? then we get more efficient editing of text const bool bold_font; unsigned int characterSize; - // 1: Normal text - // 2: CJK - // 3: Emoji - std::array vertices; - std::array vertex_buffers; + std::array vertices; + std::array vertex_buffers; float maxWidth; sf::Vector2f position; sf::Color color; diff --git a/shaders/rounded_rectangle.glsl b/shaders/rounded_rectangle.glsl index 8c379b7..5af174b 100644 --- a/shaders/rounded_rectangle.glsl +++ b/shaders/rounded_rectangle.glsl @@ -21,5 +21,5 @@ void main() { vec4 front_color = mix(gl_Color, band_color, band_blend.x*band_blend.y); float shadow_a = 1.0 - smoothstep(0.0, shadow_offset.x, rect_dist); front_color.a *= a; - gl_FragColor = mix(front_color, vec4(0.0, 0.0, 0.0, 0.135), shadow_a - a); + gl_FragColor = mix(front_color, vec4(0.0, 0.0, 0.0, 0.14), shadow_a - a); } \ No newline at end of file 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