13a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/* 23a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Mesa 3-D graphics library 33a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Version: 3.1 43a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * 53a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Copyright (C) 1999 Brian Paul All Rights Reserved. 63a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * 73a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 83a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * copy of this software and associated documentation files (the "Software"), 93a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * to deal in the Software without restriction, including without limitation 103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense, 113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * and/or sell copies of the Software, and to permit persons to whom the 123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Software is furnished to do so, subject to the following conditions: 133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * 143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * The above copyright notice and this permission notice shall be included 153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * in all copies or substantial portions of the Software. 163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * 173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */ 243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/* xfonts.c -- glXUseXFont() for Mesa written by 273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de 283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */ 293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/* 313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org This was take from Mesa and modified to work in the real GLX structure. 323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org It provides a fully client side implementation of glXUseXFont and is 333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org called by that routine when direct rendering is enabled. 343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org*/ 353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#ifdef GLX_DIRECT_RENDERING 373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "glxclient.h" 393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/* Some debugging info. */ 413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#ifdef DEBUG 433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#undef _R 443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#undef _G 453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#undef _B 463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include <ctype.h> 473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgint debug_xfonts = 0; 493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void 513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgdump_char_struct(XCharStruct * ch, char *prefix) 523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{ 533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org printf("%slbearing = %d, rbearing = %d, width = %d\n", 543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org prefix, ch->lbearing, ch->rbearing, ch->width); 553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org printf("%sascent = %d, descent = %d, attributes = %u\n", 563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org prefix, ch->ascent, ch->descent, (unsigned int) ch->attributes); 573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void 603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgdump_font_struct(XFontStruct * font) 613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{ 623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org printf("ascent = %d, descent = %d\n", font->ascent, font->descent); 633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org printf("char_or_byte2 = (%u,%u)\n", 643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org font->min_char_or_byte2, font->max_char_or_byte2); 653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org printf("byte1 = (%u,%u)\n", font->min_byte1, font->max_byte1); 663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org printf("all_chars_exist = %s\n", font->all_chars_exist ? "True" : "False"); 673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org printf("default_char = %c (\\%03o)\n", 683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org (char) (isprint(font->default_char) ? font->default_char : ' '), 693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org font->default_char); 703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org dump_char_struct(&font->min_bounds, "min> "); 713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org dump_char_struct(&font->max_bounds, "max> "); 723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#if 0 733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org for (c = font->min_char_or_byte2; c <= font->max_char_or_byte2; c++) { 743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org char prefix[8]; 753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org sprintf(prefix, "%d> ", c); 763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org dump_char_struct(&font->per_char[c], prefix); 773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#endif 793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void 823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgdump_bitmap(unsigned int width, unsigned int height, GLubyte * bitmap) 833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{ 843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org unsigned int x, y; 853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org printf(" "); 873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org for (x = 0; x < 8 * width; x++) 883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org printf("%o", 7 - (x % 8)); 893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org putchar('\n'); 903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org for (y = 0; y < height; y++) { 913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org printf("%3o:", y); 923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org for (x = 0; x < 8 * width; x++) 933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org putchar((bitmap[width * (height - y - 1) + x / 8] & (1 << (7 - (x % 943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 8)))) 953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org ? '*' : '.'); 963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org printf(" "); 973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org for (x = 0; x < width; x++) 983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org printf("0x%02x, ", bitmap[width * (height - y - 1) + x]); 993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org putchar('\n'); 1003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 1013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 1023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#endif /* DEBUG */ 1033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/* Implementation. */ 1063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/* Fill a BITMAP with a character C from thew current font 1083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org in the graphics context GC. WIDTH is the width in bytes 1093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org and HEIGHT is the height in bits. 1103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Note that the generated bitmaps must be used with 1123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE); 1143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE); 1153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); 1163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glPixelStorei (GL_UNPACK_SKIP_ROWS, 0); 1173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0); 1183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glPixelStorei (GL_UNPACK_ALIGNMENT, 1); 1193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Possible optimizations: 1213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * use only one reusable pixmap with the maximum dimensions. 1233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * draw the entire font into a single pixmap (careful with 1243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org proportional fonts!). 1253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org*/ 1263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/* 1293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Generate OpenGL-compatible bitmap. 1303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */ 1313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void 1323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgfill_bitmap(Display * dpy, Window win, GC gc, 1333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org unsigned int width, unsigned int height, 1343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org int x0, int y0, unsigned int c, GLubyte * bitmap) 1353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{ 1363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org XImage *image; 1373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org unsigned int x, y; 1383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Pixmap pixmap; 1393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org XChar2b char2b; 1403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org pixmap = XCreatePixmap(dpy, win, 8 * width, height, 1); 1423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org XSetForeground(dpy, gc, 0); 1433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org XFillRectangle(dpy, pixmap, gc, 0, 0, 8 * width, height); 1443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org XSetForeground(dpy, gc, 1); 1453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org char2b.byte1 = (c >> 8) & 0xff; 1473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org char2b.byte2 = (c & 0xff); 1483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org XDrawString16(dpy, pixmap, gc, x0, y0, &char2b, 1); 1503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org image = XGetImage(dpy, pixmap, 0, 0, 8 * width, height, 1, XYPixmap); 1523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (image) { 1533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org /* Fill the bitmap (X11 and OpenGL are upside down wrt each other). */ 1543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org for (y = 0; y < height; y++) 1553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org for (x = 0; x < 8 * width; x++) 1563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (XGetPixel(image, x, y)) 1573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org bitmap[width * (height - y - 1) + x / 8] |= 1583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org (1 << (7 - (x % 8))); 1593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org XDestroyImage(image); 1603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 1613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org XFreePixmap(dpy, pixmap); 1633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 1643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/* 1663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * determine if a given glyph is valid and return the 1673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * corresponding XCharStruct. 1683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */ 1693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic XCharStruct * 1703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgisvalid(XFontStruct * fs, int which) 1713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{ 1723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org unsigned int rows, pages; 1733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org int byte1 = 0, byte2 = 0; 1743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org int i, valid = 1; 1753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org rows = fs->max_byte1 - fs->min_byte1 + 1; 1773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1; 1783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (rows == 1) { 1803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org /* "linear" fonts */ 1813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if ((fs->min_char_or_byte2 > which) || (fs->max_char_or_byte2 < which)) 1823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org valid = 0; 1833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 1843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org else { 1853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org /* "matrix" fonts */ 1863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org byte2 = which & 0xff; 1873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org byte1 = which >> 8; 1883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if ((fs->min_char_or_byte2 > byte2) || 1893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org (fs->max_char_or_byte2 < byte2) || 1903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org (fs->min_byte1 > byte1) || (fs->max_byte1 < byte1)) 1913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org valid = 0; 1923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 1933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 1943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (valid) { 1953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (fs->per_char) { 1963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (rows == 1) { 1973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org /* "linear" fonts */ 1983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org return (fs->per_char + (which - fs->min_char_or_byte2)); 1993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 2003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org else { 2013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org /* "matrix" fonts */ 2023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org i = ((byte1 - fs->min_byte1) * pages) + 2033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org (byte2 - fs->min_char_or_byte2); 2043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org return (fs->per_char + i); 2053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 2063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 2073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org else { 2083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org return (&fs->min_bounds); 2093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 2103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 2113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org return (NULL); 2123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 2133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org_X_HIDDEN void 215760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.orgDRI_glXUseXFont(struct glx_context *CC, Font font, int first, int count, int listbase) 2163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{ 2173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Display *dpy; 2183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Window win; 2193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Pixmap pixmap; 2203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org GC gc; 2213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org XGCValues values; 2223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org unsigned long valuemask; 2233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org XFontStruct *fs; 2243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org GLint swapbytes, lsbfirst, rowlength; 2263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org GLint skiprows, skippixels, alignment; 2273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org unsigned int max_width, max_height, max_bm_width, max_bm_height; 2293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org GLubyte *bm; 2303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org int i; 2323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org dpy = CC->currentDpy; 2343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org win = CC->currentDrawable; 2353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org fs = XQueryFont(dpy, font); 2373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (!fs) { 2383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org __glXSetError(CC, GL_INVALID_VALUE); 2393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org return; 2403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 2413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org /* Allocate a bitmap that can fit all characters. */ 2433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing; 2443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org max_height = fs->max_bounds.ascent + fs->max_bounds.descent; 2453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org max_bm_width = (max_width + 7) / 8; 2463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org max_bm_height = max_height; 2473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org bm = (GLubyte *) Xmalloc((max_bm_width * max_bm_height) * sizeof(GLubyte)); 2493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (!bm) { 2503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org XFreeFontInfo(NULL, fs, 1); 2513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org __glXSetError(CC, GL_OUT_OF_MEMORY); 2523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org return; 2533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 2543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#if 0 2563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org /* get the page info */ 2573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1; 2583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org firstchar = (fs->min_byte1 << 8) + fs->min_char_or_byte2; 2593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org lastchar = (fs->max_byte1 << 8) + fs->max_char_or_byte2; 2603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org rows = fs->max_byte1 - fs->min_byte1 + 1; 2613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org unsigned int first_char, last_char, pages, rows; 2623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#endif 2633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org /* Save the current packing mode for bitmaps. */ 2653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes); 2663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst); 2673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength); 2683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows); 2693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels); 2703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment); 2713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org /* Enforce a standard packing mode which is compatible with 2733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org fill_bitmap() from above. This is actually the default mode, 2743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org except for the (non)alignment. */ 2753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); 2763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); 2773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 2783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); 2793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); 2803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 2813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org pixmap = XCreatePixmap(dpy, win, 10, 10, 1); 2833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org values.foreground = BlackPixel(dpy, DefaultScreen(dpy)); 2843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org values.background = WhitePixel(dpy, DefaultScreen(dpy)); 2853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org values.font = fs->fid; 2863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org valuemask = GCForeground | GCBackground | GCFont; 2873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org gc = XCreateGC(dpy, pixmap, valuemask, &values); 2883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org XFreePixmap(dpy, pixmap); 2893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#ifdef DEBUG 2913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (debug_xfonts) 2923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org dump_font_struct(fs); 2933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#endif 2943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 2953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org for (i = 0; i < count; i++) { 2963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org unsigned int width, height, bm_width, bm_height; 2973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org GLfloat x0, y0, dx, dy; 2983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org XCharStruct *ch; 2993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org int x, y; 3003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org unsigned int c = first + i; 3013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org int list = listbase + i; 3023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org int valid; 3033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org /* check on index validity and get the bounds */ 3053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org ch = isvalid(fs, c); 3063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (!ch) { 3073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org ch = &fs->max_bounds; 3083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org valid = 0; 3093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 3103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org else { 3113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org valid = 1; 3123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 3133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#ifdef DEBUG 3153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (debug_xfonts) { 3163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org char s[7]; 3173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org sprintf(s, isprint(c) ? "%c> " : "\\%03o> ", c); 3183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org dump_char_struct(ch, s); 3193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 3203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#endif 3213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org /* glBitmap()' parameters: 3233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org straight from the glXUseXFont(3) manpage. */ 3243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org width = ch->rbearing - ch->lbearing; 3253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org height = ch->ascent + ch->descent; 3263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org x0 = -ch->lbearing; 3273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org y0 = ch->descent - 1; 3283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org dx = ch->width; 3293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org dy = 0; 3303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org /* X11's starting point. */ 3323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org x = -ch->lbearing; 3333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org y = ch->ascent; 3343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org /* Round the width to a multiple of eight. We will use this also 3363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org for the pixmap for capturing the X11 font. This is slightly 3373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org inefficient, but it makes the OpenGL part real easy. */ 3383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org bm_width = (width + 7) / 8; 3393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org bm_height = height; 3403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glNewList(list, GL_COMPILE); 3423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (valid && (bm_width > 0) && (bm_height > 0)) { 3433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org memset(bm, '\0', bm_width * bm_height); 3453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm); 3463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glBitmap(width, height, x0, y0, dx, dy, bm); 3483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#ifdef DEBUG 3493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org if (debug_xfonts) { 3503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org printf("width/height = %u/%u\n", width, height); 3513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org printf("bm_width/bm_height = %u/%u\n", bm_width, bm_height); 3523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org dump_bitmap(bm_width, bm_height, bm); 3533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 3543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#endif 3553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 3563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org else { 3573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glBitmap(0, 0, 0.0, 0.0, dx, dy, NULL); 3583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 3593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glEndList(); 3603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org } 3613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org Xfree(bm); 3633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org XFreeFontInfo(NULL, fs, 1); 3643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org XFreeGC(dpy, gc); 3653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org /* Restore saved packing modes. */ 3673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes); 3683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst); 3693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength); 3703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows); 3713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels); 3723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); 3733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org} 3743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org 3753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#endif 376