xfonts.c File Reference

Include dependency graph for xfonts.c:

Go to the source code of this file.

Functions

static void fill_bitmap (Display *dpy, Window win, GC gc, unsigned int width, unsigned int height, int x0, int y0, unsigned int c, GLubyte *bitmap)
static XCharStruct * isvalid (XFontStruct *fs, unsigned int which)
void Fake_glXUseXFont (Font font, int first, int count, int listbase)


Function Documentation

void Fake_glXUseXFont ( Font  font,
int  first,
int  count,
int  listbase 
)

Definition at line 217 of file xfonts.c.

References fill_bitmap(), FREE, glXGetCurrentDisplay(), isvalid(), list, and MALLOC.

00218 {
00219    Display *dpy;
00220    Window win;
00221    Pixmap pixmap;
00222    GC gc;
00223    XGCValues values;
00224    unsigned long valuemask;
00225    XFontStruct *fs;
00226    GLint swapbytes, lsbfirst, rowlength;
00227    GLint skiprows, skippixels, alignment;
00228    unsigned int max_width, max_height, max_bm_width, max_bm_height;
00229    GLubyte *bm;
00230    int i;
00231 
00232    dpy = glXGetCurrentDisplay();
00233    if (!dpy)
00234       return;                   /* I guess glXMakeCurrent wasn't called */
00235    win = RootWindow(dpy, DefaultScreen(dpy));
00236 
00237    fs = XQueryFont(dpy, font);
00238    if (!fs) {
00239       _mesa_error(NULL, GL_INVALID_VALUE,
00240                   "Couldn't get font structure information");
00241       return;
00242    }
00243 
00244    /* Allocate a bitmap that can fit all characters.  */
00245    max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing;
00246    max_height = fs->max_bounds.ascent + fs->max_bounds.descent;
00247    max_bm_width = (max_width + 7) / 8;
00248    max_bm_height = max_height;
00249 
00250    bm = (GLubyte *) MALLOC((max_bm_width * max_bm_height) * sizeof(GLubyte));
00251    if (!bm) {
00252       XFreeFontInfo(NULL, fs, 1);
00253       _mesa_error(NULL, GL_OUT_OF_MEMORY,
00254                   "Couldn't allocate bitmap in glXUseXFont()");
00255       return;
00256    }
00257 
00258 #if 0
00259    /* get the page info */
00260    pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
00261    firstchar = (fs->min_byte1 << 8) + fs->min_char_or_byte2;
00262    lastchar = (fs->max_byte1 << 8) + fs->max_char_or_byte2;
00263    rows = fs->max_byte1 - fs->min_byte1 + 1;
00264    unsigned int first_char, last_char, pages, rows;
00265 #endif
00266 
00267    /* Save the current packing mode for bitmaps.  */
00268    glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes);
00269    glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst);
00270    glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength);
00271    glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows);
00272    glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels);
00273    glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
00274 
00275    /* Enforce a standard packing mode which is compatible with
00276       fill_bitmap() from above.  This is actually the default mode,
00277       except for the (non)alignment.  */
00278    glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
00279    glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
00280    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
00281    glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
00282    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
00283    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00284 
00285    pixmap = XCreatePixmap(dpy, win, 10, 10, 1);
00286    values.foreground = BlackPixel(dpy, DefaultScreen(dpy));
00287    values.background = WhitePixel(dpy, DefaultScreen(dpy));
00288    values.font = fs->fid;
00289    valuemask = GCForeground | GCBackground | GCFont;
00290    gc = XCreateGC(dpy, pixmap, valuemask, &values);
00291    XFreePixmap(dpy, pixmap);
00292 
00293 #ifdef DEBUG
00294    if (debug_xfonts)
00295       dump_font_struct(fs);
00296 #endif
00297 
00298    for (i = 0; i < count; i++) {
00299       unsigned int width, height, bm_width, bm_height;
00300       GLfloat x0, y0, dx, dy;
00301       XCharStruct *ch;
00302       int x, y;
00303       unsigned int c = first + i;
00304       int list = listbase + i;
00305       int valid;
00306 
00307       /* check on index validity and get the bounds */
00308       ch = isvalid(fs, c);
00309       if (!ch) {
00310          ch = &fs->max_bounds;
00311          valid = 0;
00312       }
00313       else {
00314          valid = 1;
00315       }
00316 
00317 #ifdef DEBUG
00318       if (debug_xfonts) {
00319          char s[7];
00320          sprintf(s, isprint(c) ? "%c> " : "\\%03o> ", c);
00321          dump_char_struct(ch, s);
00322       }
00323 #endif
00324 
00325       /* glBitmap()' parameters:
00326          straight from the glXUseXFont(3) manpage.  */
00327       width = ch->rbearing - ch->lbearing;
00328       height = ch->ascent + ch->descent;
00329       x0 = -ch->lbearing;
00330       y0 = ch->descent - 0;     /* XXX used to subtract 1 here */
00331       /* but that caused a conformace failure */
00332       dx = ch->width;
00333       dy = 0;
00334 
00335       /* X11's starting point.  */
00336       x = -ch->lbearing;
00337       y = ch->ascent;
00338 
00339       /* Round the width to a multiple of eight.  We will use this also
00340          for the pixmap for capturing the X11 font.  This is slightly
00341          inefficient, but it makes the OpenGL part real easy.  */
00342       bm_width = (width + 7) / 8;
00343       bm_height = height;
00344 
00345       glNewList(list, GL_COMPILE);
00346       if (valid && (bm_width > 0) && (bm_height > 0)) {
00347 
00348          MEMSET(bm, '\0', bm_width * bm_height);
00349          fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm);
00350 
00351          glBitmap(width, height, x0, y0, dx, dy, bm);
00352 #ifdef DEBUG
00353          if (debug_xfonts) {
00354             printf("width/height = %u/%u\n", width, height);
00355             printf("bm_width/bm_height = %u/%u\n", bm_width, bm_height);
00356             dump_bitmap(bm_width, bm_height, bm);
00357          }
00358 #endif
00359       }
00360       else {
00361          glBitmap(0, 0, 0.0, 0.0, dx, dy, NULL);
00362       }
00363       glEndList();
00364    }
00365 
00366    FREE(bm);
00367    XFreeFontInfo(NULL, fs, 1);
00368    XFreeGC(dpy, gc);
00369 
00370    /* Restore saved packing modes.  */
00371    glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes);
00372    glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst);
00373    glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength);
00374    glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows);
00375    glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels);
00376    glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
00377 }

