-The list of letters in UTF-8 format that is currently used in the fonts can be optained with:
+These are images containing glyphs of font.
+They expectde to be in RGBA pixel format and any SDL-loabale file format.
+Glyphs themselves and charsets described in data/fonts/*.stf files.
-ruby -e '((32..127).to_a + (128+32..383).to_a).each_with_index{|c,idx| print [c].pack("I"); if ((idx+1) % 16 == 0) then print [10].pack("I") end }' | recode "UCS-4LE..UTF-8"
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <config.h>
+#include <stdexcept>
#include "dispenser.hpp"
#include "object/bullet.hpp"
--- /dev/null
+#include "video/color.hpp"
+
+namespace LevelIntro {
+ Color header_color(1.0,1.0,1.0);
+ Color author_color(1.0,1.0,1.0);
+ Color stat_hdr_color(1.0,1.0,1.0);
+ Color stat_color(1.0,1.0,1.0);
+}
+
+namespace Statistics {
+ Color header_color(0.5,1.0,0.2);
+ Color text_color(1.0,1.0,1.0);
+}
+
+namespace Menu {
+ Color default_color(1.0,1.0,1.0);
+ Color active_color(0.6,1.0,1.0);
+ Color inactive_color(0.5,0.5,1.0);
+ Color label_color(0.8,0.4,0.2);
+ Color field_color(1.0,0.8,0.6);
+}
+
+namespace PlayerStatus {
+ Color text_color(1.0,1.0,0.6);
+}
+
+namespace TextObject {
+ Color default_color(1.0,1.0,0.6);
+}
+
+namespace FloatingText {
+ Color text_color(1.0,1.0,0.6);
+}
+
+namespace LevelTime {
+ Color text_color(1.0,1.0,0.6);
+}
+
+namespace SecretAreaTrigger {
+ Color text_color(1.0,1.0,0.6);
+}
+
+namespace Climbable {
+ Color text_color(1.0,1.0,0.6);
+}
+
+namespace WorldMapNS {
+ namespace WorldMap {
+ Color level_title_color(1.0,1.0,0.2);
+ Color message_color(1.0,1.0,1.0);
+ Color teleporter_message_color(0.5,1.0,0.5);
+}}
+
+
void
Console::init_graphics()
{
- font.reset(new Font(Font::FIXED,
- "images/engine/fonts/andale12.png",
- "images/engine/fonts/andale12-shadow.png", 7, 14, 1));
+ font.reset(new Font(Font::FIXED,"fonts/andale12.stf",1));
fontheight = font->get_height();
background.reset(new Surface("images/engine/console.png"));
background2.reset(new Surface("images/engine/console2.png"));
std::list<Menu*> Menu::all_menus;
Menu* Menu::current_ = 0;
Menu* Menu::previous = 0;
-Font* Menu::default_font;
-Font* Menu::active_font;
-Font* Menu::inactive_font;
-Font* Menu::label_font;
-Font* Menu::field_font;
/* just displays a Yes/No text that can be used to confirm stuff */
bool confirm_dialog(Surface *background, std::string text)
MenuItem::set_help(const std::string& help_text)
{
std::string overflow;
- help = Menu::default_font->wrap_to_width(help_text, 600, &overflow);
+ help = normal_font->wrap_to_width(help_text, 600, &overflow);
while (!overflow.empty())
{
help += "\n";
- help += Menu::default_font->wrap_to_width(overflow, 600, &overflow);
+ help += normal_font->wrap_to_width(overflow, 600, &overflow);
}
}
MenuItem& pitem = *(items[index]);
- Font* text_font = default_font;
+ Color text_color = default_color;
float x_pos = pos_x;
float y_pos = pos_y + 24*index - menu_height/2 + 12;
int shadow_size = 2;
- int text_width = int(text_font->get_text_width(pitem.text));
- int input_width = int(text_font->get_text_width(pitem.input) + 10);
+ int text_width = int(normal_font->get_text_width(pitem.text));
+ int input_width = int(normal_font->get_text_width(pitem.input) + 10);
int list_width = 0;
float left = pos_x - menu_width/2 + 16;
float right = pos_x + menu_width/2 - 16;
if(pitem.list.size() > 0) {
- list_width = (int) text_font->get_text_width(pitem.list[pitem.selected]);
+ list_width = (int) normal_font->get_text_width(pitem.list[pitem.selected]);
}
if (arrange_left)
if(index == active_item)
{
shadow_size = 3;
- text_font = active_font;
+ text_color = active_color;
}
if(active_item == index)
{
case MN_INACTIVE:
{
- context.draw_text(inactive_font, pitem.text,
- Vector(pos_x, y_pos - int(inactive_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
+ context.draw_text(normal_font, pitem.text,
+ Vector(pos_x, y_pos - int(normal_font->get_height()/2)),
+ ALIGN_CENTER, LAYER_GUI, inactive_color);
break;
}
}
case MN_LABEL:
{
- context.draw_text(label_font, pitem.text,
- Vector(pos_x, y_pos - int(label_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
+ context.draw_text(big_font, pitem.text,
+ Vector(pos_x, y_pos - int(big_font->get_height()/2)),
+ ALIGN_CENTER, LAYER_GUI, label_color);
break;
}
case MN_TEXTFIELD:
if(pitem.kind == MN_TEXTFIELD || pitem.kind == MN_NUMFIELD)
{
if(active_item == index)
- context.draw_text(field_font,
+ context.draw_text(normal_font,
pitem.get_input_with_symbol(true),
- Vector(right, y_pos - int(field_font->get_height()/2)),
- ALIGN_RIGHT, LAYER_GUI);
+ Vector(right, y_pos - int(normal_font->get_height()/2)),
+ ALIGN_RIGHT, LAYER_GUI, field_color);
else
- context.draw_text(field_font,
+ context.draw_text(normal_font,
pitem.get_input_with_symbol(false),
- Vector(right, y_pos - int(field_font->get_height()/2)),
- ALIGN_RIGHT, LAYER_GUI);
+ Vector(right, y_pos - int(normal_font->get_height()/2)),
+ ALIGN_RIGHT, LAYER_GUI, field_color);
}
else
- context.draw_text(field_font, pitem.input,
- Vector(right, y_pos - int(field_font->get_height()/2)),
- ALIGN_RIGHT, LAYER_GUI);
+ context.draw_text(normal_font, pitem.input,
+ Vector(right, y_pos - int(normal_font->get_height()/2)),
+ ALIGN_RIGHT, LAYER_GUI, field_color);
- context.draw_text(text_font, pitem.text,
- Vector(left, y_pos - int(text_font->get_height()/2)),
- ALIGN_LEFT, LAYER_GUI);
+ context.draw_text(normal_font, pitem.text,
+ Vector(left, y_pos - int(normal_font->get_height()/2)),
+ ALIGN_LEFT, LAYER_GUI, text_color);
break;
}
case MN_STRINGSELECT:
{
float roff = arrow_left->get_width();
// Draw left side
- context.draw_text(text_font, pitem.text,
- Vector(left, y_pos - int(text_font->get_height()/2)),
- ALIGN_LEFT, LAYER_GUI);
+ context.draw_text(normal_font, pitem.text,
+ Vector(left, y_pos - int(normal_font->get_height()/2)),
+ ALIGN_LEFT, LAYER_GUI, text_color);
// Draw right side
context.draw_surface(arrow_left.get(),
context.draw_surface(arrow_right.get(),
Vector(right - roff, y_pos - 8),
LAYER_GUI);
- context.draw_text(field_font, pitem.list[pitem.selected],
- Vector(right - roff, y_pos - int(text_font->get_height()/2)),
- ALIGN_RIGHT, LAYER_GUI);
+ context.draw_text(normal_font, pitem.list[pitem.selected],
+ Vector(right - roff, y_pos - int(normal_font->get_height()/2)),
+ ALIGN_RIGHT, LAYER_GUI, text_color);
break;
}
case MN_BACK:
{
- context.draw_text(text_font, pitem.text,
- Vector(pos_x, y_pos - int(text_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
+ context.draw_text(normal_font, pitem.text,
+ Vector(pos_x, y_pos - int(normal_font->get_height()/2)),
+ ALIGN_CENTER, LAYER_GUI, text_color);
context.draw_surface(back.get(),
Vector(x_pos + text_width/2 + 16, y_pos - 8),
LAYER_GUI);
case MN_TOGGLE:
{
- context.draw_text(text_font, pitem.text,
- Vector(pos_x - menu_width/2 + 16, y_pos - (text_font->get_height()/2)),
- ALIGN_LEFT, LAYER_GUI);
+ context.draw_text(normal_font, pitem.text,
+ Vector(pos_x - menu_width/2 + 16, y_pos - (normal_font->get_height()/2)),
+ ALIGN_LEFT, LAYER_GUI, text_color);
if(pitem.toggled)
context.draw_surface(checkbox_checked.get(),
break;
}
case MN_ACTION:
- context.draw_text(text_font, pitem.text,
- Vector(pos_x, y_pos - int(text_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
+ context.draw_text(normal_font, pitem.text,
+ Vector(pos_x, y_pos - int(normal_font->get_height()/2)),
+ ALIGN_CENTER, LAYER_GUI, text_color);
break;
case MN_GOTO:
- context.draw_text(text_font, pitem.text,
- Vector(pos_x, y_pos - int(text_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
+ context.draw_text(normal_font, pitem.text,
+ Vector(pos_x, y_pos - int(normal_font->get_height()/2)),
+ ALIGN_CENTER, LAYER_GUI, text_color);
break;
}
}
float menu_width = 0;
for(unsigned int i = 0; i < items.size(); ++i)
{
- Font* font = default_font;
+ Font* font = normal_font;
if(items[i]->kind == MN_LABEL)
- font = label_font;
+ font = big_font;
float w = font->get_text_width(items[i]->text) +
- label_font->get_text_width(items[i]->input) + 16;
+ big_font->get_text_width(items[i]->input) + 16;
if(items[i]->kind == MN_TOGGLE)
w += 32;
if (!items[active_item]->help.empty())
{
- int text_width = (int) default_font->get_text_width(items[active_item]->help);
- int text_height = (int) default_font->get_text_height(items[active_item]->help);
+ int text_width = (int) normal_font->get_text_width(items[active_item]->help);
+ int text_height = (int) normal_font->get_text_height(items[active_item]->help);
Rect text_rect(pos_x - text_width/2 - 8,
SCREEN_HEIGHT - 48 - text_height/2 - 4,
16.0f,
LAYER_GUI-10);
- context.draw_text(default_font, items[active_item]->help,
+ context.draw_text(normal_font, items[active_item]->help,
Vector(pos_x, SCREEN_HEIGHT - 48 - text_height/2),
ALIGN_CENTER, LAYER_GUI);
}
\f
class Menu
{
+ static Color default_color;
+ static Color active_color;
+ static Color inactive_color;
+ static Color label_color;
+ static Color field_color;
private:
static std::vector<Menu*> last_menus;
bool close;
public:
- static Font* default_font;
- static Font* active_font;
- static Font* inactive_font;
- static Font* label_font;
- static Font* field_font;
-
std::vector<MenuItem*> items;
Menu();
#include "mainloop.hpp"
#include "gettext.hpp"
#include "resources.hpp"
-#include "video/font.hpp"
#include "video/drawing_context.hpp"
#include "gui/menu.hpp"
#include "main.hpp"
#include "sprite/sprite_manager.hpp"
#include "random_generator.hpp"
-
LevelIntro::LevelIntro(const Level* level, const Statistics* best_level_statistics)
: level(level), best_level_statistics(best_level_statistics), player_sprite_py(0), player_sprite_vy(0)
{
LevelIntro::draw(DrawingContext& context)
{
const Statistics& stats = level->stats;
- int py = static_cast<int>(SCREEN_HEIGHT / 2 - gold_text->get_height() / 2);
+ int py = static_cast<int>(SCREEN_HEIGHT / 2 - normal_font->get_height() / 2);
context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT), Color(0.0f, 0.0f, 0.0f, 1.0f), 0);
{
- context.draw_center_text(gold_text, level->get_name(), Vector(0, py), LAYER_FOREGROUND1);
- py += static_cast<int>(gold_text->get_height());
+ context.draw_center_text(normal_font, level->get_name(), Vector(0, py), LAYER_FOREGROUND1, LevelIntro::header_color);
+ py += static_cast<int>(normal_font->get_height());
}
std::string author = level->get_author();
if ((author != "") && (author != "SuperTux Team")) {
std::string author_text = std::string(_("contributed by ")) + author;
- context.draw_center_text(white_small_text, author_text, Vector(0, py), LAYER_FOREGROUND1);
- py += static_cast<int>(white_small_text->get_height());
+ context.draw_center_text(small_font, author_text, Vector(0, py), LAYER_FOREGROUND1, LevelIntro::author_color);
+ py += static_cast<int>(small_font->get_height());
}
py += 32;
py += 32;
{
- context.draw_center_text(blue_text, std::string("- ") + _("Best Level Statistics") + std::string(" -"), Vector(0, py), LAYER_FOREGROUND1);
- py += static_cast<int>(blue_text->get_height());
+ context.draw_center_text(normal_font, std::string("- ") + _("Best Level Statistics") + std::string(" -"), Vector(0, py), LAYER_FOREGROUND1, LevelIntro::header_color);
+ py += static_cast<int>(normal_font->get_height());
}
{
std::stringstream ss;
ss << _("Coins") << ": " << Statistics::coins_to_string((best_level_statistics && (best_level_statistics->coins >= 0)) ? best_level_statistics->coins : 0, stats.total_coins);
- context.draw_center_text(white_text, ss.str(), Vector(0, py), LAYER_FOREGROUND1);
- py += static_cast<int>(white_text->get_height());
+ context.draw_center_text(normal_font, ss.str(), Vector(0, py), LAYER_FOREGROUND1, LevelIntro::stat_color);
+ py += static_cast<int>(normal_font->get_height());
}
{
std::stringstream ss;
ss << _("Secrets") << ": " << Statistics::secrets_to_string((best_level_statistics && (best_level_statistics->coins >= 0)) ? best_level_statistics->secrets : 0, stats.total_secrets);
- context.draw_center_text(white_text, ss.str(), Vector(0, py), LAYER_FOREGROUND1);
- py += static_cast<int>(white_text->get_height());
+ context.draw_center_text(normal_font, ss.str(), Vector(0, py), LAYER_FOREGROUND1,LevelIntro::stat_color);
+ py += static_cast<int>(normal_font->get_height());
}
{
std::stringstream ss;
ss << _("Time") << ": " << Statistics::time_to_string((best_level_statistics && (best_level_statistics->coins >= 0)) ? best_level_statistics->time : 0);
- context.draw_center_text(white_text, ss.str(), Vector(0, py), LAYER_FOREGROUND1);
- py += static_cast<int>(white_text->get_height());
+ context.draw_center_text(normal_font, ss.str(), Vector(0, py), LAYER_FOREGROUND1,LevelIntro::stat_color);
+ py += static_cast<int>(normal_font->get_height());
}
}
class DrawingContext;
class Surface;
-class Font;
/**
* Screen that welcomes the player to a level
*/
class LevelIntro : public Screen
{
+ static Color header_color;
+ static Color author_color;
+ static Color stat_color;
public:
LevelIntro(const Level* level, const Statistics* best_level_statistics);
virtual ~LevelIntro();
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), ALIGN_LEFT, LAYER_HUD);
- context.draw_text(gold_text, str, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y + 20), ALIGN_RIGHT, LAYER_HUD);
+ context.draw_text(small_font, fpstext, Vector(SCREEN_WIDTH - small_font->get_text_width(fpstext) - small_font->get_text_width(" 99999") - BORDER_X, BORDER_Y + 20), ALIGN_LEFT, LAYER_HUD);
+ context.draw_text(small_font, str, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y + 20), ALIGN_RIGHT, LAYER_HUD);
}
void
context.push_transform();
context.set_alpha(alpha);
- context.draw_text(gold_text, text, position, ALIGN_LEFT, LAYER_OBJECTS+1);
+ context.draw_text(normal_font, text, position, ALIGN_LEFT, LAYER_OBJECTS+1, FloatingText::text_color);
context.pop_transform();
}
class FloatingText : public GameObject
{
+ static Color text_color;
public:
FloatingText(const Vector& pos, const std::string& text_);
FloatingText(const Vector& pos, int s); // use this for score, for instance
Surface* time_surf = time_surface.get();
if (time_surf) {
- float all_width = time_surf->get_width() + white_text->get_text_width(time_text);
+ float all_width = time_surf->get_width() + normal_font->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), ALIGN_LEFT, LAYER_FOREGROUND1);
+ context.draw_text(normal_font, time_text, Vector((SCREEN_WIDTH - all_width)/2 + time_surf->get_width(), BORDER_Y), ALIGN_LEFT, LAYER_FOREGROUND1, LevelTime::text_color);
}
}
#include "lisp/lisp.hpp"
#include "video/surface.hpp"
#include "script_interface.hpp"
+#include "video/color.hpp"
class LevelTime : public GameObject, public ScriptInterface
{
+ static Color text_color;
public:
LevelTime(const lisp::Lisp& reader);
pos(0, 0)
{
this->name = name;
- font = blue_text;
+ font = normal_font;
centered = false;
}
void
TextObject::set_font(const std::string& name)
{
- if(name == "gold") {
- font = gold_text;
- } else if(name == "white") {
- font = white_text;
- } else if(name == "blue") {
- font = blue_text;
- } else if(name == "gray") {
- font = gray_text;
+ if(name == "normal") {
+ font = normal_font;
} else if(name == "big") {
- font = white_big_text;
+ font = big_font;
} else if(name == "small") {
- font = white_small_text;
+ font = small_font;
} else {
log_warning << "Unknown font '" << name << "'." << std::endl;
}
context.draw_filled_rect(spos, Vector(width, height),
Color(0.6f, 0.7f, 0.8f, 0.5f), LAYER_GUI-50);
if (centered) {
- context.draw_center_text(font, text, spos, LAYER_GUI-40);
+ context.draw_center_text(font, text, spos, LAYER_GUI-40, TextObject::default_color);
} else {
- context.draw_text(font, text, spos + Vector(10, 10), ALIGN_LEFT, LAYER_GUI-40);
+ context.draw_text(font, text, spos + Vector(10, 10), ALIGN_LEFT, LAYER_GUI-40, TextObject::default_color);
}
context.pop_transform();
#include "scripting/text.hpp"
#include "script_interface.hpp"
#include "anchor_point.hpp"
+#include "video/color.hpp"
class Font;
class TextObject : public GameObject, public Scripting::Text,
public ScriptInterface
{
+ static Color default_color;
public:
TextObject(std::string name = "");
virtual ~TextObject();
Surface* coin_surf = coin_surface.get();
if (coin_surf) {
- context.draw_surface(coin_surf, Vector(SCREEN_WIDTH - BORDER_X - coin_surf->get_width() - gold_fixed_text->get_text_width(coins_text), BORDER_Y + 1), LAYER_HUD);
+ context.draw_surface(coin_surf, Vector(SCREEN_WIDTH - BORDER_X - coin_surf->get_width() - fixed_font->get_text_width(coins_text), BORDER_Y + 1), LAYER_HUD);
}
- context.draw_text(gold_fixed_text, coins_text, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y), ALIGN_RIGHT, LAYER_HUD);
+ context.draw_text(fixed_font, coins_text, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y), ALIGN_RIGHT, LAYER_HUD, PlayerStatus::text_color);
context.pop_transform();
}
#include <memory>
#include "serializable.hpp"
+#include "video/color.hpp"
namespace lisp{ class Writer; }
namespace lisp{ class Lisp; }
*/
class PlayerStatus : public Serializable
{
+ static Color text_color;
public:
PlayerStatus();
~PlayerStatus();
#include <config.h>
#include "sprite/sprite_manager.hpp"
-#include "gui/menu.hpp"
-#include "gui/button.hpp"
#include "resources.hpp"
#include "file_system.hpp"
#include "tile_manager.hpp"
#include "object/gameobjs.hpp"
#include "object/player.hpp"
+#include "gui/mousecursor.hpp"
+#include "player_status.hpp"
MouseCursor* mouse_cursor = NULL;
-Font* gold_text = NULL;
-Font* gold_fixed_text = NULL;
-Font* blue_text = NULL;
-Font* gray_text = NULL;
-Font* white_text = NULL;
-Font* white_small_text = NULL;
-Font* white_big_text = NULL;
+Font* fixed_font = NULL;
+Font* normal_font = NULL;
+Font* small_font = NULL;
+Font* big_font = NULL;
/* Load graphics/sounds shared between all levels: */
void load_shared()
MouseCursor::set_current(mouse_cursor);
/* Load global images: */
- gold_text = new Font(Font::VARIABLE,
- "images/engine/fonts/gold.png",
- "images/engine/fonts/shadow.png", 16, 18);
- gold_fixed_text = new Font(Font::FIXED,
- "images/engine/fonts/gold.png",
- "images/engine/fonts/shadow.png", 16, 18);
- blue_text = new Font(Font::VARIABLE,
- "images/engine/fonts/blue.png",
- "images/engine/fonts/shadow.png", 16, 18, 3);
- white_text = new Font(Font::VARIABLE,
- "images/engine/fonts/white.png",
- "images/engine/fonts/shadow.png", 16, 18);
- gray_text = new Font(Font::VARIABLE,
- "images/engine/fonts/gray.png",
- "images/engine/fonts/shadow.png", 16, 18);
- white_small_text = new Font(Font::VARIABLE,
- "images/engine/fonts/white-small.png",
- "images/engine/fonts/shadow-small.png", 8, 9, 1);
- white_big_text = new Font(Font::VARIABLE,
- "images/engine/fonts/white-big.png",
- "images/engine/fonts/shadow-big.png", 20, 22, 3);
-
- Menu::default_font = white_text;
- Menu::active_font = blue_text;
- Menu::inactive_font = gray_text;
- Menu::label_font = white_big_text;
- Menu::field_font = gold_text;
-
- Button::info_font = white_small_text;
+ fixed_font = new Font(Font::FIXED, "fonts/white.stf");
+ normal_font = new Font(Font::VARIABLE, "fonts/white.stf");
+ small_font = new Font(Font::VARIABLE, "fonts/white-small.stf", 1);
+ big_font = new Font(Font::VARIABLE, "fonts/white-big.stf", 3);
tile_manager = new TileManager();
sprite_manager = new SpriteManager();
void unload_shared()
{
/* Free global images: */
- delete gold_text;
- delete gold_fixed_text;
- delete white_text;
- delete blue_text;
- delete gray_text;
- delete white_small_text;
- delete white_big_text;
+ delete normal_font;
+ delete small_font;
+ delete big_font;
delete sprite_manager;
sprite_manager = NULL;
extern MouseCursor* mouse_cursor;
-extern Font* gold_text;
-extern Font* gold_fixed_text;
-extern Font* white_text;
-extern Font* blue_text;
-extern Font* gray_text;
-extern Font* white_small_text;
-extern Font* white_big_text;
+extern Font* fixed_font;
+extern Font* normal_font;
+extern Font* small_font;
+extern Font* big_font;
void load_shared();
void unload_shared();
// 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), ALIGN_CENTER, LAYER_GUI);
+ context.draw_text(small_font, std::string("- ") + _("Best Level Statistics") + " -", Vector((WMAP_INFO_LEFT_X + WMAP_INFO_RIGHT_X) / 2, WMAP_INFO_TOP_Y1), ALIGN_CENTER, LAYER_GUI,Statistics::header_color);
std::string caption_buf;
std::string stat_buf;
break;
}
- context.draw_text(white_small_text, caption_buf, Vector(WMAP_INFO_LEFT_X, posy), ALIGN_LEFT, LAYER_GUI);
- context.draw_text(white_small_text, stat_buf, Vector(WMAP_INFO_RIGHT_X, posy), ALIGN_RIGHT, LAYER_GUI);
- posy += white_small_text->get_height() + 2;
+ context.draw_text(small_font, caption_buf, Vector(WMAP_INFO_LEFT_X, posy), ALIGN_LEFT, LAYER_GUI, Statistics::header_color);
+ context.draw_text(small_font, stat_buf, Vector(WMAP_INFO_RIGHT_X, posy), ALIGN_RIGHT, LAYER_GUI, Statistics::text_color);
+ posy += small_font->get_height() + 2;
}
}
context.draw_surface(backdrop, Vector(bd_x, bd_y), LAYER_GUI);
context.pop_transform();
- 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(normal_font, _("You"), Vector(col2_x, row1_y), ALIGN_LEFT, LAYER_GUI, Statistics::header_color);
+ context.draw_text(normal_font, _("Best"), Vector(col3_x, row1_y), ALIGN_LEFT, LAYER_GUI, Statistics::header_color);
- context.draw_text(white_text, _("Coins"), Vector(col2_x-16, row3_y), ALIGN_RIGHT, LAYER_GUI);
+ context.draw_text(normal_font, _("Coins"), Vector(col2_x-16, row3_y), ALIGN_RIGHT, LAYER_GUI, Statistics::header_color);
int coins_best = (best_stats && (best_stats->coins > coins)) ? best_stats->coins : coins;
int total_coins_best = (best_stats && (best_stats->total_coins > total_coins)) ? best_stats->total_coins : total_coins;
- context.draw_text(gold_text, coins_to_string(coins, total_coins), Vector(col2_x, row3_y), ALIGN_LEFT, LAYER_GUI);
- context.draw_text(gold_text, coins_to_string(coins_best, total_coins_best), Vector(col3_x, row3_y), ALIGN_LEFT, LAYER_GUI);
+ context.draw_text(normal_font, coins_to_string(coins, total_coins), Vector(col2_x, row3_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
+ context.draw_text(normal_font, coins_to_string(coins_best, total_coins_best), Vector(col3_x, row3_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
- context.draw_text(white_text, _("Secrets"), Vector(col2_x-16, row4_y), ALIGN_RIGHT, LAYER_GUI);
+ context.draw_text(normal_font, _("Secrets"), Vector(col2_x-16, row4_y), ALIGN_RIGHT, LAYER_GUI, Statistics::header_color);
int secrets_best = (best_stats && (best_stats->secrets > secrets)) ? best_stats->secrets : secrets;
int total_secrets_best = (best_stats && (best_stats->total_secrets > total_secrets)) ? best_stats->total_secrets : total_secrets;
- context.draw_text(gold_text, secrets_to_string(secrets, total_secrets), Vector(col2_x, row4_y), ALIGN_LEFT, LAYER_GUI);
- context.draw_text(gold_text, secrets_to_string(secrets_best, total_secrets_best), Vector(col3_x, row4_y), ALIGN_LEFT, LAYER_GUI);
+ context.draw_text(normal_font, secrets_to_string(secrets, total_secrets), Vector(col2_x, row4_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
+ context.draw_text(normal_font, secrets_to_string(secrets_best, total_secrets_best), Vector(col3_x, row4_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
- context.draw_text(white_text, _("Time"), Vector(col2_x-16, row2_y), ALIGN_RIGHT, LAYER_GUI);
+ context.draw_text(normal_font, _("Time"), Vector(col2_x-16, row2_y), ALIGN_RIGHT, LAYER_GUI, Statistics::header_color);
float time_best = (best_stats && (best_stats->time < time)) ? best_stats->time : time;
- context.draw_text(gold_text, time_to_string(time), Vector(col2_x, row2_y), ALIGN_LEFT, LAYER_GUI);
- context.draw_text(gold_text, time_to_string(time_best), Vector(col3_x, row2_y), ALIGN_LEFT, LAYER_GUI);
+ context.draw_text(normal_font, time_to_string(time), Vector(col2_x, row2_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
+ context.draw_text(normal_font, time_to_string(time_best), Vector(col3_x, row2_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
}
void
#define SUPERTUX_STATISTICS_H
#include <squirrel.h>
+#include "video/color.hpp"
namespace lisp { class Writer; }
namespace lisp { class Lisp; }
* number of jumps and stuff */
class Statistics
{
+ static Color header_color;
+ static Color text_color;
public:
int coins; /**< coins collected */
int total_coins; /**< coins in level */
switch(format_char)
{
case ' ':
- return white_small_text;
+ return small_font;
break;
case '\t':
- return white_text;
+ return normal_font;
break;
case '-':
- return white_big_text;
+ return big_font;
break;
case '*':
- return blue_text;
+ return normal_font; // blue_text
break;
case '#':
- return white_text;
+ return normal_font;
break;
case '!':
return 0;
}
}
-InfoBoxLine::InfoBoxLine(char format_char, const std::string& text) : lineType(NORMAL), font(white_text), text(text), image(0)
+InfoBoxLine::InfoBoxLine(char format_char, const std::string& text) : lineType(NORMAL), font(normal_font), text(text), image(0)
{
font = get_font_by_format_char(format_char);
lineType = get_linetype_by_format_char(format_char);
lines.push_back(new InfoBoxLine(format_char, s2));
s = overflow;
} while (s.length() > 0);
-
}
return lines;
context.draw_surface(image, Vector( (bbox.p1.x + bbox.p2.x - image->get_width()) / 2, position.y), layer);
break;
case NORMAL_LEFT:
- context.draw_text(font, text, Vector(position.x, position.y), ALIGN_LEFT, layer);
+ context.draw_text(font, text, Vector(position.x, position.y), ALIGN_LEFT, layer, Color(1,1,1));
break;
default:
- context.draw_text(font, text, Vector((bbox.p1.x + bbox.p2.x) / 2, position.y), ALIGN_CENTER, layer);
+ context.draw_text(font, text, Vector((bbox.p1.x + bbox.p2.x) / 2, position.y), ALIGN_CENTER, layer,Color(1,1,1));
break;
}
}
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
#include <config.h>
+#include <stdexcept>
#include "tile_set.hpp"
#include "log.hpp"
// FIXME: Add something to scale the frame to the resolution of the screen
context.draw_surface(frame.get(), Vector(0,0),LAYER_FOREGROUND1);
- context.draw_text(white_small_text, "SuperTux " PACKAGE_VERSION "\n",
+ context.draw_text(small_font, "SuperTux " PACKAGE_VERSION "\n",
Vector(5, SCREEN_HEIGHT - 50), ALIGN_LEFT, LAYER_FOREGROUND1);
- context.draw_text(white_small_text,
+ context.draw_text(small_font,
_(
"Copyright (c) 2007 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(5, SCREEN_HEIGHT - 50 + white_small_text->get_height() + 5),
+ Vector(5, SCREEN_HEIGHT - 50 + small_font->get_height() + 5),
ALIGN_LEFT, LAYER_FOREGROUND1);
}
if (climbed_by) {
context.push_transform();
context.set_translation(Vector(0, 0));
- Vector pos = Vector(0, SCREEN_HEIGHT/2 - gold_text->get_height()/2);
- context.draw_center_text(gold_text, _("Up we go..."), pos, LAYER_GUI);
+ Vector pos = Vector(0, SCREEN_HEIGHT/2 - normal_font->get_height()/2);
+ context.draw_center_text(normal_font, _("Up we go..."), pos, LAYER_GUI, Climbable::text_color);
context.pop_transform();
}
}
class Climbable : public TriggerBase, public Serializable
{
+ static Color text_color;
public:
Climbable(const lisp::Lisp& reader);
Climbable(const Rect& area);
if (message_timer.started()) {
context.push_transform();
context.set_translation(Vector(0, 0));
- Vector pos = Vector(0, SCREEN_HEIGHT/2 - gold_text->get_height()/2);
- context.draw_center_text(gold_text, _("You found a secret area!"), pos, LAYER_GUI);
+ Vector pos = Vector(0, SCREEN_HEIGHT/2 - normal_font->get_height()/2);
+ context.draw_center_text(normal_font, _("You found a secret area!"), pos, LAYER_GUI, SecretAreaTrigger::text_color);
context.pop_transform();
}
if (message_timer.check()) {
class SecretAreaTrigger : public TriggerBase, public Serializable
{
+ static Color text_color;
public:
SecretAreaTrigger(const lisp::Lisp& reader);
SecretAreaTrigger(const Rect& area, std::string fade_tilemap = "");
void
DrawingContext::draw_text(const Font* font, const std::string& text,
- const Vector& position, FontAlignment alignment, int layer)
+ const Vector& position, FontAlignment alignment, int layer, Color color)
{
DrawingRequest* request = new(obst) DrawingRequest();
request->layer = layer;
request->drawing_effect = transform.drawing_effect;
request->alpha = transform.alpha;
+ request->color = color;
TextRequest* textrequest = new(obst) TextRequest();
textrequest->font = font;
void
DrawingContext::draw_center_text(const Font* font, const std::string& text,
- const Vector& position, int layer)
+ const Vector& position, int layer, Color color)
{
draw_text(font, text, Vector(position.x + SCREEN_WIDTH/2, position.y),
- ALIGN_CENTER, layer);
+ ALIGN_CENTER, layer, color);
}
void
{
const TextRequest* textrequest = (TextRequest*) request.request_data;
textrequest->font->draw(renderer, textrequest->text, request.pos,
- textrequest->alignment, request.drawing_effect, request.alpha);
+ textrequest->alignment, request.drawing_effect, request.color, request.alpha);
}
break;
case FILLRECT:
{
const TextRequest* textrequest = (TextRequest*) request.request_data;
textrequest->font->draw(renderer, textrequest->text, request.pos,
- textrequest->alignment, request.drawing_effect, request.alpha);
+ textrequest->alignment, request.drawing_effect, request.color, request.alpha);
}
break;
case FILLRECT:
const Vector& size, const Vector& dest, int layer);
/// Draws a text.
void draw_text(const Font* font, const std::string& text,
- const Vector& position, FontAlignment alignment, int layer);
+ const Vector& position, FontAlignment alignment, int layer, Color color = Color(1.0,1.0,1.0));
/// Draws text on screen center (feed Vector.x with a 0).
/// This is the same as draw_text() with a SCREEN_WIDTH/2 position and
/// alignment set to LEFT_ALIGN
void draw_center_text(const Font* font, const std::string& text,
- const Vector& position, int layer);
+ const Vector& position, int layer, Color color = Color(1.0,1.0,1.0));
/// Draws a color gradient onto the whole screen */
void draw_gradient(const Color& from, const Color& to, int layer);
/// Fills a rectangle.
#include <SDL_image.h>
#include "physfs/physfs_sdl.hpp"
+#include <physfs.h>
+#include "file_system.hpp"
-#include "lisp/parser.hpp"
#include "lisp/lisp.hpp"
+#include "lisp/parser.hpp"
+#include "lisp/list_iterator.hpp"
#include "screen.hpp"
#include "font.hpp"
#include "renderer.hpp"
namespace {
bool has_multibyte_mark(unsigned char c);
uint32_t decode_utf8(const std::string& text, size_t& p);
+std::string encode_utf8(uint32_t code);
struct UTF8Iterator
{
Font::Font(GlyphWidth glyph_width_,
const std::string& filename,
- const std::string& shadowfile,
- int char_width, int char_height_,
int shadowsize_)
- : glyph_width(glyph_width_),
- glyph_surface(0), shadow_glyph_surface(0),
- char_height(char_height_),
- shadowsize(shadowsize_)
+: glyph_width(glyph_width_),
+ shadowsize(shadowsize_),
+ glyphs(65536)
{
- glyph_surface = new Surface(filename);
- shadow_glyph_surface = new Surface(shadowfile);
+ for(unsigned int i=0; i<65536;i++) glyphs[i].surface_idx = -1;
- first_char = 32;
- char_count = ((int) glyph_surface->get_height() / char_height) * 16;
+ const std::string fontdir = FileSystem::dirname(filename);
+ const std::string fontname = FileSystem::basename(filename);
- if (glyph_width == FIXED)
- {
- for(uint32_t i = 0; i < char_count; ++i)
- {
- float x = (i % 16) * char_width;
- float y = (i / 16) * char_height;
+ // scan for prefix-filename in addons search path
+ char **rc = PHYSFS_enumerateFiles(fontdir.c_str());
+ for (char **i = rc; *i != NULL; i++) {
+ std::string filename(*i);
+ if( filename.rfind(fontname) != std::string::npos ) {
+ loadFontFile(fontdir + filename);
+ }
+ }
+ PHYSFS_freeList(rc);
+}
- Glyph glyph;
- glyph.advance = char_width;
- glyph.offset = Vector(0, 0);
- glyph.rect = Rect(x, y, x + char_width, y + char_height);
+void
+Font::loadFontFile(const std::string &filename)
+{
+ lisp::Parser parser;
+ log_debug << "Loading font: " << filename << std::endl;
+ const lisp::Lisp* root = parser.parse(filename);
+ const lisp::Lisp* config_l = root->get_lisp("supertux-font");
+
+ if(!config_l) {
+ std::ostringstream msg;
+ msg << "Font file:" << filename << ": is not a supertux-font file";
+ throw std::runtime_error(msg.str());
+ }
- glyphs.push_back(glyph);
- shadow_glyphs.push_back(glyph);
- }
+ int def_char_width=0;
+
+ if( !config_l->get("glyph-width",def_char_width) ) {
+ log_warning << "Font:"<< filename << ": misses default glyph-width" << std::endl;
}
- else // glyph_width == VARIABLE
- {
- // Load the surface into RAM and scan the pixel data for characters
- SDL_Surface* surface = IMG_Load_RW(get_physfs_SDLRWops(filename), 1);
- if(surface == NULL) {
+
+ if( !config_l->get("glyph-height",char_height) ) {
+ std::ostringstream msg;
+ msg << "Font:" << filename << ": misses glyph-height";
+ throw std::runtime_error(msg.str());
+ }
+
+ lisp::ListIterator iter(config_l);
+ while(iter.next()) {
+ const std::string& token = iter.item();
+ if( token == "surface" ) {
+ const lisp::Lisp * glyphs_val = iter.lisp();
+ int local_char_width;
+ bool monospaced;
+ GlyphWidth local_glyph_width;
+ std::string glyph_image;
+ std::string shadow_image;
+ std::vector<std::string> chars;
+ if( ! glyphs_val->get("glyph-width", local_char_width) ) {
+ local_char_width = def_char_width;
+ }
+ if( ! glyphs_val->get("monospace", monospaced ) ) {
+ local_glyph_width = glyph_width;
+ }
+ else {
+ if( monospaced ) local_glyph_width = FIXED;
+ else local_glyph_width = VARIABLE;
+ }
+ if( ! glyphs_val->get("glyphs", glyph_image) ) {
std::ostringstream msg;
- msg << "Couldn't load image '" << filename << "' :" << SDL_GetError();
+ msg << "Font:" << filename << ": missing glyphs image";
throw std::runtime_error(msg.str());
- }
-
- SDL_LockSurface(surface);
-
- for(uint32_t i = 0; i < char_count; ++i)
- {
- int x = (i % 16) * char_width;
- int y = (i / 16) * char_height;
+ }
+ if( ! glyphs_val->get("shadows", shadow_image) ) {
+ std::ostringstream msg;
+ msg << "Font:" << filename << ": missing shadows image";
+ throw std::runtime_error(msg.str());
+ }
+ if( ! glyphs_val->get_vector("chars", chars) || chars.size() == 0) {
+ std::ostringstream msg;
+ msg << "Font:" << filename << ": missing chars definition";
+ throw std::runtime_error(msg.str());
+ }
- int left = x;
- while (left < x + char_width &&
- vline_empty(surface, left, y, y + char_height, 64))
- left += 1;
+ if( local_char_width==0 ) {
+ std::ostringstream msg;
+ msg << "Font:" << filename << ": misses glyph-width for some surface";
+ throw std::runtime_error(msg.str());
+ }
- int right = x + char_width - 1;
- while (right > left &&
- vline_empty(surface, right, y, y + char_height, 64))
- right -= 1;
+ loadFontSurface(glyph_image, shadow_image, chars,
+ local_glyph_width, local_char_width);
+ }
+ }
+}
- Glyph glyph;
- glyph.offset = Vector(0, 0);
+void
+Font::loadFontSurface(
+ const std::string &glyphimage,
+ const std::string &shadowimage,
+ const std::vector<std::string> &chars,
+ GlyphWidth glyph_width,
+ int char_width
+ )
+{
+ Surface glyph_surface = Surface("images/engine/fonts/" + glyphimage);
+ Surface shadow_surface = Surface("images/engine/fonts/" + shadowimage);
- if (left <= right)
- glyph.rect = Rect(left, y, right+1, y + char_height);
- else // glyph is completely transparent
- glyph.rect = Rect(x, y, x + char_width, y + char_height);
+ int surface_idx = glyph_surfaces.size();
+ glyph_surfaces.push_back(glyph_surface);
+ shadow_surfaces.push_back(shadow_surface);
- glyph.advance = glyph.rect.get_width() + 1; // FIXME: might be useful to make spacing configurable
+ int row=0, col=0;
+ int wrap = glyph_surface.get_width() / char_width;
+
+ SDL_Surface *surface = NULL;
+
+ if( glyph_width == VARIABLE ) {
+ //this does not work:
+ // surface = ((SDL::Texture *)glyph_surface.get_texture())->get_texture();
+ surface = IMG_Load_RW(get_physfs_SDLRWops("images/engine/fonts/"+glyphimage), 1);
+ if(surface == NULL) {
+ std::ostringstream msg;
+ msg << "Couldn't load image '" << glyphimage << "' :" << SDL_GetError();
+ throw std::runtime_error(msg.str());
+ }
+ SDL_LockSurface(surface);
+ }
- glyphs.push_back(glyph);
- shadow_glyphs.push_back(glyph);
+ for( unsigned int i = 0; i < chars.size(); i++) {
+ for(UTF8Iterator chr(chars[i]); !chr.done(); ++chr) {
+ float y = row * char_height;
+ float x = col * char_width;
+ if( ++col == wrap ) { col=0; row++; }
+ if( *chr == 0x0020 && glyphs[0x20].surface_idx != -1) continue;
+
+ Glyph glyph;
+ glyph.surface_idx = surface_idx;
+
+ if( glyph_width == FIXED ) {
+ glyph.rect = Rect(x, y, x + char_width, y + char_height);
+ glyph.offset = Vector(0, 0);
+ glyph.advance = char_width;
+ }
+ else {
+ int left = x;
+ while (left < x + char_width && vline_empty(surface, left, y, y + char_height, 64))
+ left += 1;
+ int right = x + char_width - 1;
+ while (right > left && vline_empty(surface, right, y, y + char_height, 64))
+ right -= 1;
+
+ if (left <= right)
+ glyph.rect = Rect(left, y, right+1, y + char_height);
+ else // glyph is completely transparent
+ glyph.rect = Rect(x, y, x + char_width, y + char_height);
+
+ glyph.offset = Vector(0, 0);
+ glyph.advance = glyph.rect.get_width() + 1; // FIXME: might be useful to make spacing configurable
}
- SDL_UnlockSurface(surface);
-
- SDL_FreeSurface(surface);
+ glyphs[*chr] = glyph;
+ }
+ if( col>0 && col <= wrap ) {
+ col = 0;
+ row++;
+ }
+ }
+
+ if( surface != NULL ) {
+ SDL_UnlockSurface(surface);
+ SDL_FreeSurface(surface);
}
}
Font::~Font()
{
- delete glyph_surface;
- delete shadow_glyph_surface;
}
float
}
else
{
- int idx = chr2glyph(*it);
- curr_width += glyphs[idx].advance;
+ if( glyphs.at(*it).surface_idx != -1 )
+ curr_width += glyphs[*it].advance;
+ else
+ curr_width += glyphs[0x20].advance;
}
}
void
Font::draw(Renderer *renderer, const std::string& text, const Vector& pos_,
- FontAlignment alignment, DrawingEffect drawing_effect,
+ FontAlignment alignment, DrawingEffect drawing_effect, Color color,
float alpha) const
{
float x = pos_.x;
// no blurring as we would get with subpixel positions
pos.x = static_cast<int>(pos.x);
- draw_text(renderer, temp, pos, drawing_effect, alpha);
+ draw_text(renderer, temp, pos, drawing_effect, color, alpha);
if (i == text.size())
break;
void
Font::draw_text(Renderer *renderer, const std::string& text, const Vector& pos,
- DrawingEffect drawing_effect, float alpha) const
+ DrawingEffect drawing_effect, Color color, float alpha) const
{
if(shadowsize > 0)
- {
- // FIXME: shadow_glyph_surface and glyph_surface do currently
- // share the same glyph array, this is incorrect and should be
- // fixed, it is however hardly noticeable
- draw_chars(renderer, shadow_glyph_surface, text,
- pos + Vector(shadowsize, shadowsize), drawing_effect, alpha);
- }
+ draw_chars(renderer, false, text,
+ pos + Vector(shadowsize, shadowsize), drawing_effect, Color(1,1,1), alpha);
- draw_chars(renderer, 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;
+ draw_chars(renderer, true, text, pos, drawing_effect, color, alpha);
}
void
-Font::draw_chars(Renderer *renderer, Surface* pchars, const std::string& text,
- const Vector& pos, DrawingEffect drawing_effect,
+Font::draw_chars(Renderer *renderer, bool notshadow, const std::string& text,
+ const Vector& pos, DrawingEffect drawing_effect, Color color,
float alpha) const
{
Vector p = pos;
for(UTF8Iterator it(text); !it.done(); ++it)
{
- int font_index = chr2glyph(*it);
-
if(*it == '\n')
{
p.x = pos.x;
}
else if(*it == ' ')
{
- p.x += glyphs[font_index].advance;
+ p.x += glyphs[0x20].advance;
}
else
{
- const Glyph& glyph = glyphs[font_index];
+ Glyph glyph;
+ if( glyphs.at(*it).surface_idx != -1 )
+ glyph = glyphs[*it];
+ else
+ glyph = glyphs[0x20];
+
DrawingRequest request;
request.pos = p + glyph.offset;
request.drawing_effect = drawing_effect;
+ request.color = color;
request.alpha = alpha;
SurfacePartRequest surfacepartrequest;
surfacepartrequest.size = glyph.rect.p2 - glyph.rect.p1;
surfacepartrequest.source = glyph.rect.p1;
- surfacepartrequest.surface = pchars;
+ surfacepartrequest.surface = notshadow ? &(glyph_surfaces[glyph.surface_idx]) : &(shadow_surfaces[glyph.surface_idx]);
request.request_data = &surfacepartrequest;
renderer->draw_surface_part(request);
- p.x += glyphs[font_index].advance;
+ p.x += glyph.advance;
}
}
}
#include <stdint.h>
#include "video/surface.hpp"
+#include "video/color.hpp"
#include "math/vector.hpp"
#include "math/rect.hpp"
/** Construct a fixed-width font
*
* @param glyph_width VARIABLE for proportional fonts, VARIABLE for monospace ones
- * @param filename image file containing the characters
- * @param shadowfile image file containing the characters shadows
- * @param char_width width of a character
- * @param char_height height of a character
+ * @param fontfile file in format supertux-font
+ * @param sgadowsize offset of shadow
*/
- Font(GlyphWidth glyph_width,
- const std::string& filename, const std::string& shadowfile,
- int char_width, int char_height, int shadowsize = 2);
+ Font(GlyphWidth glyph_width, const std::string& fontfile, int shadowsize = 2);
~Font();
/** returns the width of a given text. (Note that I won't add a normal
void draw(Renderer *renderer, const std::string& text, const Vector& pos,
FontAlignment alignment = ALIGN_LEFT,
DrawingEffect drawing_effect = NO_EFFECT,
+ Color color = Color(1.0,1.0,1.0),
float alpha = 1.0f) const;
private:
void draw_text(Renderer *renderer, const std::string& text, const Vector& pos,
DrawingEffect drawing_effect = NO_EFFECT,
+ Color color = Color(1.0,1.0,1.0),
float alpha = 1.0f) const;
- void draw_chars(Renderer *renderer, Surface* pchars, const std::string& text,
- const Vector& position, DrawingEffect drawing_effect,
+ void draw_chars(Renderer *renderer, bool nonshadow, const std::string& text,
+ const Vector& position, DrawingEffect drawing_effect, Color color,
float alpha) const;
- /** 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_glyph_surface;
+
+ std::vector<Surface> glyph_surfaces;
+ std::vector<Surface> shadow_surfaces;
int char_height;
int shadowsize;
- /// the number of the first character that is represented in the font
- uint32_t first_char;
- /// the number of the last character that is represented in the font
- uint32_t char_count;
-
struct Glyph {
/** How many pixels should the cursor advance after printing the
glyph */
/** Offset that is used when drawing the glyph */
Vector offset;
+ /** index of containing surface */
+ int surface_idx;
+
/** Position of the glyph inside the surface */
Rect rect;
};
- /** Location of the characters inside the surface */
+ /** 65536 of glyphs */
std::vector<Glyph> glyphs;
- std::vector<Glyph> shadow_glyphs;
+
+ void loadFontFile(const std::string &filename);
+ void loadFontSurface(const std::string &glyphimage,
+ const std::string &shadowimage,
+ const std::vector<std::string> &chars,
+ GlyphWidth glyph_width,
+ int char_width);
};
#endif
uv_bottom,
0.0,
request.alpha,
- Color(1.0, 1.0, 1.0),
+ request.color,
Blend(),
request.drawing_effect);
}
DrawingEffect effect = request.drawing_effect;
if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
- SDL_Surface *transform = sdltexture->get_transform(Color(1.0, 1.0, 1.0), effect);
+ SDL_Surface *transform = sdltexture->get_transform(request.color, effect);
// get and check SDL_Surface
if (transform == 0) {
if(level->title == "")
get_level_title(*level);
- context.draw_text(white_text, level->title,
+ context.draw_text(normal_font, level->title,
Vector(SCREEN_WIDTH/2,
- SCREEN_HEIGHT - white_text->get_height() - 30),
- ALIGN_CENTER, LAYER_FOREGROUND1);
+ SCREEN_HEIGHT - normal_font->get_height() - 30),
+ ALIGN_CENTER, LAYER_FOREGROUND1, WorldMap::level_title_color);
// if level is solved, draw level picture behind stats
/*
if (special_tile->pos == tux->get_tile_pos()) {
/* Display an in-map message in the map, if any as been selected */
if(!special_tile->map_message.empty() && !special_tile->passive_message)
- context.draw_text(gold_text, special_tile->map_message,
+ context.draw_text(normal_font, special_tile->map_message,
Vector(SCREEN_WIDTH/2,
- SCREEN_HEIGHT - white_text->get_height() - 60),
- ALIGN_CENTER, LAYER_FOREGROUND1);
+ SCREEN_HEIGHT - normal_font->get_height() - 60),
+ ALIGN_CENTER, LAYER_FOREGROUND1, WorldMap::message_color);
break;
}
}
// display teleporter messages
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, ALIGN_CENTER, LAYER_FOREGROUND1);
+ Vector pos = Vector(SCREEN_WIDTH/2, SCREEN_HEIGHT - normal_font->get_height() - 30);
+ context.draw_text(normal_font, teleporter->message, pos, ALIGN_CENTER, LAYER_FOREGROUND1, WorldMap::teleporter_message_color);
}
}
/* Display a passive message in the map, if needed */
if(passive_message_timer.started())
- context.draw_text(gold_text, passive_message,
- Vector(SCREEN_WIDTH/2, SCREEN_HEIGHT - white_text->get_height() - 60),
- ALIGN_CENTER, LAYER_FOREGROUND1);
+ context.draw_text(normal_font, passive_message,
+ Vector(SCREEN_WIDTH/2, SCREEN_HEIGHT - normal_font->get_height() - 60),
+ ALIGN_CENTER, LAYER_FOREGROUND1, WorldMap::message_color);
context.pop_transform();
}
*/
class WorldMap : public Screen
{
+ static Color level_title_color;
+ static Color message_color;
+ static Color teleporter_message_color;
private:
Tux* tux;