AllegroGL: aglf.c Source File

AllegroGL 0.4.4

- Main Page
- Related Pages
- Modules
- Files

- File List
- Globals

aglf.c
Go to the documentation of this file.
1 /* This code is (C) AllegroGL contributors, and double licensed under
2 * the GPL and zlib licenses. See gpl.txt or zlib.txt for details.
3 */
8 #include <math.h>
9 #include <string.h>
10 #include <stdio.h>
11
12 #include "allegro.h"
13
14 #include "alleggl.h"
15 #include "allglint.h"
16
17 #ifdef ALLEGRO_MACOSX
18 #include <OpenGL/glu.h>
19 #else
20 #include <GL/glu.h>
21 #endif
22
23 #if defined ALLEGRO_WITH_XWINDOWS && !defined ALLEGROGL_GENERIC_DRIVER
24 #include <xalleg.h>
25 #include <GL/glx.h>
26 #endif
27
28 #define PREFIX_E "agl-font ERROR: "
29
30
31
32 static int aglf_font_generation_mode = AGL_FONT_POLYGONS;
33
34
35 /* find_range:
36 * Searches a font for a specific character.
37 */
38 static AL_CONST FONT_AGL_DATA *find_range(AL_CONST FONT_AGL_DATA *f, int c) {
39
40 while (f) {
41 if ((c >= f->start) && (c < f->end))
42 return f;
43
44 f = f->next;
45 }
46
47 return NULL;
48 }
49
50
51
52 /* allegro_gl_printf(FONT *f, float x, float y, float z, int color,
53 char *format, ...) */
67 int allegro_gl_printf(AL_CONST FONT *f, float x, float y, float z, int color,
68 AL_CONST char *format, ...) {
69
70 #define BUF_SIZE 1024
71 char buf[BUF_SIZE];
72 va_list ap;
73
74 if (!__allegro_gl_valid_context)
75 return 0;
76
77 /* Get the string */
78 va_start(ap, format);
79 uvszprintf(buf, BUF_SIZE, format, ap);
80 va_end(ap);
81
82 #undef BUF_SIZE
83
84 /* Set color */
85 {
86 GLubyte c[4];
87 c[0] = (GLubyte)getr(color);
88 c[1] = (GLubyte)getg(color);
89 c[2] = (GLubyte)getb(color);
90 c[3] = (__allegro_gl_use_alpha && bitmap_color_depth(screen) == 32)
91 ? (GLubyte)geta(color) : 255;
92
93 glColor4ubv(c);
94 }
95
96 return allegro_gl_printf_ex(f, x, y, z, buf);
97 }
98
99
100
101 /* allegro_gl_printf_ex(FONT *f, float x, float y, float z,
102 * char *format, ...)
103 */
169 int allegro_gl_printf_ex(AL_CONST FONT *f, float x, float y, float z,
170 AL_CONST char *format, ...) {
171 #define BUF_SIZE 1024
172 char buf[BUF_SIZE];
173 va_list ap;
174
175 AL_CONST FONT_AGL_DATA *range = NULL;
176 int c, pos = 0;
177 int count = 0;
178 AL_CONST FONT_AGL_DATA *d;
179 GLint vert_order, cull_mode;
180 GLint matrix_mode;
181
182 int restore_rasterpos = 0;
183 GLuint old_texture_bind = 0;
184 GLfloat old_raster_pos[4];
185
186
187 if (!__allegro_gl_valid_context)
188 return 0;
189
190 /* Check arguments */
191 if (!format || !f) {
192 TRACE(PREFIX_E "agl_printf: Null parameter\n");
193 return 0;
194 }
195
196 if (f->vtable != font_vtable_agl) {
197 TRACE(PREFIX_E "agl_printf: Font parameter isn't of the AGL "
198 "type.\n");
199 return 0;
200 }
201
202 d = (AL_CONST FONT_AGL_DATA*)f->data;
203
204 /* Get the string */
205 va_start(ap, format);
206 uvszprintf(buf, BUF_SIZE, format, ap);
207 va_end(ap);
208
209 #undef BUF_SIZE
210
211 glGetIntegerv(GL_MATRIX_MODE, &matrix_mode);
212 glGetIntegerv(GL_FRONT_FACE, &vert_order);
213 glGetIntegerv(GL_CULL_FACE_MODE, &cull_mode);
214
215 glMatrixMode(GL_MODELVIEW);
216 glPushMatrix();
217
218 glFrontFace(GL_CW);
219 glCullFace(GL_BACK);
220
221 { GLint temp;
222 glGetIntegerv(GL_TEXTURE_BINDING_2D, &temp);
223 old_texture_bind = (GLuint)temp;
224 }
225
226 if (d->type == AGL_FONT_TYPE_BITMAP) {
227 glTranslatef(0, 0, -1);
228 glBindTexture(GL_TEXTURE_2D, 0);
229
230 glGetFloatv(GL_CURRENT_RASTER_POSITION, old_raster_pos);
231 glRasterPos2f(x, y);
232 restore_rasterpos = 1;
233 }
234 else if (d->type == AGL_FONT_TYPE_OUTLINE) {
235 glTranslatef(x, y, z);
236 glBindTexture(GL_TEXTURE_2D, 0);
237 }
238 else if (d->type == AGL_FONT_TYPE_TEXTURED) {
239 glTranslatef(x, y, z);
240 }
241
242
243 while ((c = ugetc(buf + pos)) != 0) {
244
245 pos += ucwidth(c);
246
247 if ((!range) || (c < range->start) || (c >= range->end)) {
248 /* search for a suitable character range */
249 range = find_range(d, c);
250
251 if (!range) {
252 range = find_range(d, (c = '^'));
253
254 if (!range)
255 continue;
256 }
257 }
258
259 /* Set up texture */
260 if (d->type == AGL_FONT_TYPE_TEXTURED) {
261 glBindTexture(GL_TEXTURE_2D, range->texture);
262 }
263
264 /* draw the character */
265 c -= range->start;
266 c += range->list_base;
267
268 glCallList(c);
269
270 count++;
271 }
272
273 glPopMatrix();
274
275 glMatrixMode(matrix_mode);
276 glFrontFace(vert_order);
277 glCullFace(cull_mode);
278
279 glBindTexture(GL_TEXTURE_2D, old_texture_bind);
280
281 if (restore_rasterpos) {
282 glRasterPos4fv(old_raster_pos);
283 }
284
285 return count;
286 }
287
288
289
290 #ifndef ALLEGROGL_GENERIC_DRIVER
291 #ifdef ALLEGRO_WINDOWS
292
293 static FONT *win_load_system_font(char *name, int type, int style, int w, int h, float depth, int start, int end) {
294
295 HFONT hFont;
296
297 FONT_AGL_DATA *data;
298 FONT *ret;
299
300 ret = malloc(sizeof(FONT));
301 if (!ret) {
302 TRACE(PREFIX_E "win_load_system_font: Ran out of memory "
303 "while allocating %i bytes\n", sizeof(FONT));
304 return NULL;
305 }
306 data = malloc(sizeof(FONT_AGL_DATA));
307 if (!data) {
308 free(ret);
309 TRACE(PREFIX_E "win_load_system_font: Ran out of memory "
310 "while allocating %i bytes\n", sizeof(FONT_AGL_DATA));
311 return NULL;
312 }
313 ret->vtable = font_vtable_agl;
314 ret->data = data;
315
316 data->list_base = glGenLists(end - start);
317 data->start = start;
318 data->end = end;
319 data->next = NULL;
320 data->is_free_chunk = 0;
321
322 if (type == AGL_FONT_TYPE_BITMAP || type == AGL_FONT_TYPE_DONT_CARE) {
323
324 HDC dc;
325
326 hFont = CreateFont( -h, w,
327 0, 0,
328 (style & AGL_FONT_STYLE_BOLD) ? FW_BOLD
329 : ((style & AGL_FONT_STYLE_BLACK) ? FW_BLACK : FW_NORMAL),
330 ((style & AGL_FONT_STYLE_ITALIC) ? TRUE : FALSE),
331 ((style & AGL_FONT_STYLE_UNDERLINE) ? TRUE : FALSE),
332 ((style & AGL_FONT_STYLE_STRIKEOUT) ? TRUE : FALSE),
333 ANSI_CHARSET,
334 OUT_TT_PRECIS,
335 CLIP_DEFAULT_PRECIS,
336 (style & AGL_FONT_STYLE_ANTI_ALIASED) ? ANTIALIASED_QUALITY
337 : DEFAULT_QUALITY,
338 FF_DONTCARE | DEFAULT_PITCH,
339 name);
340
341 dc = GetDC(win_get_window());
342
343 SelectObject(dc, hFont);
344
345 wglUseFontBitmaps(dc, start, end - start, data->list_base);
346 data->type = AGL_FONT_TYPE_BITMAP;
347 data->data = NULL;
348 }
349 else if (type == AGL_FONT_TYPE_OUTLINE) {
350 HDC dc;
351
352 GLYPHMETRICSFLOAT *gmf;
353 gmf = malloc(sizeof(GLYPHMETRICSFLOAT) * (end - start));
354 memset(gmf, 0, sizeof(GLYPHMETRICSFLOAT) * (end - start));
355
356 hFont = CreateFont( -h, w,
357 0, 0,
358 (style & AGL_FONT_STYLE_BOLD) ? FW_BOLD
359 : ((style & AGL_FONT_STYLE_BLACK) ? FW_BLACK : FW_NORMAL),
360 ((style & AGL_FONT_STYLE_ITALIC) ? TRUE : FALSE),
361 ((style & AGL_FONT_STYLE_UNDERLINE) ? TRUE : FALSE),
362 ((style & AGL_FONT_STYLE_STRIKEOUT) ? TRUE : FALSE),
363 ANSI_CHARSET,
364 OUT_TT_PRECIS,
365 CLIP_DEFAULT_PRECIS,
366 (style & AGL_FONT_STYLE_ANTI_ALIASED) ? ANTIALIASED_QUALITY
367 : DEFAULT_QUALITY,
368 FF_DONTCARE | DEFAULT_PITCH,
369 name);
370
371 dc = GetDC(win_get_window());
372
373 SelectObject(dc, hFont);
374 wglUseFontOutlines(dc, start, end - start, data->list_base,
375 0.0, depth, (aglf_font_generation_mode == AGL_FONT_POLYGONS)
376 ? WGL_FONT_POLYGONS : WGL_FONT_LINES, gmf);
377
378 data->type = AGL_FONT_TYPE_OUTLINE;
379 data->data = gmf;
380 }
381
382 return ret;
383 }
384 #endif
385
386
387
388 #ifdef ALLEGRO_WITH_XWINDOWS
389 static FONT *x_load_system_font(char *name, int type, int style, int w, int h,
390 float depth, int start, int end) {
391 FONT_AGL_DATA *data;
392 FONT *ret;
393 XFontStruct *xfont;
394
395 ret = malloc(sizeof(FONT));
396 if (!ret) {
397 TRACE(PREFIX_E "x_load_system_font: Ran out of memory "
398 "while allocating %zi bytes\n", sizeof(FONT));
399 return NULL;
400 }
401 data = malloc(sizeof(FONT_AGL_DATA));
402 if (!data) {
403 free(ret);
404 TRACE(PREFIX_E "x_load_system_font: Ran out of memory "
405 "while allocating %zi bytes\n", sizeof(FONT_AGL_DATA));
406 return NULL;
407 }
408 ret->vtable = font_vtable_agl;
409 ret->data = data;
410
411 data->list_base = glGenLists(end - start);
412 data->start = start;
413 data->end = end;
414 data->next = NULL;
415 data->is_free_chunk = 0;
416
417 if (type == AGL_FONT_TYPE_BITMAP || type == AGL_FONT_TYPE_DONT_CARE) {
418 char buf[256], major_type[256], minor_type[2];
419
420 usprintf(major_type, "medium");
421 if (style & AGL_FONT_STYLE_BOLD)
422 usprintf(major_type, "bold");
423 minor_type[0] = (style & AGL_FONT_STYLE_ITALIC) ? 'i' : 'r';
424 minor_type[1] = '\0';
425
426 usprintf(buf, "-*-%s-%s-%s-normal-*-%i-*-*-*-*-*-*-*", name,
427 major_type, minor_type, h);
428 /* Load the font */
429 xfont = XLoadQueryFont(_xwin.display, buf);
430 if (!xfont) {
431 free(ret);
432 free(data);
433 TRACE(PREFIX_E "x_load_system_font: Failed to load "
434 "%s\n", buf);
435 return NULL;
436 }
437 glXUseXFont(xfont->fid, start, end - start, data->list_base);
438 data->type = AGL_FONT_TYPE_BITMAP;
439 data->data = NULL;
440 XFreeFont(_xwin.display, xfont);
441 }
442 else {
443 /* Not Yet Implemented */
444 return NULL;
445 }
446
447 return ret;
448 }
449 #endif
450 #endif /* ALLEGROGL_GENERIC_DRIVER */
451
452
453
454 /* void allegro_gl_set_font_generation_mode(int mode) */
469 void allegro_gl_set_font_generation_mode(int mode) {
470 aglf_font_generation_mode = mode;
471 return;
472 }
473
474
475
476 /* FONT *allegro_gl_load_system_font(char *name, int style, int w, int h) */
485 FONT *allegro_gl_load_system_font(char *name, int style, int w, int h) {
486
487 return allegro_gl_load_system_font_ex(name, AGL_FONT_TYPE_OUTLINE,
488 style, w, h, 0.0f, 32, 256);
489 }
490
491
492
493 /* FONT *allegro_gl_load_system_font_ex(char *name, int type, int style,
494 int w, int h, float depth, int start, int end) */
526 FONT *allegro_gl_load_system_font_ex(char *name, int type, int style,
527 int w, int h, float depth, int start, int end) {
528
529 FONT *ret = NULL;
530
531 if (!__allegro_gl_valid_context)
532 return NULL;
533
534 if (!name) {
535 TRACE(PREFIX_E "load_system_font: Nameless font\n");
536 return NULL;
537 }
538
539 /* Load a system font */
540
541 #ifndef ALLEGROGL_GENERIC_DRIVER
542 #ifdef ALLEGRO_WINDOWS
543 ret = win_load_system_font(name, type, style, w, h, depth, start, end);
544 #elif defined ALLEGRO_UNIX
545 XLOCK();
546 ret = x_load_system_font(name, type, style, w, h, depth, start, end);
547 XUNLOCK();
548 #else
549 /* Other platform */
550 #endif
551 #endif
552
553 return ret;
554 }
555
556
557
573 void allegro_gl_destroy_font(FONT *f) {
574
575 FONT_AGL_DATA *data;
576
577 if (!f) {
578 return;
579 }
580 if (f->vtable != font_vtable_agl) {
581 TRACE(PREFIX_E "destroy_font: Font is not of AGL type\n");
582 return;
583 }
584
585 data = f->data;
586
587 if (!data) {
588 TRACE(PREFIX_E "destroy_font: Font is inconsistent\n");
589 return;
590 }
591
592 /* Iterate through every segment of the font */
593 while (data) {
594 FONT_AGL_DATA *datanext;
595
596 /* Release all resources taken up by this font */
597 if (data->type == AGL_FONT_TYPE_BITMAP
598 || data->type == AGL_FONT_TYPE_OUTLINE
599 || data->type == AGL_FONT_TYPE_TEXTURED) {
600
601 if (__allegro_gl_valid_context) {
602 if (data->list_base)
603 glDeleteLists(data->list_base, data->end - data->start);
604 if (data->texture)
605 glDeleteTextures(1, &data->texture);
606 }
607 }
608 if (data->type == AGL_FONT_TYPE_OUTLINE) {
609 if (data->data)
610 free(data->data);
611 }
612 else if (data->type == AGL_FONT_TYPE_TEXTURED) {
613 if (data->data)
614 destroy_bitmap(data->data);
615 if (data->glyph_coords)
616 free(data->glyph_coords);
617 }
618 else if (data->type == AGL_FONT_TYPE_BITMAP) {
619 if (data->data) {
620 int i;
621 FONT_GLYPH **gl = data->data;
622 for (i = 0; i < data->end - data->start; i++) {
623 if (gl[i])
624 free(gl[i]);
625 }
626 free(gl);
627 }
628 }
629 datanext = data->next;
630
631 if (data->is_free_chunk)
632 free(data);
633
634 data = datanext;
635 }
636 free(f->data);
637
638 if (f != font)
639 free(f);
640
641 return;
642 }
643
644
645
646 /* size_t allegro_gl_list_font_textures(FONT *f, GLuint *ids, size_t max_num_id) */
689 size_t allegro_gl_list_font_textures(FONT *f, GLuint *ids, size_t max_num_id) {
690
691 size_t num_ids = 0;
692 FONT_AGL_DATA *data;
693
694 if (!f) {
695 return 0;
696 }
697 if (f->vtable != font_vtable_agl) {
698 TRACE(PREFIX_E "list_font_textures: Font is not of AGL type\n");
699 return 0;
700 }
701
702 data = f->data;
703
704 if (!data) {
705 TRACE(PREFIX_E "list_font_textures: Font is inconsistent\n");
706 return 0;
707 }
708
709 if (!__allegro_gl_valid_context) {
710 return 0;
711 }
712
713 /* Iterate through all font segments */
714 while (data) {
715 if (data->texture) {
716 /* Add the texture ID in the array, if it's not NULL and if there
717 * is room.
718 */
719 if (ids && num_ids < max_num_id) {
720 ids[num_ids] = data->texture;
721 }
722 num_ids++;
723 }
724
725 data = data->next;
726 }
727
728 return num_ids;
729 }
730
AGL_FONT_STYLE_STRIKEOUT
#define AGL_FONT_STYLE_STRIKEOUT
Creates a font with striked out characters.
Definition: alleggl.h:684
allegro_gl_printf_ex
int allegro_gl_printf_ex(AL_CONST FONT *f, float x, float y, float z, AL_CONST char *format,...)
Prints a formatted string (printf style) on the screen.
Definition: aglf.c:169
AGL_FONT_STYLE_BOLD
#define AGL_FONT_STYLE_BOLD
Creates a font with bold characters.
Definition: alleggl.h:664
allegro_gl_set_font_generation_mode
void allegro_gl_set_font_generation_mode(int mode)
Set the font generation mode for system fonts.
Definition: aglf.c:469
allegro_gl_load_system_font_ex
FONT * allegro_gl_load_system_font_ex(char *name, int type, int style, int w, int h, float depth, int start, int end)
Loads a system font.
Definition: aglf.c:526
allegro_gl_destroy_font
void allegro_gl_destroy_font(FONT *f)
void allegro_gl_destroy_font(FONT *usefont)
Definition: aglf.c:573
AGL_FONT_STYLE_UNDERLINE
#define AGL_FONT_STYLE_UNDERLINE
Creates a font with underlined characters.
Definition: alleggl.h:679
allegro_gl_list_font_textures
size_t allegro_gl_list_font_textures(FONT *f, GLuint *ids, size_t max_num_id)
List the texture ID of all textures forming the specified font.
Definition: aglf.c:689
AGL_FONT_TYPE_TEXTURED
#define AGL_FONT_TYPE_TEXTURED
Indicates that you want fonts to be converted to a texture format.
Definition: alleggl.h:656
allegro_gl_load_system_font
FONT * allegro_gl_load_system_font(char *name, int style, int w, int h)
Short hand for aglf_load_system_font_ex(name, AGL_FONT_TYPE_OUTLINE, style, w, h, 0...
Definition: aglf.c:485
AGL_FONT_STYLE_BLACK
#define AGL_FONT_STYLE_BLACK
Creates a font with black (strong bold) characters.
Definition: alleggl.h:669
AGL_FONT_STYLE_ANTI_ALIASED
#define AGL_FONT_STYLE_ANTI_ALIASED
Creates a font with anti-aliased characters.
Definition: alleggl.h:691
AGL_FONT_STYLE_ITALIC
#define AGL_FONT_STYLE_ITALIC
Creates a font with italicized characters.
Definition: alleggl.h:674
AGL_FONT_TYPE_BITMAP
#define AGL_FONT_TYPE_BITMAP
Indicates that you want fonts to be converted to a bitmap format.
Definition: alleggl.h:632
AGL_FONT_TYPE_OUTLINE
#define AGL_FONT_TYPE_OUTLINE
Indicates that you want fonts to be converted to an outline format.
Definition: alleggl.h:644
alleggl.h
Main header file for AllegroGL.
AGL_FONT_TYPE_DONT_CARE
#define AGL_FONT_TYPE_DONT_CARE
Indicates that you don&#39;t really care how a font will be converted.
Definition: alleggl.h:621
AGL_FONT_POLYGONS
#define AGL_FONT_POLYGONS
Font generation mode.
Definition: alleggl.h:699
allegro_gl_printf
int allegro_gl_printf(AL_CONST FONT *f, float x, float y, float z, int color, AL_CONST char *format,...)
Equivalent to:
Definition: aglf.c:67