X-Git-Url: https://jasonwoof.com/gitweb/?p=vor.git;a=blobdiff_plain;f=SFont.c;h=a13e75dd0449d71e0b486458ba3e320e02b20a78;hp=e77f01bac20a71a31bf20b7f4e1787e7da076126;hb=148882a3cc520f34616a1175ed157fe258d68dcc;hpb=0ebbb01f731d0c9bb71140a93cfddd9abde509e5 diff --git a/SFont.c b/SFont.c index e77f01b..a13e75d 100644 --- a/SFont.c +++ b/SFont.c @@ -1,28 +1,46 @@ -#include +/* SFont: a simple font library that uses special images as fonts + Copyright (C) 2003 Karl Bartel + + WWW: http://www.linux-games.com/sfont/ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Karl Bartel + Cecilienstr. 14 + 12307 Berlin + GERMANY + karlb@gmx.net +*/ +#include + +#include #include #include "SFont.h" -#include "string.h" -SFont_FontInfo InternalFont; -int alpha=127; -int font_height; - -Uint32 +static Uint32 GetPixel(SDL_Surface *Surface, Sint32 X, Sint32 Y) { - Uint8 *bits; Uint32 Bpp; - if (X<0) puts("SFONT ERROR: x too small in GetPixel. Report this to "); - if (X>=Surface->w) puts("SFONT ERROR: x too big in GetPixel. Report this to "); + assert(X>=0); + assert(Xw); Bpp = Surface->format->BytesPerPixel; - bits = ((Uint8 *)Surface->pixels)+Y*Surface->pitch+X*Bpp; - // Paint the walls with the fresh blood of your enemies - // Get the pixel switch(Bpp) { case 1: @@ -44,253 +62,122 @@ GetPixel(SDL_Surface *Surface, Sint32 X, Sint32 Y) break; } - return -1; + return -1; } -void -InitFont2(SFont_FontInfo *Font) +SFont_Font * +SFont_InitFont(SDL_Surface* Surface) { int x = 0, i = 0; + Uint32 pixel; + SFont_Font* Font; + Uint32 pink; - if ( Font->Surface==NULL ) { - printf("The font has not been loaded!\n"); - exit(1); - } + if (Surface == NULL) + return NULL; + + Font = (SFont_Font *) malloc(sizeof(SFont_Font)); + Font->Surface = Surface; - while ( x < Font->Surface->w ) { - if(GetPixel(Font->Surface,x,0)==SDL_MapRGB(Font->Surface->format,255,0,255)) { + SDL_LockSurface(Surface); + + pink = SDL_MapRGB(Surface->format, 255, 0, 255); + while (x < Surface->w) { + if (GetPixel(Surface, x, 0) == pink) { Font->CharPos[i++]=x; - while (( x < Font->Surface->w-1) && (GetPixel(Font->Surface,x,0)==SDL_MapRGB(Font->Surface->format,255,0,255))) + while((x < Surface->w) && (GetPixel(Surface, x, 0)== pink)) x++; Font->CharPos[i++]=x; } x++; } + Font->MaxPos = x-1; + + pixel = GetPixel(Surface, 0, Surface->h-1); + SDL_UnlockSurface(Surface); + SDL_SetColorKey(Surface, SDL_SRCCOLORKEY, pixel); - Font->h=Font->Surface->h; - font_height = Font->h; - SDL_SetColorKey(Font->Surface, SDL_SRCCOLORKEY, GetPixel(Font->Surface, 0, Font->Surface->h-1)); + return Font; } void -InitFont(SDL_Surface *Font) +SFont_FreeFont(SFont_Font* FontInfo) { - InternalFont.Surface=Font; - InitFont2(&InternalFont); -} - -int -SFont_wide(char *text) { - int i=0,xwide=0; - int ofs; - SFont_FontInfo *Font = &InternalFont; - - while (text[i]) { - if (text[i]==' ') { - xwide += (int)(Font->CharPos[2]-Font->CharPos[1]); - } else { - ofs = (text[i]-33)*2+1; - xwide += (int)(Font->CharPos[ofs+1]-Font->CharPos[ofs]); - } - i++; - } - return xwide; -} - -int -SFont_height() { - return InternalFont.Surface->h-1; + SDL_FreeSurface(FontInfo->Surface); + free(FontInfo); } void -PutString2(SDL_Surface *Surface, SFont_FontInfo *Font, int x, int y, char *text) +SFont_Write(SDL_Surface *Surface, const SFont_Font *Font, + int x, int y, const char *text) { - int ofs; - int i=0; - SDL_Rect srcrect,dstrect; - - while (text[i]) { - if (text[i]==' ') { - x+=Font->CharPos[2]-Font->CharPos[1]; + const char* c; + int charoffset; + SDL_Rect srcrect, dstrect; + + if(text == NULL) + return; + + // these values won't change in the loop + srcrect.y = 1; + dstrect.y = y; + srcrect.h = dstrect.h = Font->Surface->h - 1; + + for(c = text; *c != '\0' && x <= Surface->w ; c++) { + charoffset = ((int) (*c - 33)) * 2 + 1; + // skip spaces and nonprintable characters + if (*c == ' ' || charoffset < 0 || charoffset > Font->MaxPos) { + x += Font->CharPos[2]-Font->CharPos[1]; + continue; } - else { -// printf("-%c- %c - %u\n",228,text[i],text[i]); - ofs=(text[i]-33)*2+1; - //printf("printing %c %d\n",text[i],ofs); - srcrect.w = dstrect.w = (Font->CharPos[ofs+2]+Font->CharPos[ofs+1])/2-(Font->CharPos[ofs]+Font->CharPos[ofs-1])/2; - srcrect.h = dstrect.h = Font->Surface->h-1; - srcrect.x = (Font->CharPos[ofs]+Font->CharPos[ofs-1])/2; - srcrect.y = 1; - dstrect.x = x-(float)(Font->CharPos[ofs]-Font->CharPos[ofs-1])/2; - dstrect.y = y; - - //SDL_SetAlpha ( Font->Surface, SDL_SRCALPHA, 127); - SDL_BlitSurface( Font->Surface, &srcrect, Surface, &dstrect); - - x+=Font->CharPos[ofs+1]-Font->CharPos[ofs]; - } - i++; - } -} -// Return a new surface, with the text on it. -// This surface is new, fresh, and must eventually be freed. -// Create the new surface with the same colour system as a parent surface. -SDL_Surface * -new_Surface_PutString(SDL_Surface *parent, char *text) { + srcrect.w = dstrect.w = + (Font->CharPos[charoffset+2] + Font->CharPos[charoffset+1])/2 - + (Font->CharPos[charoffset] + Font->CharPos[charoffset-1])/2; + srcrect.x = (Font->CharPos[charoffset]+Font->CharPos[charoffset-1])/2; + dstrect.x = x - (float)(Font->CharPos[charoffset] + - Font->CharPos[charoffset-1])/2; - Uint32 rmask = parent->format->Rmask; - Uint32 gmask = parent->format->Gmask; - Uint32 bmask = parent->format->Bmask; - Uint32 amask = parent->format->Amask; - Uint32 bytesperpixel = parent->format->BytesPerPixel; + SDL_BlitSurface(Font->Surface, &srcrect, Surface, &dstrect); - return SDL_CreateRGBSurface( - SDL_SWSURFACE, - SFont_wide(text), - SFont_height(), - bytesperpixel, rmask, gmask, bmask, amask - ); -} - -void -PutString(SDL_Surface *Surface, int x, int y, char *text) { - PutString2(Surface, &InternalFont, x, y, text); -} - -int -TextWidth2(SFont_FontInfo *Font, char *text) -{ - int x=0,i=0; - unsigned char ofs = 0; - while (text[i]!='\0') { - if (text[i]==' ') { - x+=Font->CharPos[2]-Font->CharPos[1]; - } else { - ofs=(text[i]-33)*2+1; - x+=Font->CharPos[ofs+1]-Font->CharPos[ofs]; - } - i++; + x += Font->CharPos[charoffset+1] - Font->CharPos[charoffset]; } - return x+Font->CharPos[ofs+2]-Font->CharPos[ofs+1]; } int -TextWidth(char *text) -{ - return TextWidth2(&InternalFont, text); -} - -void -TextAlpha(int a) { - alpha = a; -} - -void -XCenteredString2(SDL_Surface *Surface, SFont_FontInfo *Font, int y, char *text) +SFont_TextWidth(const SFont_Font *Font, const char *text) { - PutString2(Surface, &InternalFont, Surface->w/2-TextWidth(text)/2, y, text); -} + const char* c; + int charoffset=0; + int width = 0; -void -XCenteredString(SDL_Surface *Surface, int y, char *text) -{ - XCenteredString2(Surface, &InternalFont, y, text); -} - -SDL_Surface *Back; -char tmp[1024]; + if(text == NULL) + return 0; -void -clearBuffer() { - SDL_Event event; + for(c = text; *c != '\0'; c++) { + charoffset = ((int) *c - 33) * 2 + 1; + // skip spaces and nonprintable characters + if (*c == ' ' || charoffset < 0 || charoffset > Font->MaxPos) { + width += Font->CharPos[2]-Font->CharPos[1]; + continue; + } + + width += Font->CharPos[charoffset+1] - Font->CharPos[charoffset]; + } - // Delete the event buffer - while (SDL_PollEvent(&event)) - ; - // start input - SDL_EnableUNICODE(1); + return width; } int -SFont_Input2( SDL_Surface *Dest, SFont_FontInfo *Font, int x, int y, int PixelWidth, char *text) +SFont_TextHeight(const SFont_Font* Font) { - SDL_Event event; - int ch; - SDL_Rect rect; - int ofs=(text[0]-33)*2+1; - int leftshift; - - if (ofs<0) { - leftshift = 0; - } - else { - leftshift = (Font->CharPos[ofs]-Font->CharPos[ofs-1])/2; - } - - rect.x=x-leftshift; - rect.y=y; - rect.w=PixelWidth; - rect.h=Font->Surface->h; - - //SDL_SetAlpha (Dest, SDL_SRCALPHA, 127); - - SDL_BlitSurface(Dest, &rect, Back, NULL); - sprintf(tmp,"%s_",text); - PutString2(Dest,Font,x,y,tmp); - SDL_UpdateRect(Dest, x-leftshift, y, PixelWidth, Font->h); - - while (SDL_PollEvent(&event) && event.type==SDL_KEYDOWN) { - - // Find the character pressed - ch=event.key.keysym.unicode; - - // If backspace and the length of the text > 0, reduce the string by 1 character - if (ch=='\b') { - if (strlen(text)>0) { - text[strlen(text)-1]='\0'; - } - } - else { - sprintf(text,"%s%c",text,ch); - } - - // If the new character would exceed the allowed width - if (TextWidth2(Font,text)>PixelWidth) { - text[strlen(text)-1]='\0'; - } - - //SDL_SetAlpha (Back, SDL_SRCALPHA, 127); - SDL_BlitSurface( Back, NULL, Dest, &rect); - PutString2(Dest, Font, x, y, text); - if (ofs>0) { - SDL_UpdateRect(Dest, x-(Font->CharPos[ofs]-Font->CharPos[ofs-1])/2, y, PixelWidth, Font->Surface->h); - } - - } - //text[strlen(text)-1]='\0'; - if (ch==SDLK_RETURN) { - SDL_FreeSurface(Back); - return 1; - } - else - return 0; + return Font->Surface->h - 1; } -int -SFont_Input( SDL_Surface *Dest, int x, int y, int PixelWidth, char *text) +void +SFont_WriteCenter(SDL_Surface *Surface, const SFont_Font *Font, + int y, const char *text) { - - Back = SDL_AllocSurface(Dest->flags, - PixelWidth, - InternalFont.h, - Dest->format->BitsPerPixel, - Dest->format->Rmask, - Dest->format->Gmask, - Dest->format->Bmask, 0); - - return SFont_Input2( Dest, &InternalFont, x, y, PixelWidth, text); - // ph: - // Returns 1 when the return key is pressed - // Returns 0 when nothing exceptional happened + SFont_Write(Surface, Font, Surface->w/2 - SFont_TextWidth(Font, text)/2, + y, text); }