kill some more unneeded includes
[paraslash.git] / SFont.c
1 /*
2 * Copyright (C) Karl Bartel <karlb@gmx.net> WWW: http://www.linux-games.com
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
17 */
18
19 /*Modified 2003, 2006 by Andre Noll */
20
21 #include <SDL/SDL.h>
22 #include "SFont.h"
23 #include <stdlib.h> /* exit */
24 #include <string.h> /* strlen */
25 SFont_FontInfo InternalFont;
26
27 static Uint32 GetPixel(SDL_Surface *Surface, Sint32 X, Sint32 Y)
28 {
29
30 Uint8 *bits;
31 Uint32 Bpp;
32
33 if (X < 0)
34 puts("SFONT ERROR: x too small in GetPixel. Report this "
35 "to <karlb@gmx.net>");
36 if (X >= Surface->w)
37 puts("SFONT ERROR: x too big in GetPixel. Report this to "
38 "<karlb@gmx.net>");
39 Bpp = Surface->format->BytesPerPixel;
40 bits = ((Uint8 *) Surface->pixels) + Y * Surface->pitch + X * Bpp;
41
42 /* Get the pixel */
43 switch (Bpp) {
44 case 1:
45 return *((Uint8 *) Surface->pixels + Y * Surface->pitch + X);
46 break;
47 case 2:
48 return *((Uint16 *) Surface->pixels + Y * Surface->pitch / 2 + X);
49 break;
50 case 3:{ /* Format/endian independent */
51 Uint8 r, g, b;
52 r = *((bits) + Surface->format->Rshift / 8);
53 g = *((bits) + Surface->format->Gshift / 8);
54 b = *((bits) + Surface->format->Bshift / 8);
55 return SDL_MapRGB(Surface->format, r, g, b);
56 }
57 break;
58 case 4:
59 return *((Uint32 *) Surface->pixels + Y * Surface->pitch / 4 + X);
60 break;
61 }
62
63 return -1;
64 }
65
66 void InitFont2(SFont_FontInfo * Font)
67 {
68 int x = 0, i = 0;
69
70 if (!Font->Surface) {
71 printf("The font has not been loaded!\n");
72 exit(EXIT_FAILURE);
73 }
74
75 if (SDL_MUSTLOCK(Font->Surface))
76 SDL_LockSurface(Font->Surface);
77
78 while (x < Font->Surface->w) {
79 if (GetPixel(Font->Surface, x, 0) ==
80 SDL_MapRGB(Font->Surface->format, 255, 0, 255)) {
81 Font->CharPos[i++] = x;
82 while ((x < Font->Surface->w - 1) &&
83 (GetPixel(Font->Surface, x, 0) ==
84 SDL_MapRGB(Font->Surface->format, 255, 0, 255)))
85 x++;
86 Font->CharPos[i++] = x;
87 }
88 x++;
89 }
90 if (SDL_MUSTLOCK(Font->Surface))
91 SDL_UnlockSurface(Font->Surface);
92
93 Font->h = Font->Surface->h;
94 SDL_SetColorKey(Font->Surface, SDL_SRCCOLORKEY,
95 GetPixel(Font->Surface, 0, Font->Surface->h - 1));
96 }
97
98 void PutString2(SDL_Surface * Surface, SFont_FontInfo * Font, int x, int y,
99 const char *text)
100 {
101 int ofs;
102 int i = 0;
103 SDL_Rect srcrect, dstrect;
104
105 while (text[i] != '\0') {
106 if (text[i] == ' ') {
107 x += Font->CharPos[2] - Font->CharPos[1];
108 i++;
109 } else {
110 ofs = ((unsigned char) text[i] - 33) * 2 + 1;
111 srcrect.w = dstrect.w = (Font->CharPos[ofs + 2]
112 + Font->CharPos[ofs + 1]) / 2
113 - (Font->CharPos[ofs]
114 + Font->CharPos[ofs - 1]) / 2;
115 srcrect.h = dstrect.h = Font->Surface->h - 1;
116 srcrect.x = (Font->CharPos[ofs]
117 + Font->CharPos[ofs - 1]) / 2;
118 srcrect.y = 1;
119 dstrect.x = x - (float) (Font->CharPos[ofs]
120 - Font->CharPos[ofs - 1]) / 2;
121 dstrect.y = y;
122 SDL_BlitSurface(Font->Surface, &srcrect, Surface,
123 &dstrect);
124 x += Font->CharPos[ofs + 1] - Font->CharPos[ofs];
125 i++;
126 }
127 }
128 }
129
130 int TextWidth2(SFont_FontInfo * Font, char *text)
131 {
132 int ofs = 0;
133 int i = 0, x = 0;
134
135 while (text[i] != '\0') {
136 if (text[i] == ' ') {
137 x += Font->CharPos[2] - Font->CharPos[1];
138 i++;
139 } else {
140 ofs = ((unsigned char) text[i] - 33) * 2 + 1;
141 x += Font->CharPos[ofs + 1] - Font->CharPos[ofs];
142 i++;
143 }
144 }
145 return x;
146 }
147
148 static void SFont_InternalInput(SDL_Surface * Dest, SFont_FontInfo * Font, int x,
149 int y, int PixelWidth, char *text)
150 {
151 SDL_Event event;
152 int ch = -1, blink = 0;
153 long blinktimer = 0;
154 SDL_Surface *Back;
155 SDL_Rect rect;
156 int previous;
157
158 Back = SDL_AllocSurface(Dest->flags,
159 Dest->w,
160 Font->h,
161 Dest->format->BitsPerPixel,
162 Dest->format->Rmask,
163 Dest->format->Gmask, 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 previous = 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)
184 text[strlen(text) - 1] = '\0';
185 SDL_BlitSurface(Back, NULL, Dest, &rect);
186 PutString2(Dest, Font, x, y, text);
187 SDL_UpdateRects(Dest, 1, &rect);
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,
196 x + TextWidth2(Font, text), y, "|");
197 SDL_UpdateRects(Dest, 1, &rect);
198 } else {
199 SDL_BlitSurface(Back, NULL, Dest, &rect);
200 PutString2(Dest, Font, x, y, text);
201 SDL_UpdateRects(Dest, 1, &rect);
202 }
203 }
204 SDL_Delay(1);
205 SDL_PollEvent(&event);
206 }
207 text[strlen(text)] = '\0';
208 SDL_FreeSurface(Back);
209 /* restore the previous state */
210 SDL_EnableUNICODE(previous);
211 }
212
213 void SFont_Input2(SDL_Surface * Dest, SFont_FontInfo * Font, int x, int y,
214 int PixelWidth, char *text)
215 {
216 SFont_InternalInput(Dest, Font, x, y, PixelWidth, text);
217 }