00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <SDL_video.h>
00021 #include <SDL_gfxPrimitives.h>
00022 #include <string>
00023 #include <iostream>
00024 #include "text.h"
00025 #include "color.h"
00026 #include "colors.h"
00027 #include "font.h"
00028 #include "video.h"
00029 #include "../include/app.h"
00030 #include "../tool/error.h"
00031 #include "../interface/interface.h"
00032 #include "../map/map.h"
00033
00034 Text::Text(const std::string &new_txt, Color new_color,
00035 Font* new_font, bool shadowed)
00036 {
00037
00038 if( new_font == NULL )
00039 new_font = Font::GetInstance(Font::FONT_SMALL);
00040
00041 txt = new_txt;
00042 color = new_color;
00043 font = new_font;
00044 this->shadowed = shadowed;
00045
00046 if( shadowed ){
00047 int width = font->GetWidth("x");
00048 bg_offset = (unsigned int)width/8;
00049 if (bg_offset < 1) bg_offset = 1;
00050 }
00051 else {
00052 bg_offset = 0;
00053 }
00054 max_width = 0;
00055
00056 Render();
00057 }
00058
00059 Text::~Text()
00060 {
00061 }
00062
00063 void Text::Render()
00064 {
00065 if (txt=="") return;
00066
00067 if (max_width != 0) {
00068 RenderMultiLines();
00069 return;
00070 }
00071
00072 surf = font->CreateSurface(txt, color);
00073 if ( shadowed ) {
00074 background = font->CreateSurface(txt, black_color);
00075 }
00076 }
00077
00078 void Text::RenderMultiLines()
00079 {
00080 if (txt=="") return;
00081
00082
00083 if (font->GetWidth(txt) < int(max_width)) {
00084 surf = font->CreateSurface(txt, color);
00085 if ( shadowed ) {
00086 background = font->CreateSurface(txt, black_color);
00087 }
00088 return;
00089 }
00090
00091
00092 std::vector<std::string> tokens;
00093 std::string::size_type old_pos = 0, current_pos = 0;
00094
00095 while ( old_pos < txt.size() &&
00096 (current_pos = txt.find_first_of(" ", old_pos)) != std::string::npos )
00097 {
00098 std::string tmp = txt.substr(old_pos, current_pos-old_pos);
00099 if (tmp != " ") {
00100 tokens.push_back(tmp);
00101 }
00102 old_pos = current_pos+1;
00103 }
00104 tokens.push_back(txt.substr(old_pos));
00105
00106
00107 std::vector<std::string> lines;
00108 uint index_lines = 0;
00109 uint index_word = 0;
00110
00111 while (index_word < tokens.size())
00112 {
00113 if ( lines.size() == index_lines ) {
00114
00115 lines.push_back(tokens.at(index_word));
00116
00117 } else {
00118
00119 if ( font->GetWidth(lines.at(index_lines)+" "+tokens.at(index_word)) > int(max_width) ) {
00120
00121
00122 index_lines++;
00123 index_word--;
00124 } else {
00125 lines.at(index_lines) += " " + tokens.at(index_word);
00126 }
00127
00128 }
00129
00130 index_word++;
00131 }
00132
00133
00134
00135
00136 Point2i size(max_width, (font->GetHeight()+2) * lines.size());
00137 surf.NewSurface(size, SDL_SWSURFACE|SDL_SRCALPHA, true);
00138 surf = surf.DisplayFormatAlpha();
00139
00140
00141 surf.Lock();
00142
00143
00144 for (uint i = 0; i < lines.size(); i++) {
00145 Surface tmp=(font->CreateSurface(lines.at(i), color)).DisplayFormatAlpha();
00146 tmp.Lock();
00147
00148
00149 for (int x=0; x < tmp.GetWidth() && x < int(max_width); x++)
00150 {
00151 for (int y=0; y < tmp.GetHeight(); y++)
00152 {
00153 surf.PutPixel(x, ((font->GetHeight()+2)*i)+y,
00154 tmp.GetPixel(x, y));
00155 }
00156 }
00157 tmp.Unlock();
00158 }
00159 surf.Unlock();
00160
00161
00162 if (!shadowed) return;
00163
00164 background.NewSurface(size, SDL_SWSURFACE|SDL_SRCALPHA, true);
00165 background = background.DisplayFormatAlpha();
00166
00167
00168 background.Lock();
00169
00170
00171 for (uint i = 0; i < lines.size(); i++) {
00172 Surface tmp=(font->CreateSurface(lines.at(i), black_color)).DisplayFormatAlpha();
00173 tmp.Lock();
00174
00175
00176 for (int x=0; x < tmp.GetWidth() && x < int(max_width); x++)
00177 {
00178 for (int y=0; y < tmp.GetHeight(); y++)
00179 {
00180 background.PutPixel(x, ((font->GetHeight()+2)*i)+y,
00181 tmp.GetPixel(x, y));
00182 }
00183 }
00184 tmp.Unlock();
00185 }
00186 background.Unlock();
00187 }
00188
00189 void Text::Set(const std::string &new_txt)
00190 {
00191 if(txt == new_txt)
00192 return;
00193
00194 txt = new_txt;
00195
00196 Render();
00197 }
00198
00199 const std::string& Text::GetText() const
00200 {
00201 return txt;
00202 }
00203
00204 void Text::SetColor(const Color &new_color)
00205 {
00206 if(color == new_color)
00207 return;
00208
00209 color = new_color;
00210
00211 Render();
00212 }
00213
00214 void Text::DrawCenter (int x, int y) const
00215 {
00216 DrawTopLeft(x - surf.GetWidth() / 2, y - surf.GetHeight() / 2);
00217 }
00218
00219 void Text::DrawCenter (const Point2i &position) const
00220 {
00221 DrawCenter(position.GetX(), position.GetY());
00222 }
00223
00224 void Text::DrawTopRight (int x, int y) const
00225 {
00226 DrawTopLeft( x - surf.GetWidth(), y);
00227 }
00228
00229 void Text::DrawCenterTop (int x, int y) const
00230 {
00231 DrawTopLeft( x - surf.GetWidth()/2, y);
00232 }
00233
00234 void Text::DrawTopLeft(const Point2i &position) const
00235 {
00236 if(txt == "") return;
00237
00238 Rectanglei dst_rect(position, surf.GetSize());
00239 AppWormux * app = AppWormux::GetInstance();
00240
00241 if(shadowed){
00242 Rectanglei shad_rect;
00243
00244 shad_rect.SetPosition(dst_rect.GetPosition() + bg_offset);
00245 shad_rect.SetSize(background.GetWidth(), background.GetHeight() );
00246
00247 app->video.window.Blit(background, shad_rect.GetPosition());
00248 app->video.window.Blit(surf, dst_rect.GetPosition());
00249
00250 world.ToRedrawOnScreen(Rectanglei(dst_rect.GetPosition(),
00251 shad_rect.GetSize() + bg_offset));
00252 }else{
00253 app->video.window.Blit(surf, dst_rect.GetPosition());
00254 world.ToRedrawOnScreen(dst_rect);
00255 }
00256 }
00257
00258 void Text::DrawTopLeft (int x, int y) const
00259 {
00260 DrawTopLeft( Point2i(x, y) );
00261 }
00262
00263 void Text::DrawCenterOnMap (int x, int y) const
00264 {
00265 DrawTopLeftOnMap(x - surf.GetWidth()/2, y - surf.GetHeight()/2 );
00266 }
00267
00268 void Text::DrawCenterTopOnMap (int x, int y) const
00269 {
00270 DrawTopLeftOnMap(x - surf.GetWidth()/2, y);
00271 }
00272
00273 void Text::DrawTopLeftOnMap (int x, int y) const
00274 {
00275 if(shadowed)
00276 AbsoluteDraw(background, Point2i(bg_offset + x, bg_offset + y) );
00277 AbsoluteDraw(surf, Point2i(x, y) );
00278 }
00279
00280 void Text::SetMaxWidth(uint max_w)
00281 {
00282 if (max_width == max_w)
00283 return;
00284
00285 max_width = max_w;
00286
00287 Render();
00288 }
00289
00290 int Text::GetWidth() const
00291 {
00292 if(txt=="") return 0;
00293 return surf.GetWidth();
00294 }
00295
00296 int Text::GetHeight() const
00297 {
00298 if(txt=="") return 0;
00299 return surf.GetHeight();
00300 }
00301
00302 void DrawTmpBoxText(Font &font, Point2i pos,
00303 const std::string &txt, uint space,
00304 Color boxColor, Color rectColor)
00305 {
00306 Point2i size = font.GetSize(txt) + Point2i(space, space)*2;
00307
00308 pos.y -= font.GetHeight(txt)/2;
00309
00310 Rectanglei rect( pos - size/2, size);
00311
00312 AppWormux * app = AppWormux::GetInstance();
00313
00314 app->video.window.BoxColor(rect, boxColor);
00315 app->video.window.RectangleColor(rect, rectColor);
00316
00317 world.ToRedrawOnScreen( rect );
00318 font.WriteCenterTop( pos, txt, white_color);
00319 }
00320
00321 void DrawTmpBoxTextWithReturns(Font &font, const Point2i &position,
00322 const std::string &txt, uint space,
00323 Color boxColor,
00324 Color rectColor)
00325 {
00326 size_t pos = 0;
00327 size_t last_pos = 0;
00328 size_t max_width = 0;
00329 size_t total_height = 0;
00330 int x, y;
00331 char *lines = strdup(txt.c_str());
00332
00333 std::vector< size_t > offsets;
00334
00335
00336 offsets.push_back(0);
00337 while (lines[pos] != '\0')
00338 {
00339 if (lines[pos] == '\n')
00340 {
00341 lines[pos] = 0;
00342 if (!lines[pos+1]) break;
00343
00344 offsets.push_back(pos+1);
00345 int w = font.GetWidth(lines+last_pos) + space*2;
00346 if ((int)max_width < w) max_width = w;
00347 total_height += font.GetHeight(lines+last_pos);
00348 #if DEBUG
00349 if (last_pos)
00350 {
00351 std::cerr << "(" << pos << "," << pos-last_pos
00352 << ") >>> " << lines+last_pos << " <<<\n";
00353 }
00354 #endif
00355 last_pos = pos+1;
00356 }
00357 pos++;
00358 }
00359 if (max_width == 0) {
00360 max_width = font.GetWidth(lines) + space*2;
00361 }
00362
00363
00364 total_height += 5*space;
00365 x = position.x - max_width / 2;
00366 y = position.y - total_height / 2;
00367
00368 Rectanglei rect(x, y, max_width, total_height);
00369
00370 AppWormux * app = AppWormux::GetInstance();
00371
00372 app->video.window.BoxColor(rect, boxColor);
00373 app->video.window.RectangleColor(rect, rectColor);
00374
00375 world.ToRedrawOnScreen(rect);
00376
00377 for( std::vector<size_t>::iterator it=offsets.begin();
00378 it != offsets.end();
00379 ++it)
00380 {
00381 font.WriteLeft( Point2i(x+space, y+space), lines+(*it), white_color);
00382 y += font.GetHeight(lines+(*it));
00383 }
00384 offsets.clear();
00385 free(lines);
00386 }