Importing SDLPerl 2.2
[sdlgit/SDL_perl.git] / src / SDL / SFont.c
1 /*
2  * This file was generated automatically by xsubpp version 1.9508 from the
3  * contents of SFont.xs. Do not edit this file, edit SFont.xs instead.
4  *
5  *      ANY CHANGES MADE HERE WILL BE LOST!
6  *
7  */
8
9 #line 1 "SFont.xs"
10 //
11 // SFont.xs
12 //
13 // Original SFont code Copyright (C) Karl Bartel 
14 // Copyright (C) 2005 David J. Goehrig <dgoehrig@cpan.org>
15 //
16 // ------------------------------------------------------------------------------
17 //
18 // This library is free software; you can redistribute it and/or
19 // modify it under the terms of the GNU Lesser General Public
20 // License as published by the Free Software Foundation; either
21 // version 2.1 of the License, or (at your option) any later version.
22 // 
23 // This library is distributed in the hope that it will be useful,
24 // but WITHOUT ANY WARRANTY; without even the implied warranty of
25 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
26 // Lesser General Public License for more details.
27 // 
28 // You should have received a copy of the GNU Lesser General Public
29 // License along with this library; if not, write to the Free Software
30 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
31 //
32 // ------------------------------------------------------------------------------
33 //
34 // Please feel free to send questions, suggestions or improvements to:
35 //
36 //      David J. Goehrig
37 //      dgoehrig@cpan.org
38 //
39
40 #include "EXTERN.h"
41 #include "perl.h"
42 #include "XSUB.h"
43
44 #ifndef aTHX_
45 #define aTHX_
46 #endif
47
48 #include <SDL.h>
49 #include <string.h>
50 #include <stdlib.h>
51
52 #ifdef USE_THREADS
53 #define HAVE_TLS_CONTEXT
54 #endif
55
56 #include "../defines.h"
57 #include "../SFont.h"
58
59 #ifdef HAVE_SDL_IMAGE
60 #include <SDL_image.h>
61
62 SFont_FontInfo InternalFont;
63 Uint32 SFont_GetPixel(SDL_Surface *Surface, Sint32 X, Sint32 Y)
64 {
65
66    Uint8  *bits;
67    Uint32 Bpp;
68    if (X<0) puts("SFONT ERROR: x too small in SFont_GetPixel. Report this to <karlb@gmx.net>");
69    if (X>=Surface->w) puts("SFONT ERROR: x too big in SFont_GetPixel. Report this to <karlb@gmx.net>");
70    
71    Bpp = Surface->format->BytesPerPixel;
72
73    bits = ((Uint8 *)Surface->pixels)+Y*Surface->pitch+X*Bpp;
74
75    // Get the pixel
76    switch(Bpp) {
77       case 1:
78          return *((Uint8 *)Surface->pixels + Y * Surface->pitch + X);
79          break;
80       case 2:
81          return *((Uint16 *)Surface->pixels + Y * Surface->pitch/2 + X);
82          break;
83       case 3: { // Format/endian independent 
84          Uint8 r, g, b;
85          r = *((bits)+Surface->format->Rshift/8);
86          g = *((bits)+Surface->format->Gshift/8);
87          b = *((bits)+Surface->format->Bshift/8);
88          return SDL_MapRGB(Surface->format, r, g, b);
89          }
90          break;
91       case 4:
92          return *((Uint32 *)Surface->pixels + Y * Surface->pitch/4 + X);
93          break;
94    }
95
96     return -1;
97 }
98
99 void SFont_InitFont2(SFont_FontInfo *Font)
100 {
101     int x = 0, i = 0;
102
103     if ( Font->Surface==NULL ) {
104         printf("The font has not been loaded!\n");
105         exit(1);
106     }
107
108     if (SDL_MUSTLOCK(Font->Surface)) SDL_LockSurface(Font->Surface);
109
110     while ( x < Font->Surface->w ) {
111         if(SFont_GetPixel(Font->Surface,x,0)==SDL_MapRGB(Font->Surface->format,255,0,255)) { 
112             Font->CharPos[i++]=x;
113             while (( x < Font->Surface->w-1) && (SFont_GetPixel(Font->Surface,x,0)==SDL_MapRGB(Font->Surface->format,255,0,255)))
114                 x++;
115             Font->CharPos[i++]=x;
116         }
117         x++;
118     }
119     if (SDL_MUSTLOCK(Font->Surface)) SDL_UnlockSurface(Font->Surface);
120
121     Font->h=Font->Surface->h;
122     SDL_SetColorKey(Font->Surface, SDL_SRCCOLORKEY, SFont_GetPixel(Font->Surface, 0, Font->Surface->h-1));
123 }
124
125 void SFont_InitFont(SDL_Surface *Font)
126 {
127     InternalFont.Surface=Font;
128     SFont_InitFont2(&InternalFont);
129 }
130
131 void SFont_PutString2(SDL_Surface *Surface, SFont_FontInfo *Font, int x, int y, char *text)
132 {
133     int ofs;
134     int i=0;
135     SDL_Rect srcrect,dstrect; 
136
137     while (text[i]!='\0') {
138         if (text[i]==' ') {
139             x+=Font->CharPos[2]-Font->CharPos[1];
140             i++;
141         }
142         else {
143 //          printf("-%c- %c - %u\n",228,text[i],text[i]);
144             ofs=(text[i]-33)*2+1;
145 //          printf("printing %c %d\n",text[i],ofs);
146             srcrect.w = dstrect.w = (Font->CharPos[ofs+2]+Font->CharPos[ofs+1])/2-(Font->CharPos[ofs]+Font->CharPos[ofs-1])/2;
147             srcrect.h = dstrect.h = Font->Surface->h-1;
148             srcrect.x = (Font->CharPos[ofs]+Font->CharPos[ofs-1])/2;
149             srcrect.y = 1;
150             dstrect.x = x-(float)(Font->CharPos[ofs]-Font->CharPos[ofs-1])/2;
151             dstrect.y = y;
152
153             SDL_BlitSurface( Font->Surface, &srcrect, Surface, &dstrect); 
154
155             x+=Font->CharPos[ofs+1]-Font->CharPos[ofs];
156             i++;
157         }
158     }
159 }
160
161 void SFont_PutString(SDL_Surface *Surface, int x, int y, char *text)
162 {
163     SFont_PutString2(Surface, &InternalFont, x, y, text);
164 }
165
166 int SFont_TextWidth2(SFont_FontInfo *Font, char *text)
167 {
168     int ofs=0;
169     int i=0,x=0;
170
171     while (text[i]!='\0') {
172         if (text[i]==' ') {
173             x+=Font->CharPos[2]-Font->CharPos[1];
174             i++;
175         }
176         else {
177             ofs=(text[i]-33)*2+1;
178             x+=Font->CharPos[ofs+1]-Font->CharPos[ofs];
179             i++;
180         }
181     }
182 //    printf ("--%d\n",x);
183     return x;
184 }
185
186 int SFont_TextWidth(char *text)
187 {
188     return SFont_TextWidth2(&InternalFont, text);
189 }
190
191 void SFont_XCenteredString2(SDL_Surface *Surface, SFont_FontInfo *Font, int y, char *text)
192 {
193     SFont_PutString2(Surface, Font, Surface->w/2-SFont_TextWidth2(Font,text)/2, y, text);
194 }
195
196 void SFont_XCenteredString(SDL_Surface *Surface, int y, char *text)
197 {
198     SFont_XCenteredString2(Surface, &InternalFont, y, text);
199 }
200
201 void SFont_InternalInput( SDL_Surface *Dest, SFont_FontInfo *Font, int x, int y, int PixelWidth, char *text)
202 {
203     SDL_Event event;
204     int ch=-1,blink=0;
205     long blinktimer=0;
206     SDL_Surface *Back;
207     SDL_Rect rect;
208     int previous;
209 //    int ofs=(text[0]-33)*2+1;
210 //    int leftshift=(Font->CharPos[ofs]-Font->CharPos[ofs-1])/2;
211     
212     Back = SDL_AllocSurface(Dest->flags,
213                             Dest->w,
214                             Font->h,
215                             Dest->format->BitsPerPixel,
216                             Dest->format->Rmask,
217                             Dest->format->Gmask,
218                             Dest->format->Bmask, 0);
219     rect.x=0;
220     rect.y=y;
221     rect.w=Dest->w;
222     rect.h=Font->Surface->h;
223     SDL_BlitSurface(Dest, &rect, Back, NULL);
224     SFont_PutString2(Dest,Font,x,y,text);
225     SDL_UpdateRects(Dest, 1, &rect);
226         
227     // start input
228     previous=SDL_EnableUNICODE(1);
229     blinktimer=SDL_GetTicks();
230     while (ch!=SDLK_RETURN) {
231         if (event.type==SDL_KEYDOWN) {
232             ch=event.key.keysym.unicode;
233             if (((ch>31)||(ch=='\b')) && (ch<128)) {
234                 if ((ch=='\b')&&(strlen(text)>0))
235                     text[strlen(text)-1]='\0';
236                 else if (ch!='\b')
237                     sprintf(text,"%s%c",text,ch);
238                 if (SFont_TextWidth2(Font,text)>PixelWidth) text[strlen(text)-1]='\0';
239                 SDL_BlitSurface( Back, NULL, Dest, &rect);
240                 SFont_PutString2(Dest, Font, x, y, text);
241                 SDL_UpdateRects(Dest, 1, &rect);
242 //              printf("%s ## %d\n",text,strlen(text));
243                 SDL_WaitEvent(&event);
244             }
245         }
246         if (SDL_GetTicks()>blinktimer) {
247             blink=1-blink;
248             blinktimer=SDL_GetTicks()+500;
249             if (blink) {
250                 SFont_PutString2(Dest, Font, x+SFont_TextWidth2(Font,text), y, "|");
251                 SDL_UpdateRects(Dest, 1, &rect);
252 //              SDL_UpdateRect(Dest, x+SFont_TextWidth2(Font,text), y, SFont_TextWidth2(Font,"|"), Font->Surface->h);
253             } else {
254                 SDL_BlitSurface( Back, NULL, Dest, &rect);
255                 SFont_PutString2(Dest, Font, x, y, text);
256                 SDL_UpdateRects(Dest, 1, &rect);
257 //              SDL_UpdateRect(Dest, x-(Font->CharPos[ofs]-Font->CharPos[ofs-1])/2, y, PixelWidth, Font->Surface->h);
258             }
259         }
260         SDL_Delay(1);
261         SDL_PollEvent(&event);
262     }
263     text[strlen(text)]='\0';
264     SDL_FreeSurface(Back);
265     SDL_EnableUNICODE(previous);  //restore the previous state
266 }
267
268 void SFont_Input2( SDL_Surface *Dest, SFont_FontInfo *Font, int x, int y, int PixelWidth, char *text)
269 {
270     SFont_InternalInput( Dest, Font, x, y, PixelWidth,  text);
271 }
272 void SFont_Input( SDL_Surface *Dest, int x, int y, int PixelWidth, char *text)
273 {
274     SFont_Input2( Dest, &InternalFont, x, y, PixelWidth, text);
275 }
276
277 #endif
278
279 #line 280 "SFont.c"
280 #ifdef HAVE_SDL_IMAGE
281 #define XSubPPtmpAAAA 1
282
283 XS(XS_SDL__SFont_NewFont); /* prototype to pass -Wmissing-prototypes */
284 XS(XS_SDL__SFont_NewFont)
285 {
286     dXSARGS;
287     if (items != 1)
288         Perl_croak(aTHX_ "Usage: SDL::SFont::NewFont(filename)");
289     {
290         char *  filename = (char *)SvPV_nolen(ST(0));
291         SDL_Surface *   RETVAL;
292         dXSTARG;
293 #line 279 "SFont.xs"
294                 RETVAL = IMG_Load(filename);
295                 SFont_InitFont(RETVAL);
296 #line 297 "SFont.c"
297         XSprePUSH; PUSHi(PTR2IV(RETVAL));
298     }
299     XSRETURN(1);
300 }
301
302 XS(XS_SDL__SFont_UseFont); /* prototype to pass -Wmissing-prototypes */
303 XS(XS_SDL__SFont_UseFont)
304 {
305     dXSARGS;
306     if (items != 1)
307         Perl_croak(aTHX_ "Usage: SDL::SFont::UseFont(surface)");
308     {
309         SDL_Surface *   surface = INT2PTR(SDL_Surface *,SvIV(ST(0)));
310 #line 288 "SFont.xs"
311                 SFont_InitFont(surface);
312 #line 313 "SFont.c"
313     }
314     XSRETURN_EMPTY;
315 }
316
317 XS(XS_SDL__SFont_PutString); /* prototype to pass -Wmissing-prototypes */
318 XS(XS_SDL__SFont_PutString)
319 {
320     dXSARGS;
321     if (items != 4)
322         Perl_croak(aTHX_ "Usage: SDL::SFont::PutString(surface, x, y, text)");
323     {
324         SDL_Surface *   surface = INT2PTR(SDL_Surface *,SvIV(ST(0)));
325         int     x = (int)SvIV(ST(1));
326         int     y = (int)SvIV(ST(2));
327         char *  text = (char *)SvPV_nolen(ST(3));
328 #line 297 "SFont.xs"
329                 SFont_PutString( surface, x, y, text );
330 #line 331 "SFont.c"
331     }
332     XSRETURN_EMPTY;
333 }
334
335 XS(XS_SDL__SFont_TextWidth); /* prototype to pass -Wmissing-prototypes */
336 XS(XS_SDL__SFont_TextWidth)
337 {
338     dXSARGS;
339     if (items != 1)
340         Perl_croak(aTHX_ "Usage: SDL::SFont::TextWidth(text)");
341     {
342         char *  text = (char *)SvPV_nolen(ST(0));
343         int     RETVAL;
344         dXSTARG;
345 #line 303 "SFont.xs"
346                 RETVAL = SFont_TextWidth(text);
347 #line 348 "SFont.c"
348         XSprePUSH; PUSHi((IV)RETVAL);
349     }
350     XSRETURN(1);
351 }
352
353 #endif
354 #ifdef __cplusplus
355 extern "C"
356 #endif
357 XS(boot_SDL__SFont); /* prototype to pass -Wmissing-prototypes */
358 XS(boot_SDL__SFont)
359 {
360     dXSARGS;
361     char* file = __FILE__;
362
363     XS_VERSION_BOOTCHECK ;
364
365 #if XSubPPtmpAAAA
366         newXS("SDL::SFont::NewFont", XS_SDL__SFont_NewFont, file);
367         newXS("SDL::SFont::UseFont", XS_SDL__SFont_UseFont, file);
368         newXS("SDL::SFont::PutString", XS_SDL__SFont_PutString, file);
369         newXS("SDL::SFont::TextWidth", XS_SDL__SFont_TextWidth, file);
370 #endif
371
372     /* Initialisation Section */
373
374 #if XSubPPtmpAAAA
375 #endif
376 #line 377 "SFont.c"
377
378     /* End of Initialisation Section */
379
380     XSRETURN_YES;
381 }
382