X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=lib%2Fvideo%2Ffont.cpp;h=12d96c741889941adee471478debbe3fcf0b1b22;hb=58bf708dc9f036b2c7d8d3edfdbfa62f0da3481a;hp=260c6f75322cd3e7fd674b28988cd0f460f47c89;hpb=ce77ac2dc07853488c61e430f7fa6fa25a91f3e3;p=supertux.git diff --git a/lib/video/font.cpp b/lib/video/font.cpp index 260c6f753..12d96c741 100644 --- a/lib/video/font.cpp +++ b/lib/video/font.cpp @@ -18,14 +18,18 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. +#include + #include #include +#include -#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 "lisp/parser.h" +#include "lisp/lisp.h" +#include "screen.h" +#include "font.h" +#include "drawing_context.h" using namespace SuperTux; @@ -74,15 +78,16 @@ 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; - hl = 0; l = -1; + 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) - hl = l; + if(hl < l-ol) + hl = l-ol; } if(hl == 0) hl = text.size(); @@ -95,11 +100,11 @@ 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 = -1; + hh = h; l = 0; while(true) { l = text.find("\n", l+1); - if(l == (int)std::string::npos) + if(l == std::string::npos) break; hh += h + 2; } @@ -116,32 +121,33 @@ Font::get_height() const void Font::draw(const std::string& text, const Vector& pos_, int allignment, Uint32 drawing_effect, int alpha) { - // calculate X positions based on the allignment type - Vector pos = Vector(pos_); - if(allignment == CENTER_ALLIGN) - pos.x -= get_text_width(text) / 2; - else if(allignment == RIGHT_ALLIGN) - pos.x -= get_text_width(text); - /* 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; - unsigned int i, y; + std::string::size_type l, i, y; + bool done = false; i = y = 0; - while(true) + while(!done) { l = text.find("\n", i); if(l == std::string::npos) { - temp[text.copy(temp, text.size() - i, i)] = '\0'; - draw_text(temp, pos + Vector(0,y), drawing_effect, alpha); - break; + 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; @@ -198,27 +204,36 @@ 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, Font* heading_font, Font* normal_font, Font* small_font, Font* reference_font ) +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::string background_file; std::vector names; - LispReader* reader = LispReader::load(datadir + "/" + file, "supertux-text"); + std::string filename = datadir + "/" + file; + lisp::Parser parser; + try { + std::auto_ptr root (parser.parse(filename)); - if(!reader) - { - std::cerr << "Error: Could not open text. Ignoring...\n"; + const lisp::Lisp* text_lisp = root->get_lisp("supertux-text"); + if(!text_lisp) + throw std::runtime_error("File isn't a supertux-text file"); + + if(!text_lisp->get("text", text)) + throw std::runtime_error("file doesn't contain a text field"); + if(!text_lisp->get("background", background_file)) + throw std::runtime_error("file doesn't contain a background file"); + } catch(std::exception& e) { + std::cerr << "Couldn't load file '" << filename << "': " << e.what() << + "\n"; return; - } - - reader->read_string("text", text, true); - std::string background_file; - reader->read_string("background", background_file, true); - delete reader; + } // Split text string lines into a vector names.clear(); - unsigned int i, l; + std::string::size_type i, l; i = 0; while(true) { @@ -245,6 +260,7 @@ void SuperTux::display_text_file(const std::string& file, float scroll_speed, Fo int done = 0; float scroll = 0; float speed = scroll_speed / 50; + float left_border = 50; DrawingContext context; SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); @@ -301,18 +317,32 @@ void SuperTux::display_text_file(const std::string& file, float scroll_speed, Fo } Font* font = 0; + bool center = true; switch(names[i][0]) { 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; + case '#': font = normal_font; center = false; break; + default: + break; } - - context.draw_text(font, - names[i].substr(1, names[i].size()-1), - Vector(screen->w/2, screen->h + y - scroll), CENTER_ALLIGN, LAYER_FOREGROUND1); + + if(font) { + if(center) { + context.draw_text(font, + names[i].substr(1, names[i].size()-1), + Vector(screen->w/2, screen->h + y - scroll), + CENTER_ALLIGN, LAYER_FOREGROUND1); + } else { + context.draw_text(font, + names[i].substr(1, names[i].size()-1), + Vector(left_border, screen->h + y - scroll), + LEFT_ALLIGN, LAYER_FOREGROUND1); + } + } + y += font->get_height() + ITEMS_SPACE; }