1ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul/* 2ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul * Mesa 3-D graphics library 3ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul * 44a4039e1996a65ebced473fa03a3a970825746ffBrian Paul * Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de 54a4039e1996a65ebced473fa03a3a970825746ffBrian Paul * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 64a4039e1996a65ebced473fa03a3a970825746ffBrian Paul * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 7ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul * 8ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a 9ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul * copy of this software and associated documentation files (the "Software"), 10ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul * to deal in the Software without restriction, including without limitation 11ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul * and/or sell copies of the Software, and to permit persons to whom the 13ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul * Software is furnished to do so, subject to the following conditions: 14ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul * 15ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul * The above copyright notice and this permission notice shall be included 16ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul * in all copies or substantial portions of the Software. 17ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul * 18ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 213d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 223d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 233d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 243d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * OTHER DEALINGS IN THE SOFTWARE. 25ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul */ 26ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 27ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 284a4039e1996a65ebced473fa03a3a970825746ffBrian Paul/** 294a4039e1996a65ebced473fa03a3a970825746ffBrian Paul * Fake implementation of glXUseXFont(). 30ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul */ 31ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 324a4039e1996a65ebced473fa03a3a970825746ffBrian Paul 338c68987d0962f0a6c0b5157ccc2d8ab074fbadfdBrian Paul#include <stdio.h> 3440fd4323b4be0eee6d4204463737a37011739333Chia-I Wu#include "main/core.h" 3505f8e41b9567695e9b96276d3ac5734ed2b268a8Keith Whitwell#include <GL/glx.h> 36ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 37ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 38ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul/* Some debugging info. */ 39ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 40ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul#ifdef DEBUG 41ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul#include <ctype.h> 42ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 43ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paulint debug_xfonts = 0; 44ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 45ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paulstatic void 46ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Pauldump_char_struct(XCharStruct * ch, char *prefix) 47ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul{ 48ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul printf("%slbearing = %d, rbearing = %d, width = %d\n", 49ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul prefix, ch->lbearing, ch->rbearing, ch->width); 50ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul printf("%sascent = %d, descent = %d, attributes = %u\n", 51ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul prefix, ch->ascent, ch->descent, (unsigned int) ch->attributes); 52ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul} 53ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 54ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paulstatic void 55ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Pauldump_font_struct(XFontStruct * font) 56ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul{ 57ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul printf("ascent = %d, descent = %d\n", font->ascent, font->descent); 58ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul printf("char_or_byte2 = (%u,%u)\n", 59ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul font->min_char_or_byte2, font->max_char_or_byte2); 60ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul printf("byte1 = (%u,%u)\n", font->min_byte1, font->max_byte1); 61ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul printf("all_chars_exist = %s\n", font->all_chars_exist ? "True" : "False"); 62ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul printf("default_char = %c (\\%03o)\n", 63ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul (char) (isprint(font->default_char) ? font->default_char : ' '), 64ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul font->default_char); 65ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul dump_char_struct(&font->min_bounds, "min> "); 66ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul dump_char_struct(&font->max_bounds, "max> "); 67ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul#if 0 68ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul for (c = font->min_char_or_byte2; c <= font->max_char_or_byte2; c++) { 69ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul char prefix[8]; 70ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul sprintf(prefix, "%d> ", c); 71ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul dump_char_struct(&font->per_char[c], prefix); 72ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul } 73ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul#endif 74ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul} 75ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 76ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paulstatic void 77ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Pauldump_bitmap(unsigned int width, unsigned int height, GLubyte * bitmap) 78ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul{ 79ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul unsigned int x, y; 80ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 81ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul printf(" "); 82ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul for (x = 0; x < 8 * width; x++) 83ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul printf("%o", 7 - (x % 8)); 84ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul putchar('\n'); 85ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul for (y = 0; y < height; y++) { 86ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul printf("%3o:", y); 87ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul for (x = 0; x < 8 * width; x++) 88ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul putchar((bitmap[width * (height - y - 1) + x / 8] & (1 << (7 - (x % 89ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 8)))) 90ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul ? '*' : '.'); 91ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul printf(" "); 92ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul for (x = 0; x < width; x++) 93ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul printf("0x%02x, ", bitmap[width * (height - y - 1) + x]); 94ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul putchar('\n'); 95ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul } 96ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul} 97ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul#endif /* DEBUG */ 98ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 99ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 100ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul/* Implementation. */ 101ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 102ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul/* Fill a BITMAP with a character C from thew current font 103ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul in the graphics context GC. WIDTH is the width in bytes 104ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul and HEIGHT is the height in bits. 105ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 106ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul Note that the generated bitmaps must be used with 107ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 108ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE); 109ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE); 110ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); 111ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glPixelStorei (GL_UNPACK_SKIP_ROWS, 0); 112ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0); 113ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glPixelStorei (GL_UNPACK_ALIGNMENT, 1); 114ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 115ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul Possible optimizations: 116ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 117ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul * use only one reusable pixmap with the maximum dimensions. 118ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul * draw the entire font into a single pixmap (careful with 119ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul proportional fonts!). 120ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul*/ 121ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 122ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 123ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul/* 124ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul * Generate OpenGL-compatible bitmap. 125ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul */ 126ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paulstatic void 127ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paulfill_bitmap(Display * dpy, Window win, GC gc, 128ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul unsigned int width, unsigned int height, 129ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul int x0, int y0, unsigned int c, GLubyte * bitmap) 130ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul{ 131ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul XImage *image; 132ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul unsigned int x, y; 133ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul Pixmap pixmap; 134ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul XChar2b char2b; 135ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 136ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul pixmap = XCreatePixmap(dpy, win, 8 * width, height, 1); 137ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul XSetForeground(dpy, gc, 0); 138ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul XFillRectangle(dpy, pixmap, gc, 0, 0, 8 * width, height); 139ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul XSetForeground(dpy, gc, 1); 140ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 141ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul char2b.byte1 = (c >> 8) & 0xff; 142ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul char2b.byte2 = (c & 0xff); 143ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 144ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul XDrawString16(dpy, pixmap, gc, x0, y0, &char2b, 1); 145ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 146ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul image = XGetImage(dpy, pixmap, 0, 0, 8 * width, height, 1, XYPixmap); 147ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul if (image) { 148ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul /* Fill the bitmap (X11 and OpenGL are upside down wrt each other). */ 149ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul for (y = 0; y < height; y++) 150ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul for (x = 0; x < 8 * width; x++) 151ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul if (XGetPixel(image, x, y)) 152ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul bitmap[width * (height - y - 1) + x / 8] |= 153ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul (1 << (7 - (x % 8))); 154ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul XDestroyImage(image); 155ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul } 156ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 157ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul XFreePixmap(dpy, pixmap); 158ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul} 159ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 160ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul/* 161ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul * determine if a given glyph is valid and return the 162ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul * corresponding XCharStruct. 163ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul */ 164ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paulstatic XCharStruct * 165ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paulisvalid(XFontStruct * fs, unsigned int which) 166ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul{ 167ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul unsigned int rows, pages; 168ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul unsigned int byte1 = 0, byte2 = 0; 169ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul int i, valid = 1; 170ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 171ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul rows = fs->max_byte1 - fs->min_byte1 + 1; 172ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1; 173ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 174ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul if (rows == 1) { 175ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul /* "linear" fonts */ 176ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul if ((fs->min_char_or_byte2 > which) || (fs->max_char_or_byte2 < which)) 177ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul valid = 0; 178ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul } 179ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul else { 180ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul /* "matrix" fonts */ 181ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul byte2 = which & 0xff; 182ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul byte1 = which >> 8; 183ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul if ((fs->min_char_or_byte2 > byte2) || 184ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul (fs->max_char_or_byte2 < byte2) || 185ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul (fs->min_byte1 > byte1) || (fs->max_byte1 < byte1)) 186ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul valid = 0; 187ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul } 188ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 189ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul if (valid) { 190ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul if (fs->per_char) { 191ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul if (rows == 1) { 192ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul /* "linear" fonts */ 193ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul return (fs->per_char + (which - fs->min_char_or_byte2)); 194ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul } 195ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul else { 196ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul /* "matrix" fonts */ 197ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul i = ((byte1 - fs->min_byte1) * pages) + 198ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul (byte2 - fs->min_char_or_byte2); 199ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul return (fs->per_char + i); 200ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul } 201ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul } 202ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul else { 203ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul return (&fs->min_bounds); 204ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul } 205ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul } 206ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul return (NULL); 207ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul} 208ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 209ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 210cca66dbb59673168d57b4e3499ccc31f4ddc86adChia-I WuPUBLIC void 2114a4039e1996a65ebced473fa03a3a970825746ffBrian PaulglXUseXFont(Font font, int first, int count, int listbase) 212ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul{ 213ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul Display *dpy; 214ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul Window win; 215ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul Pixmap pixmap; 216ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul GC gc; 217ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul XGCValues values; 218ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul unsigned long valuemask; 219ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul XFontStruct *fs; 220ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul GLint swapbytes, lsbfirst, rowlength; 221ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul GLint skiprows, skippixels, alignment; 222ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul unsigned int max_width, max_height, max_bm_width, max_bm_height; 223ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul GLubyte *bm; 224ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul int i; 225ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 226ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul dpy = glXGetCurrentDisplay(); 227ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul if (!dpy) 228ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul return; /* I guess glXMakeCurrent wasn't called */ 2294a4039e1996a65ebced473fa03a3a970825746ffBrian Paul i = DefaultScreen(dpy); 2304a4039e1996a65ebced473fa03a3a970825746ffBrian Paul win = RootWindow(dpy, i); 231ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 232ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul fs = XQueryFont(dpy, font); 233ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul if (!fs) { 234ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul _mesa_error(NULL, GL_INVALID_VALUE, 235ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul "Couldn't get font structure information"); 236ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul return; 237ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul } 238ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 239ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul /* Allocate a bitmap that can fit all characters. */ 240ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing; 241ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul max_height = fs->max_bounds.ascent + fs->max_bounds.descent; 242ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul max_bm_width = (max_width + 7) / 8; 243ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul max_bm_height = max_height; 244ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 2458af4aaf351313f9d4692697bf28d3c3f84e01ca4Matt Turner bm = malloc((max_bm_width * max_bm_height) * sizeof(GLubyte)); 246ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul if (!bm) { 247ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul XFreeFontInfo(NULL, fs, 1); 248ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul _mesa_error(NULL, GL_OUT_OF_MEMORY, 249ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul "Couldn't allocate bitmap in glXUseXFont()"); 250ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul return; 251ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul } 252ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 253ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul#if 0 254ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul /* get the page info */ 255ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1; 256ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul firstchar = (fs->min_byte1 << 8) + fs->min_char_or_byte2; 257ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul lastchar = (fs->max_byte1 << 8) + fs->max_char_or_byte2; 258ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul rows = fs->max_byte1 - fs->min_byte1 + 1; 259ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul unsigned int first_char, last_char, pages, rows; 260ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul#endif 261ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 262ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul /* Save the current packing mode for bitmaps. */ 263ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes); 264ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst); 265ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength); 266ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows); 267ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels); 268ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment); 269ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 270ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul /* Enforce a standard packing mode which is compatible with 271ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul fill_bitmap() from above. This is actually the default mode, 272ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul except for the (non)alignment. */ 273ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); 274ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); 275ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 276ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); 277ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); 278ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 279ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 280ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul pixmap = XCreatePixmap(dpy, win, 10, 10, 1); 281ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul values.foreground = BlackPixel(dpy, DefaultScreen(dpy)); 282ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul values.background = WhitePixel(dpy, DefaultScreen(dpy)); 283ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul values.font = fs->fid; 284ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul valuemask = GCForeground | GCBackground | GCFont; 285ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul gc = XCreateGC(dpy, pixmap, valuemask, &values); 286ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul XFreePixmap(dpy, pixmap); 287ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 288ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul#ifdef DEBUG 289ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul if (debug_xfonts) 290ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul dump_font_struct(fs); 291ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul#endif 292ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 293ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul for (i = 0; i < count; i++) { 294ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul unsigned int width, height, bm_width, bm_height; 295ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul GLfloat x0, y0, dx, dy; 296ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul XCharStruct *ch; 297ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul int x, y; 298ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul unsigned int c = first + i; 299ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul int list = listbase + i; 300ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul int valid; 301ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 302ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul /* check on index validity and get the bounds */ 303ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul ch = isvalid(fs, c); 304ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul if (!ch) { 305ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul ch = &fs->max_bounds; 306ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul valid = 0; 307ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul } 308ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul else { 309ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul valid = 1; 310ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul } 311ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 312ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul#ifdef DEBUG 313ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul if (debug_xfonts) { 314ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul char s[7]; 315ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul sprintf(s, isprint(c) ? "%c> " : "\\%03o> ", c); 316ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul dump_char_struct(ch, s); 317ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul } 318ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul#endif 319ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 320ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul /* glBitmap()' parameters: 321ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul straight from the glXUseXFont(3) manpage. */ 322ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul width = ch->rbearing - ch->lbearing; 323ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul height = ch->ascent + ch->descent; 324ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul x0 = -ch->lbearing; 325ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul y0 = ch->descent - 0; /* XXX used to subtract 1 here */ 326ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul /* but that caused a conformace failure */ 327ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul dx = ch->width; 328ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul dy = 0; 329ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 330ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul /* X11's starting point. */ 331ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul x = -ch->lbearing; 332ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul y = ch->ascent; 333ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 334ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul /* Round the width to a multiple of eight. We will use this also 335ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul for the pixmap for capturing the X11 font. This is slightly 336ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul inefficient, but it makes the OpenGL part real easy. */ 337ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul bm_width = (width + 7) / 8; 338ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul bm_height = height; 339ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 340ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glNewList(list, GL_COMPILE); 341ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul if (valid && (bm_width > 0) && (bm_height > 0)) { 342ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 3432240ba10f30315410bcff77e372ee71664ac4453Brian Paul memset(bm, '\0', bm_width * bm_height); 344ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm); 345ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 346ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glBitmap(width, height, x0, y0, dx, dy, bm); 347ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul#ifdef DEBUG 348ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul if (debug_xfonts) { 349ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul printf("width/height = %u/%u\n", width, height); 350ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul printf("bm_width/bm_height = %u/%u\n", bm_width, bm_height); 351ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul dump_bitmap(bm_width, bm_height, bm); 352ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul } 353ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul#endif 354ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul } 355ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul else { 356ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glBitmap(0, 0, 0.0, 0.0, dx, dy, NULL); 357ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul } 358ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glEndList(); 359ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul } 360ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 361fe72a069d1fcce943f315907b4744b63158938b1Brian Paul free(bm); 362ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul XFreeFontInfo(NULL, fs, 1); 363ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul XFreeGC(dpy, gc); 364ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul 365ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul /* Restore saved packing modes. */ 366ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes); 367ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst); 368ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength); 369ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows); 370ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels); 371ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); 372ef25c496d52f4f6c45816b64b4c0999321476cd7Brian Paul} 373