Applied patch for NetResolveIP
[sdlgit/SDL_perl.git] / src / SFont.xs
CommitLineData
8fde61e3 1// SDL::SFont
2//
3// SFont bitmap font support
4//
5// SFont library code by Karl Bartel <karlb@gmx.net>
6//
7// SFont.xs Copyright (C) 2004 David J. Goehrig
8//
9
10#include "EXTERN.h"
11#include "perl.h"
12#include "XSUB.h"
13
14#ifndef aTHX_
15#define aTHX_
16#endif
17
18#include <SDL.h>
19#include <string.h>
20#include <stdlib.h>
21
22#ifdef USE_THREADS
23#define HAVE_TLS_CONTEXT
24#endif
25
e00a4871 26#include "defines.h"
27#include "SFont.h"
8fde61e3 28
29#ifdef HAVE_SDL_IMAGE
30#include <SDL_image.h>
31
32SFont_FontInfo InternalFont;
33Uint32 SFont_GetPixel(SDL_Surface *Surface, Sint32 X, Sint32 Y)
34{
35
36 Uint8 *bits;
37 Uint32 Bpp;
38 if (X<0) puts("SFONT ERROR: x too small in SFont_GetPixel. Report this to <karlb@gmx.net>");
39 if (X>=Surface->w) puts("SFONT ERROR: x too big in SFont_GetPixel. Report this to <karlb@gmx.net>");
40
41 Bpp = Surface->format->BytesPerPixel;
42
43 bits = ((Uint8 *)Surface->pixels)+Y*Surface->pitch+X*Bpp;
44
45 // Get the pixel
46 switch(Bpp) {
47 case 1:
48 return *((Uint8 *)Surface->pixels + Y * Surface->pitch + X);
49 break;
50 case 2:
51 return *((Uint16 *)Surface->pixels + Y * Surface->pitch/2 + X);
52 break;
53 case 3: { // Format/endian independent
54 Uint8 r, g, b;
55 r = *((bits)+Surface->format->Rshift/8);
56 g = *((bits)+Surface->format->Gshift/8);
57 b = *((bits)+Surface->format->Bshift/8);
58 return SDL_MapRGB(Surface->format, r, g, b);
59 }
60 break;
61 case 4:
62 return *((Uint32 *)Surface->pixels + Y * Surface->pitch/4 + X);
63 break;
64 }
65
66 return -1;
67}
68
69void SFont_InitFont2(SFont_FontInfo *Font)
70{
71 int x = 0, i = 0;
72
73 if ( Font->Surface==NULL ) {
74 printf("The font has not been loaded!\n");
75 exit(1);
76 }
77
78 if (SDL_MUSTLOCK(Font->Surface)) SDL_LockSurface(Font->Surface);
79
80 while ( x < Font->Surface->w ) {
81 if(SFont_GetPixel(Font->Surface,x,0)==SDL_MapRGB(Font->Surface->format,255,0,255)) {
82 Font->CharPos[i++]=x;
83 while (( x < Font->Surface->w-1) && (SFont_GetPixel(Font->Surface,x,0)==SDL_MapRGB(Font->Surface->format,255,0,255)))
84 x++;
85 Font->CharPos[i++]=x;
86 }
87 x++;
88 }
89 if (SDL_MUSTLOCK(Font->Surface)) SDL_UnlockSurface(Font->Surface);
90
91 Font->h=Font->Surface->h;
92 SDL_SetColorKey(Font->Surface, SDL_SRCCOLORKEY, SFont_GetPixel(Font->Surface, 0, Font->Surface->h-1));
93}
94
95void SFont_InitFont(SDL_Surface *Font)
96{
97 InternalFont.Surface=Font;
98 SFont_InitFont2(&InternalFont);
99}
100
101void SFont_PutString2(SDL_Surface *Surface, SFont_FontInfo *Font, int x, int y, char *text)
102{
103 int ofs;
104 int i=0;
105 SDL_Rect srcrect,dstrect;
106
107 while (text[i]!='\0') {
108 if (text[i]==' ') {
109 x+=Font->CharPos[2]-Font->CharPos[1];
110 i++;
111 }
112 else {
113// printf("-%c- %c - %u\n",228,text[i],text[i]);
114 ofs=(text[i]-33)*2+1;
115// printf("printing %c %d\n",text[i],ofs);
116 srcrect.w = dstrect.w = (Font->CharPos[ofs+2]+Font->CharPos[ofs+1])/2-(Font->CharPos[ofs]+Font->CharPos[ofs-1])/2;
117 srcrect.h = dstrect.h = Font->Surface->h-1;
118 srcrect.x = (Font->CharPos[ofs]+Font->CharPos[ofs-1])/2;
119 srcrect.y = 1;
120 dstrect.x = x-(float)(Font->CharPos[ofs]-Font->CharPos[ofs-1])/2;
121 dstrect.y = y;
122
123 SDL_BlitSurface( Font->Surface, &srcrect, Surface, &dstrect);
124
125 x+=Font->CharPos[ofs+1]-Font->CharPos[ofs];
126 i++;
127 }
128 }
129}
130
131void SFont_PutString(SDL_Surface *Surface, int x, int y, char *text)
132{
133 SFont_PutString2(Surface, &InternalFont, x, y, text);
134}
135
136int SFont_TextWidth2(SFont_FontInfo *Font, char *text)
137{
138 int ofs=0;
139 int i=0,x=0;
140
141 while (text[i]!='\0') {
142 if (text[i]==' ') {
143 x+=Font->CharPos[2]-Font->CharPos[1];
144 i++;
145 }
146 else {
147 ofs=(text[i]-33)*2+1;
148 x+=Font->CharPos[ofs+1]-Font->CharPos[ofs];
149 i++;
150 }
151 }
152// printf ("--%d\n",x);
153 return x;
154}
155
156int SFont_TextWidth(char *text)
157{
158 return SFont_TextWidth2(&InternalFont, text);
159}
160
161void SFont_XCenteredString2(SDL_Surface *Surface, SFont_FontInfo *Font, int y, char *text)
162{
163 SFont_PutString2(Surface, Font, Surface->w/2-SFont_TextWidth2(Font,text)/2, y, text);
164}
165
166void SFont_XCenteredString(SDL_Surface *Surface, int y, char *text)
167{
168 SFont_XCenteredString2(Surface, &InternalFont, y, text);
169}
170
171void SFont_InternalInput( SDL_Surface *Dest, SFont_FontInfo *Font, int x, int y, int PixelWidth, char *text)
172{
173 SDL_Event event;
174 int ch=-1,blink=0;
175 long blinktimer=0;
176 SDL_Surface *Back;
177 SDL_Rect rect;
178 int previous;
179// int ofs=(text[0]-33)*2+1;
180// int leftshift=(Font->CharPos[ofs]-Font->CharPos[ofs-1])/2;
181
182 Back = SDL_AllocSurface(Dest->flags,
183 Dest->w,
184 Font->h,
185 Dest->format->BitsPerPixel,
186 Dest->format->Rmask,
187 Dest->format->Gmask,
188 Dest->format->Bmask, 0);
189 rect.x=0;
190 rect.y=y;
191 rect.w=Dest->w;
192 rect.h=Font->Surface->h;
193 SDL_BlitSurface(Dest, &rect, Back, NULL);
194 SFont_PutString2(Dest,Font,x,y,text);
195 SDL_UpdateRects(Dest, 1, &rect);
196
197 // start input
198 previous=SDL_EnableUNICODE(1);
199 blinktimer=SDL_GetTicks();
200 while (ch!=SDLK_RETURN) {
201 if (event.type==SDL_KEYDOWN) {
202 ch=event.key.keysym.unicode;
203 if (((ch>31)||(ch=='\b')) && (ch<128)) {
204 if ((ch=='\b')&&(strlen(text)>0))
205 text[strlen(text)-1]='\0';
206 else if (ch!='\b')
207 sprintf(text,"%s%c",text,ch);
208 if (SFont_TextWidth2(Font,text)>PixelWidth) text[strlen(text)-1]='\0';
209 SDL_BlitSurface( Back, NULL, Dest, &rect);
210 SFont_PutString2(Dest, Font, x, y, text);
211 SDL_UpdateRects(Dest, 1, &rect);
212// printf("%s ## %d\n",text,strlen(text));
213 SDL_WaitEvent(&event);
214 }
215 }
216 if (SDL_GetTicks()>blinktimer) {
217 blink=1-blink;
218 blinktimer=SDL_GetTicks()+500;
219 if (blink) {
220 SFont_PutString2(Dest, Font, x+SFont_TextWidth2(Font,text), y, "|");
221 SDL_UpdateRects(Dest, 1, &rect);
222// SDL_UpdateRect(Dest, x+SFont_TextWidth2(Font,text), y, SFont_TextWidth2(Font,"|"), Font->Surface->h);
223 } else {
224 SDL_BlitSurface( Back, NULL, Dest, &rect);
225 SFont_PutString2(Dest, Font, x, y, text);
226 SDL_UpdateRects(Dest, 1, &rect);
227// SDL_UpdateRect(Dest, x-(Font->CharPos[ofs]-Font->CharPos[ofs-1])/2, y, PixelWidth, Font->Surface->h);
228 }
229 }
230 SDL_Delay(1);
231 SDL_PollEvent(&event);
232 }
233 text[strlen(text)]='\0';
234 SDL_FreeSurface(Back);
235 SDL_EnableUNICODE(previous); //restore the previous state
236}
237
238void SFont_Input2( SDL_Surface *Dest, SFont_FontInfo *Font, int x, int y, int PixelWidth, char *text)
239{
240 SFont_InternalInput( Dest, Font, x, y, PixelWidth, text);
241}
242void SFont_Input( SDL_Surface *Dest, int x, int y, int PixelWidth, char *text)
243{
244 SFont_Input2( Dest, &InternalFont, x, y, PixelWidth, text);
245}
246
247#endif
248
249MODULE = SDL::SFont PACKAGE = SDL::SFont
250PROTOTYPES : DISABLE
251
252#ifdef HAVE_SDL_IMAGE
253
254SDL_Surface *
255NewFont ( filename )
256 char *filename
257 CODE:
258 RETVAL = IMG_Load(filename);
259 SFont_InitFont(RETVAL);
260 OUTPUT:
261 RETVAL
262
263void
264UseFont ( surface )
265 SDL_Surface *surface
266 CODE:
267 SFont_InitFont(surface);
268
269void
270PutString ( surface, x, y, text )
271 SDL_Surface *surface
272 int x
273 int y
274 char *text
275 CODE:
276 SFont_PutString( surface, x, y, text );
277
278int
279TextWidth ( text )
280 char *text
281 CODE:
282 RETVAL = SFont_TextWidth(text);
283 OUTPUT:
284 RETVAL
285
286
287#endif