1 #include <SDL.h>
2 #include "SFont.h"
3 #include <string.h>
4 #include <stdlib.h>
5 
6 SFont_FontInfo InternalFont;
7 
GetPixel(SDL_Surface * Surface,Sint32 X,Sint32 Y)8 Sint32 GetPixel(SDL_Surface *Surface, Sint32 X, Sint32 Y)
9 {
10 
11    Uint8  *bits;
12    Uint32 Bpp;
13 
14    if (X<0) puts("SFONT ERROR: x too small in GetPixel. Report this to <karlb@gmx.net>");
15    if (X>=Surface->w) puts("SFONT ERROR: x too big in GetPixel. Report this to <karlb@gmx.net>");
16 
17    Bpp = Surface->format->BytesPerPixel;
18 
19    bits = ((Uint8 *)Surface->pixels)+Y*Surface->pitch+X*Bpp;
20 
21    // Get the pixel
22    switch(Bpp) {
23       case 1:
24          return *((Uint8 *)Surface->pixels + Y * Surface->pitch + X);
25          break;
26       case 2:
27          return *((Uint16 *)Surface->pixels + Y * Surface->pitch/2 + X);
28          break;
29       case 3: { // Format/endian independent
30          Uint8 r, g, b;
31          r = *((bits)+Surface->format->Rshift/8);
32          g = *((bits)+Surface->format->Gshift/8);
33          b = *((bits)+Surface->format->Bshift/8);
34          return SDL_MapRGB(Surface->format, r, g, b);
35          }
36          break;
37       case 4:
38          return *((Uint32 *)Surface->pixels + Y * Surface->pitch/4 + X);
39          break;
40    }
41 
42     return -1;
43 }
44 
InitFont2(SFont_FontInfo * Font)45 void InitFont2(SFont_FontInfo *Font)
46 {
47     int x = 0, i = 0;
48 
49     if ( Font->Surface==NULL ) {
50 	printf("The font has not been loaded!\n");
51 	exit(1);
52     }
53 
54     if (SDL_MUSTLOCK(Font->Surface)) SDL_LockSurface(Font->Surface);
55 
56     while ( x < Font->Surface->w ) {
57 	if(GetPixel(Font->Surface,x,0)==SDL_MapRGB(Font->Surface->format,255,0,255)) {
58     	    Font->CharPos[i++]=x;
59     	    while (( x < Font->Surface->w-1) && (GetPixel(Font->Surface,x,0)==SDL_MapRGB(Font->Surface->format,255,0,255)))
60 		x++;
61 	    Font->CharPos[i++]=x;
62 	}
63 	x++;
64     }
65     if (SDL_MUSTLOCK(Font->Surface)) SDL_UnlockSurface(Font->Surface);
66 
67     Font->h=Font->Surface->h;
68     SDL_SetColorKey(Font->Surface, SDL_SRCCOLORKEY, GetPixel(Font->Surface, 0, Font->Surface->h-1));
69 }
70 
InitFont(SDL_Surface * Font)71 void InitFont(SDL_Surface *Font)
72 {
73     InternalFont.Surface=Font;
74     InitFont2(&InternalFont);
75 }
76 
PutString2(SDL_Surface * Surface,SFont_FontInfo * Font,int x,int y,char * text)77 void PutString2(SDL_Surface *Surface, SFont_FontInfo *Font, int x, int y, char *text)
78 {
79     int ofs;
80     int i=0;
81     SDL_Rect srcrect,dstrect;
82 
83     while (text[i]!='\0') {
84         if (text[i]==' ') {
85             x+=Font->CharPos[2]-Font->CharPos[1];
86             i++;
87 	}
88 	else {
89 //	    printf("-%c- %c - %u\n",228,text[i],text[i]);
90 	    ofs=(text[i]-33)*2+1;
91 //	    printf("printing %c %d\n",text[i],ofs);
92             srcrect.w = dstrect.w = (Font->CharPos[ofs+2]+Font->CharPos[ofs+1])/2-(Font->CharPos[ofs]+Font->CharPos[ofs-1])/2;
93             srcrect.h = dstrect.h = Font->Surface->h-1;
94             srcrect.x = (Font->CharPos[ofs]+Font->CharPos[ofs-1])/2;
95             srcrect.y = 1;
96     	    dstrect.x = x-(float)(Font->CharPos[ofs]-Font->CharPos[ofs-1])/2;
97 	    dstrect.y = y;
98 
99 	    SDL_BlitSurface( Font->Surface, &srcrect, Surface, &dstrect);
100 
101             x+=Font->CharPos[ofs+1]-Font->CharPos[ofs];
102             i++;
103         }
104     }
105 }
106 
PutString(SDL_Surface * Surface,int x,int y,char * text)107 void PutString(SDL_Surface *Surface, int x, int y, char *text)
108 {
109     PutString2(Surface, &InternalFont, x, y, text);
110 }
111 
TextWidth2(SFont_FontInfo * Font,char * text)112 int TextWidth2(SFont_FontInfo *Font, char *text)
113 {
114     int ofs=0;
115     int i=0,x=0;
116 
117     while (text[i]!='\0') {
118         if (text[i]==' ') {
119             x+=Font->CharPos[2]-Font->CharPos[1];
120             i++;
121 	}
122 	else {
123 	    ofs=(text[i]-33)*2+1;
124             x+=Font->CharPos[ofs+1]-Font->CharPos[ofs];
125             i++;
126         }
127     }
128 //    printf ("--%d\n",x);
129     return x;
130 }
131 
TextWidth(char * text)132 int TextWidth(char *text)
133 {
134     return TextWidth2(&InternalFont, text);
135 }
136 
XCenteredString2(SDL_Surface * Surface,SFont_FontInfo * Font,int y,char * text)137 void XCenteredString2(SDL_Surface *Surface, SFont_FontInfo *Font, int y, char *text)
138 {
139     PutString2(Surface, &InternalFont, Surface->w/2-TextWidth2(Font,text)/2, y, text);
140 }
141 
XCenteredString(SDL_Surface * Surface,int y,char * text)142 void XCenteredString(SDL_Surface *Surface, int y, char *text)
143 {
144     XCenteredString2(Surface, &InternalFont, y, text);
145 }
146 
SFont_InternalInput(SDL_Surface * Dest,SFont_FontInfo * Font,int x,int y,int PixelWidth,char * text)147 void SFont_InternalInput( SDL_Surface *Dest, SFont_FontInfo *Font, int x, int y, int PixelWidth, char *text)
148 {
149     SDL_Event event;
150     int ch=-1,blink=0;
151     long blinktimer=0;
152     SDL_Surface *Back;
153     SDL_Rect rect;
154 //    int ofs=(text[0]-33)*2+1;
155 //    int leftshift=(Font->CharPos[ofs]-Font->CharPos[ofs-1])/2;
156 
157     Back = SDL_AllocSurface(Dest->flags,
158     			    Dest->w,
159     			    Font->h,
160     			    Dest->format->BitsPerPixel,
161     			    Dest->format->Rmask,
162     			    Dest->format->Gmask,
163 			    Dest->format->Bmask, 0);
164     rect.x=0;
165     rect.y=y;
166     rect.w=Dest->w;
167     rect.h=Font->Surface->h;
168     SDL_BlitSurface(Dest, &rect, Back, NULL);
169     PutString2(Dest,Font,x,y,text);
170     SDL_UpdateRects(Dest, 1, &rect);
171 
172     // start input
173     SDL_EnableUNICODE(1);
174     blinktimer=SDL_GetTicks();
175     while (ch!=SDLK_RETURN) {
176 	if (event.type==SDL_KEYDOWN) {
177 	    ch=event.key.keysym.unicode;
178 	    if (((ch>31)||(ch=='\b')) && (ch<128)) {
179 		if ((ch=='\b')&&(strlen(text)>0))
180 		    text[strlen(text)-1]='\0';
181 		else if (ch!='\b')
182 		    sprintf(text,"%s%c",text,ch);
183 	        if (TextWidth2(Font,text)>PixelWidth) text[strlen(text)-1]='\0';
184 		SDL_BlitSurface( Back, NULL, Dest, &rect);
185 		PutString2(Dest, Font, x, y, text);
186 		SDL_UpdateRects(Dest, 1, &rect);
187 //		printf("%s ## %d\n",text,strlen(text));
188 		SDL_WaitEvent(&event);
189 	    }
190 	}
191 	if (SDL_GetTicks()>blinktimer) {
192 	    blink=1-blink;
193 	    blinktimer=SDL_GetTicks()+500;
194 	    if (blink) {
195 		PutString2(Dest, Font, x+TextWidth2(Font,text), y, "|");
196 		SDL_UpdateRects(Dest, 1, &rect);
197 //		SDL_UpdateRect(Dest, x+TextWidth2(Font,text), y, TextWidth2(Font,"|"), Font->Surface->h);
198 	    } else {
199 		SDL_BlitSurface( Back, NULL, Dest, &rect);
200 		PutString2(Dest, Font, x, y, text);
201 		SDL_UpdateRects(Dest, 1, &rect);
202 //		SDL_UpdateRect(Dest, x-(Font->CharPos[ofs]-Font->CharPos[ofs-1])/2, y, PixelWidth, Font->Surface->h);
203 	    }
204 	}
205 	SDL_Delay(1);
206 	SDL_PollEvent(&event);
207     }
208     text[strlen(text)]='\0';
209     SDL_FreeSurface(Back);
210 }
211 
SFont_Input2(SDL_Surface * Dest,SFont_FontInfo * Font,int x,int y,int PixelWidth,char * text)212 void SFont_Input2( SDL_Surface *Dest, SFont_FontInfo *Font, int x, int y, int PixelWidth, char *text)
213 {
214     SFont_InternalInput( Dest, Font, x, y, PixelWidth,  text);
215 }
SFont_Input(SDL_Surface * Dest,int x,int y,int PixelWidth,char * text)216 void SFont_Input( SDL_Surface *Dest, int x, int y, int PixelWidth, char *text)
217 {
218     SFont_Input2( Dest, &InternalFont, x, y, PixelWidth, text);
219 }
220