49
/* Mostly lifted from the Mesa implementation of glXUseXFont(), since
50
Mac OS 10.6 no longer supports aglUseFont() which was their analog
51
of that. This code could be in libjwxyz instead, but we might as
52
well use the same text-drawing code on both X11 and Cocoa.
55
fill_bitmap (Display *dpy, Window win, GC gc,
56
unsigned int width, unsigned int height,
57
int x0, int y0, char c, GLubyte *bitmap)
63
pixmap = XCreatePixmap (dpy, win, 8*width, height, 1);
64
XSetForeground(dpy, gc, 0);
65
XFillRectangle (dpy, pixmap, gc, 0, 0, 8*width, height);
66
XSetForeground(dpy, gc, 1);
67
XDrawString (dpy, pixmap, gc, x0, y0, &c, 1);
69
image = XGetImage (dpy, pixmap, 0, 0, 8*width, height, 1, XYPixmap);
71
/* Fill the bitmap (X11 and OpenGL are upside down wrt each other). */
72
for (y = 0; y < height; y++)
73
for (x = 0; x < 8*width; x++)
74
if (XGetPixel (image, x, y))
75
bitmap[width*(height - y - 1) + x/8] |= (1 << (7 - (x % 8)));
77
XFreePixmap (dpy, pixmap);
78
XDestroyImage (image);
84
dump_bitmap (unsigned int width, unsigned int height, GLubyte *bitmap)
89
for (x = 0; x < 8*width; x++)
90
printf ("%o", 7 - (x % 8));
92
for (y = 0; y < height; y++)
95
for (x = 0; x < 8*width; x++)
96
putchar ((bitmap[width*(height - y - 1) + x/8] & (1 << (7 - (x % 8))))
99
for (x = 0; x < width; x++)
100
printf ("0x%02x, ", bitmap[width*(height - y - 1) + x]);
108
xscreensaver_glXUseXFont (Display *dpy, Font font,
109
int first, int count, int listbase)
111
Window win = RootWindowOfScreen (DefaultScreenOfDisplay (dpy));
115
unsigned long valuemask;
119
GLint swapbytes, lsbfirst, rowlength;
120
GLint skiprows, skippixels, alignment;
122
unsigned int max_width, max_height, max_bm_width, max_bm_height;
127
fs = XQueryFont (dpy, font);
130
/*gl_error (CC->gl_ctx, GL_INVALID_VALUE,
131
"Couldn't get font structure information");*/
136
/* Allocate a bitmap that can fit all characters. */
137
max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing;
138
max_height = fs->max_bounds.ascent + fs->max_bounds.descent;
139
max_bm_width = (max_width + 7) / 8;
140
max_bm_height = max_height;
142
bm = (GLubyte *) malloc ((max_bm_width * max_bm_height) * sizeof (GLubyte));
145
/*gl_error (CC->gl_ctx, GL_OUT_OF_MEMORY,
146
"Couldn't allocate bitmap in glXUseXFont()");*/
151
/* Save the current packing mode for bitmaps. */
152
glGetIntegerv (GL_UNPACK_SWAP_BYTES, &swapbytes);
153
glGetIntegerv (GL_UNPACK_LSB_FIRST, &lsbfirst);
154
glGetIntegerv (GL_UNPACK_ROW_LENGTH, &rowlength);
155
glGetIntegerv (GL_UNPACK_SKIP_ROWS, &skiprows);
156
glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &skippixels);
157
glGetIntegerv (GL_UNPACK_ALIGNMENT, &alignment);
159
/* Enforce a standard packing mode which is compatible with
160
fill_bitmap() from above. This is actually the default mode,
161
except for the (non)alignment. */
162
glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
163
glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
164
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
165
glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
166
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
167
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
169
pixmap = XCreatePixmap (dpy, win, 10, 10, 1);
170
values.foreground = 0;
171
values.background = 1;
172
values.font = fs->fid;
173
valuemask = GCForeground | GCBackground | GCFont;
174
gc = XCreateGC (dpy, pixmap, valuemask, &values);
175
XFreePixmap (dpy, pixmap);
178
/* Anti-aliasing of fonts looks like crap with 1-bit bitmaps.
179
It would be nice if we were using full-depth bitmaps, so
180
that the text showed up anti-aliased on screen, but
181
glBitmap() doesn't work that way. */
182
jwxyz_XSetAntiAliasing (dpy, gc, False);
185
for (i = 0; i < count; i++)
187
unsigned int width, height, bm_width, bm_height;
188
GLfloat x0, y0, dx, dy;
192
int list = listbase + i;
195
&& (c >= fs->min_char_or_byte2) && (c <= fs->max_char_or_byte2))
196
ch = &fs->per_char[c-fs->min_char_or_byte2];
198
ch = &fs->max_bounds;
200
/* I'm not entirely clear on why this is necessary on OSX, but
201
without it, the characters are clipped. And it does not hurt
202
under real X11. -- jwz. */
206
/* glBitmap()'s parameters:
207
"Bitmap parameters xorig, yorig, width, and height are
208
computed from font metrics as descent-1, -lbearing,
209
rbearing-lbearing, and ascent+descent, respectively.
210
xmove is taken from the glyph's width metric, and
211
ymove is set to zero. Finally, the glyph's image is
212
converted to the appropriate format for glBitmap."
214
width = ch->rbearing - ch->lbearing;
215
height = ch->ascent + ch->descent;
217
y0 = ch->descent - 1;
221
/* X11's starting point. */
225
/* Round the width to a multiple of eight. We will use this also
226
for the pixmap for capturing the X11 font. This is slightly
227
inefficient, but it makes the OpenGL part real easy. */
228
bm_width = (width + 7) / 8;
231
glNewList (list, GL_COMPILE);
232
if ((c >= fs->min_char_or_byte2) && (c <= fs->max_char_or_byte2)
233
&& (bm_width > 0) && (bm_height > 0))
235
memset (bm, '\0', bm_width * bm_height);
236
fill_bitmap (dpy, win, gc, bm_width, bm_height, x, y, c, bm);
237
glBitmap (width, height, x0, y0, dx, dy, bm);
239
printf ("width/height = %d/%d\n", width, height);
240
printf ("bm_width/bm_height = %d/%d\n", bm_width, bm_height);
241
dump_bitmap (bm_width, bm_height, bm);
245
glBitmap (0, 0, 0.0, 0.0, dx, dy, NULL);
250
XFreeFontInfo( NULL, fs, 0 );
253
/* Restore saved packing modes. */
254
glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes);
255
glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst);
256
glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength);
257
glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows);
258
glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels);
259
glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
49
264
/* Loads the font named by the X resource "res".
50
265
Returns an XFontStruct.
51
266
Also converts the font to a set of GL lists and returns the first list.