static void fill_bitmap ( Display *  dpy,
Window  win,
GC  gc,
unsigned int  width,
unsigned int  height,
int  x0,
int  y0,
unsigned int  c,
GLubyte *  bitmap 
) [static]

Definition at line 133 of file xfonts.c.

00136 {
00137    XImage *image;
00138    unsigned int x, y;
00139    Pixmap pixmap;
00140    XChar2b char2b;
00141 
00142    pixmap = XCreatePixmap(dpy, win, 8 * width, height, 1);
00143    XSetForeground(dpy, gc, 0);
00144    XFillRectangle(dpy, pixmap, gc, 0, 0, 8 * width, height);
00145    XSetForeground(dpy, gc, 1);
00146 
00147    char2b.byte1 = (c >> 8) & 0xff;
00148    char2b.byte2 = (c & 0xff);
00149 
00150    XDrawString16(dpy, pixmap, gc, x0, y0, &char2b, 1);
00151 
00152    image = XGetImage(dpy, pixmap, 0, 0, 8 * width, height, 1, XYPixmap);
00153    if (image) {
00154       /* Fill the bitmap (X11 and OpenGL are upside down wrt each other).  */
00155       for (y = 0; y < height; y++)
00156          for (x = 0; x < 8 * width; x++)
00157             if (XGetPixel(image, x, y))
00158                bitmap[width * (height - y - 1) + x / 8] |=
00159                   (1 << (7 - (x % 8)));
00160       XDestroyImage(image);
00161    }
00162 
00163    XFreePixmap(dpy, pixmap);
00164 }

static XCharStruct* isvalid ( XFontStruct *  fs,
unsigned int  which 
) [static]

Definition at line 171 of file xfonts.c.

00172 {
00173    unsigned int rows, pages;
00174    unsigned int byte1 = 0, byte2 = 0;
00175    int i, valid = 1;
00176 
00177    rows = fs->max_byte1 - fs->min_byte1 + 1;
00178    pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
00179 
00180    if (rows == 1) {
00181       /* "linear" fonts */
00182       if ((fs->min_char_or_byte2 > which) || (fs->max_char_or_byte2 < which))
00183          valid = 0;
00184    }
00185    else {
00186       /* "matrix" fonts */
00187       byte2 = which & 0xff;
00188       byte1 = which >> 8;
00189       if ((fs->min_char_or_byte2 > byte2) ||
00190           (fs->max_char_or_byte2 < byte2) ||
00191           (fs->min_byte1 > byte1) || (fs->max_byte1 < byte1))
00192          valid = 0;
00193    }
00194 
00195    if (valid) {
00196       if (fs->per_char) {
00197          if (rows == 1) {
00198             /* "linear" fonts */
00199             return (fs->per_char + (which - fs->min_char_or_byte2));
00200          }
00201          else {
00202             /* "matrix" fonts */
00203             i = ((byte1 - fs->min_byte1) * pages) +
00204                (byte2 - fs->min_char_or_byte2);
00205             return (fs->per_char + i);
00206          }
00207       }
00208       else {
00209          return (&fs->min_bounds);
00210       }
00211    }
00212    return (NULL);
00213 }


Generated on Tue Sep 29 06:25:50 2009 for Gallium3D by  doxygen 1.5.4