git repos / blockattack-game

blame: source/code/SFont.c

normal view · raw

89c4a3a6 sago007 2008-08-29 14:32 1
/*  SFont: a simple font-library that uses special .pngs as fonts
89c4a3a6 sago007 2008-08-29 14:32 2
    Copyright (C) 2003 Karl Bartel
89c4a3a6 sago007 2008-08-29 14:32 3
89c4a3a6 sago007 2008-08-29 14:32 4
    License: GPL or LGPL (at your choice)
89c4a3a6 sago007 2008-08-29 14:32 5
    WWW: http://www.linux-games.com/sfont/
89c4a3a6 sago007 2008-08-29 14:32 6
89c4a3a6 sago007 2008-08-29 14:32 7
    This program is free software; you can redistribute it and/or modify        
89c4a3a6 sago007 2008-08-29 14:32 8
    it under the terms of the GNU General Public License as published by        
89c4a3a6 sago007 2008-08-29 14:32 9
    the Free Software Foundation; either version 2 of the License, or           
89c4a3a6 sago007 2008-08-29 14:32 10
    (at your option) any later version.                                         
89c4a3a6 sago007 2008-08-29 14:32 11
                                                                                
89c4a3a6 sago007 2008-08-29 14:32 12
    This program is distributed in the hope that it will be useful,       
89c4a3a6 sago007 2008-08-29 14:32 13
    but WITHOUT ANY WARRANTY; without even the implied warranty of              
89c4a3a6 sago007 2008-08-29 14:32 14
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               
89c4a3a6 sago007 2008-08-29 14:32 15
    GNU General Public License for more details.                
89c4a3a6 sago007 2008-08-29 14:32 16
                                                                               
89c4a3a6 sago007 2008-08-29 14:32 17
    You should have received a copy of the GNU General Public License           
89c4a3a6 sago007 2008-08-29 14:32 18
    along with this program; if not, write to the Free Software                 
89c4a3a6 sago007 2008-08-29 14:32 19
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   
89c4a3a6 sago007 2008-08-29 14:32 20
                                                                                
89c4a3a6 sago007 2008-08-29 14:32 21
    Karl Bartel
89c4a3a6 sago007 2008-08-29 14:32 22
    Cecilienstr. 14                                                    
89c4a3a6 sago007 2008-08-29 14:32 23
    12307 Berlin
89c4a3a6 sago007 2008-08-29 14:32 24
    GERMANY
89c4a3a6 sago007 2008-08-29 14:32 25
    karlb@gmx.net                                                      
89c4a3a6 sago007 2008-08-29 14:32 26
*/                                                                            
89c4a3a6 sago007 2008-08-29 14:32 27
#include <SDL.h>
89c4a3a6 sago007 2008-08-29 14:32 28
89c4a3a6 sago007 2008-08-29 14:32 29
#include <assert.h>
89c4a3a6 sago007 2008-08-29 14:32 30
#include <stdlib.h>
89c4a3a6 sago007 2008-08-29 14:32 31
#include "SFont.h"
89c4a3a6 sago007 2008-08-29 14:32 32
89c4a3a6 sago007 2008-08-29 14:32 33
static long GetPixel(SDL_Surface *Surface, Sint32 X, Sint32 Y)
89c4a3a6 sago007 2008-08-29 14:32 34
{
89c4a3a6 sago007 2008-08-29 14:32 35
   Uint8  *bits;
89c4a3a6 sago007 2008-08-29 14:32 36
   Uint32 Bpp;
89c4a3a6 sago007 2008-08-29 14:32 37
89c4a3a6 sago007 2008-08-29 14:32 38
   assert(X>=0);
89c4a3a6 sago007 2008-08-29 14:32 39
   assert(X<Surface->w);
89c4a3a6 sago007 2008-08-29 14:32 40
   
89c4a3a6 sago007 2008-08-29 14:32 41
   Bpp = Surface->format->BytesPerPixel;
89c4a3a6 sago007 2008-08-29 14:32 42
   bits = ((Uint8 *)Surface->pixels)+Y*Surface->pitch+X*Bpp;
89c4a3a6 sago007 2008-08-29 14:32 43
89c4a3a6 sago007 2008-08-29 14:32 44
   // Get the pixel
89c4a3a6 sago007 2008-08-29 14:32 45
   switch(Bpp) {
89c4a3a6 sago007 2008-08-29 14:32 46
      case 1:
89c4a3a6 sago007 2008-08-29 14:32 47
         return *((Uint8 *)Surface->pixels + Y * Surface->pitch + X);
89c4a3a6 sago007 2008-08-29 14:32 48
         break;
89c4a3a6 sago007 2008-08-29 14:32 49
      case 2:
89c4a3a6 sago007 2008-08-29 14:32 50
         return *((Uint16 *)Surface->pixels + Y * Surface->pitch/2 + X);
89c4a3a6 sago007 2008-08-29 14:32 51
         break;
89c4a3a6 sago007 2008-08-29 14:32 52
      case 3: { // Format/endian independent 
89c4a3a6 sago007 2008-08-29 14:32 53
         Uint8 r, g, b;
89c4a3a6 sago007 2008-08-29 14:32 54
         r = *((bits)+Surface->format->Rshift/8);
89c4a3a6 sago007 2008-08-29 14:32 55
         g = *((bits)+Surface->format->Gshift/8);
89c4a3a6 sago007 2008-08-29 14:32 56
         b = *((bits)+Surface->format->Bshift/8);
89c4a3a6 sago007 2008-08-29 14:32 57
         return SDL_MapRGB(Surface->format, r, g, b);
89c4a3a6 sago007 2008-08-29 14:32 58
         }
89c4a3a6 sago007 2008-08-29 14:32 59
         break;
89c4a3a6 sago007 2008-08-29 14:32 60
      case 4:
89c4a3a6 sago007 2008-08-29 14:32 61
         return *((Uint32 *)Surface->pixels + Y * Surface->pitch/4 + X);
89c4a3a6 sago007 2008-08-29 14:32 62
         break;
89c4a3a6 sago007 2008-08-29 14:32 63
   }
89c4a3a6 sago007 2008-08-29 14:32 64
89c4a3a6 sago007 2008-08-29 14:32 65
   return -1;
89c4a3a6 sago007 2008-08-29 14:32 66
}
89c4a3a6 sago007 2008-08-29 14:32 67
89c4a3a6 sago007 2008-08-29 14:32 68
SFont_Font* SFont_InitFont(SDL_Surface* Surface)
89c4a3a6 sago007 2008-08-29 14:32 69
{
89c4a3a6 sago007 2008-08-29 14:32 70
    int x = 0, i = 0;
89c4a3a6 sago007 2008-08-29 14:32 71
    Uint32 pixel;
89c4a3a6 sago007 2008-08-29 14:32 72
    SFont_Font* Font;
89c4a3a6 sago007 2008-08-29 14:32 73
    Uint32 pink;
89c4a3a6 sago007 2008-08-29 14:32 74
89c4a3a6 sago007 2008-08-29 14:32 75
    if (Surface == NULL)
89c4a3a6 sago007 2008-08-29 14:32 76
	return NULL;
89c4a3a6 sago007 2008-08-29 14:32 77
89c4a3a6 sago007 2008-08-29 14:32 78
    Font = (SFont_Font *) malloc(sizeof(SFont_Font));
89c4a3a6 sago007 2008-08-29 14:32 79
    Font->Surface = Surface;
89c4a3a6 sago007 2008-08-29 14:32 80
89c4a3a6 sago007 2008-08-29 14:32 81
    SDL_LockSurface(Surface);
89c4a3a6 sago007 2008-08-29 14:32 82
89c4a3a6 sago007 2008-08-29 14:32 83
    pink = SDL_MapRGB(Surface->format, 255, 0, 255);
89c4a3a6 sago007 2008-08-29 14:32 84
    while (x < Surface->w) {
89c4a3a6 sago007 2008-08-29 14:32 85
	if (GetPixel(Surface, x, 0) == pink) { 
89c4a3a6 sago007 2008-08-29 14:32 86
    	    Font->CharPos[i++]=x;
89c4a3a6 sago007 2008-08-29 14:32 87
    	    while((x < Surface->w) && (GetPixel(Surface, x, 0)== pink))
89c4a3a6 sago007 2008-08-29 14:32 88
		x++;
89c4a3a6 sago007 2008-08-29 14:32 89
	    Font->CharPos[i++]=x;
89c4a3a6 sago007 2008-08-29 14:32 90
	}
89c4a3a6 sago007 2008-08-29 14:32 91
	x++;
89c4a3a6 sago007 2008-08-29 14:32 92
    }
89c4a3a6 sago007 2008-08-29 14:32 93
    Font->MaxPos = x-1;
89c4a3a6 sago007 2008-08-29 14:32 94
    
89c4a3a6 sago007 2008-08-29 14:32 95
    pixel = GetPixel(Surface, 0, Surface->h-1);
89c4a3a6 sago007 2008-08-29 14:32 96
    SDL_UnlockSurface(Surface);
89c4a3a6 sago007 2008-08-29 14:32 97
    SDL_SetColorKey(Surface, SDL_SRCCOLORKEY, pixel);
89c4a3a6 sago007 2008-08-29 14:32 98
89c4a3a6 sago007 2008-08-29 14:32 99
    return Font;
89c4a3a6 sago007 2008-08-29 14:32 100
}
89c4a3a6 sago007 2008-08-29 14:32 101
89c4a3a6 sago007 2008-08-29 14:32 102
void SFont_FreeFont(SFont_Font* FontInfo)
89c4a3a6 sago007 2008-08-29 14:32 103
{
89c4a3a6 sago007 2008-08-29 14:32 104
    SDL_FreeSurface(FontInfo->Surface);
89c4a3a6 sago007 2008-08-29 14:32 105
    free(FontInfo);
89c4a3a6 sago007 2008-08-29 14:32 106
}
89c4a3a6 sago007 2008-08-29 14:32 107
89c4a3a6 sago007 2008-08-29 14:32 108
void SFont_Write(SDL_Surface *Surface, const SFont_Font *Font,
89c4a3a6 sago007 2008-08-29 14:32 109
		 int x, int y, const char *text)
