Fixed some more possible utf-8 related terminations.

This commit is contained in:
Mark de Wever 2007-11-24 12:36:19 +00:00
parent b7c86f8088
commit 97ec101021
5 changed files with 124 additions and 74 deletions

View file

@ -28,6 +28,7 @@ Version 1.3.11+svn:
* addon interface: added support for an ignore file (.ign) to configure what
shouldn't be uploaded on the addon server (it's useful if you use a svn
checkout for example)
* fixed some more possible utf-8 related terminations
Version 1.3.11:
* campaigns

View file

@ -857,7 +857,13 @@ void campaign_preview_pane::draw_contents()
f.draw_border();
/* description text */
const std::string& desc_text = font::word_wrap_text((*descriptions_)[index_].first,font::SIZE_SMALL,area.w-2*campaign_preview_border);
std::string desc_text;
try {
desc_text = font::word_wrap_text((*descriptions_)[index_].first,
font::SIZE_SMALL, area.w - 2 * campaign_preview_border);
} catch (utils::invalid_utf8_exception&) {
LOG_STREAM(err, engine) << "Invalid utf-8 found, campaign description is ignored.\n";
}
const std::vector<std::string> lines = utils::split(desc_text, '\n',utils::STRIP_SPACES);
SDL_Rect txt_area = { area.x+campaign_preview_border,area.y+campaign_preview_border,0,0 };

View file

