From 2f7bf5676ef8b6b9ff3cf28468efe536888808b5 Mon Sep 17 00:00:00 2001 From: Ingo Ruhnke Date: Sun, 28 Jan 2007 19:45:34 +0000 Subject: [PATCH] - renamed LEFT_ALLIGN to ALIGN_LEFT - some cleanup and bug fixes with the variable width font handling SVN-Revision: 4716 --- src/console.cpp | 7 +- src/game_session.cpp | 6 +- src/gui/button.cpp | 4 +- src/gui/menu.cpp | 24 ++--- src/mainloop.cpp | 4 +- src/object/gameobjs.cpp | 2 +- src/object/level_time.cpp | 2 +- src/object/text_object.cpp | 3 +- src/player_status.cpp | 2 +- src/resources.cpp | 21 ++-- src/statistics.cpp | 46 ++++----- src/textscroller.cpp | 4 +- src/title.cpp | 8 +- src/video/drawing_context.cpp | 2 +- src/video/font.cpp | 219 ++++++++++++++++++++++++------------------ src/video/font.hpp | 30 ++++-- src/worldmap/worldmap.cpp | 12 +-- 17 files changed, 225 insertions(+), 171 deletions(-) diff --git a/src/console.cpp b/src/console.cpp index ead91286e..a605702d3 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -50,7 +50,8 @@ Console::~Console() void Console::init_graphics() { - font.reset(new Font("images/engine/fonts/white-small.png", + font.reset(new Font(Font::FIXED, + "images/engine/fonts/white-small.png", "images/engine/fonts/shadow-small.png", 8, 9, 1)); fontheight = font->get_height(); background.reset(new Surface("images/engine/console.png")); @@ -457,7 +458,7 @@ Console::draw(DrawingContext& context) if (focused) { lineNo++; float py = height-4-1*9; - context.draw_text(font.get(), "> "+inputBuffer.str()+"_", Vector(4, py), LEFT_ALLIGN, layer); + context.draw_text(font.get(), "> "+inputBuffer.str()+"_", Vector(4, py), ALIGN_LEFT, layer); } int skipLines = -offset; @@ -466,7 +467,7 @@ Console::draw(DrawingContext& context) lineNo++; float py = height-4-lineNo*9; if (py < -9) break; - context.draw_text(font.get(), *i, Vector(4, py), LEFT_ALLIGN, layer); + context.draw_text(font.get(), *i, Vector(4, py), ALIGN_LEFT, layer); } context.pop_transform(); } diff --git a/src/game_session.cpp b/src/game_session.cpp index 38b6f46d3..c4ee38348 100644 --- a/src/game_session.cpp +++ b/src/game_session.cpp @@ -248,19 +248,19 @@ GameSession::levelintro() } // context.draw_text(gold_text, level->get_name(), Vector(SCREEN_WIDTH/2, 160), -// CENTER_ALLIGN, LAYER_FOREGROUND1); +// ALIGN_CENTER, LAYER_FOREGROUND1); context.draw_center_text(gold_text, level->get_name(), Vector(0, 160), LAYER_FOREGROUND1); std::stringstream ss_coins; ss_coins << _("Coins") << ": " << player_status->coins; context.draw_text(white_text, ss_coins.str(), Vector(SCREEN_WIDTH/2, 210), - CENTER_ALLIGN, LAYER_FOREGROUND1); + ALIGN_CENTER, LAYER_FOREGROUND1); if((level->get_author().size()) && (level->get_author() != "SuperTux Team")) context.draw_text(white_small_text, std::string(_("contributed by ")) + level->get_author(), - Vector(SCREEN_WIDTH/2, 350), CENTER_ALLIGN, LAYER_FOREGROUND1); + Vector(SCREEN_WIDTH/2, 350), ALIGN_CENTER, LAYER_FOREGROUND1); if(best_level_statistics != NULL) best_level_statistics->draw_message_info(context, _("Best Level Statistics")); diff --git a/src/gui/button.cpp b/src/gui/button.cpp index 4ddaa1492..6b16a130d 100644 --- a/src/gui/button.cpp +++ b/src/gui/button.cpp @@ -63,11 +63,11 @@ if(state == BT_SHOW_INFO) offset = Vector(size.x, 0); else offset = Vector(-30, -size.y/2); - context.draw_text(info_font, info, pos + offset, LEFT_ALLIGN, LAYER_GUI+2); + context.draw_text(info_font, info, pos + offset, ALIGN_LEFT, LAYER_GUI+2); if(binding != 0) context.draw_text(info_font, "(" + std::string(SDL_GetKeyName(binding)) + ")", pos + offset + Vector(0,12), - LEFT_ALLIGN, LAYER_GUI+2); + ALIGN_LEFT, LAYER_GUI+2); } context.draw_surface_part(image, Vector(0,0), size, pos, LAYER_GUI+1); diff --git a/src/gui/menu.cpp b/src/gui/menu.cpp index e2ec179c3..613c8faea 100644 --- a/src/gui/menu.cpp +++ b/src/gui/menu.cpp @@ -531,7 +531,7 @@ Menu::draw_item(DrawingContext& context, int index) { context.draw_text(deactive_font, pitem.text, Vector(SCREEN_WIDTH/2, y_pos - int(deactive_font->get_height()/2)), - CENTER_ALLIGN, LAYER_GUI); + ALIGN_CENTER, LAYER_GUI); break; } @@ -553,7 +553,7 @@ Menu::draw_item(DrawingContext& context, int index) { context.draw_text(label_font, pitem.text, Vector(SCREEN_WIDTH/2, y_pos - int(label_font->get_height()/2)), - CENTER_ALLIGN, LAYER_GUI); + ALIGN_CENTER, LAYER_GUI); break; } case MN_TEXTFIELD: @@ -579,21 +579,21 @@ Menu::draw_item(DrawingContext& context, int index) context.draw_text(field_font, pitem.get_input_with_symbol(true), Vector(input_pos, y_pos - int(field_font->get_height()/2)), - LEFT_ALLIGN, LAYER_GUI); + ALIGN_LEFT, LAYER_GUI); else context.draw_text(field_font, pitem.get_input_with_symbol(false), Vector(input_pos, y_pos - int(field_font->get_height()/2)), - LEFT_ALLIGN, LAYER_GUI); + ALIGN_LEFT, LAYER_GUI); } else context.draw_text(field_font, pitem.input, Vector(input_pos, y_pos - int(field_font->get_height()/2)), - LEFT_ALLIGN, LAYER_GUI); + ALIGN_LEFT, LAYER_GUI); context.draw_text(text_font, pitem.text, Vector(text_pos, y_pos - int(text_font->get_height()/2)), - LEFT_ALLIGN, LAYER_GUI); + ALIGN_LEFT, LAYER_GUI); break; } case MN_STRINGSELECT: @@ -622,17 +622,17 @@ Menu::draw_item(DrawingContext& context, int index) context.draw_text(text_font, pitem.list[pitem.selected], Vector(SCREEN_WIDTH/2 + text_pos, y_pos - int(text_font->get_height()/2)), - CENTER_ALLIGN, LAYER_GUI); + ALIGN_CENTER, LAYER_GUI); context.draw_text(text_font, pitem.text, Vector(SCREEN_WIDTH/2 + list_pos_2/2, y_pos - int(text_font->get_height()/2)), - CENTER_ALLIGN, LAYER_GUI); + ALIGN_CENTER, LAYER_GUI); break; } case MN_BACK: { context.draw_text(text_font, pitem.text, Vector(SCREEN_WIDTH/2, y_pos - int(text_font->get_height()/2)), - CENTER_ALLIGN, LAYER_GUI); + ALIGN_CENTER, LAYER_GUI); context.draw_surface(back.get(), Vector(x_pos + text_width/2 + 16, y_pos - 8), LAYER_GUI); @@ -643,7 +643,7 @@ Menu::draw_item(DrawingContext& context, int index) { context.draw_text(text_font, pitem.text, Vector(SCREEN_WIDTH/2, y_pos - (text_font->get_height()/2)), - CENTER_ALLIGN, LAYER_GUI); + ALIGN_CENTER, LAYER_GUI); if(pitem.toggled) context.draw_surface(checkbox_checked.get(), @@ -658,13 +658,13 @@ Menu::draw_item(DrawingContext& context, int index) case MN_ACTION: context.draw_text(text_font, pitem.text, Vector(SCREEN_WIDTH/2, y_pos - int(text_font->get_height()/2)), - CENTER_ALLIGN, LAYER_GUI); + ALIGN_CENTER, LAYER_GUI); break; case MN_GOTO: context.draw_text(text_font, pitem.text, Vector(SCREEN_WIDTH/2, y_pos - int(text_font->get_height()/2)), - CENTER_ALLIGN, LAYER_GUI); + ALIGN_CENTER, LAYER_GUI); break; } } diff --git a/src/mainloop.cpp b/src/mainloop.cpp index 52ccf6092..b49915b99 100644 --- a/src/mainloop.cpp +++ b/src/mainloop.cpp @@ -115,8 +115,8 @@ MainLoop::draw_fps(DrawingContext& context, float fps_fps) char str[60]; snprintf(str, sizeof(str), "%3.1f", fps_fps); const char* fpstext = "FPS"; - context.draw_text(white_text, fpstext, Vector(SCREEN_WIDTH - white_text->get_text_width(fpstext) - gold_text->get_text_width(" 99999") - BORDER_X, BORDER_Y + 20), LEFT_ALLIGN, LAYER_HUD); - context.draw_text(gold_text, str, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y + 20), RIGHT_ALLIGN, LAYER_HUD); + context.draw_text(white_text, fpstext, Vector(SCREEN_WIDTH - white_text->get_text_width(fpstext) - gold_text->get_text_width(" 99999") - BORDER_X, BORDER_Y + 20), ALIGN_LEFT, LAYER_HUD); + context.draw_text(gold_text, str, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y + 20), ALIGN_RIGHT, LAYER_HUD); } void diff --git a/src/object/gameobjs.cpp b/src/object/gameobjs.cpp index 2da97746f..1eed690db 100644 --- a/src/object/gameobjs.cpp +++ b/src/object/gameobjs.cpp @@ -142,7 +142,7 @@ FloatingText::draw(DrawingContext& context) context.push_transform(); context.set_alpha(alpha); - context.draw_text(gold_text, text, position, LEFT_ALLIGN, LAYER_OBJECTS+1); + context.draw_text(gold_text, text, position, ALIGN_LEFT, LAYER_OBJECTS+1); context.pop_transform(); } diff --git a/src/object/level_time.cpp b/src/object/level_time.cpp index 5ac1ba2cd..92a5a9082 100644 --- a/src/object/level_time.cpp +++ b/src/object/level_time.cpp @@ -98,7 +98,7 @@ LevelTime::draw(DrawingContext& context) if (time_surf) { float all_width = time_surf->get_width() + white_text->get_text_width(time_text); context.draw_surface(time_surf, Vector((SCREEN_WIDTH - all_width)/2, BORDER_Y + 1), LAYER_FOREGROUND1); - context.draw_text(gold_text, time_text, Vector((SCREEN_WIDTH - all_width)/2 + time_surf->get_width(), BORDER_Y), LEFT_ALLIGN, LAYER_FOREGROUND1); + context.draw_text(gold_text, time_text, Vector((SCREEN_WIDTH - all_width)/2 + time_surf->get_width(), BORDER_Y), ALIGN_LEFT, LAYER_FOREGROUND1); } } diff --git a/src/object/text_object.cpp b/src/object/text_object.cpp index 305193762..aa16a2989 100644 --- a/src/object/text_object.cpp +++ b/src/object/text_object.cpp @@ -128,8 +128,9 @@ TextObject::draw(DrawingContext& context) Color(0.6f, 0.7f, 0.8f, 0.5f), LAYER_GUI-50); if (centered) { context.draw_center_text(font, text, Vector(0, 50+35), LAYER_GUI-40); + } else { + context.draw_text(font, text, Vector(125+35, 50+35), ALIGN_LEFT, LAYER_GUI-40); } - else context.draw_text(font, text, Vector(125+35, 50+35), LEFT_ALLIGN, LAYER_GUI-40); context.pop_transform(); } diff --git a/src/player_status.cpp b/src/player_status.cpp index 1f233bd4b..a5fcf1e3d 100644 --- a/src/player_status.cpp +++ b/src/player_status.cpp @@ -155,7 +155,7 @@ PlayerStatus::draw(DrawingContext& context) if (coin_surf) { context.draw_surface(coin_surf, Vector(SCREEN_WIDTH - BORDER_X - coin_surf->get_width() - gold_text->get_text_width(coins_text), BORDER_Y + 1), LAYER_HUD); } - context.draw_text(gold_text, coins_text, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y), RIGHT_ALLIGN, LAYER_HUD); + context.draw_text(gold_text, coins_text, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y), ALIGN_RIGHT, LAYER_HUD); context.pop_transform(); } diff --git a/src/resources.cpp b/src/resources.cpp index a4a3f80a1..ef251a658 100644 --- a/src/resources.cpp +++ b/src/resources.cpp @@ -45,18 +45,25 @@ void load_shared() MouseCursor::set_current(mouse_cursor); /* Load global images: */ - gold_text = new Font("images/engine/fonts/gold.png", + gold_text = new Font(Font::FIXED, + "images/engine/fonts/gold.png", "images/engine/fonts/shadow.png", 16, 18); - blue_text = new Font("images/engine/fonts/blue.png", + blue_text = new Font(Font::FIXED, + "images/engine/fonts/blue.png", "images/engine/fonts/shadow.png", 16, 18, 3); // white_text = new Font("images/engine/fonts/white.png", // "images/engine/fonts/shadow.png", 16, 18); - white_text = new Font("images/engine/fonts/white.png", 16, 18); - gray_text = new Font("images/engine/fonts/gray.png", + white_text = new Font(Font::VARIABLE, + "images/engine/fonts/white.png", 16, 18); + gray_text = new Font(Font::FIXED, + "images/engine/fonts/gray.png", "images/engine/fonts/shadow.png", 16, 18); - white_small_text = new Font("images/engine/fonts/white-small.png", - "images/engine/fonts/shadow-small.png", 8, 9, 1); - white_big_text = new Font("images/engine/fonts/white-big.png", + white_small_text = new Font(Font::VARIABLE, + "images/engine/fonts/white-small.png", + 8, 9); + // "images/engine/fonts/shadow-small.png", 8, 9, 1); + white_big_text = new Font(Font::FIXED, + "images/engine/fonts/white-big.png", "images/engine/fonts/shadow-big.png", 20, 22, 3); Menu::default_font = white_text; diff --git a/src/statistics.cpp b/src/statistics.cpp index 0086eeec0..c21ec3d0c 100644 --- a/src/statistics.cpp +++ b/src/statistics.cpp @@ -95,7 +95,7 @@ Statistics::draw_worldmap_info(DrawingContext& context) // skip draw if stats were declared invalid if (!valid) return; - context.draw_text(white_small_text, std::string("- ") + _("Best Level Statistics") + " -", Vector((WMAP_INFO_LEFT_X + WMAP_INFO_RIGHT_X) / 2, WMAP_INFO_TOP_Y1), CENTER_ALLIGN, LAYER_GUI); + context.draw_text(white_small_text, std::string("- ") + _("Best Level Statistics") + " -", Vector((WMAP_INFO_LEFT_X + WMAP_INFO_RIGHT_X) / 2, WMAP_INFO_TOP_Y1), ALIGN_CENTER, LAYER_GUI); float alpha; if(timer.get_timegone() < FADING_TIME) @@ -145,8 +145,8 @@ Statistics::draw_worldmap_info(DrawingContext& context) if (display_stat > 3) display_stat = 0; } - context.draw_text(white_small_text, caption_buf, Vector(WMAP_INFO_LEFT_X, WMAP_INFO_TOP_Y2), LEFT_ALLIGN, LAYER_GUI); - context.draw_text(white_small_text, stat_buf, Vector(WMAP_INFO_RIGHT_X, WMAP_INFO_TOP_Y2), RIGHT_ALLIGN, LAYER_GUI); + context.draw_text(white_small_text, caption_buf, Vector(WMAP_INFO_LEFT_X, WMAP_INFO_TOP_Y2), ALIGN_LEFT, LAYER_GUI); + context.draw_text(white_small_text, stat_buf, Vector(WMAP_INFO_RIGHT_X, WMAP_INFO_TOP_Y2), ALIGN_RIGHT, LAYER_GUI); context.pop_transform(); } @@ -164,32 +164,32 @@ Statistics::draw_message_info(DrawingContext& context, std::string title) const float left = (SCREEN_WIDTH - width) / 2; const float right = (SCREEN_WIDTH + width) / 2; - context.draw_text(gold_text, title, Vector(SCREEN_WIDTH/2, 410), CENTER_ALLIGN, LAYER_GUI); + context.draw_text(gold_text, title, Vector(SCREEN_WIDTH/2, 410), ALIGN_CENTER, LAYER_GUI); char stat_buf[128]; int py = 450 + 18; snprintf(stat_buf, sizeof(stat_buf), "%d/%d", coins, total_coins); - context.draw_text(white_small_text, _("Max coins collected:"), Vector(left, py), LEFT_ALLIGN, LAYER_GUI); - context.draw_text(white_small_text, "%d / %d", Vector(right, py), RIGHT_ALLIGN, LAYER_GUI); + context.draw_text(white_small_text, _("Max coins collected:"), Vector(left, py), ALIGN_LEFT, LAYER_GUI); + context.draw_text(white_small_text, "%d / %d", Vector(right, py), ALIGN_RIGHT, LAYER_GUI); py+=18; snprintf(stat_buf, sizeof(stat_buf), "%d/%d", badguys, total_badguys); - context.draw_text(white_small_text, _("Max fragging:"), Vector(left, py), LEFT_ALLIGN, LAYER_GUI); - context.draw_text(white_small_text, "%d / %d", Vector(right, py), RIGHT_ALLIGN, LAYER_GUI); + context.draw_text(white_small_text, _("Max fragging:"), Vector(left, py), ALIGN_LEFT, LAYER_GUI); + context.draw_text(white_small_text, "%d / %d", Vector(right, py), ALIGN_RIGHT, LAYER_GUI); py+=18; int csecs = (int)(time * 100); int mins = (int)(csecs / 6000); int secs = (csecs % 6000) / 100; snprintf(stat_buf, sizeof(stat_buf), "%02d:%02d", mins,secs); - context.draw_text(white_small_text, _("Min time needed:"), Vector(left, py), LEFT_ALLIGN, LAYER_GUI); - context.draw_text(white_small_text, "%02d:%02d", Vector(right, py), RIGHT_ALLIGN, LAYER_GUI); + context.draw_text(white_small_text, _("Min time needed:"), Vector(left, py), ALIGN_LEFT, LAYER_GUI); + context.draw_text(white_small_text, "%02d:%02d", Vector(right, py), ALIGN_RIGHT, LAYER_GUI); py+=18; snprintf(stat_buf, sizeof(stat_buf), "%d/%d", secrets, total_secrets); - context.draw_text(white_small_text, _("Max secrets found:"), Vector(left, py), LEFT_ALLIGN, LAYER_GUI); - context.draw_text(white_small_text, "%d / %d", Vector(right, py), RIGHT_ALLIGN, LAYER_GUI); + context.draw_text(white_small_text, _("Max secrets found:"), Vector(left, py), ALIGN_LEFT, LAYER_GUI); + context.draw_text(white_small_text, "%d / %d", Vector(right, py), ALIGN_RIGHT, LAYER_GUI); py+=18; } @@ -231,38 +231,38 @@ Statistics::draw_endseq_panel(DrawingContext& context, Statistics* best_stats, S context.pop_transform(); char buf[129]; - context.draw_text(white_text, _("You"), Vector(col2_x, row1_y), LEFT_ALLIGN, LAYER_GUI); - context.draw_text(white_text, _("Best"), Vector(col3_x, row1_y), LEFT_ALLIGN, LAYER_GUI); + context.draw_text(white_text, _("You"), Vector(col2_x, row1_y), ALIGN_LEFT, LAYER_GUI); + context.draw_text(white_text, _("Best"), Vector(col3_x, row1_y), ALIGN_LEFT, LAYER_GUI); - context.draw_text(white_text, _("Coins"), Vector(col2_x-16, row2_y), RIGHT_ALLIGN, LAYER_GUI); + context.draw_text(white_text, _("Coins"), Vector(col2_x-16, row2_y), ALIGN_RIGHT, LAYER_GUI); snprintf(buf, sizeof(buf), "%d/%d", std::min(coins, 999), std::min(total_coins, 999)); - context.draw_text(gold_text, buf, Vector(col2_x, row2_y), LEFT_ALLIGN, LAYER_GUI); + context.draw_text(gold_text, buf, Vector(col2_x, row2_y), ALIGN_LEFT, LAYER_GUI); if (best_stats && (best_stats->coins > coins)) { snprintf(buf, sizeof(buf), "%d/%d", std::min(best_stats->coins, 999), std::min(best_stats->total_coins, 999)); } - context.draw_text(gold_text, buf, Vector(col3_x, row2_y), LEFT_ALLIGN, LAYER_GUI); + context.draw_text(gold_text, buf, Vector(col3_x, row2_y), ALIGN_LEFT, LAYER_GUI); - context.draw_text(white_text, _("Secrets"), Vector(col2_x-16, row4_y), RIGHT_ALLIGN, LAYER_GUI); + context.draw_text(white_text, _("Secrets"), Vector(col2_x-16, row4_y), ALIGN_RIGHT, LAYER_GUI); snprintf(buf, sizeof(buf), "%d/%d", secrets, total_secrets); - context.draw_text(gold_text, buf, Vector(col2_x, row4_y), LEFT_ALLIGN, LAYER_GUI); + context.draw_text(gold_text, buf, Vector(col2_x, row4_y), ALIGN_LEFT, LAYER_GUI); if (best_stats && (best_stats->secrets > secrets)) { snprintf(buf, sizeof(buf), "%d/%d", best_stats->secrets, best_stats->total_secrets); } - context.draw_text(gold_text, buf, Vector(col3_x, row4_y), LEFT_ALLIGN, LAYER_GUI); + context.draw_text(gold_text, buf, Vector(col3_x, row4_y), ALIGN_LEFT, LAYER_GUI); - context.draw_text(white_text, _("Time"), Vector(col2_x-16, row3_y), RIGHT_ALLIGN, LAYER_GUI); + context.draw_text(white_text, _("Time"), Vector(col2_x-16, row3_y), ALIGN_RIGHT, LAYER_GUI); int csecs = (int)(time * 100); int mins = (int)(csecs / 6000); int secs = (csecs % 6000) / 100; snprintf(buf, sizeof(buf), "%02d:%02d", mins,secs); - context.draw_text(gold_text, buf, Vector(col2_x, row3_y), LEFT_ALLIGN, LAYER_GUI); + context.draw_text(gold_text, buf, Vector(col2_x, row3_y), ALIGN_LEFT, LAYER_GUI); if (best_stats && (best_stats->time < time)) { int csecs = (int)(best_stats->time * 100); int mins = (int)(csecs / 6000); int secs = (csecs % 6000) / 100; snprintf(buf, sizeof(buf), "%02d:%02d", mins,secs); } - context.draw_text(gold_text, buf, Vector(col3_x, row3_y), LEFT_ALLIGN, LAYER_GUI); + context.draw_text(gold_text, buf, Vector(col3_x, row3_y), ALIGN_LEFT, LAYER_GUI); } void diff --git a/src/textscroller.cpp b/src/textscroller.cpp index 2db45c9b1..bca514c5d 100644 --- a/src/textscroller.cpp +++ b/src/textscroller.cpp @@ -311,10 +311,10 @@ InfoBoxLine::draw(DrawingContext& context, const Vector& position, int layer) context.draw_surface(image, Vector( (SCREEN_WIDTH - image->get_width()) / 2, position.y), layer); break; case NORMAL_LEFT: - context.draw_text(font, text, Vector(position.x, position.y), LEFT_ALLIGN, layer); + context.draw_text(font, text, Vector(position.x, position.y), ALIGN_LEFT, layer); break; default: - context.draw_text(font, text, Vector(SCREEN_WIDTH/2, position.y), CENTER_ALLIGN, layer); + context.draw_text(font, text, Vector(SCREEN_WIDTH/2, position.y), ALIGN_CENTER, layer); break; } } diff --git a/src/title.cpp b/src/title.cpp index 6abfa3c32..aa10f7912 100644 --- a/src/title.cpp +++ b/src/title.cpp @@ -396,16 +396,16 @@ TitleScreen::draw(DrawingContext& context) Sector* sector = titlesession->get_current_sector(); sector->draw(context); - context.draw_text(white_small_text, " SuperTux " PACKAGE_VERSION "\n", - Vector(0, SCREEN_HEIGHT - 50), LEFT_ALLIGN, LAYER_FOREGROUND1); + context.draw_text(white_small_text, "SuperTux " PACKAGE_VERSION "\n", + Vector(5, SCREEN_HEIGHT - 50), ALIGN_LEFT, LAYER_FOREGROUND1); context.draw_text(white_small_text, _( "Copyright (c) 2006 SuperTux Devel Team\n" "This game comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to\n" "redistribute it under certain conditions; see the file COPYING for details.\n" ), - Vector(0, SCREEN_HEIGHT - 50 + white_small_text->get_height() + 5), - LEFT_ALLIGN, LAYER_FOREGROUND1); + Vector(5, SCREEN_HEIGHT - 50 + white_small_text->get_height() + 5), + ALIGN_LEFT, LAYER_FOREGROUND1); } void diff --git a/src/video/drawing_context.cpp b/src/video/drawing_context.cpp index 61e64328c..4c5f17927 100644 --- a/src/video/drawing_context.cpp +++ b/src/video/drawing_context.cpp @@ -170,7 +170,7 @@ DrawingContext::draw_center_text(const Font* font, const std::string& text, const Vector& position, int layer) { draw_text(font, text, Vector(position.x + SCREEN_WIDTH/2, position.y), - CENTER_ALLIGN, layer); + ALIGN_CENTER, layer); } void diff --git a/src/video/font.cpp b/src/video/font.cpp index 640ee3add..395b6c331 100644 --- a/src/video/font.cpp +++ b/src/video/font.cpp @@ -2,6 +2,7 @@ // // SuperTux // Copyright (C) 2006 Matthias Braun +// Ingo Ruhnke // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -37,6 +38,41 @@ namespace { bool has_multibyte_mark(unsigned char c); uint32_t decode_utf8(const std::string& text, size_t& p); +struct UTF8Iterator +{ + const std::string& text; + std::string::size_type pos; + uint32_t chr; + + UTF8Iterator(const std::string& text_) + : text(text_), + pos(0) + { + chr = decode_utf8(text, pos); + } + + bool done() const + { + return pos > text.size(); + } + + UTF8Iterator& operator++() { + try { + chr = decode_utf8(text, pos); + } catch (std::runtime_error) { + log_debug << "Malformed utf-8 sequence beginning with " << *((uint32_t*)(text.c_str() + pos)) << " found " << std::endl; + chr = 0; + ++pos; + } + + return *this; + } + + uint32_t operator*() const { + return chr; + } +}; + bool vline_empty(SDL_Surface* surface, int x, int start_y, int end_y, Uint8 threshold) { Uint8* pixels = (Uint8*)surface->pixels; @@ -53,10 +89,12 @@ bool vline_empty(SDL_Surface* surface, int x, int start_y, int end_y, Uint8 thre } } // namespace -Font::Font(const std::string& file, const std::string& shadowfile, - int w, int h, int shadowsize) - : glyph_surface(0), shadow_chars(0), - char_width(w), char_height(h), +Font::Font(GlyphWidth glyph_width_, + const std::string& file, const std::string& shadowfile, + int char_width, int char_height_, int shadowsize) + : glyph_width(glyph_width_), + glyph_surface(0), shadow_chars(0), + char_height(char_height_), shadowsize(shadowsize) { glyph_surface = new Surface(file); @@ -74,9 +112,10 @@ Font::Font(const std::string& file, const std::string& shadowfile, } } -Font::Font(const std::string& filename, int char_width_, int char_height_) - : glyph_surface(0), shadow_chars(0), - char_width(char_width_), char_height(char_height_), +Font::Font(GlyphWidth glyph_width_, const std::string& filename, int char_width, int char_height_) + : glyph_width(glyph_width_), + glyph_surface(0), shadow_chars(0), + char_height(char_height_), shadowsize(0) { glyph_surface = new Surface(filename); @@ -135,18 +174,17 @@ Font::get_text_width(const std::string& text) const float curr_width = 0; float last_width = 0; - // FIXME: add UTF8 decode here - for(std::string::size_type i = 0; i < text.size(); ++i) + for(UTF8Iterator it(text); !it.done(); ++it) { - uint32_t chr = text[i]; - if (chr == '\n') + if (*it == '\n') { last_width = std::max(last_width, curr_width); curr_width = 0; } else { - curr_width += glyphs[static_cast(text[i])].get_width() + 1; + int idx = chr2glyph(*it); + curr_width += glyphs[idx].get_width(); } } @@ -158,9 +196,11 @@ Font::get_text_height(const std::string& text) const { std::string::size_type text_height = char_height; - for(std::string::size_type i = 0; i < text.size(); ++i) - { - if (i == '\n') + for(std::string::const_iterator it = text.begin(); it != text.end(); ++it) + { // since UTF8 multibyte characters are decoded with values + // outside the ASCII range there is no risk of overlapping and + // thus we don't need to decode the utf-8 string + if (*it == '\n') text_height += char_height + 2; } @@ -199,39 +239,33 @@ void Font::draw(const std::string& text, const Vector& pos_, FontAlignment alignment, DrawingEffect drawing_effect, float alpha) const { - /* Cut lines changes into seperate strings, needed to support center/right text - alignments with break lines. - Feel free to replace this hack with a more elegant solution - */ - char temp[1024]; - std::string::size_type l, i, y; - bool done = false; - i = y = 0; - - while(!done) { - l = text.find("\n", i); - if(l == std::string::npos) { - l = text.size(); - done = true; - } - - if(l > sizeof(temp)-1) - l = sizeof(temp)-1; - - temp[text.copy(temp, l - i, i)] = '\0'; - - // calculate X positions based on the alignment type - Vector pos = Vector(pos_); - if(alignment == CENTER_ALLIGN) - pos.x -= get_text_width(temp) / 2; - else if(alignment == RIGHT_ALLIGN) - pos.x -= get_text_width(temp); - - draw_text(temp, pos + Vector(0,y), drawing_effect, alpha); + float x = pos_.x; + float y = pos_.y; - i = l+1; - y += char_height + 2; - } + std::string::size_type last = 0; + for(std::string::size_type i = 0;; ++i) + { + if (text[i] == '\n' || i == text.size()) + { + std::string temp = text.substr(last, i - last); + + // calculate X positions based on the alignment type + Vector pos = Vector(x, y); + + if(alignment == ALIGN_CENTER) + pos.x -= get_text_width(temp) / 2; + else if(alignment == ALIGN_RIGHT) + pos.x -= get_text_width(temp); + + draw_text(temp, pos, drawing_effect, alpha); + + if (i == text.size()) + break; + + y += char_height + 2; + last = i + 1; + } + } } void @@ -245,57 +279,56 @@ Font::draw_text(const std::string& text, const Vector& pos, draw_chars(glyph_surface, text, pos, drawing_effect, alpha); } +int +Font::chr2glyph(uint32_t chr) const +{ + int glyph_index = chr - first_char; + + // we don't have the control chars 0x80-0xa0 in the font + if (chr >= 0x80) { // non-ascii character + glyph_index -= 32; + if(chr <= 0xa0) { + log_debug << "Unsupported utf-8 character '" << chr << "' found" << std::endl; + glyph_index = 0; + } + } + + if(glyph_index < 0 || glyph_index >= (int) char_count) { + log_debug << "Unsupported utf-8 character found" << std::endl; + glyph_index = 0; + } + + return glyph_index; +} + void Font::draw_chars(Surface* pchars, const std::string& text, const Vector& pos, DrawingEffect drawing_effect, float alpha) const { Vector p = pos; - size_t i = 0; - while(i < text.size()) { - uint32_t c; - try { - c = decode_utf8(text, i); // FIXME: this seems wrong, since when incrementing i by - } - catch (std::runtime_error) { - log_debug << "Malformed utf-8 sequence beginning with " << *((uint32_t*)(text.c_str() + i)) << " found " << std::endl; - c = 0; - i++; - } - - int font_index = c - first_char; - - // a non-printable character? - if(c == '\n') { - p.x = pos.x; - p.y += char_height + 2; - continue; - } - if(c == ' ') { - p.x += glyphs[font_index].get_width(); - continue; - } - - // we don't have the control chars 0x80-0xa0 in the font - if (c >= 0x80) { - font_index -= 32; - if(c <= 0xa0) { - log_debug << "Unsupported utf-8 character '" << c << "' found" << std::endl; - font_index = 0; - } - } + for(UTF8Iterator it(text); !it.done(); ++it) + { + int font_index = chr2glyph(*it); - if(font_index < 0 || font_index >= (int) char_count) { - log_debug << "Unsupported utf-8 character found" << std::endl; - font_index = 0; + if(*it == '\n') + { + p.x = pos.x; + p.y += char_height + 2; + } + else if(*it == ' ') + { + p.x += glyphs[font_index].get_width(); + } + else + { + const Rect& glyph = glyphs[font_index]; + pchars->draw_part(glyph.get_left(), glyph.get_top(), + p.x, p.y, + glyph.get_width(), glyph.get_height(), + alpha, drawing_effect); + p.x += glyphs[font_index].get_width(); + } } - - const Rect& glyph = glyphs[font_index]; - pchars->draw_part(glyph.get_left(), glyph.get_top(), - p.x, p.y, - glyph.get_width(), glyph.get_height(), - alpha, drawing_effect); - p.x += glyphs[font_index].get_width(); - } } @@ -309,7 +342,9 @@ bool has_multibyte_mark(unsigned char c) { } /** - * gets unicode character at byte position @a p of UTF-8 encoded @a text, then advances @a p to the next character. + * gets unicode character at byte position @a p of UTF-8 encoded @a + * text, then advances @a p to the next character. + * * @throws std::runtime_error if decoding fails. * See unicode standard section 3.10 table 3-5 and 3-6 for details. */ diff --git a/src/video/font.hpp b/src/video/font.hpp index c30dba215..c8973b08a 100644 --- a/src/video/font.hpp +++ b/src/video/font.hpp @@ -1,7 +1,8 @@ // $Id$ // // SuperTux -// Copyright (C) 2006 Matthias Braun +// Copyright (C) 2006 Matthias Braun , +// Ingo Ruhnke // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -28,14 +29,19 @@ #include "math/rect.hpp" enum FontAlignment { - LEFT_ALLIGN, - CENTER_ALLIGN, - RIGHT_ALLIGN + ALIGN_LEFT, + ALIGN_CENTER, + ALIGN_RIGHT }; class Font { public: + enum GlyphWidth { + FIXED, + VARIABLE + }; + /** Construct a fixed-width font * * @param file image file containing the characters @@ -43,14 +49,15 @@ public: * @param w width of a character * @param h height of a character */ - Font(const std::string& file, const std::string& shadowfile, + Font(GlyphWidth glyph_width, const std::string& file, const std::string& shadowfile, int w, int h, int shadowsize = 2); /** Construct a variable-width font * * @param file image file containing the characters */ - Font(const std::string& file, int char_width, int char_height); + Font(GlyphWidth glyph_width, const std::string& filename, + int char_width, int char_height); ~Font(); @@ -80,7 +87,7 @@ public: /** Draws the given text to the screen. Also needs the position. * Type of alignment, drawing effect and alpha are optional. */ void draw(const std::string& text, const Vector& pos, - FontAlignment allignment = LEFT_ALLIGN, + FontAlignment allignment = ALIGN_LEFT, DrawingEffect drawing_effect = NO_EFFECT, float alpha = 1.0f) const; @@ -95,9 +102,12 @@ private: const Vector& position, DrawingEffect drawing_effect, float alpha) const; - Surface* glyph_surface; - Surface* shadow_chars; - int char_width; + /** Convert a Unicode character code to the index of its glyph */ + int chr2glyph(uint32_t chr) const; + + GlyphWidth glyph_width; + Surface* glyph_surface; + Surface* shadow_chars; int char_height; int shadowsize; diff --git a/src/worldmap/worldmap.cpp b/src/worldmap/worldmap.cpp index 58fd9fc2f..cc4ec202f 100644 --- a/src/worldmap/worldmap.cpp +++ b/src/worldmap/worldmap.cpp @@ -703,9 +703,9 @@ WorldMap::draw_status(DrawingContext& context) get_level_title(*level); context.draw_text(white_text, level->title, - Vector(SCREEN_WIDTH/2, - SCREEN_HEIGHT - white_text->get_height() - 30), - CENTER_ALLIGN, LAYER_FOREGROUND1); + Vector(SCREEN_WIDTH/2, + SCREEN_HEIGHT - white_text->get_height() - 30), + ALIGN_CENTER, LAYER_FOREGROUND1); // if level is solved, draw level picture behind stats /* @@ -735,7 +735,7 @@ WorldMap::draw_status(DrawingContext& context) context.draw_text(gold_text, special_tile->map_message, Vector(SCREEN_WIDTH/2, SCREEN_HEIGHT - white_text->get_height() - 60), - CENTER_ALLIGN, LAYER_FOREGROUND1); + ALIGN_CENTER, LAYER_FOREGROUND1); break; } } @@ -744,7 +744,7 @@ WorldMap::draw_status(DrawingContext& context) Teleporter* teleporter = at_teleporter(tux->get_tile_pos()); if (teleporter && (teleporter->message != "")) { Vector pos = Vector(SCREEN_WIDTH/2, SCREEN_HEIGHT - white_text->get_height() - 30); - context.draw_text(white_text, teleporter->message, pos, CENTER_ALLIGN, LAYER_FOREGROUND1); + context.draw_text(white_text, teleporter->message, pos, ALIGN_CENTER, LAYER_FOREGROUND1); } } @@ -753,7 +753,7 @@ WorldMap::draw_status(DrawingContext& context) if(passive_message_timer.started()) context.draw_text(gold_text, passive_message, Vector(SCREEN_WIDTH/2, SCREEN_HEIGHT - white_text->get_height() - 60), - CENTER_ALLIGN, LAYER_FOREGROUND1); + ALIGN_CENTER, LAYER_FOREGROUND1); context.pop_transform(); } -- 2.11.0