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