1 /*
2 showfont: An example of using the SDL_ttf library with 2D graphics.
3 Copyright (C) 2001-2018 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20 */
21
22 /* A simple program to test the text rendering feature of the TTF library */
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27
28 #include "SDL.h"
29 #include "SDL_ttf.h"
30
31 #define DEFAULT_PTSIZE 18
32 #define DEFAULT_TEXT "The quick brown fox jumped over the lazy dog"
33 #define NUM_COLORS 256
34 #define WIDTH 640
35 #define HEIGHT 480
36
37 static char *Usage =
38 "Usage: %s [-solid] [-shaded] [-blended] [-utf8|-unicode] [-b] [-i] [-u] [-s] [-outline size] [-hintlight|-hintmono|-hintnone] [-nokerning] [-fgcol r,g,b,a] [-bgcol r,g,b,a] <font>.ttf [ptsize] [text]\n";
39
40 typedef enum
41 {
42 TextRenderSolid,
43 TextRenderShaded,
44 TextRenderBlended
45 } TextRenderMethod;
46
47 typedef struct {
48 SDL_Texture *caption;
49 SDL_Rect captionRect;
50 SDL_Texture *message;
51 SDL_Rect messageRect;
52 } Scene;
53
draw_scene(SDL_Renderer * renderer,Scene * scene)54 static void draw_scene(SDL_Renderer *renderer, Scene *scene)
55 {
56 /* Clear the background to background color */
57 SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
58 SDL_RenderClear(renderer);
59
60 SDL_RenderCopy(renderer, scene->caption, NULL, &scene->captionRect);
61 SDL_RenderCopy(renderer, scene->message, NULL, &scene->messageRect);
62 SDL_RenderPresent(renderer);
63 }
64
cleanup(int exitcode)65 static void cleanup(int exitcode)
66 {
67 TTF_Quit();
68 SDL_Quit();
69 exit(exitcode);
70 }
71
main(int argc,char * argv[])72 int main(int argc, char *argv[])
73 {
74 char *argv0 = argv[0];
75 SDL_Window *window;
76 SDL_Renderer *renderer;
77 TTF_Font *font;
78 SDL_Surface *text;
79 Scene scene;
80 int ptsize;
81 int i, done;
82 SDL_Color white = { 0xFF, 0xFF, 0xFF, 0 };
83 SDL_Color black = { 0x00, 0x00, 0x00, 0 };
84 SDL_Color *forecol;
85 SDL_Color *backcol;
86 SDL_Event event;
87 TextRenderMethod rendermethod;
88 int renderstyle;
89 int outline;
90 int hinting;
91 int kerning;
92 int dump;
93 enum {
94 RENDER_LATIN1,
95 RENDER_UTF8,
96 RENDER_UNICODE
97 } rendertype;
98 char *message, string[128];
99
100 /* Look for special execution mode */
101 dump = 0;
102 /* Look for special rendering types */
103 rendermethod = TextRenderShaded;
104 renderstyle = TTF_STYLE_NORMAL;
105 rendertype = RENDER_LATIN1;
106 outline = 0;
107 hinting = TTF_HINTING_NORMAL;
108 kerning = 1;
109 /* Default is black and white */
110 forecol = &black;
111 backcol = &white;
112 for (i=1; argv[i] && argv[i][0] == '-'; ++i) {
113 if (strcmp(argv[i], "-solid") == 0) {
114 rendermethod = TextRenderSolid;
115 } else
116 if (strcmp(argv[i], "-shaded") == 0) {
117 rendermethod = TextRenderShaded;
118 } else
119 if (strcmp(argv[i], "-blended") == 0) {
120 rendermethod = TextRenderBlended;
121 } else
122 if (strcmp(argv[i], "-utf8") == 0) {
123 rendertype = RENDER_UTF8;
124 } else
125 if (strcmp(argv[i], "-unicode") == 0) {
126 rendertype = RENDER_UNICODE;
127 } else
128 if (strcmp(argv[i], "-b") == 0) {
129 renderstyle |= TTF_STYLE_BOLD;
130 } else
131 if (strcmp(argv[i], "-i") == 0) {
132 renderstyle |= TTF_STYLE_ITALIC;
133 } else
134 if (strcmp(argv[i], "-u") == 0) {
135 renderstyle |= TTF_STYLE_UNDERLINE;
136 } else
137 if (strcmp(argv[i], "-s") == 0) {
138 renderstyle |= TTF_STYLE_STRIKETHROUGH;
139 } else
140 if (strcmp(argv[i], "-outline") == 0) {
141 if (sscanf (argv[++i], "%d", &outline) != 1) {
142 fprintf(stderr, Usage, argv0);
143 return(1);
144 }
145 } else
146 if (strcmp(argv[i], "-hintlight") == 0) {
147 hinting = TTF_HINTING_LIGHT;
148 } else
149 if (strcmp(argv[i], "-hintmono") == 0) {
150 hinting = TTF_HINTING_MONO;
151 } else
152 if (strcmp(argv[i], "-hintnone") == 0) {
153 hinting = TTF_HINTING_NONE;
154 } else
155 if (strcmp(argv[i], "-nokerning") == 0) {
156 kerning = 0;
157 } else
158 if (strcmp(argv[i], "-dump") == 0) {
159 dump = 1;
160 } else
161 if (strcmp(argv[i], "-fgcol") == 0) {
162 int r, g, b, a = 0xFF;
163 if (sscanf (argv[++i], "%d,%d,%d,%d", &r, &g, &b, &a) < 3) {
164 fprintf(stderr, Usage, argv0);
165 return(1);
166 }
167 forecol->r = (Uint8)r;
168 forecol->g = (Uint8)g;
169 forecol->b = (Uint8)b;
170 forecol->a = (Uint8)a;
171 } else
172 if (strcmp(argv[i], "-bgcol") == 0) {
173 int r, g, b, a = 0xFF;
174 if (sscanf (argv[++i], "%d,%d,%d,%d", &r, &g, &b, &a) < 3) {
175 fprintf(stderr, Usage, argv0);
176 return(1);
177 }
178 backcol->r = (Uint8)r;
179 backcol->g = (Uint8)g;
180 backcol->b = (Uint8)b;
181 backcol->a = (Uint8)a;
182 } else {
183 fprintf(stderr, Usage, argv0);
184 return(1);
185 }
186 }
187 argv += i;
188 argc -= i;
189
190 /* Check usage */
191 if (!argv[0]) {
192 fprintf(stderr, Usage, argv0);
193 return(1);
194 }
195
196 /* Initialize the TTF library */
197 if (TTF_Init() < 0) {
198 fprintf(stderr, "Couldn't initialize TTF: %s\n",SDL_GetError());
199 SDL_Quit();
200 return(2);
201 }
202
203 /* Open the font file with the requested point size */
204 ptsize = 0;
205 if (argc > 1) {
206 ptsize = atoi(argv[1]);
207 }
208 if (ptsize == 0) {
209 i = 2;
210 ptsize = DEFAULT_PTSIZE;
211 } else {
212 i = 3;
213 }
214 font = TTF_OpenFont(argv[0], ptsize);
215 if (font == NULL) {
216 fprintf(stderr, "Couldn't load %d pt font from %s: %s\n",
217 ptsize, argv[0], SDL_GetError());
218 cleanup(2);
219 }
220 TTF_SetFontStyle(font, renderstyle);
221 TTF_SetFontOutline(font, outline);
222 TTF_SetFontKerning(font, kerning);
223 TTF_SetFontHinting(font, hinting);
224
225 if(dump) {
226 for(i = 48; i < 123; i++) {
227 SDL_Surface* glyph = NULL;
228
229 glyph = TTF_RenderGlyph_Shaded(font, i, *forecol, *backcol);
230
231 if(glyph) {
232 char outname[64];
233 SDL_snprintf(outname, sizeof(outname), "glyph-%d.bmp", i);
234 SDL_SaveBMP(glyph, outname);
235 }
236
237 }
238 cleanup(0);
239 }
240
241 /* Create a window */
242 if (SDL_CreateWindowAndRenderer(WIDTH, HEIGHT, 0, &window, &renderer) < 0) {
243 fprintf(stderr, "SDL_CreateWindowAndRenderer() failed: %s\n", SDL_GetError());
244 cleanup(2);
245 }
246
247 /* Show which font file we're looking at */
248 SDL_snprintf(string, sizeof(string), "Font file: %s", argv[0]); /* possible overflow */
249 switch (rendermethod) {
250 case TextRenderSolid:
251 text = TTF_RenderText_Solid(font, string, *forecol);
252 break;
253 case TextRenderShaded:
254 text = TTF_RenderText_Shaded(font, string, *forecol, *backcol);
255 break;
256 case TextRenderBlended:
257 text = TTF_RenderText_Blended(font, string, *forecol);
258 break;
259 }
260 if (text != NULL) {
261 scene.captionRect.x = 4;
262 scene.captionRect.y = 4;
263 scene.captionRect.w = text->w;
264 scene.captionRect.h = text->h;
265 scene.caption = SDL_CreateTextureFromSurface(renderer, text);
266 SDL_FreeSurface(text);
267 }
268
269 /* Render and center the message */
270 if (argc > 2) {
271 message = argv[2];
272 } else {
273 message = DEFAULT_TEXT;
274 }
275 switch (rendertype) {
276 case RENDER_LATIN1:
277 switch (rendermethod) {
278 case TextRenderSolid:
279 text = TTF_RenderText_Solid(font, message, *forecol);
280 break;
281 case TextRenderShaded:
282 text = TTF_RenderText_Shaded(font, message, *forecol, *backcol);
283 break;
284 case TextRenderBlended:
285 text = TTF_RenderText_Blended(font, message, *forecol);
286 break;
287 }
288 break;
289
290 case RENDER_UTF8:
291 switch (rendermethod) {
292 case TextRenderSolid:
293 text = TTF_RenderUTF8_Solid(font, message, *forecol);
294 break;
295 case TextRenderShaded:
296 text = TTF_RenderUTF8_Shaded(font, message, *forecol, *backcol);
297 break;
298 case TextRenderBlended:
299 text = TTF_RenderUTF8_Blended(font, message, *forecol);
300 break;
301 }
302 break;
303
304 case RENDER_UNICODE:
305 {
306 Uint16 *unicode_text = SDL_iconv_utf8_ucs2(message);
307 switch (rendermethod) {
308 case TextRenderSolid:
309 text = TTF_RenderUNICODE_Solid(font, unicode_text, *forecol);
310 break;
311 case TextRenderShaded:
312 text = TTF_RenderUNICODE_Shaded(font, unicode_text, *forecol, *backcol);
313 break;
314 case TextRenderBlended:
315 text = TTF_RenderUNICODE_Blended(font, unicode_text, *forecol);
316 break;
317 }
318 SDL_free(unicode_text);
319 }
320 break;
321
322 default:
323 text = NULL; /* This shouldn't happen */
324 break;
325 }
326 if (text == NULL) {
327 fprintf(stderr, "Couldn't render text: %s\n", SDL_GetError());
328 TTF_CloseFont(font);
329 cleanup(2);
330 }
331 scene.messageRect.x = (WIDTH - text->w)/2;
332 scene.messageRect.y = (HEIGHT - text->h)/2;
333 scene.messageRect.w = text->w;
334 scene.messageRect.h = text->h;
335 scene.message = SDL_CreateTextureFromSurface(renderer, text);
336 printf("Font is generally %d big, and string is %d big\n",
337 TTF_FontHeight(font), text->h);
338
339 draw_scene(renderer, &scene);
340
341 /* Wait for a keystroke, and blit text on mouse press */
342 done = 0;
343 while (!done) {
344 if (SDL_WaitEvent(&event) < 0) {
345 fprintf(stderr, "SDL_PullEvent() error: %s\n",
346 SDL_GetError());
347 done = 1;
348 continue;
349 }
350 switch (event.type) {
351 case SDL_MOUSEBUTTONDOWN:
352 scene.messageRect.x = event.button.x - text->w/2;
353 scene.messageRect.y = event.button.y - text->h/2;
354 scene.messageRect.w = text->w;
355 scene.messageRect.h = text->h;
356 draw_scene(renderer, &scene);
357 break;
358
359 case SDL_KEYDOWN:
360 case SDL_QUIT:
361 done = 1;
362 break;
363 default:
364 break;
365 }
366 }
367 SDL_FreeSurface(text);
368 TTF_CloseFont(font);
369 SDL_DestroyTexture(scene.caption);
370 SDL_DestroyTexture(scene.message);
371 cleanup(0);
372
373 /* Not reached, but fixes compiler warnings */
374 return 0;
375 }
376
377 /* vi: set ts=4 sw=4 expandtab: */
378