sprintf(str, "%d", player_status.distros);
context.draw_text(white_text, "COINS",
- Vector(screen->w - white_text->w*9, 0), LAYER_FOREGROUND1);
+ Vector(screen->w - white_text->get_text_width("COINS "), 0),
+ LAYER_FOREGROUND1);
context.draw_text(gold_text, str,
- Vector(screen->w - gold_text->w*2, 0), LAYER_FOREGROUND1);
+ Vector(screen->w - gold_text->get_text_width("99"), 0),LAYER_FOREGROUND1);
context.draw_text(white_text, "LIVES",
- Vector(screen->w - white_text->w*9, 20), LAYER_FOREGROUND1);
+ Vector(screen->w - white_text->get_text_width("LIVES "), 20),
+ LAYER_FOREGROUND1);
if (player_status.lives >= 5)
{
sprintf(str, "%dx", player_status.lives);
{
sprintf(str, "%2.1f", fps_fps);
context.draw_text(white_text, "FPS",
- Vector(screen->w - white_text->w*9, 40), LAYER_FOREGROUND1);
+ Vector(screen->w - white_text->get_text_width("FPS "), 40),
+ LAYER_FOREGROUND1);
context.draw_text(gold_text, str,
Vector(screen->w-4*16, 40), LAYER_FOREGROUND1);
}
#include "font.h"
#include "drawing_context.h"
-Font::Font(const std::string& file, int kind_, int w_, int h_, int shadowsize_)
+Font::Font(const std::string& file, FontType ntype, int nw, int nh,
+ int nshadowsize)
+ : chars(0), shadow_chars(0), type(ntype), w(nw), h(nh),
+ shadowsize(nshadowsize)
{
- kind = kind_;
- w = w_;
- h = h_;
- shadowsize = shadowsize_;
-
- int mx, my;
- SDL_Surface *conv;
- int pixels;
- int i;
-
- if(kind == TEXT_TEXT)
- {
- mx = 26;
- my = 3;
- }
- else if(kind == TEXT_NUM)
- {
- mx = 10;
- my = 1;
- }
- else
- {
- mx = 0;
- my = 0;
- }
-
chars = new Surface(file, USE_ALPHA);
-
+
+ switch(type) {
+ case TEXT:
+ first_char = 32;
+ break;
+ case NUM:
+ first_char = 48;
+ break;
+ }
+ last_char = first_char + (chars->h / h) * 16;
+ if(last_char > 127) // we have left out some control chars at 128-159
+ last_char += 32;
+ printf("Chars: %d-%d.\n", first_char, last_char);
+
// Load shadow font.
- conv = SDL_DisplayFormatAlpha(chars->impl->get_sdl_surface());
- pixels = conv->w * conv->h;
- SDL_LockSurface(conv);
- for(i = 0; i < pixels; ++i)
- {
+ if(shadowsize > 0) {
+ SDL_Surface* conv = SDL_DisplayFormatAlpha(chars->impl->get_sdl_surface());
+ int pixels = conv->w * conv->h;
+ SDL_LockSurface(conv);
+ for(int i = 0; i < pixels; ++i) {
Uint32 *p = (Uint32 *)conv->pixels + i;
*p = *p & conv->format->Amask;
}
- SDL_UnlockSurface(conv);
- SDL_SetAlpha(conv, SDL_SRCALPHA, 128);
- shadow_chars = new Surface(conv, USE_ALPHA);
-
- SDL_FreeSurface(conv);
+ SDL_UnlockSurface(conv);
+ SDL_SetAlpha(conv, SDL_SRCALPHA, 128);
+ shadow_chars = new Surface(conv, USE_ALPHA);
+ SDL_FreeSurface(conv);
+ }
}
Font::~Font()
void
Font::draw(const std::string& text, const Vector& pos)
{
- if(shadowsize != 0)
+ if(shadowsize > 0)
draw_chars(shadow_chars, text, pos + Vector(shadowsize, shadowsize));
draw_chars(chars, text, pos);
void
Font::draw_chars(Surface* pchars, const std::string& text, const Vector& pos)
{
- size_t i, j;
-
SurfaceImpl* impl = pchars->impl;
- int x = int(pos.x);
- int y = int(pos.y);
- if(kind == TEXT_TEXT)
- {
- for( i = 0, j = 0; i < text.size(); ++i,++j)
- {
- if( text[i] >= ' ' && text[i] <= '/')
- impl->draw_part((int)(text[i] - ' ')*w, 0 , x+(j*w), y, w, h, 255);
- else if( text[i] >= '0' && text[i] <= '?')
- impl->draw_part((int)(text[i] - '0')*w, h*1, x+(j*w), y, w, h, 255);
- else if ( text[i] >= '@' && text[i] <= 'O')
- impl->draw_part((int)(text[i] - '@')*w, h*2, x+(j*w), y, w, h, 255);
- else if ( text[i] >= 'P' && text[i] <= '_')
- impl->draw_part((int)(text[i] - 'P')*w, h*3, x+(j*w), y, w, h, 255);
- else if ( text[i] >= '`' && text[i] <= 'o')
- impl->draw_part((int)(text[i] - '`')*w, h*4, x+(j*w), y, w, h, 255);
- else if ( text[i] >= 'p' && text[i] <= '~')
- impl->draw_part((int)(text[i] - 'p')*w, h*5, x+(j*w), y, w, h, 255);
- else if ( text[i] == '\n')
- {
- y += h + 2;
- j = 0;
- }
- }
+ Vector p = pos;
+ for(size_t i = 0; i < text.size(); ++i)
+ {
+ int c = (unsigned char) text[i];
+ if(c > 127) // correct for the 32 controlchars at 128-159
+ c -= 32;
+ // a non-printable character?
+ if(c == '\n') {
+ p.x = pos.x;
+ p.y += h + 2;
+ continue;
}
- else if(kind == TEXT_NUM)
- {
- for( i = 0, j = 0; i < text.size(); ++i, ++j)
- {
- if ( text[i] >= '0' && text[i] <= '9')
- impl->draw_part((int)(text[i] - '0')*w, 0, x+(j*w), y, w, h, 255);
- else if ( text[i] == '\n')
- {
- y += h + 2;
- j = 0;
- }
- }
+ if(c == ' ' || c < first_char || c > last_char) {
+ p.x += w;
+ continue;
}
+
+ int index = c - first_char;
+ int source_x = (index % 16) * w;
+ int source_y = (index / 16) * h;
+
+ impl->draw_part(source_x, source_y, p.x, p.y, w, h, 255);
+ p.x += w;
+ }
}
/* --- SCROLL TEXT FUNCTION --- */
void display_text_file(const std::string& file, const std::string& surface, float scroll_speed);
void display_text_file(const std::string& file, Surface* surface, float scroll_speed);
-/* Kinds of texts. */
-enum {
- TEXT_TEXT,
- TEXT_NUM
-};
-
/* Text type */
class Font
{
public:
- Surface* chars;
- Surface* shadow_chars;
- int kind;
- int w;
- int h;
- int shadowsize;
-public:
- Font(const std::string& file, int kind, int w, int h, int shadowsize = 2);
+ /* Kinds of texts. */
+ enum FontType {
+ TEXT, // images for all characters
+ NUM // only images for numbers
+ };
+
+ Font(const std::string& file, FontType type, int w, int h, int shadowsize=2);
~Font();
+ /** returns the height of the font */
float get_height() const;
+ /** returns the width of a given text. (Note that I won't add a normal
+ * get_width function here, as we might switch to variable width fonts in the
+ * future.
+ */
float get_text_width(const std::string& text) const;
private:
void draw(const std::string& text, const Vector& pos);
void draw_chars(Surface* pchars, const std::string& text,
const Vector& position);
+
+ Surface* chars;
+ Surface* shadow_chars;
+ FontType type;
+ int w;
+ int h;
+ int shadowsize;
+
+ /// the number of the first character that is represented in the font
+ int first_char;
+ /// the number of the last character that is represented in the font
+ int last_char;
};
#endif /*SUPERTUX_TEXT_H*/
/* Load global images: */
- black_text = new Font(datadir + "/images/status/letters-black.png", TEXT_TEXT, 16,18);
- gold_text = new Font(datadir + "/images/status/letters-gold.png", TEXT_TEXT, 16,18);
- silver_text = new Font(datadir + "/images/status/letters-silver.png", TEXT_TEXT, 16,18);
- blue_text = new Font(datadir + "/images/status/letters-blue.png", TEXT_TEXT,
- 16,18, 3);
- red_text = new Font(datadir + "/images/status/letters-red.png", TEXT_TEXT, 16,18);
- green_text = new Font(datadir + "/images/status/letters-green.png", TEXT_TEXT, 16,18);
- white_text = new Font(datadir + "/images/status/letters-white.png", TEXT_TEXT, 16,18);
+ black_text = new Font(datadir + "/images/status/letters-black.png",
+ Font::TEXT, 16,18);
+ gold_text = new Font(datadir + "/images/status/letters-gold.png",
+ Font::TEXT, 16,18);
+ silver_text = new Font(datadir + "/images/status/letters-silver.png",
+ Font::TEXT, 16,18);
+ blue_text = new Font(datadir + "/images/status/letters-blue.png",
+ Font::TEXT, 16, 18, 3);
+ red_text = new Font(datadir + "/images/status/letters-red.png",
+ Font::TEXT, 16,18);
+ green_text = new Font(datadir + "/images/status/letters-green.png",
+ Font::TEXT, 16,18);
+ white_text = new Font(datadir + "/images/fonts/letters-white.png",
+ Font::TEXT, 16,18);
white_small_text = new Font(datadir +
- "/images/status/letters-white-small.png", TEXT_TEXT, 8,9, 1);
- white_big_text = new Font(datadir + "/images/status/letters-white-big.png",
- TEXT_TEXT, 20,22, 3);
- yellow_nums = new Font(datadir + "/images/status/numbers.png", TEXT_NUM, 32,32);
+ "/images/status/letters-white-small.png", Font::TEXT, 8,9, 1);
+ white_big_text = new Font(datadir + "/images/fonts/letters-white-big.png",
+ Font::TEXT, 20,22, 3);
+ yellow_nums = new Font(datadir + "/images/status/numbers.png",
+ Font::TEXT, 32,32);
/* Load GUI/menu images: */
checkbox = new Surface(datadir + "/images/status/checkbox.png", USE_ALPHA);
context.draw_text(gold_text, str,
Vector(screen->w - gold_text->get_text_width(str) - tux_life->w, 0),
LAYER_FOREGROUND1);
- context.draw_surface(tux_life, Vector(screen->w - gold_text->w, 0),
- LAYER_FOREGROUND1);
+ context.draw_surface(tux_life, Vector(screen->w -
+ gold_text->get_text_width("9"), 0), LAYER_FOREGROUND1);
}
else
{