~ubuntu-branches/ubuntu/lucid/xscreensaver/lucid

« back to all changes in this revision

Viewing changes to hacks/glx/texfont.c

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2007-12-06 09:53:12 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20071206095312-fkzcwe4vqm50z208
Tags: 5.04-1ubuntu1
* Merge from debian unstable, remaining changes:
  - split xscreensaver into xscreensaver, xscreensaver-data (hacks we ship),
    xscreensaver-data-extra (hacks in universe). split out gl hacks for
    universe to xscreensaver-gl-extra
  - use fridge for rss screensavers
  - create and install .desktop files for gnome-screensaver

Show diffs side-by-side

added added

removed removed

Lines of Context:
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.
3
3
 *
4
4
 * Permission to use, copy, modify, distribute, and sell this software and its
11
11
 */
12
12
 
13
13
 
14
 
#include "config.h"
 
14
#ifdef HAVE_CONFIG_H
 
15
# include "config.h"
 
16
#endif
 
17
 
15
18
#include <stdio.h>
16
19
#include <string.h>
17
20
#include <stdlib.h>
18
21
#include <ctype.h>
19
 
#include <GL/glx.h>
20
 
#include <GL/glu.h>
 
22
 
 
23
#ifdef HAVE_COCOA
 
24
# include <OpenGL/glu.h>
 
25
#else
 
26
# include <GL/glx.h>
 
27
# include <GL/glu.h>
 
28
#endif
 
29
 
21
30
#include "resources.h"
22
31
#include "texfont.h"
23
32
 
37
46
  int grid_mag;                 /* 1,  2,  4, or 8 */
38
47
  int ntextures;                /* 1,  4, 16, or 64 (grid_mag ^ 2) */
39
48
 
40
 
  GLuint texid[32];
 
49
  GLuint texid[64];             /* must hold ntextures */
41
50
};
42
51
 
43
52
 
45
54
static int
46
55
to_pow2 (int i)
47
56
{
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 };
50
60
  int j;
51
61
  for (j = 0; j < sizeof(pow2)/sizeof(*pow2); j++)
52
62
    if (pow2[j] >= i) return pow2[j];
54
64
}
55
65
 
56
66
 
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.)
 
71
 
 
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.
61
74
 */
62
75
static void
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)
64
77
{
65
78
  Bool mipmap_p = True;
66
79
  int ow = *wP;
68
81
  int w2 = to_pow2 (ow);
69
82
  int h2 = to_pow2 (oh);
70
83
  int x, y;
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;
77
90
 
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;
 
98
      *out++ = pixel;
 
99
    }
82
100
  XDestroyImage (image);
83
101
  image = 0;
84
102
 
116
134
texture_font_data *
117
135
load_texture_font (Display *dpy, char *res)
118
136
{
 
137
  Screen *screen = DefaultScreenOfDisplay (dpy);
 
138
  Window root = RootWindowOfScreen (screen);
 
139
  XWindowAttributes xgwa;
 
140
 
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";
126
148
 
127
149
  check_gl_error ("stale texture font");
128
150
 
 
151
  XGetWindowAttributes (dpy, root, &xgwa);
 
152
 
129
153
  if (!res || !*res) abort();
130
 
  if (!font) font = def1;
 
154
  if (!font) font = strdup(def1);
131
155
 
132
156
  f = XLoadQueryFont(dpy, font);
133
157
  if (!f && !!strcmp (font, def1))
134
158
    {
135
159
      fprintf (stderr, "%s: unable to load font \"%s\", using \"%s\"\n",
136
160
               progname, font, def1);
137
 
      font = def1;
 
161
      free (font);
 
162
      font = strdup (def1);
138
163
      f = XLoadQueryFont(dpy, font);
139
164
    }
140
165
 
142
167
    {
143
168
      fprintf (stderr, "%s: unable to load font \"%s\", using \"%s\"\n",
144
169
               progname, font, def2);
145
 
      font = def2;
 
170
      free (font);
 
171
      font = strdup (def2);
146
172
      f = XLoadQueryFont(dpy, font);
147
173
    }
148
174
 
150
176
    {
151
177
      fprintf (stderr, "%s: unable to load font \"%s\", using \"%s\"\n",
152
178
               progname, font, def3);
153
 
      font = def3;
 
179
      free (font);
 
180
      font = strdup (def3);
154
181
      f = XLoadQueryFont(dpy, font);
155
182
    }
156
183
 
161
188
      exit (1);
162
189
    }
163
190
 
 
191
  free (font);
 
192
  font = 0;
 
193
 
164
194
  data = (texture_font_data *) calloc (1, sizeof(*data));
165
195
  data->dpy = dpy;
166
196
  data->font = f;
198
228
         (modulo the "ntextures" scaling.)
199
229
         Make it square-ish, since GL likes dimensions to be powers of 2.
200
230
       */
201
 
      Screen *screen = DefaultScreenOfDisplay (dpy);
202
 
      Window root = RootWindowOfScreen (screen);
203
231
      XGCValues gcv;
204
232
      GC gc;
205
233
      Pixmap p;
213
241
      data->cell_width  = cw;
214
242
      data->cell_height = ch;
215
243
 
216
 
      p = XCreatePixmap (dpy, root, w, h, 1);
 
244
      p = XCreatePixmap (dpy, root, w, h, xgwa.depth);
217
245
      gcv.font = f->fid;
218
 
      gcv.foreground = 0;
219
 
      gcv.background = 0;
 
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++)
224
252
        {
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);
262
290
        usleep (100000);
263
291
      }
264
292
#endif
265
293
 
266
 
      bitmap_to_texture (dpy, p, &data->tex_width, &data->tex_height);
 
294
#if 0  /* debugging: write the bitmap to a pgm file */
 
295
      {
 
296
        char file[255];
 
297
        XImage *image;
 
298
        int x, y;
 
299
        FILE *f;
 
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);
 
310
          }
 
311
        fclose (f);
 
312
        XDestroyImage (image);
 
313
        fprintf (stderr, "%s: wrote %s\n", progname, file);
 
314
      }
 
315
#endif
 
316
 
 
317
      bitmap_to_texture (dpy, p, xgwa.visual, 
 
318
                         &data->tex_width, &data->tex_height);
267
319
      XFreePixmap (dpy, p);
268
320
    }
269
321