~ubuntu-branches/ubuntu/trusty/xscreensaver/trusty

« back to all changes in this revision

Viewing changes to hacks/glx/glxfonts.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Ancell
  • Date: 2009-11-30 13:33:13 UTC
  • mfrom: (1.1.8 upstream) (2.1.6 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091130133313-3b5nz2e7hvbb8h3l
Tags: 5.10-3ubuntu1
* Merge with Debian unstable, remaining changes: (LP: #489062)
  - debian/control: add Build-Depends on ubuntu-artwork
  - debian/rules: use /usr/share/backgrounds
  - debian/control: Move xli | xloadimage recommends to suggests
  - debian/split-hacks.config: Use different set of default hacks to Debian
  - debian/source_xscreensaver.py: Add apport hook
  - debian/patches/53_XScreenSaver.ad.in.patch: Use Ubuntu branding

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* glxfonts, Copyright (c) 2001-2008 Jamie Zawinski <jwz@jwz.org>
 
1
/* glxfonts, Copyright (c) 2001-2009 Jamie Zawinski <jwz@jwz.org>
2
2
 * Loads X11 fonts for use with OpenGL.
3
3
 *
4
4
 * Permission to use, copy, modify, distribute, and sell this software and its
46
46
               */
47
47
 
48
48
 
 
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.
 
53
 */
 
54
static void
 
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)
 
58
{
 
59
  XImage *image;
 
60
  int x, y;
 
61
  Pixmap pixmap;
 
62
 
 
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);
 
68
 
 
69
  image = XGetImage (dpy, pixmap, 0, 0, 8*width, height, 1, XYPixmap);
 
70
 
 
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)));
 
76
  
 
77
  XFreePixmap (dpy, pixmap);
 
78
  XDestroyImage (image);
 
79
}
 
80
 
 
81
 
 
82
#if 0
 
83
static void
 
84
dump_bitmap (unsigned int width, unsigned int height, GLubyte *bitmap)
 
85
{
 
86
  int x, y;
 
87
 
 
88
  printf ("    ");
 
89
  for (x = 0; x < 8*width; x++)
 
90
    printf ("%o", 7 - (x % 8));
 
91
  putchar ('\n');
 
92
  for (y = 0; y < height; y++)
 
93
    {
 
94
      printf ("%3o:", y);
 
95
      for (x = 0; x < 8*width; x++)
 
96
        putchar ((bitmap[width*(height - y - 1) + x/8] & (1 << (7 - (x % 8))))
 
97
                 ? '#' : '.');
 
98
      printf ("   ");
 
99
      for (x = 0; x < width; x++)
 
100
        printf ("0x%02x, ", bitmap[width*(height - y - 1) + x]);
 
101
      putchar ('\n');
 
102
    }
 
103
}
 
104
#endif
 
105
 
 
106
 
 
107
void
 
108
xscreensaver_glXUseXFont (Display *dpy, Font font, 
 
109
                          int first, int count, int listbase)
 
110
{
 
111
  Window win = RootWindowOfScreen (DefaultScreenOfDisplay (dpy));
 
112
  Pixmap pixmap;
 
113
  GC gc;
 
114
  XGCValues values;
 
115
  unsigned long valuemask;
 
116
 
 
117
  XFontStruct *fs;
 
118
 
 
119
  GLint swapbytes, lsbfirst, rowlength;
 
120
  GLint skiprows, skippixels, alignment;
 
121
 
 
122
  unsigned int max_width, max_height, max_bm_width, max_bm_height;
 
123
  GLubyte *bm;
 
124
 
 
125
  int i;
 
126
 
 
127
  fs = XQueryFont (dpy, font);  
 
128
  if (!fs)
 
129
    {
 
130
      /*gl_error (CC->gl_ctx, GL_INVALID_VALUE,
 
131
                "Couldn't get font structure information");*/
 
132
      abort();
 
133
      return;
 
134
    }
 
135
 
 
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;
 
141
 
 
142
  bm = (GLubyte *) malloc ((max_bm_width * max_bm_height) * sizeof (GLubyte));
 
143
  if (!bm)
 
144
    {
 
145
      /*gl_error (CC->gl_ctx, GL_OUT_OF_MEMORY,
 
146
                "Couldn't allocate bitmap in glXUseXFont()");*/
 
147
      abort();
 
148
      return;
 
149
    }
 
150
 
 
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);
 
