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) |
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 }