1
/* texfonts, Copyright (c) 2005 Jamie Zawinski <jwz@jwz.org>
1
/* texfonts, Copyright (c) 2005-2007 Jamie Zawinski <jwz@jwz.org>
2
2
* Loads X11 fonts into textures for use with OpenGL.
4
4
* Permission to use, copy, modify, distribute, and sell this software and its
37
46
int grid_mag; /* 1, 2, 4, or 8 */
38
47
int ntextures; /* 1, 4, 16, or 64 (grid_mag ^ 2) */
49
GLuint texid[64]; /* must hold ntextures */
48
static unsigned int pow2[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024,
49
2048, 4096, 8192, 16384, 32768, 65536 };
57
static const unsigned int pow2[] = {
58
1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024,
59
2048, 4096, 8192, 16384, 32768, 65536 };
51
61
for (j = 0; j < sizeof(pow2)/sizeof(*pow2); j++)
52
62
if (pow2[j] >= i) return pow2[j];
57
/* Given a Pixmap of depth 1, converts it to an OpenGL luminance mipmap.
58
The 1 bits are drawn, the 0 bits are alpha.
67
/* Given a Pixmap (of screen depth), converts it to an OpenGL luminance mipmap.
68
RGB are averaged to grayscale, and the resulting value is treated as alpha.
59
69
Pass in the size of the pixmap; the size of the texture is returned
60
70
(it may be larger, since GL like powers of 2.)
72
We use a screen-depth pixmap instead of a 1bpp bitmap so that if the fonts
73
were drawn with antialiasing, that is preserved.
63
bitmap_to_texture (Display *dpy, Pixmap p, int *wP, int *hP)
76
bitmap_to_texture (Display *dpy, Pixmap p, Visual *visual, int *wP, int *hP)
65
78
Bool mipmap_p = True;
68
81
int w2 = to_pow2 (ow);
69
82
int h2 = to_pow2 (oh);
71
XImage *image = XGetImage (dpy, p, 0, 0, ow, oh, ~0L, XYPixmap);
84
XImage *image = XGetImage (dpy, p, 0, 0, ow, oh, ~0L, ZPixmap);
72
85
unsigned char *data = (unsigned char *) calloc (w2, (h2 + 1));
73
86
unsigned char *out = data;
74
87
GLuint iformat = GL_INTENSITY;
76
89
GLuint type = GL_UNSIGNED_BYTE;
78
91
for (y = 0; y < h2; y++)
79
for (x = 0; x < w2; x++)
80
*out++ = (x >= ow || y >= oh ? 0 :
81
XGetPixel (image, x, y) ? 255 : 0);
92
for (x = 0; x < w2; x++) {
93
unsigned long pixel = (x >= ow || y >= oh ? 0 : XGetPixel (image, x, y));
94
/* instead of averaging all three channels, let's just use red,
95
and assume it was already grayscale. */
96
unsigned long r = pixel & visual->red_mask;
97
pixel = ((r >> 24) | (r >> 16) | (r >> 8) | r) & 0xFF;
82
100
XDestroyImage (image);
116
134
texture_font_data *
117
135
load_texture_font (Display *dpy, char *res)
137
Screen *screen = DefaultScreenOfDisplay (dpy);
138
Window root = RootWindowOfScreen (screen);
139
XWindowAttributes xgwa;
119
141
texture_font_data *data = 0;
120
const char *font = get_string_resource (res, "Font");
142
char *font = get_string_resource (dpy, res, "Font");
121
143
const char *def1 = "-*-times-bold-r-normal-*-240-*";
122
144
const char *def2 = "-*-times-bold-r-normal-*-180-*";
123
145
const char *def3 = "fixed";
127
149
check_gl_error ("stale texture font");
151
XGetWindowAttributes (dpy, root, &xgwa);
129
153
if (!res || !*res) abort();
130
if (!font) font = def1;
154
if (!font) font = strdup(def1);
132
156
f = XLoadQueryFont(dpy, font);
133
157
if (!f && !!strcmp (font, def1))
135
159
fprintf (stderr, "%s: unable to load font \"%s\", using \"%s\"\n",
136
160
progname, font, def1);
162
font = strdup (def1);
138
163
f = XLoadQueryFont(dpy, font);
213
241
data->cell_width = cw;
214
242
data->cell_height = ch;
216
p = XCreatePixmap (dpy, root, w, h, 1);
244
p = XCreatePixmap (dpy, root, w, h, xgwa.depth);
217
245
gcv.font = f->fid;
246
gcv.foreground = BlackPixelOfScreen (xgwa.screen);
247
gcv.background = BlackPixelOfScreen (xgwa.screen);
220
248
gc = XCreateGC (dpy, p, (GCFont|GCForeground|GCBackground), &gcv);
221
249
XFillRectangle (dpy, p, gc, 0, 0, w, h);
222
XSetForeground (dpy, gc, 1);
250
XSetForeground (dpy, gc, WhitePixelOfScreen (xgwa.screen));
223
251
for (i = 0; i < 256 / data->ntextures; i++)
225
253
int ii = (i + (which * 256 / data->ntextures));
256
284
GC gc2 = XCreateGC (dpy, win, 0, &gcv);
257
285
XSetForeground (dpy, gc2, BlackPixel (dpy, 0));
258
286
XSetBackground (dpy, gc2, WhitePixel (dpy, 0));
259
XCopyPlane (dpy, p, win, gc2, 0, 0, w, h, 0, 0, 1);
287
XCopyArea (dpy, p, win, gc2, 0, 0, w, h, 0, 0);
260
288
XFreeGC (dpy, gc2);
261
289
XSync(dpy, False);
266
bitmap_to_texture (dpy, p, &data->tex_width, &data->tex_height);
294
#if 0 /* debugging: write the bitmap to a pgm file */
300
sprintf (file, "/tmp/%02d.pgm", which);
301
image = XGetImage (dpy, p, 0, 0, w, h, ~0L, ZPixmap);
302
f = fopen (file, "w");
303
fprintf (f, "P5\n%d %d\n255\n", w, h);
304
for (y = 0; y < h; y++)
305
for (x = 0; x < w; x++) {
306
unsigned long pix = XGetPixel (image, x, y);
307
unsigned long r = (pix & xgwa.visual->red_mask);
308
r = ((r >> 24) | (r >> 16) | (r >> 8) | r);
309
fprintf (f, "%c", (char) r);
312
XDestroyImage (image);
313
fprintf (stderr, "%s: wrote %s\n", progname, file);
317
bitmap_to_texture (dpy, p, xgwa.visual,
318
&data->tex_width, &data->tex_height);
267
319
XFreePixmap (dpy, p);