applied 'adding a draw_wrapped_text method to font.cpp/font.hpp' patch

This commit is contained in:
uid66289 2004-02-20 18:29:05 +00:00
parent 0bc7078b00
commit f5e4cef460
2 changed files with 144 additions and 0 deletions

View file

@ -328,4 +328,120 @@ bool is_format_char(char c)
}
}
std::string remove_first_space(const std::string& text)
{
if (text.length() > 0 && text[0] == ' ') {
return text.substr(1);
}
return text;
}
}
namespace font {
int line_width(const std::string line, int font_size)
{
TTF_Font* const font = get_font(font_size);
if(font == NULL) {
std::cerr << "Could not get font\n";
return 0;
}
int w = 0;
int h = 0;
switch(charset())
{
case CHARSET_UTF8:
TTF_SizeUTF8(font, line.c_str(), &w, &h);
break;
case CHARSET_LATIN1:
TTF_SizeText(font, line.c_str(), &w, &h);
break;
default:
std::cerr << "Unrecognized charset\n";
}
return w;
}
std::string word_wrap_text(const std::string& unwrapped_text, int font_size, int max_width)
{
std::string wrapped_text; // the final result
size_t word_start_pos = 0;
std::string cur_word; // including start-whitespace
std::string cur_line; // the whole line so far
for(int c = 0; c < unwrapped_text.length(); c++) {
// Find the next word
bool forced_line_break = false;
if (c == unwrapped_text.length() - 1) {
cur_word = unwrapped_text.substr(word_start_pos, c + 1 - word_start_pos);
word_start_pos = c + 1;
} else if (unwrapped_text[c] == '\n') {
cur_word = unwrapped_text.substr(word_start_pos, c + 1 - word_start_pos);
word_start_pos = c + 1;
forced_line_break = true;
} else if (unwrapped_text[c] == ' ') {
cur_word = unwrapped_text.substr(word_start_pos, c - word_start_pos);
word_start_pos = c;
} else {
continue;
}
// Test if the line should be wrapped or not
if (line_width(cur_line + cur_word, font_size) > max_width) {
if (line_width(cur_word, font_size) > (max_width /*/ 2*/)) {
// The last word is too big to fit in a nice way, split it on a char basis
for (std::string::iterator i = cur_word.begin(); i != cur_word.end(); ++i) {
if (line_width(cur_line + *i, font_size) > max_width) {
wrapped_text += cur_line + '\n';
cur_line = *i;
} else {
cur_line += *i;
}
}
} else {
// Split the line on a word basis
wrapped_text += cur_line + '\n';
cur_line = remove_first_space(cur_word);
}
} else {
cur_line += cur_word;
}
if (forced_line_break) {
wrapped_text += cur_line;
cur_line = "";
forced_line_break = false;
}
}
// Don't forget to add the text left in cur_line
if (cur_line != "") {
wrapped_text += cur_line + '\n';
}
return wrapped_text;
}
SDL_Rect draw_wrapped_text(display* gui, const SDL_Rect& area, int font_size,
const SDL_Color& colour, const std::string& text,
int x, int y, int max_width, SDL_Surface* bg)
{
std::string wrapped_text = word_wrap_text(text, font_size, max_width);
return font::draw_text(gui, area, font_size, colour, wrapped_text, x, y, bg, false, NO_MARKUP);
}
}

View file

@ -63,8 +63,36 @@ SDL_Rect draw_text(display* gui, const SDL_Rect& area, int size,
int x, int y, SDL_Surface* bg=NULL,
bool use_tooltips=false, MARKUP use_markup=USE_MARKUP);
bool is_format_char(char c);
///
/// Determine the width of a line of text given a certain font size.
/// The font type used is the default wesnoth font type.
///
int line_width(const std::string line, int font_size);
///
/// If the text exceedes the specified max width, wrap it one a word basis.
/// 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);
///
/// Draw text on the screen. This method makes sure that the text
/// fits within a given maximum width. If a line exceedes this width it
/// will be wrapped on a word basis if possible, otherwise on a char
/// basis. This method is otherwise similar to the draw_text method,
/// but it doesn't support special markup or tooltips.
///
/// @return a bounding rectangle of the text.
///
SDL_Rect draw_wrapped_text(display* gui, const SDL_Rect& area, int font_size,
const SDL_Color& colour, const std::string& text,
int x, int y, int max_width, SDL_Surface* bg = NULL);
}
#endif