void Label::update_text_cache() { // try and render with a font cache if (cache_is_dirty) { Renderer* renderer = get_compositor()->get_renderer(); size_t height; int ascender, descender; renderer->font_metrics(font_handle, height, ascender, descender); content_bounds.origin = origin + scroll_offset; cache_is_dirty = 0; font_cache.clear(false); size_t last_start = 0; glm::vec2 origin_offset = glm::vec2(LABEL_LEFT_MARGIN, LABEL_TOP_MARGIN); origin_offset.y += font_height; content_bounds.size.width = size.width; content_bounds.size.height = -font_height; const bool enable_word_wrap = true; // keep track of the last segment in text to handle word wraps. size_t last_word_break = 0; const size_t character_count = text.size(); for (size_t index = 0; index < character_count+1; ++index) { const bool is_last_character = (index == character_count); Rect text_bounds; if (text[index] == '\n' || is_last_character) { create_cache_entry(index, last_start, origin_offset); if (is_last_character) { break; } } else if (enable_word_wrap && (text[index] == ' ')) { renderer->font_measure_string(font_handle, &text[last_start], (index - last_start), text_bounds); float test_width = content_bounds.width(); if (has_vertical_scrollbar()) { test_width -= vertical_bar->get_size().width; } if (text_bounds.width() > test_width) { // we need to wrap text starting from last index; create_cache_entry(last_word_break, last_start, origin_offset); // reset index, last_start. Advance it past the space. index = (last_word_break + 1); last_start = (index + 1); } last_word_break = index; } } } } // update_text_cache
/** * Tries to use a vertical scrollbar with the widget. * * @todo implement this function properly. * * @param maximum_height The wanted maximum height of the widget. * * @pre has_vertical_scrollbar() == true. */ virtual void layout_use_vertical_scrollbar(const unsigned /*maximum_height*/) { assert(has_vertical_scrollbar()); }