made help system faster and fixed formatting problems with it

This commit is contained in:
Dave White 2005-05-14 19:18:31 +00:00
parent 7bef33d908
commit 5dcfc67cab
3 changed files with 57 additions and 27 deletions

View file

@ -95,6 +95,12 @@ struct text_chunk
std::vector<subset_id> font_map;
//cache sizes of small text
typedef std::map<std::string,SDL_Rect> line_size_cache_map;
//map of styles -> sizes -> cache
std::map<int,std::map<int,line_size_cache_map> > line_size_cache;
//Splits the UTF-8 text into text_chunks using the same font.
std::vector<text_chunk> split_text(std::string const & utf8_text) {
text_chunk current_chunk(0);
@ -214,6 +220,7 @@ void clear_fonts()
font_table.clear();
font_names.clear();
font_map.clear();
line_size_cache.clear();
}
struct font_style_setter
@ -852,14 +859,21 @@ std::string remove_first_space(const std::string& text)
int line_width(const std::string& line, int font_size, int style)
{
const SDL_Color col = { 0, 0, 0, 0 };
text_surface s(line, font_size, col, style);
return s.width();
return line_size(line,font_size,style).w;
}
SDL_Rect line_size(const std::string& line, int font_size, int style)
{
const size_t max_cache_size = 12;
line_size_cache_map& cache = line_size_cache[style][font_size];
if(line.size() < max_cache_size) {
const line_size_cache_map::const_iterator i = cache.find(line);
if(i != cache.end()) {
return i->second;
}
}
SDL_Rect res;
const SDL_Color col = { 0, 0, 0, 0 };
@ -868,6 +882,10 @@ SDL_Rect line_size(const std::string& line, int font_size, int style)
res.w = s.width();
res.h = s.height();
if(line.size() < max_cache_size) {
cache.insert(std::pair<std::string,SDL_Rect>(line,res));
}
return res;
}
@ -956,11 +974,14 @@ inline bool break_after(wchar_t ch)
}
}
std::string word_wrap_text(const std::string& unwrapped_text, int font_size, int max_width, int max_height)
std::string word_wrap_text(const std::string& unwrapped_text, int font_size, int max_width, int max_height, int max_lines)
{
assert(max_width > 0);
utils::utf8_iterator ch(unwrapped_text);
std::string current_word;
std::string current_line;
size_t line_width = 0;
size_t current_height = 0;
bool line_break = false;
bool first = true;
@ -971,6 +992,7 @@ std::string word_wrap_text(const std::string& unwrapped_text, int font_size, int
while(1) {
if(start_of_line) {
line_width = 0;
format_string = "";
while(ch != end && *ch < 0x100U && is_format_char(*ch)) {
format_string.append(ch.substr().first, ch.substr().second);
@ -1014,11 +1036,15 @@ std::string word_wrap_text(const std::string& unwrapped_text, int font_size, int
current_word = "";
start_of_line = true;
} else {
SDL_Rect size = line_size(current_line + current_word, font_size);
if(size.w > max_width) {
SDL_Rect wsize = line_size(current_word, font_size);
if(wsize.w > max_width) {
const std::string word = format_string + current_word;
const size_t word_width = line_size(word,font_size).w;
line_width += word_width;
if(line_width > max_width) {
if(word_width > max_width) {
cut_word(current_line, current_word, font_size, max_width);
}
if(current_word == " ")
@ -1032,16 +1058,24 @@ std::string word_wrap_text(const std::string& unwrapped_text, int font_size, int
if(line_break || current_word.empty() && ch == end) {
SDL_Rect size = line_size(current_line, font_size);
if(max_height > 0 && current_height + size.h >= size_t(max_height))
if(max_height > 0 && current_height + size.h >= size_t(max_height)) {
return wrapped_text;
}
if(!first)
if(!first) {
wrapped_text += '\n';
}
wrapped_text += current_line;
current_line = format_string;
line_width = 0;
current_height += size.h;
line_break = false;
first = false;
if(--max_lines == 0) {
return wrapped_text;
}
}
}
return wrapped_text;

View file

@ -124,7 +124,7 @@ SDL_Rect line_size(const std::string& line, int font_size, int style=TTF_STYLE_N
/// If the is not possible, e.g. the word is too big to fit, wrap it on a
/// char basis.
///
std::string word_wrap_text(const std::string& unwrapped_text, int font_size, int max_width, int max_height=-1);
std::string word_wrap_text(const std::string& unwrapped_text, int font_size, int max_width, int max_height=-1, int max_lines=-1);
///
/// If the text excedes the specified max width, end it with an ellipsis (...)

View file

@ -1908,20 +1908,11 @@ void help_text_area::add_text_item(const std::string text, const std::string ref
if (!surf.null())
add_item(item(surf, curr_loc_.first, curr_loc_.second, first_part, ref_dst));
if (parts.size() > 1) {
// Parts remain, remove the first part from the string and
// add the remaining parts.
std::string s = text;
s.erase(0, first_part.size());
if (s.length() < 1) {
return;
}
std::string& s = parts.back();
const std::string first_word_before = get_first_word(s);
const std::string first_word_after = get_first_word(remove_first_space(s));
//std::cout << "before: '" << first_word_before << "'\n"
// << "after: '" << first_word_after << "'\n"
// << "before linewidth: " << font::line_width(first_word_before, font_size)
// << "\nafter linewidth: " << font::line_width(first_word_after, font_size)
// << "\nremaining width: " << get_remaining_width() << std::endl;
if (get_remaining_width() >= font::line_width(first_word_after, font_size, state)
&& get_remaining_width()
< font::line_width(first_word_before, font_size, state)) {
@ -2513,9 +2504,14 @@ SDL_Color string_to_color(const std::string &s)
std::vector<std::string> split_in_width(const std::string &s, const int font_size,
const unsigned width)
{
std::string wrapped = font::word_wrap_text(s, font_size, width);
std::vector<std::string> parts = utils::split(wrapped, '\n', 0);
return parts;
std::vector<std::string> res;
const std::string& first_line = font::word_wrap_text(s, font_size, width, -1, 1);
res.push_back(first_line);
if(s.size() > first_line.size()) {
res.push_back(s.substr(first_line.size()));
}
return res;
}
std::string remove_first_space(const std::string& text)