cleaned up font drawing code and added support for latin1 font of litespeed
authorMatthias Braun <matze@braunis.de>
Wed, 2 Jun 2004 20:06:56 +0000 (20:06 +0000)
committerMatthias Braun <matze@braunis.de>
Wed, 2 Jun 2004 20:06:56 +0000 (20:06 +0000)
SVN-Revision: 1383

src/gameloop.cpp
src/screen/font.cpp
src/screen/font.h
src/setup.cpp
src/worldmap.cpp

index 613d927..3667ae4 100644 (file)
@@ -720,12 +720,14 @@ GameSession::drawstatus(DrawingContext& context)
 
   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);
@@ -746,7 +748,8 @@ GameSession::drawstatus(DrawingContext& context)
     {
       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);
     }
index 45f9e93..d77e335 100644 (file)
 #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()
@@ -93,7 +83,7 @@ Font::get_text_width(const std::string& text) const
 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);
@@ -102,48 +92,32 @@ Font::draw(const std::string& text, const Vector& 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 --- */
index 7f398bc..00b5041 100644 (file)
 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:
@@ -57,6 +55,18 @@ 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*/
index dbec4db..83eac4c 100644 (file)
@@ -584,19 +584,26 @@ void st_general_setup(void)
 
   /* 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);
index 5a52357..2988acf 100644 (file)
@@ -864,8 +864,8 @@ WorldMap::draw_status(DrawingContext& context)
       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
     {