1afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 2afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/* 3afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Mesa 3-D graphics library 4e9bf776711b22ce336cd462adf534ad3e2d61eecKeith Whitwell * Version: 3.5 5afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * 671dea349d2be623b7819389428b0d6a124e8d184Brian Paul * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. 7afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * 8afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Permission is hereby granted, free of charge, to any person obtaining a 9afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * copy of this software and associated documentation files (the "Software"), 10afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * to deal in the Software without restriction, including without limitation 11afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * and/or sell copies of the Software, and to permit persons to whom the 13afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Software is furnished to do so, subject to the following conditions: 14afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * 15afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * The above copyright notice and this permission notice shall be included 16afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * in all copies or substantial portions of the Software. 17afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * 18afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */ 25afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 26afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 27afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/* xfonts.c -- glXUseXFont() for Mesa written by 28afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de 29afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */ 30afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 31b5b5c52034840dbfcd3f76a9e7cde8b379e7d517Jouk Jansen#ifdef __VMS 32b5b5c52034840dbfcd3f76a9e7cde8b379e7d517Jouk Jansen#include <GL/vms_x_fix.h> 33b5b5c52034840dbfcd3f76a9e7cde8b379e7d517Jouk Jansen#endif 34afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 353c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "glxheader.h" 36374e7fd6cc95d3d91629a6e1c951d77e8a29c31cBrian Paul#include "main/context.h" 37374e7fd6cc95d3d91629a6e1c951d77e8a29c31cBrian Paul#include "main/imports.h" 3871dea349d2be623b7819389428b0d6a124e8d184Brian Paul#include "xfonts.h" 39afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 4071dea349d2be623b7819389428b0d6a124e8d184Brian Paul 41afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/* Some debugging info. */ 42afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 43afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#ifdef DEBUG 44afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#undef _R 45afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#undef _G 46afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#undef _B 47afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include <ctype.h> 48afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 49afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgint debug_xfonts = 0; 50afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 51afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgstatic void 5249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Pauldump_char_struct(XCharStruct * ch, char *prefix) 53afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{ 5449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul printf("%slbearing = %d, rbearing = %d, width = %d\n", 5549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul prefix, ch->lbearing, ch->rbearing, ch->width); 5649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul printf("%sascent = %d, descent = %d, attributes = %u\n", 5749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul prefix, ch->ascent, ch->descent, (unsigned int) ch->attributes); 58afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg} 59afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 60afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgstatic void 6149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Pauldump_font_struct(XFontStruct * font) 62afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{ 6349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul printf("ascent = %d, descent = %d\n", font->ascent, font->descent); 6449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul printf("char_or_byte2 = (%u,%u)\n", 6549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul font->min_char_or_byte2, font->max_char_or_byte2); 6649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul printf("byte1 = (%u,%u)\n", font->min_byte1, font->max_byte1); 6749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul printf("all_chars_exist = %s\n", font->all_chars_exist ? "True" : "False"); 6849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul printf("default_char = %c (\\%03o)\n", 6949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul (char) (isprint(font->default_char) ? font->default_char : ' '), 7049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul font->default_char); 7149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul dump_char_struct(&font->min_bounds, "min> "); 7249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul dump_char_struct(&font->max_bounds, "max> "); 73afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#if 0 7449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul for (c = font->min_char_or_byte2; c <= font->max_char_or_byte2; c++) { 75afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg char prefix[8]; 7649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul sprintf(prefix, "%d> ", c); 7749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul dump_char_struct(&font->per_char[c], prefix); 7849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul } 79afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#endif 80afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg} 81afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 82afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgstatic void 8349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Pauldump_bitmap(unsigned int width, unsigned int height, GLubyte * bitmap) 84afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{ 8549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul unsigned int x, y; 8649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul 8749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul printf(" "); 8849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul for (x = 0; x < 8 * width; x++) 8949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul printf("%o", 7 - (x % 8)); 9049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul putchar('\n'); 9149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul for (y = 0; y < height; y++) { 9249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul printf("%3o:", y); 9349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul for (x = 0; x < 8 * width; x++) 9449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul putchar((bitmap[width * (height - y - 1) + x / 8] & (1 << (7 - (x % 9549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul 8)))) 9649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul ? '*' : '.'); 9749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul printf(" "); 98afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg for (x = 0; x < width; x++) 9949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul printf("0x%02x, ", bitmap[width * (height - y - 1) + x]); 10049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul putchar('\n'); 10149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul } 102afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg} 103afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#endif /* DEBUG */ 104afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 105afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 106afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/* Implementation. */ 107afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 108afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/* Fill a BITMAP with a character C from thew current font 109afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg in the graphics context GC. WIDTH is the width in bytes 110afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg and HEIGHT is the height in bits. 111afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 112afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg Note that the generated bitmaps must be used with 113afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 114afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE); 115afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE); 116afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); 117afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg glPixelStorei (GL_UNPACK_SKIP_ROWS, 0); 118afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0); 119afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg glPixelStorei (GL_UNPACK_ALIGNMENT, 1); 120afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 121afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg Possible optimizations: 122afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 123afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * use only one reusable pixmap with the maximum dimensions. 124afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * draw the entire font into a single pixmap (careful with 125afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg proportional fonts!). 126afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg*/ 127afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 128afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 129afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/* 130afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Generate OpenGL-compatible bitmap. 131afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */ 132afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgstatic void 13349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paulfill_bitmap(Display * dpy, Window win, GC gc, 13449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul unsigned int width, unsigned int height, 13549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul int x0, int y0, unsigned int c, GLubyte * bitmap) 136afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{ 13749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul XImage *image; 13849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul unsigned int x, y; 13949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul Pixmap pixmap; 14049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul XChar2b char2b; 14149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul 14249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul pixmap = XCreatePixmap(dpy, win, 8 * width, height, 1); 14349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul XSetForeground(dpy, gc, 0); 14449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul XFillRectangle(dpy, pixmap, gc, 0, 0, 8 * width, height); 14549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul XSetForeground(dpy, gc, 1); 14649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul 14749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul char2b.byte1 = (c >> 8) & 0xff; 14849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul char2b.byte2 = (c & 0xff); 14949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul 15049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul XDrawString16(dpy, pixmap, gc, x0, y0, &char2b, 1); 15149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul 15249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul image = XGetImage(dpy, pixmap, 0, 0, 8 * width, height, 1, XYPixmap); 15349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul if (image) { 15449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul /* Fill the bitmap (X11 and OpenGL are upside down wrt each other). */ 15549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul for (y = 0; y < height; y++) 15649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul for (x = 0; x < 8 * width; x++) 15749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul if (XGetPixel(image, x, y)) 15849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul bitmap[width * (height - y - 1) + x / 8] |= 15949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul (1 << (7 - (x % 8))); 16049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul XDestroyImage(image); 16149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul } 16249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul 16349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul XFreePixmap(dpy, pixmap); 164afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg} 165afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 166afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/* 167afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * determine if a given glyph is valid and return the 168afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * corresponding XCharStruct. 169afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */ 17049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paulstatic XCharStruct * 17149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paulisvalid(XFontStruct * fs, unsigned int which) 172afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{ 17349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul unsigned int rows, pages; 17449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul unsigned int byte1 = 0, byte2 = 0; 17549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul int i, valid = 1; 17649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul 17749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul rows = fs->max_byte1 - fs->min_byte1 + 1; 17849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1; 17949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul 18049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul if (rows == 1) { 18149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul /* "linear" fonts */ 18249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul if ((fs->min_char_or_byte2 > which) || (fs->max_char_or_byte2 < which)) 18349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul valid = 0; 18449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul } 18549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul else { 18649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul /* "matrix" fonts */ 18749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul byte2 = which & 0xff; 18849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul byte1 = which >> 8; 18949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul if ((fs->min_char_or_byte2 > byte2) || 19049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul (fs->max_char_or_byte2 < byte2) || 19149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul (fs->min_byte1 > byte1) || (fs->max_byte1 < byte1)) 19249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul valid = 0; 19349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul } 19449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul 19549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul if (valid) { 19649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul if (fs->per_char) { 19749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul if (rows == 1) { 19849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul /* "linear" fonts */ 19949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul return (fs->per_char + (which - fs->min_char_or_byte2)); 20049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul } 20149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul else { 20249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul /* "matrix" fonts */ 20349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul i = ((byte1 - fs->min_byte1) * pages) + 20449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul (byte2 - fs->min_char_or_byte2); 20549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul return (fs->per_char + i); 20649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul } 207afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg } 20849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul else { 20949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul return (&fs->min_bounds); 21049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul } 21149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul } 21249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul return (NULL); 213afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg} 214afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 215afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 21649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paulvoid 21749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian PaulFake_glXUseXFont(Font font, int first, int count, int listbase) 218afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{ 21949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul Display *dpy; 22049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul Window win; 22149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul Pixmap pixmap; 22249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul GC gc; 22349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul XGCValues values; 22449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul unsigned long valuemask; 22549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul XFontStruct *fs; 22649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul GLint swapbytes, lsbfirst, rowlength; 22749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul GLint skiprows, skippixels, alignment; 22849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul unsigned int max_width, max_height, max_bm_width, max_bm_height; 22949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul GLubyte *bm; 23049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul int i; 23149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul 23249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul dpy = glXGetCurrentDisplay(); 23349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul if (!dpy) 23449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul return; /* I guess glXMakeCurrent wasn't called */ 23549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul win = RootWindow(dpy, DefaultScreen(dpy)); 23649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul 23749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul fs = XQueryFont(dpy, font); 23849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul if (!fs) { 23908836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul _mesa_error(NULL, GL_INVALID_VALUE, 24049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul "Couldn't get font structure information"); 241afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg return; 24249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul } 24349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul 24449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul /* Allocate a bitmap that can fit all characters. */ 24549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing; 24649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul max_height = fs->max_bounds.ascent + fs->max_bounds.descent; 24749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul max_bm_width = (max_width + 7) / 8; 24849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul max_bm_height = max_height; 24949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul 25049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul bm = (GLubyte *) MALLOC((max_bm_width * max_bm_height) * sizeof(GLubyte)); 25149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul if (!bm) { 25249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul XFreeFontInfo(NULL, fs, 1); 25308836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul _mesa_error(NULL, GL_OUT_OF_MEMORY, 25449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul "Couldn't allocate bitmap in glXUseXFont()"); 255afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg return; 25649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul } 257afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 258afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#if 0 25949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul /* get the page info */ 26049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1; 26149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul firstchar = (fs->min_byte1 << 8) + fs->min_char_or_byte2; 26249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul lastchar = (fs->max_byte1 << 8) + fs->max_char_or_byte2; 26349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul rows = fs->max_byte1 - fs->min_byte1 + 1; 26449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul unsigned int first_char, last_char, pages, rows; 265afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#endif 266afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 26749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul /* Save the current packing mode for bitmaps. */ 26849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes); 26949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst); 27049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength); 27149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows); 27249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels); 27349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment); 27449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul 27549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul /* Enforce a standard packing mode which is compatible with 27649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul fill_bitmap() from above. This is actually the default mode, 27749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul except for the (non)alignment. */ 27849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); 27949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); 28049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 28149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); 28249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); 28349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 28449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul 28549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul pixmap = XCreatePixmap(dpy, win, 10, 10, 1); 28649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul values.foreground = BlackPixel(dpy, DefaultScreen(dpy)); 28749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul values.background = WhitePixel(dpy, DefaultScreen(dpy)); 28849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul values.font = fs->fid; 28949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul valuemask = GCForeground | GCBackground | GCFont; 29049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul gc = XCreateGC(dpy, pixmap, valuemask, &values); 29149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul XFreePixmap(dpy, pixmap); 292afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 293afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#ifdef DEBUG 29449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul if (debug_xfonts) 29549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul dump_font_struct(fs); 296afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#endif 297afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 29849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul for (i = 0; i < count; i++) { 299afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg unsigned int width, height, bm_width, bm_height; 300afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg GLfloat x0, y0, dx, dy; 301afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg XCharStruct *ch; 302afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg int x, y; 303afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg unsigned int c = first + i; 304afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg int list = listbase + i; 305afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg int valid; 306afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 307afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg /* check on index validity and get the bounds */ 308afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg ch = isvalid(fs, c); 309afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg if (!ch) { 31049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul ch = &fs->max_bounds; 31149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul valid = 0; 31249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul } 31349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul else { 31449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul valid = 1; 315afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg } 316afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 317afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#ifdef DEBUG 318afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg if (debug_xfonts) { 31949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul char s[7]; 32049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul sprintf(s, isprint(c) ? "%c> " : "\\%03o> ", c); 32149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul dump_char_struct(ch, s); 322afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg } 323afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#endif 324afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 325afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg /* glBitmap()' parameters: 326afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg straight from the glXUseXFont(3) manpage. */ 327afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg width = ch->rbearing - ch->lbearing; 328afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg height = ch->ascent + ch->descent; 32949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul x0 = -ch->lbearing; 33049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul y0 = ch->descent - 0; /* XXX used to subtract 1 here */ 33149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul /* but that caused a conformace failure */ 332afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg dx = ch->width; 333afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg dy = 0; 334afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 335afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg /* X11's starting point. */ 33649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul x = -ch->lbearing; 337afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg y = ch->ascent; 338afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 339afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg /* Round the width to a multiple of eight. We will use this also 340afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg for the pixmap for capturing the X11 font. This is slightly 341afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg inefficient, but it makes the OpenGL part real easy. */ 342afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg bm_width = (width + 7) / 8; 343afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg bm_height = height; 344afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 34549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glNewList(list, GL_COMPILE); 34649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul if (valid && (bm_width > 0) && (bm_height > 0)) { 347afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 3482240ba10f30315410bcff77e372ee71664ac4453Brian Paul memset(bm, '\0', bm_width * bm_height); 34949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm); 350afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 35149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glBitmap(width, height, x0, y0, dx, dy, bm); 352afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#ifdef DEBUG 35349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul if (debug_xfonts) { 35449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul printf("width/height = %u/%u\n", width, height); 35549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul printf("bm_width/bm_height = %u/%u\n", bm_width, bm_height); 35649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul dump_bitmap(bm_width, bm_height, bm); 35749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul } 358afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#endif 35949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul } 36049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul else { 36149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glBitmap(0, 0, 0.0, 0.0, dx, dy, NULL); 36249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul } 36349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glEndList(); 36449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul } 36549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul 36649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul FREE(bm); 36749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul XFreeFontInfo(NULL, fs, 1); 36849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul XFreeGC(dpy, gc); 36949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul 37049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul /* Restore saved packing modes. */ 37149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes); 37249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst); 37349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength); 37449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows); 37549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels); 37649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); 377afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg} 378