aboutsummaryrefslogtreecommitdiff
path: root/src/Text.cpp
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-06-13 04:21:35 +0200
committerdec05eba <dec05eba@protonmail.com>2021-06-13 04:21:35 +0200
commitf51a76e6febb27923e3ca8e853974a24465c4739 (patch)
tree03eda2424e5ec20d076e057ee55a04756f005e08 /src/Text.cpp
parentc7e10b0910473c99dbc139f514220b134093c9f0 (diff)
Support braille, temporary disable video cache to support seeking in long videos on youtube...
Diffstat (limited to 'src/Text.cpp')
-rw-r--r--src/Text.cpp62
1 files changed, 42 insertions, 20 deletions
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;