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