Go to the source code of this file.
Functions | |
void | Fake_glXUseXFont (Font font, int first, int count, int listbase) |
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 }