diff options
Diffstat (limited to 'src/Text.cpp')
-rw-r--r-- | src/Text.cpp | 63 |
1 files changed, 58 insertions, 5 deletions
diff --git a/src/Text.cpp b/src/Text.cpp index e6fe90c..e67d879 100644 --- a/src/Text.cpp +++ b/src/Text.cpp @@ -18,6 +18,8 @@ #include <sstream> // TODO: text editing should take into consideration FORMATTED_TEXT_START/FORMATTED_TEXT_END. +// TODO: Add elipses at end when using max_lines. Also allow choosing where the text is cut. +// Right now the text is always cut at the end but it should be possible to cut in the middle and start too. namespace QuickMedia { @@ -154,6 +156,17 @@ namespace QuickMedia dirtyText = true; } + void Text::set_max_lines(int max_lines) { + if(max_lines < 0) + max_lines = 0; + + if(max_lines != this->max_lines) { + this->max_lines = max_lines; + dirty = true; + dirtyText = true; + } + } + // static std::string Text::to_printable_string(const std::string &str) { std::string result; @@ -906,9 +919,11 @@ namespace QuickMedia float text_offset_y = 0.0f; int last_space_index = -1; num_lines = 1; + bool cut_lines = false; // TODO: Binary search? - for(int i = 0; i < (int)vertices_linear.size(); ++i) { - VertexRef &vertex_ref = vertices_linear[i]; + int vertices_linear_index = 0; + for(vertices_linear_index = 0; vertices_linear_index < (int)vertices_linear.size(); ++vertices_linear_index) { + VertexRef &vertex_ref = vertices_linear[vertices_linear_index]; mgl::Vertex *vertex = &vertices[vertex_ref.vertices_index][vertex_ref.index]; for(int v = 0; v < 6; ++v) { @@ -920,12 +935,17 @@ namespace QuickMedia switch(vertex_ref.codepoint) { case ' ': case '\t': - last_space_index = i; + last_space_index = vertices_linear_index; break; case '\n': text_wrap_offset = 0.0f; last_space_index = -1; ++num_lines; + if(max_lines != 0 && num_lines > max_lines) { + --num_lines; + cut_lines = true; + goto vertices_linear_done; + } break; default: break; @@ -934,10 +954,16 @@ namespace QuickMedia float vertex_right_side = get_text_quad_right_side(vertex_ref); if(vertex_right_side > maxWidth && maxWidth > WORD_WRAP_MIN_SIZE) { ++num_lines; + if(max_lines != 0 && num_lines > max_lines) { + --num_lines; + cut_lines = true; + goto vertices_linear_done; + } + // TODO: Ignore line wrap on space - if(last_space_index != -1 && last_space_index != i) { + if(last_space_index != -1 && last_space_index != vertices_linear_index) { float vertex_left_side = get_text_quad_left_side(vertices_linear[last_space_index + 1]); - for(int j = last_space_index + 1; j <= i; ++j) { + for(int j = last_space_index + 1; j <= vertices_linear_index; ++j) { VertexRef &vertex_ref_wrap = vertices_linear[j]; mgl::Vertex *vertex = &vertices[vertex_ref_wrap.vertices_index][vertex_ref_wrap.index]; for(int v = 0; v < 6; ++v) { @@ -961,6 +987,7 @@ namespace QuickMedia text_offset_y += line_height; } } + vertices_linear_done:; // TODO: Optimize for(TextElement &textElement : textElements) { @@ -971,6 +998,23 @@ namespace QuickMedia } } + std::array<bool, FONT_ARRAY_SIZE> resized_vertices; + for(size_t i = 0; i < resized_vertices.size(); ++i) { + resized_vertices[i] = false; + } + + if(cut_lines) { + for(int i = vertices_linear_index; i < (int)vertices_linear.size(); ++i) { + VertexRef &vertex_ref = vertices_linear[i]; + if(resized_vertices[vertex_ref.vertices_index]) + continue; + + vertices[vertex_ref.vertices_index].resize(vertex_ref.index); + resized_vertices[vertex_ref.vertices_index] = true; + } + vertices_linear.resize(vertices_linear_index); + } + boundingBox.size.x = 0.0f; for(VertexRef &vertex_ref : vertices_linear) { boundingBox.size.x = std::max(boundingBox.size.x, get_text_quad_right_side(vertex_ref)); @@ -1190,6 +1234,9 @@ namespace QuickMedia { if(!editable) return; + if(caretIndex > (int)vertices_linear.size()) + caretIndex = vertices_linear.size(); + bool caretAtEnd = caretIndex == (int)vertices_linear.size(); if(event.type == mgl::Event::KeyPressed) @@ -1374,6 +1421,9 @@ namespace QuickMedia for(const TextElement &textElement : textElements) { if(textElement.text_type == TextElement::TextType::EMOJI) { + if(textElement.pos.to_vec2f().y + vspace > boundingBox.size.y) + continue; + auto emoji_data = AsyncImageLoader::get_instance().get_thumbnail(textElement.url, textElement.local, { (int)vspace, (int)vspace }); if(emoji_data->loading_state == LoadingState::FINISHED_LOADING) { if(!emoji_data->texture.load_from_image(*emoji_data->image)) @@ -1408,6 +1458,9 @@ namespace QuickMedia } if(thumbnail_data->loading_state == LoadingState::APPLIED_TO_TEXTURE) { + if(textElement.pos.to_vec2f().y + thumbnail_data->texture->get_size().y > boundingBox.size.y) + continue; + sprite.set_texture(&thumbnail_data->texture); sprite.set_position(pos + textElement.pos.to_vec2f()); sprite.set_size(textElement.size.to_vec2f()); |