00001
00002
00003
00004
00005
00006 #include "iostream"
00007 using namespace std;
00008 #include "string.h"
00009 #include "stdlib.h"
00010 #include "stdarg.h"
00011
00012 #include <SDL/SDL_image.h>
00013 #include "bfont.h"
00014
00015 void BFont::InitFont()
00016 {
00017 int x = 0, i = '!';
00018 Uint32 sentry = GetPixel(0,0);
00019
00020 if (SDL_MUSTLOCK(Surface))
00021 SDL_LockSurface(Surface);
00022
00023 while ( x < (Surface->w-1))
00024 {
00025 if(GetPixel(x,0) != sentry)
00026 {
00027 Chars[i].x = x;
00028 Chars[i].y = 1;
00029 Chars[i].h = Surface->h;
00030 for (; GetPixel(x, 0) != sentry && x < (Surface->w); ++x) ;
00031 Chars[i].w = (x - Chars[i].x);
00032 i++;
00033 } else
00034 { x++; }
00035 }
00036 Chars[' '].x = 0;
00037 Chars[' '].y = 0;
00038 Chars[' '].h = Surface->h;
00039 Chars[' '].w = Chars['!'].w;
00040
00041 if (SDL_MUSTLOCK(Surface))
00042 SDL_UnlockSurface(Surface);
00043
00044 h = Surface->h;
00045
00046 SDL_SetColorKey(Surface, SDL_SRCCOLORKEY, GetPixel(0, Surface->h-1));
00047 }
00048
00049
00050
00051 void BFont::LoadFont (const char *filename)
00052 {
00053 SDL_Surface *surface(NULL);
00054 int x;
00055
00056
00057
00058
00059 if ((filename != NULL ) && (this != NULL))
00060 {
00061 surface = IMG_Load( filename );
00062
00063 if (surface != NULL)
00064 {
00065 Surface = surface;
00066 for (x=0; x<256; x++)
00067 {
00068 Chars[x].x = 0;
00069 Chars[x].y = 0;
00070 Chars[x].h = 0;
00071 Chars[x].w = 0;
00072 }
00073 InitFont();
00074 }
00075 }
00076 }
00077
00078 BFont * BFont :: SetFontColor(Uint8 r, Uint8 g, Uint8 b)
00079 {
00080 int x,y;
00081
00082 BFont *newfont;
00083 SDL_Surface *surface = NULL;
00084
00085 Uint32 pixel;
00086 Uint8 old_r, old_g, old_b;
00087 Uint8 new_r, new_g, new_b;
00088 Uint32 color_key;
00089
00090 newfont = new BFont(NULL);
00091
00092 if (newfont != NULL) {
00093
00094 newfont->h = h;
00095
00096 for (x=0; x<256; x++) {
00097 newfont->Chars[x].x = Chars[x].x;
00098 newfont->Chars[x].y = Chars[x].y;
00099 newfont->Chars[x].h = Chars[x].h;
00100 newfont->Chars[x].w = Chars[x].w;
00101 }
00102
00103 surface = SDL_CreateRGBSurface(SDL_SWSURFACE, Surface->w, Surface->h, 32,
00104 0x000000ff,0x0000ff00, 0x00ff0000, 0xff000000);
00105 if (surface != NULL) {
00106
00107 if (SDL_MUSTLOCK(surface)) SDL_LockSurface(surface);
00108 if (SDL_MUSTLOCK(Surface)) SDL_LockSurface(Surface);
00109
00110 color_key = xGetPixel(Surface, 0, Surface->h-1);
00111
00112 for( x=0; x < Surface->w; x++) {
00113 for( y=0; y < Surface->h; y++) {
00114 old_r = old_g = old_b = 0;
00115 pixel = xGetPixel(Surface,x,y);
00116
00117 if (pixel != color_key) {
00118 SDL_GetRGB(pixel, Surface->format, &old_r,&old_g,&old_b);
00119
00120 new_r = (Uint8) ((old_r * r) / 255);
00121 new_g = (Uint8) ((old_g * g) / 255);
00122 new_b = (Uint8) ((old_b * b) / 255);
00123
00124 pixel = SDL_MapRGB(surface->format,new_r,new_g,new_b);
00125 }
00126 PutPixel(surface,x,y,pixel);
00127 }
00128 }
00129
00130 if (SDL_MUSTLOCK(surface)) SDL_UnlockSurface(surface);
00131 if (SDL_MUSTLOCK(Surface)) SDL_UnlockSurface(Surface);
00132
00133 SDL_SetColorKey(surface, SDL_SRCCOLORKEY, color_key);
00134 }
00135
00136 newfont->Surface = surface;
00137 }
00138 return newfont;
00139 }
00140
00141
00142
00143 int BFont::PutChar(SDL_Surface *screen, int x, int y, char c)
00144 {
00145 int r=0;
00146 SDL_Rect dest;
00147
00148 dest.w = CharWidth(' ');
00149 dest.h = FontHeight();
00150 dest.x = x;
00151 dest.y = y;
00152
00153 if (c != ' ')
00154 SDL_BlitSurface( Surface, &Chars[c], screen, &dest);
00155
00156 r = dest.w;
00157 return r;
00158 }
00159
00160
00161 void BFont::PutString(SDL_Surface *screen, int x, int y, const char *text)
00162 {
00163 int i(0);
00164 while (text[i]!='\0')
00165 {
00166 x += PutChar(screen,x,y,text[i]);
00167 i++;
00168 }
00169 }
00170
00171 int BFont::TextWidth(const char *text)
00172 {
00173 int i(0),x(0);
00174
00175 while (text[i]!='\0')
00176 {
00177 x += CharWidth(text[i]);
00178 i++;
00179 }
00180 return x;
00181 }
00182
00183
00184
00185 int BFont::count (const char *text)
00186 {
00187 char *p(NULL);
00188 int pos(-1),i(0);
00189
00190
00191 while ((p=strchr(&text[pos+1],' ')) != NULL)
00192 {
00193 i++;
00194 pos = p - text;
00195 }
00196 return i;
00197 }
00198
00199
00200 void BFont::JustifiedPutString( SDL_Surface *screen, int y, const char *text)
00201 {
00202 int spaces(0),gap,single_gap,dif;
00203 char *strtmp,*p;
00204 int pos(-1),xpos(0);
00205
00206
00207 if (strchr(text,' ') == NULL)
00208 {
00209 PutString(screen, 0, y, text);
00210 }
00211 else {
00212 gap = (screen->w-1) - TextWidth(text);
00213
00214 if (gap <= 0) {
00215 PutString(screen, 0,y,text);
00216 } else {
00217 spaces = count(text);
00218 dif = gap % spaces;
00219 single_gap = (gap - dif) / spaces;
00220 xpos=0;
00221 pos = -1;
00222 while ( spaces > 0 )
00223 {
00224 p = strstr(&text[pos+1]," ");
00225 strtmp = NULL;
00226 strtmp = (char *) calloc ( (p - &text[pos+1]) + 1,sizeof(char));
00227 if (strtmp != NULL)
00228 {
00229 strncpy (strtmp, &text[pos+1], (p - &text[pos+1]));
00230 PutString(screen, xpos, y, strtmp);
00231 xpos = xpos + TextWidth(strtmp) + single_gap + CharWidth(' ');
00232 if (dif >= 0)
00233 {
00234 xpos ++;
00235 dif--;
00236 }
00237 pos = p - text;
00238 spaces--;
00239 free(strtmp);
00240 }
00241 }
00242 strtmp = NULL;
00243 strtmp = (char *) calloc ( strlen( &text[pos+1]) + 1,sizeof(char));
00244
00245 if (strtmp != NULL) {
00246 strncpy (strtmp, &text[pos+1], strlen( &text[pos+1]));
00247 PutString(screen, xpos, y, strtmp);
00248 free(strtmp);
00249 }
00250 }
00251 }
00252 }
00253
00254
00255 void BFont::CenteredPutString(SDL_Surface *screen, int y, const char *text)
00256 {
00257 printf( "xpos - %d, %d <%s>\n", screen->w/2-TextWidth(text)/2, TextWidth(text), text );
00258 PutString( screen, screen->w/2-TextWidth(text)/2, y, text);
00259 }
00260
00261
00262 void BFont::RightPutString(SDL_Surface *screen, int y, const char *text)
00263 {
00264 PutString( screen, screen->w - TextWidth(text) - 1, y, text);
00265 }
00266
00267 void BFont::LeftPutString(SDL_Surface *screen, int y, const char *text)
00268 {
00269 PutString( screen, 0, y, text);
00270 }
00271
00272
00273
00274 void BFont::PrintString (SDL_Surface *screen, int x, int y, char *fmt, ...)
00275 {
00276 va_list args;
00277 char *temp;
00278 va_start (args,fmt);
00279
00280 if ( (temp = (char *) malloc(1000+1)) != NULL) {
00281 vsprintf(temp,fmt,args);
00282 PutString(screen, x, y, temp);
00283 free (temp);
00284 }
00285 va_end(args);
00286 }
00287
00288 void BFont::CenteredPrintString(SDL_Surface *screen, int y, char *fmt, ...)
00289 {
00290 va_list args;
00291 char *temp;
00292 va_start (args,fmt);
00293
00294 if ( (temp = (char *) malloc(1000+1)) != NULL) {
00295 vsprintf(temp,fmt,args);
00296 CenteredPutString(screen, y, temp);
00297 free (temp);
00298 }
00299 va_end(args);
00300 }
00301
00302 void BFont::RightPrintString(SDL_Surface *screen, int y, char *fmt, ...)
00303 {
00304 va_list args;
00305 char *temp;
00306 va_start (args,fmt);
00307
00308 if ( (temp = (char *) malloc(1000+1)) != NULL) {
00309 vsprintf(temp,fmt,args);
00310 RightPutString(screen, y, temp);
00311 free (temp);
00312 }
00313 va_end(args);
00314 }
00315
00316 void BFont::LeftPrintString( SDL_Surface *screen, int y, char *fmt, ...)
00317 {
00318 va_list args;
00319 char *temp;
00320 va_start (args,fmt);
00321
00322 if ( (temp = (char *) malloc(1000+1)) != NULL) {
00323 vsprintf(temp,fmt,args);
00324 LeftPutString(screen, y, temp);
00325 free (temp);
00326 }
00327 va_end(args);
00328 }
00329
00330 void BFont::JustifiedPrintString( SDL_Surface *screen, int y, char *fmt, ...)
00331 {
00332 va_list args;
00333 char *temp;
00334 va_start (args,fmt);
00335
00336 if ( (temp = (char *) malloc(1000+1)) != NULL) {
00337 vsprintf(temp,fmt,args);
00338 JustifiedPutString( screen, y,temp);
00339 free (temp);
00340 }
00341 va_end(args);
00342 }
00343
00344
00345 void BFont::PutPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
00346 {
00347 int bpp = surface->format->BytesPerPixel;
00348
00349 Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
00350
00351 switch(bpp) {
00352 case 1:
00353 *p = pixel;
00354 break;
00355
00356 case 2:
00357 *(Uint16 *)p = pixel;
00358 break;
00359
00360 case 3:
00361 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
00362 p[0] = (pixel >> 16) & 0xff;
00363 p[1] = (pixel >> 8) & 0xff;
00364 p[2] = pixel & 0xff;
00365 } else {
00366 p[0] = pixel & 0xff;
00367 p[1] = (pixel >> 8) & 0xff;
00368 p[2] = (pixel >> 16) & 0xff;
00369 }
00370 break;
00371
00372 case 4:
00373 *(Uint32 *)p = pixel;
00374 break;
00375 }
00376 }
00377
00378 Uint32 BFont :: xGetPixel(SDL_Surface *surface, int x, int y)
00379 {
00380 int bpp = surface->format->BytesPerPixel;
00381
00382 Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
00383
00384 switch(bpp) {
00385 case 1:
00386 return *p;
00387
00388 case 2:
00389 return *(Uint16 *)p;
00390
00391 case 3:
00392 if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
00393 return p[0] << 16 | p[1] << 8 | p[2];
00394 else
00395 return p[0] | p[1] << 8 | p[2] << 16;
00396
00397 case 4:
00398 return *(Uint32 *)p;
00399
00400 default:
00401 return 0;
00402 }
00403 }
00404
00405 Uint32 BFont::GetPixel( Sint32 X, Sint32 Y)
00406 {
00407
00408 Uint8 *bits;
00409 Uint32 Bpp;
00410
00411 if (X<0) puts("x too small in GetPixel!");
00412 if (X>=Surface->w) puts("x too big in GetPixel!");
00413
00414 Bpp = Surface->format->BytesPerPixel;
00415
00416 bits = ((Uint8 *)Surface->pixels)+Y*Surface->pitch+X*Bpp;
00417
00418
00419 switch(Bpp) {
00420 case 1:
00421 return *((Uint8 *)Surface->pixels + Y * Surface->pitch + X);
00422 break;
00423 case 2:
00424 return *((Uint16 *)Surface->pixels + Y * Surface->pitch/2 + X);
00425 break;
00426 case 3: {
00427 Uint8 r, g, b;
00428 r = *((bits)+Surface->format->Rshift/8);
00429 g = *((bits)+Surface->format->Gshift/8);
00430 b = *((bits)+Surface->format->Bshift/8);
00431 return SDL_MapRGB(Surface->format, r, g, b);
00432 }
00433 break;
00434 case 4:
00435 return *((Uint32 *)Surface->pixels + Y * Surface->pitch/4 + X);
00436 break;
00437 }
00438 }