ortp_send.c: fix a gcc warning
[paraslash.git] / SFont.c
1 /*
2 * Copyright (C) Karl Bartel <karlb@gmx.net> WWW: http://www.linux-games.com
3 *
4 * Licensed under the GPL v2. For licencing details see COPYING.
5 */
6
7 /*Modified 2003, 2006 by Andre Noll */
8
9 #include <SDL/SDL.h>
10 #include "SFont.h"
11 #include <stdlib.h> /* exit */
12 #include <string.h> /* strlen */
13 SFont_FontInfo InternalFont;
14
15 static Uint32 GetPixel(SDL_Surface *Surface, Sint32 X, Sint32 Y)
16 {
17
18 Uint8 *bits;
19 Uint32 Bpp;
20
21 if (X < 0)
22 puts("SFONT ERROR: x too small in GetPixel. Report this "
23 "to <karlb@gmx.net>");
24 if (X >= Surface->w)
25 puts("SFONT ERROR: x too big in GetPixel. Report this to "
26 "<karlb@gmx.net>");
27 Bpp = Surface->format->BytesPerPixel;
28 bits = ((Uint8 *) Surface->pixels) + Y * Surface->pitch + X * Bpp;
29
30 /* Get the pixel */
31 switch (Bpp) {
32 case 1:
33 return *((Uint8 *) Surface->pixels + Y * Surface->pitch + X);
34 break;
35 case 2:
36 return *((Uint16 *) Surface->pixels + Y * Surface->pitch / 2 + X);
37 break;
38 case 3:{ /* Format/endian independent */
39 Uint8 r, g, b;
40 r = *((bits) + Surface->format->Rshift / 8);
41 g = *((bits) + Surface->format->Gshift / 8);
42 b = *((bits) + Surface->format->Bshift / 8);
43 return SDL_MapRGB(Surface->format, r, g, b);
44 }
45 break;
46 case 4:
47 return *((Uint32 *) Surface->pixels + Y * Surface->pitch / 4 + X);
48 break;
49 }
50
51 return -1;
52 }
53
54 void InitFont2(SFont_FontInfo * Font)
55 {
56 int x = 0, i = 0;
57
58 if (!Font->Surface) {
59 printf("The font has not been loaded!\n");
60 exit(EXIT_FAILURE);
61 }
62
63 if (SDL_MUSTLOCK(Font->Surface))
64 SDL_LockSurface(Font->Surface);
65
66 while (x < Font->Surface->w) {
67 if (GetPixel(Font->Surface, x, 0) ==
68 SDL_MapRGB(Font->Surface->format, 255, 0, 255)) {
69 Font->CharPos[i++] = x;
70 while ((x < Font->Surface->w - 1) &&
71 (GetPixel(Font->Surface, x, 0) ==
72 SDL_MapRGB(Font->Surface->format, 255, 0, 255)))
73 x++;
74 Font->CharPos[i++] = x;
75 }
76 x++;
77 }
78 if (SDL_MUSTLOCK(Font->Surface))
79 SDL_UnlockSurface(Font->Surface);
80
81 Font->h = Font->Surface->h;
82 SDL_SetColorKey(Font->Surface, SDL_SRCCOLORKEY,
83 GetPixel(Font->Surface, 0, Font->Surface->h - 1));
84 }
85
86 void PutString2(SDL_Surface * Surface, SFont_FontInfo * Font, int x, int y,
87 const char *text)
88 {
89 int ofs;
90 int i = 0;
91 SDL_Rect srcrect, dstrect;
92
93 while (text[i] != '\0') {
94 if (text[i] == ' ') {
95 x += Font->CharPos[2] - Font->CharPos[1];
96 i++;
97 } else {
98 ofs = ((unsigned char) text[i] - 33) * 2 + 1;
99 srcrect.w = dstrect.w = (Font->CharPos[ofs + 2]
100 + Font->CharPos[ofs + 1]) / 2
101 - (Font->CharPos[ofs]
102 + Font->CharPos[ofs - 1]) / 2;
103 srcrect.h = dstrect.h = Font->Surface->h - 1;
104 srcrect.x = (Font->CharPos[ofs]
105 + Font->CharPos[ofs - 1]) / 2;
106 srcrect.y = 1;
107 dstrect.x = x - (float) (Font->CharPos[ofs]
108 - Font->CharPos[ofs - 1]) / 2;
109 dstrect.y = y;
110 SDL_BlitSurface(Font->Surface, &srcrect, Surface,
111 &dstrect);
112 x += Font->CharPos[ofs + 1] - Font->CharPos[ofs];
113 i++;
114 }
115 }
116 }
117
118 int TextWidth2(SFont_FontInfo * Font, char *text)
119 {
120 int ofs = 0;
121 int i = 0, x = 0;
122
123 while (text[i] != '\0') {
124 if (text[i] == ' ') {
125 x += Font->CharPos[2] - Font->CharPos[1];
126 i++;
127 } else {
128 ofs = ((unsigned char) text[i] - 33) * 2 + 1;
129 x += Font->CharPos[ofs + 1] - Font->CharPos[ofs];
130 i++;
131 }
132 }
133 return x;
134 }
135
136 static void SFont_InternalInput(SDL_Surface * Dest, SFont_FontInfo * Font, int x,
137 int y, int PixelWidth, char *text)
138 {
139 SDL_Event event;
140 int ch = -1, blink = 0;
141 long blinktimer = 0;
142 SDL_Surface *Back;
143 SDL_Rect rect;
144 int previous;
145
146 Back = SDL_AllocSurface(Dest->flags,
147 Dest->w,
148 Font->h,
149 Dest->format->BitsPerPixel,
150 Dest->format->Rmask,
151 Dest->format->Gmask, Dest->format->Bmask, 0);
152 rect.x = 0;
153 rect.y = y;
154 rect.w = Dest->w;
155 rect.h = Font->Surface->h;
156 SDL_BlitSurface(Dest, &rect, Back, NULL);
157 PutString2(Dest, Font, x, y, text);
158 SDL_UpdateRects(Dest, 1, &rect);
159
160 /* start input */
161 previous = SDL_EnableUNICODE(1);
162 blinktimer = SDL_GetTicks();
163 while (ch != SDLK_RETURN) {
164 if (event.type == SDL_KEYDOWN) {
165 ch = event.key.keysym.unicode;
166 if (((ch > 31) || (ch == '\b')) && (ch < 128)) {
167 if ((ch == '\b') && (strlen(text) > 0))
168 text[strlen(text) - 1] = '\0';
169 else if (ch != '\b')
170 sprintf(text, "%s%c", text, ch);
171 if (TextWidth2(Font, text) > PixelWidth)
172 text[strlen(text) - 1] = '\0';
173 SDL_BlitSurface(Back, NULL, Dest, &rect);
174 PutString2(Dest, Font, x, y, text);
175 SDL_UpdateRects(Dest, 1, &rect);
176 SDL_WaitEvent(&event);
177 }
178 }
179 if (SDL_GetTicks() > blinktimer) {
180 blink = 1 - blink;
181 blinktimer = SDL_GetTicks() + 500;
182 if (blink) {
183 PutString2(Dest, Font,
184 x + TextWidth2(Font, text), y, "|");
185 SDL_UpdateRects(Dest, 1, &rect);
186 } else {
187 SDL_BlitSurface(Back, NULL, Dest, &rect);
188 PutString2(Dest, Font, x, y, text);
189 SDL_UpdateRects(Dest, 1, &rect);
190 }
191 }
192 SDL_Delay(1);
193 SDL_PollEvent(&event);
194 }
195 text[strlen(text)] = '\0';
196 SDL_FreeSurface(Back);
197 /* restore the previous state */
198 SDL_EnableUNICODE(previous);
199 }
200
201 void SFont_Input2(SDL_Surface * Dest, SFont_FontInfo * Font, int x, int y,
202 int PixelWidth, char *text)
203 {
204 SFont_InternalInput(Dest, Font, x, y, PixelWidth, text);
205 }