@ -1551,14 +1551,20 @@ bool event_handler::handle_event_command(const queued_event& event_info,
// Redraw the unit, with its new stats
screen->draw();
const std::string duration_str = cfg["duration"];
const unsigned int lifetime = average_frame_time * lexical_cast_default<unsigned int>(duration_str, prevent_misclick_duration);
wml_event_dialog to_show(*screen,((surface.null())? caption : ""),text);
if(!surface.null()) {
to_show.set_image(surface, caption);
try {
const std::string duration_str = cfg["duration"];
const unsigned int lifetime = average_frame_time
* lexical_cast_default<unsigned int>(duration_str, prevent_misclick_duration);
wml_event_dialog to_show(*screen,((surface.null())? caption : ""),text);
if(!surface.null()) {
to_show.set_image(surface, caption);
}
to_show.layout();
to_show.show(lifetime);
} catch(utils::invalid_utf8_exception&) {
// we already had a warning so do nothing.
}
to_show.layout();
to_show.show(lifetime);
}
const vconfig::child_list commands = cfg.get_children(command_type);
@ -1717,34 +1723,37 @@ bool event_handler::handle_event_command(const queued_event& event_info,
const unsigned int lifetime = average_frame_time * lexical_cast_default<unsigned int>(duration_str, prevent_misclick_duration);
const SDL_Rect& map_area = screen->map_outside_area();
wml_event_dialog to_show(*screen, ((surface.null())? caption : ""),
msg, ((options.empty())? gui::MESSAGE : gui::OK_ONLY));
if(!surface.null()) {
to_show.set_image(surface, caption);
}
if(!options.empty()) {
to_show.set_menu(options);
}
gui::dialog::dimension_measurements dim = to_show.layout();
to_show.get_menu().set_width( dim.menu_width );
to_show.get_menu().set_max_width( dim.menu_width );
to_show.get_menu().wrap_words();
static const int dialog_top_offset = 26;
to_show.layout(-1, map_area.y + dialog_top_offset);
option_chosen = to_show.show(lifetime);
LOG_DP << "showed dialog...\n";
try {
wml_event_dialog to_show(*screen, ((surface.null())? caption : ""),
msg, ((options.empty())? gui::MESSAGE : gui::OK_ONLY));
if(!surface.null()) {
to_show.set_image(surface, caption);
}
if(!options.empty()) {
to_show.set_menu(options);
}
gui::dialog::dimension_measurements dim = to_show.layout();
to_show.get_menu().set_width( dim.menu_width );
to_show.get_menu().set_max_width( dim.menu_width );
to_show.get_menu().wrap_words();
static const int dialog_top_offset = 26;
to_show.layout(-1, map_area.y + dialog_top_offset);
option_chosen = to_show.show(lifetime);
LOG_DP << "showed dialog...\n";
if (option_chosen == gui::ESCAPE_DIALOG){
rval = false;
}
if (option_chosen == gui::ESCAPE_DIALOG){
rval = false;
}
if(options.empty() == false) {
recorder.choose_option(option_chosen);
if(options.empty() == false) {
recorder.choose_option(option_chosen);
}
} catch(utils::invalid_utf8_exception&) {
// we already had a warning so do nothing.
}
}
// Otherwise if a choice has to be made, get it from the replay data
else {
} else {
const config* action = get_replay_source().get_next_action();
if (action != NULL && !action->get_children("start").empty()){
action = get_replay_source().get_next_action();

View file

@ -79,6 +79,15 @@ void show_intro(display &disp, const config& data, const config& level)
LOG_NG << "intro sequence finished...\n";
}
//! show_intro_part() is split into two parts, the second part can cause
//! an utils::invalid_utf8_exception exception and it's to much code
//! to indent. The solution is not very clean but the entire routine could
//! use a cleanup.
static bool show_intro_part_helper(display &disp, const config& part,
int textx, int texty,
gui::button& next_button, gui::button& skip_button,
CKey& key);
bool show_intro_part(display &disp, const config& part,
const std::string& scenario)
{
@ -93,7 +102,6 @@ bool show_intro_part(display &disp, const config& part,
}
CKey key;
bool lang_rtl = current_language_rtl();
gui::button next_button(video,_("Next") + std::string(">>>"));
gui::button skip_button(video,_("Skip"));
@ -244,9 +252,30 @@ bool show_intro_part(display &disp, const config& part,
}
}
}
try {
return show_intro_part_helper(
disp, part, textx, texty, next_button, skip_button, key);
} catch (utils::invalid_utf8_exception&) {
LOG_STREAM(err, engine) << "Invalid utf-8 found, story message is ignored.\n";
// stop showing on an error, there might be more badly formed utf-8 messages
return false;
}
}
static bool show_intro_part_helper(display &disp, const config& part,
int textx, int texty,
gui::button& next_button, gui::button& skip_button,
CKey& key)
{
bool lang_rtl = current_language_rtl();
CVideo &video = disp.video();
const int max_width = next_button.location().x - 10 - textx;
const std::string story = font::word_wrap_text(part["story"], font::SIZE_PLUS, max_width);
const std::string story =
font::word_wrap_text(part["story"], font::SIZE_PLUS, max_width);
utils::utf8_iterator itor(story);
bool skip = false, last_key = true;

View file

@ -192,57 +192,62 @@ static void draw_tip_of_day(game_display& screen,
const config* tip = get_tip_of_day(tips_of_day);
if(tip != NULL) {
int tip_width = game_config::title_tip_width * screen.w() / 1024;
//const std::string& std::string text = (*tip)["text"];
//const std::string& std::string text = (*tip)["source"];
const std::string& text = font::word_wrap_text((*tip)["text"], font::SIZE_NORMAL, tip_width);
const std::string& source = font::word_wrap_text((*tip)["source"], font::SIZE_NORMAL, tip_width);
try {
const std::string& text =
font::word_wrap_text((*tip)["text"], font::SIZE_NORMAL, tip_width);
const std::string& source =
font::word_wrap_text((*tip)["source"], font::SIZE_NORMAL, tip_width);
const int pad = game_config::title_tip_padding;
const int pad = game_config::title_tip_padding;
SDL_Rect area = font::text_area(text,font::SIZE_NORMAL);
area.w = tip_width;
SDL_Rect source_area = font::text_area(source, font::SIZE_NORMAL, TTF_STYLE_ITALIC);
area.w = maximum<size_t>(area.w, source_area.w) + 2*pad;
area.h += source_area.h + next_tip_button->location().h + 3*pad;
SDL_Rect area = font::text_area(text,font::SIZE_NORMAL);
area.w = tip_width;
SDL_Rect source_area = font::text_area(source, font::SIZE_NORMAL, TTF_STYLE_ITALIC);
area.w = maximum<size_t>(area.w, source_area.w) + 2*pad;
area.h += source_area.h + next_tip_button->location().h + 3*pad;
area.x = main_dialog_area->x - (game_config::title_tip_x * screen.w() / 1024) - area.w;
area.y = main_dialog_area->y + main_dialog_area->h - area.h;
area.x = main_dialog_area->x - (game_config::title_tip_x * screen.w() / 1024) - area.w;
area.y = main_dialog_area->y + main_dialog_area->h - area.h;
// Note: The buttons' locations need to be set before the dialog frame is drawn.
// Otherwise, when the buttons restore their area, they
// draw parts of the old dialog frame at their old locations.
// This way, the buttons draw a part of the title image,
// because the call to restore above restored the area
// of the old tip of the day to its initial state (the title image).
int button_x = area.x + area.w - next_tip_button->location().w - pad;
int button_y = area.y + area.h - pad - next_tip_button->location().h;
next_tip_button->set_location(button_x, button_y);
next_tip_button->set_dirty(); //force redraw even if location did not change.
// Note: The buttons' locations need to be set before the dialog frame is drawn.
// Otherwise, when the buttons restore their area, they
// draw parts of the old dialog frame at their old locations.
// This way, the buttons draw a part of the title image,
// because the call to restore above restored the area
// of the old tip of the day to its initial state (the title image).
int button_x = area.x + area.w - next_tip_button->location().w - pad;
int button_y = area.y + area.h - pad - next_tip_button->location().h;
next_tip_button->set_location(button_x, button_y);
next_tip_button->set_dirty(); //force redraw even if location did not change.
button_x -= previous_tip_button->location().w + pad;
previous_tip_button->set_location(button_x, button_y);
previous_tip_button->set_dirty();
button_x -= previous_tip_button->location().w + pad;
previous_tip_button->set_location(button_x, button_y);
previous_tip_button->set_dirty();
button_x = area.x + pad;
help_tip_button->set_location(button_x, button_y);
help_tip_button->set_dirty();
button_x = area.x + pad;
help_tip_button->set_location(button_x, button_y);
help_tip_button->set_dirty();
gui::dialog_frame f(screen.video(), "", style, false);
tip_of_day_restorer = surface_restorer(&screen.video(), f.layout(area).exterior);
f.draw_background();
f.draw_border();
gui::dialog_frame f(screen.video(), "", style, false);
tip_of_day_restorer = surface_restorer(&screen.video(), f.layout(area).exterior);
f.draw_background();
f.draw_border();
font::draw_text(&screen.video(), area, font::SIZE_NORMAL, font::NORMAL_COLOUR,
text, area.x + pad, area.y + pad);
// todo
font::draw_text(&screen.video(), area, font::SIZE_NORMAL, font::NORMAL_COLOUR,
source, area.x + area.w - source_area.w - pad,
next_tip_button->location().y - source_area.h - pad,
false, TTF_STYLE_ITALIC);
}
font::draw_text(&screen.video(), area, font::SIZE_NORMAL, font::NORMAL_COLOUR,
text, area.x + pad, area.y + pad);
// todo
font::draw_text(&screen.video(), area, font::SIZE_NORMAL, font::NORMAL_COLOUR,
source, area.x + area.w - source_area.w - pad,
next_tip_button->location().y - source_area.h - pad,
false, TTF_STYLE_ITALIC);
} catch (utils::invalid_utf8_exception&) {
LOG_STREAM(err, engine) << "Invalid utf-8 found, tips of day aren't drawn.\n";
return;
}
LOG_DP << "drew tip of day\n";
LOG_DP << "drew tip of day\n";
}
}
namespace gui {