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