demos: Fix and cleanup GP_BackendInit() + docs.
[gfxprim/pasky.git] / demos / c_simple / fonttest.c
blobfb888e2f0a3a17ff32cc71db9388e8b49ebc2f01
1 /*****************************************************************************
2 * This file is part of gfxprim library. *
3 * *
4 * Gfxprim is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU Lesser General Public *
6 * License as published by the Free Software Foundation; either *
7 * version 2.1 of the License, or (at your option) any later version. *
8 * *
9 * Gfxprim 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 GNU *
12 * Lesser General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU Lesser General Public *
15 * License along with gfxprim; if not, write to the Free Software *
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
17 * Boston, MA 02110-1301 USA *
18 * *
19 * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
20 * <jiri.bluebear.dluhos@gmail.com> *
21 * *
22 * Copyright (C) 2009-2013 Cyril Hrubis <metan@ucw.cz> *
23 * *
24 *****************************************************************************/
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
30 #include <GP.h>
32 static GP_Backend *win;
34 static const char *font_path = NULL;
35 static unsigned int font_h = 16;
37 static GP_Pixel white_pixel, gray_pixel, dark_gray_pixel, black_pixel,
38 red_pixel, blue_pixel;
40 static const char *test_strings[] = {
41 " !\"#$%&\047()*+,-./0123456789:;<=>?@",
42 "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`",
43 "abcdefghijklmnopqrstuvwxyz{|}~",
44 "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor..."
47 static int font_flag = 0;
48 static int tracking = 0;
49 static GP_FontFace *font = NULL;
51 static const char *glyph_bitmap_format_name(const GP_FontBitmapFormat format)
53 switch (format) {
54 case GP_FONT_BITMAP_1BPP:
55 return "1BPP";
56 break;
57 case GP_FONT_BITMAP_8BPP:
58 return "8BPP";
59 break;
60 default:
61 return "Unknown";
65 static void print_character_metadata(const GP_FontFace *font, int c)
67 const GP_GlyphBitmap *glyph = GP_GetGlyphBitmap(font, c);
68 fprintf(stderr, "Properties of the character '%c':\n", c);
70 if (glyph) {
71 fprintf(stderr, " bitmap width: %d, height: %d\n",
72 glyph->width, glyph->height);
73 fprintf(stderr, " bearing_x: %d bearing_y %d\n",
74 glyph->bearing_x, glyph->bearing_y);
75 fprintf(stderr, " advance_x: %d\n",
76 glyph->advance_x);
77 } else {
78 fprintf(stderr, "(null)\n");
82 static void print_font_properties(const GP_FontFace *font)
84 fprintf(stderr, "Font '%s %s' properties:\n",
85 GP_FontFamily(font), GP_FontStyle(font));
86 fprintf(stderr, " Height: ascend: %d, descend: %d\n",
87 GP_FontAscend(font), GP_FontDescend(font));
88 fprintf(stderr, " Max advance_x: %u\n",
89 GP_FontMaxAdvanceX(font));
90 fprintf(stderr, " Glyph bitmap format: %s\n",
91 glyph_bitmap_format_name(font->glyph_bitmap_format));
92 fprintf(stderr, " Bounding box width: %d, heigth: %d\n",
93 GP_FontMaxWidth(font), GP_FontHeight(font));
95 print_character_metadata(font, 'a');
96 print_character_metadata(font, 'm');
97 print_character_metadata(font, '0');
100 #define SPACING 120
102 void redraw_screen(void)
104 GP_Fill(win->context, black_pixel);
106 GP_TextStyle style = GP_DEFAULT_TEXT_STYLE;
108 switch (font_flag) {
109 case 0:
110 style.font = &GP_DefaultProportionalFont;
111 break;
112 case 1:
113 style.font = &GP_DefaultConsoleFont;
114 break;
115 case 2:
116 style.font = GP_FontTiny;
117 break;
118 case 3:
119 style.font = GP_FontTinyMono;
120 break;
121 case 4:
122 style.font = GP_FontC64;
123 break;
124 case 5:
125 style.font = font;
126 break;
129 print_font_properties(style.font);
131 /* Text alignment (we are always drawing to the right
132 * and below the starting point).
134 int align = GP_ALIGN_RIGHT|GP_VALIGN_BELOW;
136 const size_t TEST_STRING_COUNT = sizeof(test_strings)/sizeof(const char *);
137 size_t i;
138 for (i = 0; i < TEST_STRING_COUNT; i++) {
139 const char *test_string = test_strings[i];
141 style.pixel_xmul = 1;
142 style.pixel_ymul = 1;
143 style.pixel_xspace = 0;
144 style.pixel_yspace = 0;
145 style.char_xspace = tracking;
147 GP_FillRectXYWH(win->context,
148 16, SPACING*i + 16,
149 GP_TextWidth(&style, test_string),
150 GP_FontHeight(style.font),
151 dark_gray_pixel);
153 GP_RectXYWH(win->context,
154 15, SPACING*i + 15,
155 GP_TextMaxWidth(&style, strlen(test_string)) + 1,
156 GP_FontHeight(style.font) + 1,
157 blue_pixel);
159 GP_Text(win->context, &style, 16, SPACING*i + 16, align,
160 white_pixel, dark_gray_pixel, test_string);
162 style.pixel_xmul = 2;
163 style.pixel_ymul = 2;
164 style.pixel_yspace = 1;
166 GP_Text(win->context, &style, 34, SPACING * i + 44, align,
167 white_pixel, black_pixel, test_string);
169 GP_RectXYWH(win->context, 33, SPACING * i + 43,
170 GP_TextWidth(&style, test_string) + 1,
171 GP_TextHeight(&style) + 1, dark_gray_pixel);
173 style.pixel_xmul = 4;
174 style.pixel_ymul = 2;
176 style.pixel_xspace = 1;
177 style.pixel_yspace = 1;
179 if (font_flag == 2 || font_flag == 3) {
180 style.pixel_xmul = 2;
181 style.pixel_ymul = 5;
183 style.pixel_xspace = 2;
184 style.pixel_yspace = 2;
187 GP_Text(win->context, &style, 64, SPACING*i + 88, align,
188 dark_gray_pixel, black_pixel, test_string);
192 void event_loop(void)
194 GP_Event ev;
196 for (;;) {
197 GP_BackendWaitEvent(win, &ev);
199 switch (ev.type) {
200 case GP_EV_KEY:
201 if (ev.code != GP_EV_KEY_DOWN)
202 continue;
204 switch (ev.val.key.key) {
205 case GP_KEY_SPACE:
206 if (font)
207 font_flag = (font_flag + 1) % 6;
208 else
209 font_flag = (font_flag + 1) % 5;
211 redraw_screen();
212 GP_BackendFlip(win);
213 break;
214 case GP_KEY_UP:
215 tracking++;
216 redraw_screen();
217 GP_BackendFlip(win);
218 break;
219 case GP_KEY_DOWN:
220 tracking--;
221 redraw_screen();
222 GP_BackendFlip(win);
223 break;
224 case GP_KEY_B:
225 font_h++;
226 if (font_path) {
227 GP_FontFaceFree(font);
228 font = GP_FontFaceLoad(font_path, 0, font_h);
229 redraw_screen();
230 GP_BackendFlip(win);
232 break;
233 case GP_KEY_S:
234 font_h--;
235 if (font_path) {
236 GP_FontFaceFree(font);
237 font = GP_FontFaceLoad(font_path, 0, font_h);
238 redraw_screen();
239 GP_BackendFlip(win);
241 break;
242 case GP_KEY_ESC:
243 GP_BackendExit(win);
244 exit(0);
245 break;
251 void print_instructions(void)
253 printf("Use the following keys to control the test:\n");
254 printf(" Esc ................. exit\n");
255 printf(" Space ............... change font\n");
256 printf(" up/down ............. increase/decrease tracking\n");
257 printf(" b/s ................. change font size (freetype only)\n");
260 int main(int argc, char *argv[])
262 const char *backend_opts = "X11";
264 print_instructions();
266 GP_SetDebugLevel(10);
268 if (argc > 1) {
269 font_path = argv[1];
270 fprintf(stderr, "\nLoading font '%s'\n", argv[1]);
271 font = GP_FontFaceLoad(argv[1], 0, font_h);
274 win = GP_BackendInit(backend_opts, "Font Test");
276 if (win == NULL) {
277 fprintf(stderr, "Failed to initalize backend '%s'\n",
278 backend_opts);
279 return 1;
282 white_pixel = GP_ColorToContextPixel(GP_COL_WHITE, win->context);
283 gray_pixel = GP_ColorToContextPixel(GP_COL_GRAY_LIGHT, win->context);
284 dark_gray_pixel = GP_ColorToContextPixel(GP_COL_GRAY_DARK, win->context);
285 black_pixel = GP_ColorToContextPixel(GP_COL_BLACK, win->context);
286 red_pixel = GP_ColorToContextPixel(GP_COL_RED, win->context);
287 blue_pixel = GP_ColorToContextPixel(GP_COL_BLUE, win->context);
289 redraw_screen();
290 GP_BackendFlip(win);
292 event_loop();
294 return 0;