1 /*
2 * OpenTyrian: A modern cross-platform port of Tyrian
3 * Copyright (C) 2007-2009 The OpenTyrian Development Team
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19 #include "font.h"
20 #include "fonthand.h"
21 #include "sprite.h"
22
23 /**
24 * \file font.c
25 * \brief Text drawing routines.
26 */
27
28 /**
29 * \brief Draws text in a color specified by hue and value and with a drop
30 * shadow.
31 *
32 * A '~' in the text is not drawn but instead toggles highlighting which
33 * increases \c value by 4.
34 *
35 * \li like JE_dString() if (black == false && shadow_dist == 2 && hue == 15)
36 * \li like JE_textShade() with PART_SHADE if (black == true && shadow_dist == 1)
37 * \li like JE_outTextAndDarken() if (black == false && shadow_dist == 1)
38 * \li like JE_outTextAdjust() with shadow if (black == false && shadow_dist == 2)
39 *
40 * @param surface destination surface
41 * @param x initial x-position in pixels; which direction(s) the text is drawn
42 * from this position depends on the alignment
43 * @param y initial upper y-position in pixels
44 * @param text text to be drawn
45 * @param font style/size of text
46 * @param alignment left_aligned, centered, or right_aligned
47 * @param hue hue component of text color
48 * @param value value component of text color
49 * @param black if true the shadow is drawn as solid black, if false the shadow
50 * is drawn by darkening the pixels of the destination surface
51 * @param shadow_dist distance in pixels that the shadow will be drawn away from
52 * the text. (This is added to both the x and y positions, so a value of
53 * 1 causes the shadow to be drawn 1 pixel right and 1 pixel lower than
54 * the text.)
55 */
draw_font_hv_shadow(SDL_Surface * surface,int x,int y,const char * text,Font font,FontAlignment alignment,Uint8 hue,Sint8 value,bool black,int shadow_dist)56 void draw_font_hv_shadow( SDL_Surface *surface, int x, int y, const char *text, Font font, FontAlignment alignment, Uint8 hue, Sint8 value, bool black, int shadow_dist )
57 {
58 draw_font_dark(surface, x + shadow_dist, y + shadow_dist, text, font, alignment, black);
59
60 draw_font_hv(surface, x, y, text, font, alignment, hue, value);
61 }
62
63 /**
64 * \brief Draws text in a color specified by hue and value and with a
65 * surrounding shadow.
66 *
67 * A '~' in the text is not drawn but instead toggles highlighting which
68 * increases \c value by 4.
69 *
70 * \li like JE_textShade() with FULL_SHADE if (black == true && shadow_dist == 1)
71 *
72 * @param surface destination surface
73 * @param x initial x-position in pixels; which direction(s) the text is drawn
74 * from this position depends on the alignment
75 * @param y initial upper y-position in pixels
76 * @param text text to be drawn
77 * @param font style/size of text
78 * @param alignment left_aligned, centered, or right_aligned
79 * @param hue hue component of text color
80 * @param value value component of text color
81 * @param black if true the shadow is drawn as solid black, if false the shadow
82 * is drawn by darkening the pixels of the destination surface
83 * @param shadow_dist distance in pixels that the shadows will be drawn away
84 * from the text. (This distance is separately added to and subtracted
85 * from the x position and y position, resulting in four shadows -- one
86 * in each cardinal direction. If this shadow distance is small enough,
87 * this produces a shadow that outlines the text.)
88 */
draw_font_hv_full_shadow(SDL_Surface * surface,int x,int y,const char * text,Font font,FontAlignment alignment,Uint8 hue,Sint8 value,bool black,int shadow_dist)89 void draw_font_hv_full_shadow( SDL_Surface *surface, int x, int y, const char *text, Font font, FontAlignment alignment, Uint8 hue, Sint8 value, bool black, int shadow_dist )
90 {
91 draw_font_dark(surface, x, y - shadow_dist, text, font, alignment, black);
92 draw_font_dark(surface, x + shadow_dist, y, text, font, alignment, black);
93 draw_font_dark(surface, x, y + shadow_dist, text, font, alignment, black);
94 draw_font_dark(surface, x - shadow_dist, y, text, font, alignment, black);
95
96 draw_font_hv(surface, x, y, text, font, alignment, hue, value);
97 }
98
99 /**
100 * \brief Draws text in a color specified by hue and value.
101 *
102 * A '~' in the text is not drawn but instead toggles highlighting which
103 * increases \c value by 4.
104 *
105 * \li like JE_outText() with (brightness >= 0)
106 * \li like JE_outTextAdjust() without shadow
107 *
108 * @param surface destination surface
109 * @param x initial x-position in pixels; which direction(s) the text is drawn
110 * from this position depends on the alignment
111 * @param y initial upper y-position in pixels
112 * @param text text to be drawn
113 * @param font style/size of text
114 * @param alignment left_aligned, centered, or right_aligned
115 * @param hue hue component of text color
116 * @param value value component of text color
117 */
draw_font_hv(SDL_Surface * surface,int x,int y,const char * text,Font font,FontAlignment alignment,Uint8 hue,Sint8 value)118 void draw_font_hv( SDL_Surface *surface, int x, int y, const char *text, Font font, FontAlignment alignment, Uint8 hue, Sint8 value )
119 {
120 switch (alignment)
121 {
122 case left_aligned:
123 break;
124 case centered:
125 x -= JE_textWidth(text, font) / 2;
126 break;
127 case right_aligned:
128 x -= JE_textWidth(text, font);
129 break;
130 }
131
132 bool highlight = false;
133
134 for (; *text != '\0'; ++text)
135 {
136 int sprite_id = font_ascii[(unsigned char)*text];
137
138 switch (*text)
139 {
140 case ' ':
141 x += 6;
142 break;
143
144 case '~':
145 highlight = !highlight;
146 if (highlight)
147 value += 4;
148 else
149 value -= 4;
150 break;
151
152 default:
153 if (sprite_id != -1 && sprite_exists(font, sprite_id))
154 {
155 blit_sprite_hv(surface, x, y, font, sprite_id, hue, value);
156
157 x += sprite(font, sprite_id)->width + 1;
158 }
159 break;
160 }
161 }
162 }
163
164 /**
165 * \brief Draws blended text in a color specified by hue and value.
166 *
167 * Corresponds to blit_sprite_hv_blend()
168 *
169 * \li like JE_outTextModify()
170 *
171 * @param surface destination surface
172 * @param x initial x-position in pixels; which direction(s) the text is drawn
173 * from this position depends on the alignment
174 * @param y initial upper y-position in pixels
175 * @param text text to be drawn
176 * @param font style/size of text
177 * @param alignment left_aligned, centered, or right_aligned
178 * @param hue hue component of text color
179 * @param value value component of text color
180 */
draw_font_hv_blend(SDL_Surface * surface,int x,int y,const char * text,Font font,FontAlignment alignment,Uint8 hue,Sint8 value)181 void draw_font_hv_blend( SDL_Surface *surface, int x, int y, const char *text, Font font, FontAlignment alignment, Uint8 hue, Sint8 value )
182 {
183 switch (alignment)
184 {
185 case left_aligned:
186 break;
187 case centered:
188 x -= JE_textWidth(text, font) / 2;
189 break;
190 case right_aligned:
191 x -= JE_textWidth(text, font);
192 break;
193 }
194
195 for (; *text != '\0'; ++text)
196 {
197 int sprite_id = font_ascii[(unsigned char)*text];
198
199 switch (*text)
200 {
201 case ' ':
202 x += 6;
203 break;
204
205 case '~':
206 break;
207
208 default:
209 if (sprite_id != -1 && sprite_exists(font, sprite_id))
210 {
211 blit_sprite_hv_blend(surface, x, y, font, sprite_id, hue, value);
212
213 x += sprite(font, sprite_id)->width + 1;
214 }
215 break;
216 }
217 }
218 }
219
220 /**
221 * \brief Draws darkened text.
222 *
223 * Corresponds to blit_sprite_dark()
224 *
225 * \li like JE_outText() with (brightness < 0) if (black == true)
226 *
227 * @param surface destination surface
228 * @param x initial x-position in pixels; which direction(s) the text is drawn
229 * from this position depends on the alignment
230 * @param y initial upper y-position in pixels
231 * @param text text to be drawn
232 * @param font style/size of text
233 * @param alignment left_aligned, centered, or right_aligned
234 * @param black if true text is drawn as solid black, if false text is drawn by
235 * darkening the pixels of the destination surface
236 */
draw_font_dark(SDL_Surface * surface,int x,int y,const char * text,Font font,FontAlignment alignment,bool black)237 void draw_font_dark( SDL_Surface *surface, int x, int y, const char *text, Font font, FontAlignment alignment, bool black )
238 {
239 switch (alignment)
240 {
241 case left_aligned:
242 break;
243 case centered:
244 x -= JE_textWidth(text, font) / 2;
245 break;
246 case right_aligned:
247 x -= JE_textWidth(text, font);
248 break;
249 }
250
251 for (; *text != '\0'; ++text)
252 {
253 int sprite_id = font_ascii[(unsigned char)*text];
254
255 switch (*text)
256 {
257 case ' ':
258 x += 6;
259 break;
260
261 case '~':
262 break;
263
264 default:
265 if (sprite_id != -1 && sprite_exists(font, sprite_id))
266 {
267 blit_sprite_dark(surface, x, y, font, sprite_id, black);
268
269 x += sprite(font, sprite_id)->width + 1;
270 }
271 break;
272 }
273 }
274 }
275