Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

bfont.cpp

Go to the documentation of this file.
00001 /***********************************************************/
00002 /*                                                         */
00003 /*   BFONT.c v. 1.0.2 - Billi Font Library by Diego Billi  */
00004 /*   BFONT++ C++ port by Gianluigi Davassi                 */
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 /* Load the font and stores it in the BFont_Info structure */
00051 void BFont::LoadFont (const char *filename)
00052 {
00053     SDL_Surface *surface(NULL);
00054     int x;
00055     // tutta roba inutile in C++.... :-)
00056     /*    BFont_Info *Font=NULL;
00057      Font = (BFont_Info *) malloc(sizeof(BFont_Info));*/
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(); // Init the font
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 /* Puts a single char on the surface with the specified font */
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 /* counts the spaces of the strings */
00185 int BFont::count (const char *text)
00186 {
00187     char *p(NULL);
00188     int pos(-1),i(0);
00189 
00190     /* Calculate the space occupied by the text without spaces */
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     /* Here p is the address to the pixel we want to set */
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     /* Here p is the address to the pixel we want to retrieve */
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;       /* shouldn't happen, but avoids warnings */
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    // Get the pixel
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: { // Format/endian independent
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 }

Generated on Sat Nov 5 16:17:24 2005 for OPIE by  doxygen 1.4.2