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