158
 
 
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);
 
168
 
 
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);
 
176
 
 
177
# ifdef HAVE_COCOA
 
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);
 
183
# endif
 
184
 
 
185
  for (i = 0; i < count; i++)
 
186
    {
 
187
      unsigned int width, height, bm_width, bm_height;
 
188
      GLfloat x0, y0, dx, dy;
 
189
      XCharStruct *ch;
 
190
      int x, y;
 
191
      int c = first + i;
 
192
      int list = listbase + i;
 
193
 
 
194
      if (fs->per_char
 
195
          && (c >= fs->min_char_or_byte2) && (c <= fs->max_char_or_byte2))
 
196
        ch = &fs->per_char[c-fs->min_char_or_byte2];
 
197
      else
 
198
        ch = &fs->max_bounds;
 
199
 
 
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. */
 
203
      ch->lbearing--;
 
204
      ch->ascent++;
 
205
 
 
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."
 
213
      */
 
214
      width = ch->rbearing - ch->lbearing;
 
215
      height = ch->ascent + ch->descent;
 
216
      x0 = - ch->lbearing;
 
217
      y0 = ch->descent - 1;
 
218
      dx = ch->width;
 
219
      dy = 0;
 
220
 
 
221
      /* X11's starting point.  */
 
222
      x = - ch->lbearing;
 
223
      y = ch->ascent;
 
224
      
 
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;
 
229
      bm_height = height;
 
230
 
 
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))
 
234
          {
 
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);
 
238
#if 0
 
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);
 
242
#endif
 
243
          }
 
244
        else
 
245
          glBitmap (0, 0, 0.0, 0.0, dx, dy, NULL);
 
246
      glEndList ();
 
247
    }
 
248
 
 
249
  free (bm);
 
250
  XFreeFontInfo( NULL, fs, 0 );
 
251
  XFreeGC (dpy, gc);
 
252
 
 
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);
 
260
}
 
261
 
 
262
 
 
263
 
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.
95
310
  last = f->max_char_or_byte2;
96
311
  
97
312
 
98
 
# ifndef HAVE_COCOA /* Xlib version */
99
 
 
100
313
  if (dlist_ret)
101
314
    {
102
315
      clear_gl_error ();
103
316
      *dlist_ret = glGenLists ((GLuint) last+1);
104
317
      check_gl_error ("glGenLists");
105
 
      glXUseXFont(id, first, last-first+1, *dlist_ret + first);
106
 
      check_gl_error ("glXUseXFont");
107
 
    }
108
 
 
109
 
# else  /* HAVE_COCOA */
110
 
 
111
 
  {
112
 
    int afid, face, size;
113
 
    afid = jwxyz_font_info (id, &size, &face);
114
 
 
115
 
    if (dlist_ret)
116
 
      {
117
 
        clear_gl_error ();
118
 
        *dlist_ret = glGenLists ((GLuint) last+1);
119
 
        check_gl_error ("glGenLists");
120
 
 
121
 
        AGLContext ctx = aglGetCurrentContext();
122
 
        if (! aglUseFont (ctx, afid, face, size, 
123
 
                          first, last-first+1, *dlist_ret + first)) {
124
 
          check_gl_error ("aglUseFont");
125
 
          abort();
126
 
      }
127
 
    }
128
 
  }
129
 
 
130
 
# endif  /* HAVE_COCOA */
 
318
      xscreensaver_glXUseXFont(dpy, id, first, last-first+1,
 
319
                               *dlist_ret + first);
 
320
      check_gl_error ("xscreensaver_glXUseXFont");
 
321
    }
131
322
 
132
323
  if (font_ret)
133
324
    *font_ret = f;