1 /* glxfonts, Copyright (c) 2001-2006 Jamie Zawinski <jwz@jwz.org>
2 * Loads X11 fonts for use with OpenGL.
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation. No representations are made about the suitability of this
9 * software for any purpose. It is provided "as is" without express or
24 # include <OpenGL/gl.h>
25 # include <OpenGL/glu.h>
32 #include "resources.h"
35 /* These are in xlock-gl.c */
36 extern void clear_gl_error (void);
37 extern void check_gl_error (const char *type);
40 extern char *progname;
43 /* Loads the font named by the X resource "res".
44 Returns an XFontStruct.
45 Also converts the font to a set of GL lists and returns the first list.
48 load_font (Display *dpy, char *res, XFontStruct **font_ret, GLuint *dlist_ret)
52 const char *font = get_string_resource (dpy, res, "Font");
53 const char *def1 = "-*-times-bold-r-normal-*-180-*";
54 const char *def2 = "fixed";
58 if (!res || !*res) abort();
59 if (!font_ret && !dlist_ret) abort();
61 if (!font) font = def1;
63 f = XLoadQueryFont(dpy, font);
64 if (!f && !!strcmp (font, def1))
66 fprintf (stderr, "%s: unable to load font \"%s\", using \"%s\"\n",
67 progname, font, def1);
69 f = XLoadQueryFont(dpy, font);
72 if (!f && !!strcmp (font, def2))
74 fprintf (stderr, "%s: unable to load font \"%s\", using \"%s\"\n",
75 progname, font, def2);
77 f = XLoadQueryFont(dpy, font);
82 fprintf (stderr, "%s: unable to load fallback font \"%s\" either!\n",
88 first = f->min_char_or_byte2;
89 last = f->max_char_or_byte2;
92 # ifndef HAVE_COCOA /* Xlib version */
97 *dlist_ret = glGenLists ((GLuint) last+1);
98 check_gl_error ("glGenLists");
99 glXUseXFont(id, first, last-first+1, *dlist_ret + first);
100 check_gl_error ("glXUseXFont");
103 # else /* HAVE_COCOA */
106 int afid, face, size;
107 afid = jwxyz_font_info (id, &size, &face);
112 *dlist_ret = glGenLists ((GLuint) last+1);
113 check_gl_error ("glGenLists");
115 AGLContext ctx = aglGetCurrentContext();
116 if (! aglUseFont (ctx, afid, face, size,
117 first, last-first+1, *dlist_ret + first)) {
118 check_gl_error ("aglUseFont");
124 # endif /* HAVE_COCOA */
131 /* Width of the string in pixels.
134 string_width (XFontStruct *f, const char *c)
139 int cc = *((unsigned char *) c);
141 ? f->per_char[cc-f->min_char_or_byte2].rbearing
142 : f->min_bounds.rbearing);
149 /* Draws the string on the window at the given pixel position.
150 Newlines and tab stops are honored.
151 Any text inside [] will be rendered as a subscript.
152 Assumes the font has been loaded as with load_font().
155 print_gl_string (Display *dpy,
158 int window_width, int window_height,
159 GLfloat x, GLfloat y,
162 GLfloat line_height = font->ascent + font->descent;
163 GLfloat sub_shift = (line_height * 0.3);
164 int cw = string_width (font, "m");
169 glPushAttrib (GL_TRANSFORM_BIT | /* for matrix contents */
170 GL_ENABLE_BIT); /* for various glDisable calls */
171 glDisable (GL_LIGHTING);
172 glDisable (GL_DEPTH_TEST);
173 glDisable (GL_TEXTURE_2D);
175 glMatrixMode(GL_PROJECTION);
180 glMatrixMode(GL_MODELVIEW);
188 gluOrtho2D (0, window_width, 0, window_height);
190 glRasterPos2f (x, y);
191 for (i = 0; i < strlen(string); i++)
196 glRasterPos2f (x, (y -= line_height));
202 x2 = ((x2 + tabs) / tabs) * tabs; /* tab to tab stop */
204 glRasterPos2f (x2, y);
206 else if (c == '[' && (isdigit (string[i+1])))
209 glRasterPos2f (x2, (y -= sub_shift));
211 else if (c == ']' && sub_p)
214 glRasterPos2f (x2, (y += sub_shift));
218 glCallList (font_dlist + (int)(c));
219 x2 += (font->per_char
220 ? font->per_char[c - font->min_char_or_byte2].width
221 : font->min_bounds.width);
227 glMatrixMode(GL_PROJECTION);
232 glMatrixMode(GL_MODELVIEW);