89c4a3a6 sago007 2008-08-29 14:32 110
{
89c4a3a6 sago007 2008-08-29 14:32 111
    const char* c;
89c4a3a6 sago007 2008-08-29 14:32 112
    int charoffset;
89c4a3a6 sago007 2008-08-29 14:32 113
    SDL_Rect srcrect, dstrect;
89c4a3a6 sago007 2008-08-29 14:32 114
89c4a3a6 sago007 2008-08-29 14:32 115
    if(text == NULL)
89c4a3a6 sago007 2008-08-29 14:32 116
	return;
89c4a3a6 sago007 2008-08-29 14:32 117
89c4a3a6 sago007 2008-08-29 14:32 118
    // these values won't change in the loop
89c4a3a6 sago007 2008-08-29 14:32 119
    srcrect.y = 1;
89c4a3a6 sago007 2008-08-29 14:32 120
    dstrect.y = y;
89c4a3a6 sago007 2008-08-29 14:32 121
    srcrect.h = dstrect.h = Font->Surface->h - 1;
89c4a3a6 sago007 2008-08-29 14:32 122
89c4a3a6 sago007 2008-08-29 14:32 123
    for(c = text; *c != '\0' && x <= Surface->w ; c++) {
89c4a3a6 sago007 2008-08-29 14:32 124
	charoffset = ((int) (*c - 33)) * 2 + 1;
89c4a3a6 sago007 2008-08-29 14:32 125
	// skip spaces and nonprintable characters
89c4a3a6 sago007 2008-08-29 14:32 126
	if (*c == ' ' || charoffset < 0 || charoffset > Font->MaxPos) {
89c4a3a6 sago007 2008-08-29 14:32 127
	    x += Font->CharPos[2]-Font->CharPos[1];
89c4a3a6 sago007 2008-08-29 14:32 128
	    continue;
89c4a3a6 sago007 2008-08-29 14:32 129
	}
89c4a3a6 sago007 2008-08-29 14:32 130
89c4a3a6 sago007 2008-08-29 14:32 131
	srcrect.w = dstrect.w = 
89c4a3a6 sago007 2008-08-29 14:32 132
	    (Font->CharPos[charoffset+2] + Font->CharPos[charoffset+1])/2 -
89c4a3a6 sago007 2008-08-29 14:32 133
	    (Font->CharPos[charoffset] + Font->CharPos[charoffset-1])/2;
89c4a3a6 sago007 2008-08-29 14:32 134
	srcrect.x = (Font->CharPos[charoffset]+Font->CharPos[charoffset-1])/2;
89c4a3a6 sago007 2008-08-29 14:32 135
	dstrect.x = x - (int)(Font->CharPos[charoffset]
89c4a3a6 sago007 2008-08-29 14:32 136
			      - Font->CharPos[charoffset-1])/2;
89c4a3a6 sago007 2008-08-29 14:32 137
89c4a3a6 sago007 2008-08-29 14:32 138
	SDL_BlitSurface(Font->Surface, &srcrect, Surface, &dstrect); 
89c4a3a6 sago007 2008-08-29 14:32 139
89c4a3a6 sago007 2008-08-29 14:32 140
	x += Font->CharPos[charoffset+1] - Font->CharPos[charoffset];
89c4a3a6 sago007 2008-08-29 14:32 141
    }
89c4a3a6 sago007 2008-08-29 14:32 142
}
89c4a3a6 sago007 2008-08-29 14:32 143
89c4a3a6 sago007 2008-08-29 14:32 144
int SFont_TextWidth(const SFont_Font *Font, const char *text)
89c4a3a6 sago007 2008-08-29 14:32 145
{
89c4a3a6 sago007 2008-08-29 14:32 146
    const char* c;
89c4a3a6 sago007 2008-08-29 14:32 147
    int charoffset=0;
89c4a3a6 sago007 2008-08-29 14:32 148
    int width = 0;
89c4a3a6 sago007 2008-08-29 14:32 149
89c4a3a6 sago007 2008-08-29 14:32 150
    if(text == NULL)
89c4a3a6 sago007 2008-08-29 14:32 151
	return 0;
89c4a3a6 sago007 2008-08-29 14:32 152
89c4a3a6 sago007 2008-08-29 14:32 153
    for(c = text; *c != '\0'; c++) {
89c4a3a6 sago007 2008-08-29 14:32 154
	charoffset = ((int) *c - 33) * 2 + 1;
89c4a3a6 sago007 2008-08-29 14:32 155
	// skip spaces and nonprintable characters
89c4a3a6 sago007 2008-08-29 14:32 156
        if (*c == ' ' || charoffset < 0 || charoffset > Font->MaxPos) {
89c4a3a6 sago007 2008-08-29 14:32 157
            width += Font->CharPos[2]-Font->CharPos[1];
89c4a3a6 sago007 2008-08-29 14:32 158
	    continue;
89c4a3a6 sago007 2008-08-29 14:32 159
	}
89c4a3a6 sago007 2008-08-29 14:32 160
	
89c4a3a6 sago007 2008-08-29 14:32 161
	width += Font->CharPos[charoffset+1] - Font->CharPos[charoffset];
89c4a3a6 sago007 2008-08-29 14:32 162
    }
89c4a3a6 sago007 2008-08-29 14:32 163
89c4a3a6 sago007 2008-08-29 14:32 164
    return width;
89c4a3a6 sago007 2008-08-29 14:32 165
}
89c4a3a6 sago007 2008-08-29 14:32 166
89c4a3a6 sago007 2008-08-29 14:32 167
int SFont_TextHeight(const SFont_Font* Font)
89c4a3a6 sago007 2008-08-29 14:32 168
{
89c4a3a6 sago007 2008-08-29 14:32 169
    return Font->Surface->h - 1;
89c4a3a6 sago007 2008-08-29 14:32 170
}
89c4a3a6 sago007 2008-08-29 14:32 171
89c4a3a6 sago007 2008-08-29 14:32 172
void SFont_WriteCenter(SDL_Surface *Surface, const SFont_Font *Font,
89c4a3a6 sago007 2008-08-29 14:32 173
		       int y, const char *text)
89c4a3a6 sago007 2008-08-29 14:32 174
{
89c4a3a6 sago007 2008-08-29 14:32 175
    SFont_Write(Surface, Font, Surface->w/2 - SFont_TextWidth(Font, text)/2,
89c4a3a6 sago007 2008-08-29 14:32 176
	    	y, text);
89c4a3a6 sago007 2008-08-29 14:32 177
}
89c4a3a6 sago007 2008-08-29 14:32 178
1970-01-01 00:00 179