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