JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
whitespace changes: return types in function definitions on previous line, deleted...
[vor.git] / SFont.c
1 #include <SDL/SDL.h>
2 #include <stdlib.h>
3 #include "SFont.h"
4 #include "string.h"
5
6 SFont_FontInfo InternalFont;
7 int alpha=127;
8 int font_height;
9
10 Uint32
11 GetPixel(SDL_Surface *Surface, Sint32 X, Sint32 Y)
12 {
13
14    Uint8  *bits;
15    Uint32 Bpp;
16
17    if (X<0) puts("SFONT ERROR: x too small in GetPixel. Report this to <karlb@gmx.net>");
18    if (X>=Surface->w) puts("SFONT ERROR: x too big in GetPixel. Report this to <karlb@gmx.net>");
19    
20    Bpp = Surface->format->BytesPerPixel;
21
22    bits = ((Uint8 *)Surface->pixels)+Y*Surface->pitch+X*Bpp;
23
24    // Paint the walls with the fresh blood of your enemies
25
26    // Get the pixel
27    switch(Bpp) {
28       case 1:
29          return *((Uint8 *)Surface->pixels + Y * Surface->pitch + X);
30          break;
31       case 2:
32          return *((Uint16 *)Surface->pixels + Y * Surface->pitch/2 + X);
33          break;
34       case 3: { // Format/endian independent 
35          Uint8 r, g, b;
36          r = *((bits)+Surface->format->Rshift/8);
37          g = *((bits)+Surface->format->Gshift/8);
38          b = *((bits)+Surface->format->Bshift/8);
39          return SDL_MapRGB(Surface->format, r, g, b);
40          }
41          break;
42       case 4:
43          return *((Uint32 *)Surface->pixels + Y * Surface->pitch/4 + X);
44          break;
45    }
46
47     return -1;
48 }
49
50 void
51 InitFont2(SFont_FontInfo *Font)
52 {
53     int x = 0, i = 0;
54
55     if ( Font->Surface==NULL ) {
56         printf("The font has not been loaded!\n");
57         exit(1);
58     }
59
60     while ( x < Font->Surface->w ) {
61         if(GetPixel(Font->Surface,x,0)==SDL_MapRGB(Font->Surface->format,255,0,255)) { 
62             Font->CharPos[i++]=x;
63             while (( x < Font->Surface->w-1) && (GetPixel(Font->Surface,x,0)==SDL_MapRGB(Font->Surface->format,255,0,255)))
64                 x++;
65             Font->CharPos[i++]=x;
66         }
67         x++;
68     }
69
70     Font->h=Font->Surface->h;
71     font_height = Font->h;
72     SDL_SetColorKey(Font->Surface, SDL_SRCCOLORKEY, GetPixel(Font->Surface, 0, Font->Surface->h-1));
73 }
74
75 void
76 InitFont(SDL_Surface *Font)
77 {
78     InternalFont.Surface=Font;
79     InitFont2(&InternalFont);
80 }
81
82 int
83 SFont_wide(char *text) {
84     int i=0,xwide=0;
85     int ofs;
86     SFont_FontInfo *Font = &InternalFont;
87
88     while (text[i]) {
89         if (text[i]==' ') {
90             xwide += (int)(Font->CharPos[2]-Font->CharPos[1]);
91                 } else {
92                         ofs = (text[i]-33)*2+1;
93             xwide += (int)(Font->CharPos[ofs+1]-Font->CharPos[ofs]);
94                 }
95                 i++;
96     }
97     return xwide;
98 }
99
100 int
101 SFont_height() {
102     return InternalFont.Surface->h-1;
103 }
104
105 void
106 PutString2(SDL_Surface *Surface, SFont_FontInfo *Font, int x, int y, char *text)
107 {
108     int ofs;
109     int i=0;
110     SDL_Rect srcrect,dstrect; 
111
112     while (text[i]) {
113         if (text[i]==' ') {
114             x+=Font->CharPos[2]-Font->CharPos[1];
115         }
116         else {
117 //          printf("-%c- %c - %u\n",228,text[i],text[i]);
118             ofs=(text[i]-33)*2+1;
119             //printf("printing %c %d\n",text[i],ofs);
120             srcrect.w = dstrect.w = (Font->CharPos[ofs+2]+Font->CharPos[ofs+1])/2-(Font->CharPos[ofs]+Font->CharPos[ofs-1])/2;
121             srcrect.h = dstrect.h = Font->Surface->h-1;
122             srcrect.x = (Font->CharPos[ofs]+Font->CharPos[ofs-1])/2;
123             srcrect.y = 1;
124             dstrect.x = x-(float)(Font->CharPos[ofs]-Font->CharPos[ofs-1])/2;
125             dstrect.y = y;
126
127             //SDL_SetAlpha ( Font->Surface, SDL_SRCALPHA, 127);
128             SDL_BlitSurface( Font->Surface, &srcrect, Surface, &dstrect); 
129
130             x+=Font->CharPos[ofs+1]-Font->CharPos[ofs];
131         }
132         i++;
133     }
134 }
135
136 // Return a new surface, with the text on it.
137 // This surface is new, fresh, and must eventually be freed.
138 // Create the new surface with the same colour system as a parent surface.
139 SDL_Surface *
140 new_Surface_PutString(SDL_Surface *parent, char *text) {
141
142      Uint32 rmask = parent->format->Rmask;
143      Uint32 gmask = parent->format->Gmask;
144      Uint32 bmask = parent->format->Bmask;
145      Uint32 amask = parent->format->Amask;
146      Uint32 bytesperpixel = parent->format->BytesPerPixel;
147
148      return SDL_CreateRGBSurface(
149         SDL_SWSURFACE, 
150         SFont_wide(text), 
151         SFont_height(), 
152         bytesperpixel, rmask, gmask, bmask, amask
153     );
154 }
155
156 void
157 PutString(SDL_Surface *Surface, int x, int y, char *text) {
158     PutString2(Surface, &InternalFont, x, y, text);
159 }
160
161 int
162 TextWidth2(SFont_FontInfo *Font, char *text)
163 {
164     int x=0,i=0;
165     unsigned char ofs = 0;
166     while (text[i]!='\0') {
167         if (text[i]==' ') {
168                         x+=Font->CharPos[2]-Font->CharPos[1];
169                 } else {
170                         ofs=(text[i]-33)*2+1;
171                         x+=Font->CharPos[ofs+1]-Font->CharPos[ofs];
172                 }
173                 i++;
174     }
175     return x+Font->CharPos[ofs+2]-Font->CharPos[ofs+1];
176 }
177
178 int
179 TextWidth(char *text)
180 {
181     return TextWidth2(&InternalFont, text);
182 }
183
184 void
185 TextAlpha(int a) {
186     alpha = a;
187 }
188
189 void
190 XCenteredString2(SDL_Surface *Surface, SFont_FontInfo *Font, int y, char *text)
191 {
192     PutString2(Surface, &InternalFont, Surface->w/2-TextWidth(text)/2, y, text);
193 }
194
195 void
196 XCenteredString(SDL_Surface *Surface, int y, char *text)
197 {
198     XCenteredString2(Surface, &InternalFont, y, text);
199 }
200
201 SDL_Surface *Back;
202 char tmp[1024];
203
204 void
205 clearBuffer() {
206     SDL_Event event;
207
208     // Delete the event buffer
209     while (SDL_PollEvent(&event))
210         ;
211     // start input
212     SDL_EnableUNICODE(1);
213 }
214
215 int
216 SFont_Input2( SDL_Surface *Dest, SFont_FontInfo *Font, int x, int y, int PixelWidth, char *text)
217 {
218     SDL_Event event;
219     int ch;
220     SDL_Rect rect;
221     int ofs=(text[0]-33)*2+1;
222     int leftshift;
223
224     if (ofs<0) {
225         leftshift = 0;
226     }
227     else {
228         leftshift = (Font->CharPos[ofs]-Font->CharPos[ofs-1])/2;
229     }
230
231     rect.x=x-leftshift;
232     rect.y=y;
233     rect.w=PixelWidth;
234     rect.h=Font->Surface->h;
235
236     //SDL_SetAlpha (Dest, SDL_SRCALPHA, 127);
237
238     SDL_BlitSurface(Dest, &rect, Back, NULL);
239     sprintf(tmp,"%s_",text);
240     PutString2(Dest,Font,x,y,tmp);
241     SDL_UpdateRect(Dest, x-leftshift, y, PixelWidth, Font->h);
242
243     while (SDL_PollEvent(&event) && event.type==SDL_KEYDOWN) {
244
245         // Find the character pressed
246         ch=event.key.keysym.unicode;
247
248         // If backspace and the length of the text > 0, reduce the string by 1 character
249         if (ch=='\b') {
250             if (strlen(text)>0) {
251                 text[strlen(text)-1]='\0';
252             }
253         }
254         else {
255             sprintf(text,"%s%c",text,ch);
256         }
257
258         // If the new character would exceed the allowed width
259         if (TextWidth2(Font,text)>PixelWidth) {
260             text[strlen(text)-1]='\0';
261         }
262
263         //SDL_SetAlpha (Back, SDL_SRCALPHA, 127);
264         SDL_BlitSurface( Back, NULL, Dest, &rect);
265         PutString2(Dest, Font, x, y, text);
266         if (ofs>0) {
267             SDL_UpdateRect(Dest, x-(Font->CharPos[ofs]-Font->CharPos[ofs-1])/2, y, PixelWidth, Font->Surface->h);
268         }
269
270     }
271     //text[strlen(text)-1]='\0';
272     if (ch==SDLK_RETURN) {
273         SDL_FreeSurface(Back);
274         return 1;
275     }
276     else
277         return 0;
278 }
279
280 int
281 SFont_Input( SDL_Surface *Dest, int x, int y, int PixelWidth, char *text)
282 {
283     
284     Back = SDL_AllocSurface(Dest->flags,
285                             PixelWidth,
286                             InternalFont.h,
287                             Dest->format->BitsPerPixel,
288                             Dest->format->Rmask,
289                             Dest->format->Gmask,
290                             Dest->format->Bmask, 0);
291
292     return SFont_Input2( Dest, &InternalFont, x, y, PixelWidth, text);
293     // ph:
294     // Returns 1 when the return key is pressed
295     // Returns 0 when nothing exceptional happened
296 }