get_text_width() was broken. Fixed.
[supertux.git] / lib / video / font.cpp
index fe9f288..8f34991 100644 (file)
 #include <cstdlib>
 #include <cstring>
 
-#include "app/globals.h"
-#include "video/screen.h"
-#include "video/font.h"
-#include "video/drawing_context.h"
-#include "utils/lispreader.h"
+#include "../app/globals.h"
+#include "../video/screen.h"
+#include "../video/font.h"
+#include "../video/drawing_context.h"
+#include "../utils/lispreader.h"
 
 using namespace SuperTux;
 
@@ -71,30 +71,99 @@ Font::~Font()
 }
 
 float
+Font::get_text_width(const std::string& text) const
+{
+  /** Let's calculate the size of the biggest paragraph */
+  std::string::size_type l, hl, ol;
+  hl = 0; l = 0;
+  while(true)
+    {
+    ol = l;
+    l = text.find("\n", l+1);
+    if(l == std::string::npos)
+      break;
+    if(hl < l-ol)
+      hl = l-ol;
+    }
+  if(hl == 0)
+    hl = text.size();
+
+  return hl * w;
+}
+
+float
+Font::get_text_height(const std::string& text) const
+{
+  /** Let's calculate height of the text */
+  std::string::size_type l, hh;
+  hh = h; l = 0;
+  while(true)
+    {
+    l = text.find("\n", l+1);
+    if(l == std::string::npos)
+      break;
+    hh += h + 2;
+    }
+
+  return hh;
+}
+
+float
 Font::get_height() const
 {
   return h;
 }
 
-float
-Font::get_text_width(const std::string& text) const
+void
+Font::draw(const std::string& text, const Vector& pos_, int allignment, Uint32 drawing_effect, int alpha)
 {
-  return text.size() * w;
+  /* Cut lines changes into seperate strings, needed to support center/right text
+     allignments 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;
+      }
+
+    temp[text.copy(temp, l - i, i)] = '\0';
+
+    // calculate X positions based on the allignment type
+    Vector pos = Vector(pos_);
+    if(allignment == CENTER_ALLIGN)
+      pos.x -= get_text_width(temp) / 2;
+    else if(allignment == RIGHT_ALLIGN)
+      pos.x -= get_text_width(temp);
+
+    draw_text(temp, pos + Vector(0,y), drawing_effect, alpha);
+
+    i = l+1;
+    y += h + 2;
+    }
 }
 
 void
-Font::draw(const std::string& text, const Vector& pos, Uint32 drawing_effect)
+Font::draw_text(const std::string& text, const Vector& pos, Uint32 drawing_effect, int alpha)
 {
   if(shadowsize > 0)
     draw_chars(shadow_chars, text, pos + Vector(shadowsize, shadowsize),
-               drawing_effect);
+               drawing_effect, alpha);
 
-  draw_chars(chars, text, pos, drawing_effect);
+  draw_chars(chars, text, pos, drawing_effect, alpha);
 }
 
 void
 Font::draw_chars(Surface* pchars, const std::string& text, const Vector& pos,
-                 Uint32 drawing_effect)
+                 Uint32 drawing_effect, int alpha)
 {
   SurfaceImpl* impl = pchars->impl;
 
@@ -119,7 +188,7 @@ Font::draw_chars(Surface* pchars, const std::string& text, const Vector& pos,
     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, drawing_effect);
+    impl->draw_part(source_x, source_y, p.x, p.y, w, h, alpha, drawing_effect);
     p.x += w;
   }
 }
@@ -131,7 +200,7 @@ Font::draw_chars(Surface* pchars, const std::string& text, const Vector& pos,
 #define SCROLL      60
 #define ITEMS_SPACE 4
 
-void SuperTux::display_text_file(const std::string& file, float scroll_speed)
+void SuperTux::display_text_file(const std::string& file, float scroll_speed, Font* heading_font, Font* normal_font, Font* small_font, Font* reference_font )
 {
   std::string text;
   std::vector<std::string> names;
@@ -151,7 +220,7 @@ void SuperTux::display_text_file(const std::string& file, float scroll_speed)
 
   // Split text string lines into a vector
   names.clear();
-  unsigned int i, l;
+  std::string::size_type i, l;
   i = 0;
   while(true)
     {
@@ -229,23 +298,23 @@ void SuperTux::display_text_file(const std::string& file, float scroll_speed)
       float y = 0;
       for(size_t i = 0; i < names.size(); i++) {
         if(names[i].size() == 0) {
-          y += white_text->get_height() + ITEMS_SPACE;
+          y += normal_font->get_height() + ITEMS_SPACE;
           continue;
         }
 
         Font* font = 0;
         switch(names[i][0])
         {
-          case ' ': font = white_small_text; break;
-          case '\t': font = white_text; break;
-          case '-': font = white_big_text; break;
-          case '*': font = blue_text; break;
-          default: font = blue_text; break;
+          case ' ': font = small_font; break;
+          case '\t': font = normal_font; break;
+          case '-': font = heading_font; break;
+          case '*': font = reference_font; break;
+          default: font = reference_font; break;
         }
 
-        context.draw_text_center(font,
+        context.draw_text(font,
             names[i].substr(1, names[i].size()-1),
-            Vector(0, screen->h + y - scroll), LAYER_FOREGROUND1);
+            Vector(screen->w/2, screen->h + y - scroll), CENTER_ALLIGN, LAYER_FOREGROUND1);
         y += font->get_height() + ITEMS_SPACE;
       }