1cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson/* 2cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * Mesa 3-D graphics library 3cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * Version: 3.1 4cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * 5cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * Copyright (C) 1999 Brian Paul All Rights Reserved. 6cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * 7cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * Permission is hereby granted, free of charge, to any person obtaining a 8cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * copy of this software and associated documentation files (the "Software"), 9cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * to deal in the Software without restriction, including without limitation 10cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * and/or sell copies of the Software, and to permit persons to whom the 12cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * Software is furnished to do so, subject to the following conditions: 13cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * 14cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * The above copyright notice and this permission notice shall be included 15cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * in all copies or substantial portions of the Software. 16cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * 17cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson */ 24cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 25cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 26cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson/* xfonts.c -- glXUseXFont() for Mesa written by 27cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de 28cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson */ 29cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 30cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson/* 31cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson This was take from Mesa and modified to work in the real GLX structure. 32cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson It provides a fully client side implementation of glXUseXFont and is 33cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson called by that routine when direct rendering is enabled. 34cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson*/ 35cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 36286ce2719395485ffafb38097fa2551b066acd96Kristian Høgsberg#ifdef GLX_DIRECT_RENDERING 37cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 38cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#include "glxclient.h" 39cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 40cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson/* Some debugging info. */ 41cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 42cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#ifdef DEBUG 43cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#undef _R 44cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#undef _G 45cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#undef _B 46cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#include <ctype.h> 47cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 48cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksonint debug_xfonts = 0; 49cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 50cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksonstatic void 511d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristófdump_char_struct(XCharStruct * ch, char *prefix) 52cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson{ 531d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf printf("%slbearing = %d, rbearing = %d, width = %d\n", 54cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson prefix, ch->lbearing, ch->rbearing, ch->width); 551d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf printf("%sascent = %d, descent = %d, attributes = %u\n", 56cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson prefix, ch->ascent, ch->descent, (unsigned int) ch->attributes); 57cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson} 58cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 59cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksonstatic void 601d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristófdump_font_struct(XFontStruct * font) 61cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson{ 621d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf printf("ascent = %d, descent = %d\n", font->ascent, font->descent); 631d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf printf("char_or_byte2 = (%u,%u)\n", 64cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson font->min_char_or_byte2, font->max_char_or_byte2); 651d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf printf("byte1 = (%u,%u)\n", font->min_byte1, font->max_byte1); 661d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf printf("all_chars_exist = %s\n", font->all_chars_exist ? "True" : "False"); 671d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf printf("default_char = %c (\\%03o)\n", 681d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf (char) (isprint(font->default_char) ? font->default_char : ' '), 69cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson font->default_char); 701d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf dump_char_struct(&font->min_bounds, "min> "); 711d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf dump_char_struct(&font->max_bounds, "max> "); 72cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#if 0 731d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf for (c = font->min_char_or_byte2; c <= font->max_char_or_byte2; c++) { 74cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson char prefix[8]; 751d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf sprintf(prefix, "%d> ", c); 761d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf dump_char_struct(&font->per_char[c], prefix); 771d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf } 78cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#endif 79cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson} 80cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 81cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksonstatic void 821d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristófdump_bitmap(unsigned int width, unsigned int height, GLubyte * bitmap) 83cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson{ 841d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf unsigned int x, y; 851d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf 861d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf printf(" "); 871d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf for (x = 0; x < 8 * width; x++) 881d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf printf("%o", 7 - (x % 8)); 891d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf putchar('\n'); 901d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf for (y = 0; y < height; y++) { 911d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf printf("%3o:", y); 921d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf for (x = 0; x < 8 * width; x++) 931d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf putchar((bitmap[width * (height - y - 1) + x / 8] & (1 << (7 - (x % 941d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf 8)))) 95cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson ? '*' : '.'); 961d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf printf(" "); 97cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson for (x = 0; x < width; x++) 981d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf printf("0x%02x, ", bitmap[width * (height - y - 1) + x]); 991d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf putchar('\n'); 1001d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf } 101cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson} 102cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#endif /* DEBUG */ 103cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 104cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 105cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson/* Implementation. */ 106cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 107cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson/* Fill a BITMAP with a character C from thew current font 108cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson in the graphics context GC. WIDTH is the width in bytes 109cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson and HEIGHT is the height in bits. 110cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 111cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson Note that the generated bitmaps must be used with 112cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 113cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE); 114cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE); 115cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); 116cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson glPixelStorei (GL_UNPACK_SKIP_ROWS, 0); 117cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0); 118cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson glPixelStorei (GL_UNPACK_ALIGNMENT, 1); 119cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 120cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson Possible optimizations: 121cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 122cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * use only one reusable pixmap with the maximum dimensions. 123cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * draw the entire font into a single pixmap (careful with 124cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson proportional fonts!). 125cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson*/ 126cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 127cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 128cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson/* 129cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * Generate OpenGL-compatible bitmap. 130cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson */ 131cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksonstatic void 1321d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóffill_bitmap(Display * dpy, Window win, GC gc, 1331d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf unsigned int width, unsigned int height, 1341d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf int x0, int y0, unsigned int c, GLubyte * bitmap) 135cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson{ 1361d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf XImage *image; 1371d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf unsigned int x, y; 1381d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf Pixmap pixmap; 1391d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf XChar2b char2b; 1401d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf 1411d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf pixmap = XCreatePixmap(dpy, win, 8 * width, height, 1); 1421d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf XSetForeground(dpy, gc, 0); 1431d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf XFillRectangle(dpy, pixmap, gc, 0, 0, 8 * width, height); 1441d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf XSetForeground(dpy, gc, 1); 1451d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf 1461d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf char2b.byte1 = (c >> 8) & 0xff; 1471d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf char2b.byte2 = (c & 0xff); 1481d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf 1491d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf XDrawString16(dpy, pixmap, gc, x0, y0, &char2b, 1); 1501d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf 1511d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf image = XGetImage(dpy, pixmap, 0, 0, 8 * width, height, 1, XYPixmap); 1521d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf if (image) { 1531d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf /* Fill the bitmap (X11 and OpenGL are upside down wrt each other). */ 1541d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf for (y = 0; y < height; y++) 1551d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf for (x = 0; x < 8 * width; x++) 1561d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf if (XGetPixel(image, x, y)) 1571d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf bitmap[width * (height - y - 1) + x / 8] |= 1581d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf (1 << (7 - (x % 8))); 1591d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf XDestroyImage(image); 1601d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf } 1611d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf 1621d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf XFreePixmap(dpy, pixmap); 163cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson} 164cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 165cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson/* 166cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * determine if a given glyph is valid and return the 167cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * corresponding XCharStruct. 168cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson */ 1691d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristófstatic XCharStruct * 1701d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristófisvalid(XFontStruct * fs, int which) 171cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson{ 1721d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf unsigned int rows, pages; 1731d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf int byte1 = 0, byte2 = 0; 1741d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf int i, valid = 1; 1751d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf 1761d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf rows = fs->max_byte1 - fs->min_byte1 + 1; 1771d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1; 1781d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf 1791d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf if (rows == 1) { 1801d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf /* "linear" fonts */ 1811d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf if ((fs->min_char_or_byte2 > which) || (fs->max_char_or_byte2 < which)) 1821d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf valid = 0; 1831d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf } 1841d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf else { 1851d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf /* "matrix" fonts */ 1861d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf byte2 = which & 0xff; 1871d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf byte1 = which >> 8; 1881d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf if ((fs->min_char_or_byte2 > byte2) || 1891d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf (fs->max_char_or_byte2 < byte2) || 1901d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf (fs->min_byte1 > byte1) || (fs->max_byte1 < byte1)) 1911d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf valid = 0; 1921d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf } 1931d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf 1941d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf if (valid) { 1951d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf if (fs->per_char) { 1961d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf if (rows == 1) { 1971d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf /* "linear" fonts */ 1981d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf return (fs->per_char + (which - fs->min_char_or_byte2)); 1991d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf } 2001d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf else { 2011d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf /* "matrix" fonts */ 2021d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf i = ((byte1 - fs->min_byte1) * pages) + 2031d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf (byte2 - fs->min_char_or_byte2); 2041d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf return (fs->per_char + i); 2051d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf } 206cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson } 2071d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf else { 2081d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf return (&fs->min_bounds); 2091d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf } 2101d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf } 2111d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf return (NULL); 212cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson} 213cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 2141d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf_X_HIDDEN void 215c356f5867f2c1fad7155df538b9affa8dbdcf869Kristian HøgsbergDRI_glXUseXFont(struct glx_context *CC, Font font, int first, int count, int listbase) 216cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson{ 2171d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf Display *dpy; 2181d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf Window win; 2191d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf Pixmap pixmap; 2201d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf GC gc; 2211d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf XGCValues values; 2221d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf unsigned long valuemask; 2231d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf XFontStruct *fs; 2241d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf 2251d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf GLint swapbytes, lsbfirst, rowlength; 2261d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf GLint skiprows, skippixels, alignment; 2271d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf 2281d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf unsigned int max_width, max_height, max_bm_width, max_bm_height; 2291d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf GLubyte *bm; 2301d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf 2311d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf int i; 2321d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf 2331d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf dpy = CC->currentDpy; 2341d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf win = CC->currentDrawable; 2351d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf 2361d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf fs = XQueryFont(dpy, font); 2371d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf if (!fs) { 238cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson __glXSetError(CC, GL_INVALID_VALUE); 239cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson return; 2401d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf } 2411d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf 2421d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf /* Allocate a bitmap that can fit all characters. */ 2431d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing; 2441d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf max_height = fs->max_bounds.ascent + fs->max_bounds.descent; 2451d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf max_bm_width = (max_width + 7) / 8; 2461d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf max_bm_height = max_height; 2471d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf 2481d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf bm = (GLubyte *) Xmalloc((max_bm_width * max_bm_height) * sizeof(GLubyte)); 2491d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf if (!bm) { 2501d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf XFreeFontInfo(NULL, fs, 1); 251cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson __glXSetError(CC, GL_OUT_OF_MEMORY); 252cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson return; 2531d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf } 254cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 255cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#if 0 2561d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf /* get the page info */ 2571d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1; 2581d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf firstchar = (fs->min_byte1 << 8) + fs->min_char_or_byte2; 2591d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf lastchar = (fs->max_byte1 << 8) + fs->max_char_or_byte2; 2601d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf rows = fs->max_byte1 - fs->min_byte1 + 1; 2611d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf unsigned int first_char, last_char, pages, rows; 262cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#endif 263cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 2641d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf /* Save the current packing mode for bitmaps. */ 2651d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes); 2661d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst); 2671d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength); 2681d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows); 2691d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels); 2701d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment); 2711d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf 2721d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf /* Enforce a standard packing mode which is compatible with 2731d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf fill_bitmap() from above. This is actually the default mode, 2741d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf except for the (non)alignment. */ 2751d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); 2761d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); 2771d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 2781d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); 2791d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); 2801d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 2811d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf 2821d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf pixmap = XCreatePixmap(dpy, win, 10, 10, 1); 2831d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf values.foreground = BlackPixel(dpy, DefaultScreen(dpy)); 2841d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf values.background = WhitePixel(dpy, DefaultScreen(dpy)); 2851d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf values.font = fs->fid; 2861d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf valuemask = GCForeground | GCBackground | GCFont; 2871d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf gc = XCreateGC(dpy, pixmap, valuemask, &values); 2881d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf XFreePixmap(dpy, pixmap); 289cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 290cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#ifdef DEBUG 2911d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf if (debug_xfonts) 2921d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf dump_font_struct(fs); 293cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#endif 294cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 2951d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf for (i = 0; i < count; i++) { 296cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson unsigned int width, height, bm_width, bm_height; 297cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson GLfloat x0, y0, dx, dy; 298cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson XCharStruct *ch; 299cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson int x, y; 300cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson unsigned int c = first + i; 301cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson int list = listbase + i; 302cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson int valid; 303cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 304cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson /* check on index validity and get the bounds */ 305cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson ch = isvalid(fs, c); 306cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson if (!ch) { 3071d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf ch = &fs->max_bounds; 3081d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf valid = 0; 3091d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf } 3101d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf else { 3111d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf valid = 1; 312cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson } 313cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 314cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#ifdef DEBUG 315cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson if (debug_xfonts) { 3161d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf char s[7]; 3171d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf sprintf(s, isprint(c) ? "%c> " : "\\%03o> ", c); 3181d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf dump_char_struct(ch, s); 319cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson } 320cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#endif 321cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 322cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson /* glBitmap()' parameters: 323cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson straight from the glXUseXFont(3) manpage. */ 324cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson width = ch->rbearing - ch->lbearing; 325cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson height = ch->ascent + ch->descent; 3261d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf x0 = -ch->lbearing; 327cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson y0 = ch->descent - 1; 328cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson dx = ch->width; 329cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson dy = 0; 330cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 331cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson /* X11's starting point. */ 3321d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf x = -ch->lbearing; 333cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson y = ch->ascent; 334cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 335cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson /* Round the width to a multiple of eight. We will use this also 336cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson for the pixmap for capturing the X11 font. This is slightly 337cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson inefficient, but it makes the OpenGL part real easy. */ 338cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson bm_width = (width + 7) / 8; 339cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson bm_height = height; 340cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 3411d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glNewList(list, GL_COMPILE); 3421d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf if (valid && (bm_width > 0) && (bm_height > 0)) { 343cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 3441d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf memset(bm, '\0', bm_width * bm_height); 3451d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm); 346cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 3471d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glBitmap(width, height, x0, y0, dx, dy, bm); 348cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#ifdef DEBUG 3491d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf if (debug_xfonts) { 3501d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf printf("width/height = %u/%u\n", width, height); 3511d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf printf("bm_width/bm_height = %u/%u\n", bm_width, bm_height); 3521d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf dump_bitmap(bm_width, bm_height, bm); 3531d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf } 354cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#endif 3551d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf } 3561d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf else { 3571d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glBitmap(0, 0, 0.0, 0.0, dx, dy, NULL); 3581d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf } 3591d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glEndList(); 3601d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf } 3611d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf 3621d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf Xfree(bm); 3631d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf XFreeFontInfo(NULL, fs, 1); 3641d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf XFreeGC(dpy, gc); 3651d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf 3661d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf /* Restore saved packing modes. */ 3671d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes); 3681d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst); 3691d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength); 3701d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows); 3711d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels); 3721d0a9e4377b89dffb201eb3cb76c7f72969675b3RALOVICH, Kristóf glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); 373cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson} 374cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson 375286ce2719395485ffafb38097fa2551b066acd96Kristian Høgsberg#endif 376