xfont.c revision 23215ef4d60a86d9f3b3fdc08e3fdadc59e98890
1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/* 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Mesa 3-D graphics library 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Version: 3.1 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Copyright (C) 1999 Brian Paul All Rights Reserved. 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Permission is hereby granted, free of charge, to any person obtaining a 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * copy of this software and associated documentation files (the "Software"), 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * to deal in the Software without restriction, including without limitation 10bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) * and/or sell copies of the Software, and to permit persons to whom the 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Software is furnished to do so, subject to the following conditions: 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * The above copyright notice and this permission notice shall be included 155b892326406927b709cdaf6c384d4ababf456332Ben Murdoch * in all copies or substantial portions of the Software. 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */ 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/* xfonts.c -- glXUseXFont() for Mesa written by 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */ 29a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 30a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)/* 31a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) This was take from Mesa and modified to work in the real GLX structure. 32a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch It provides a fully client side implementation of glXUseXFont and is 33a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) called by that routine when direct rendering is enabled. 34a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch*/ 35a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 36a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#ifdef GLX_DIRECT_RENDERING 37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 38a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "glxclient.h" 39a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 40a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)/* Some debugging info. */ 41a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 42a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#ifdef DEBUG 43a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#undef _R 44a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#undef _G 45a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#undef _B 46a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include <ctype.h> 47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int debug_xfonts = 0; 49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 50c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochstatic void 51a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)dump_char_struct(XCharStruct * ch, char *prefix) 52a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles){ 53a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) printf("%slbearing = %d, rbearing = %d, width = %d\n", 54a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) prefix, ch->lbearing, ch->rbearing, ch->width); 55a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) printf("%sascent = %d, descent = %d, attributes = %u\n", 56a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) prefix, ch->ascent, ch->descent, (unsigned int) ch->attributes); 57a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 58a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 59a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochstatic void 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)dump_font_struct(XFontStruct * font) 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 6258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch printf("ascent = %d, descent = %d\n", font->ascent, font->descent); 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) printf("char_or_byte2 = (%u,%u)\n", 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) font->min_char_or_byte2, font->max_char_or_byte2); 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) printf("byte1 = (%u,%u)\n", font->min_byte1, font->max_byte1); 665b892326406927b709cdaf6c384d4ababf456332Ben Murdoch printf("all_chars_exist = %s\n", font->all_chars_exist ? "True" : "False"); 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) printf("default_char = %c (\\%03o)\n", 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (char) (isprint(font->default_char) ? font->default_char : ' '), 69a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch font->default_char); 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dump_char_struct(&font->min_bounds, "min> "); 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dump_char_struct(&font->max_bounds, "max> "); 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if 0 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (c = font->min_char_or_byte2; c <= font->max_char_or_byte2; c++) { 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) char prefix[8]; 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sprintf(prefix, "%d> ", c); 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) dump_char_struct(&font->per_char[c], prefix); 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)static void 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)dump_bitmap(unsigned int width, unsigned int height, GLubyte * bitmap) 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int x, y; 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) printf(" "); 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (x = 0; x < 8 * width; x++) 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) printf("%o", 7 - (x % 8)); 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) putchar('\n'); 90b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) for (y = 0; y < height; y++) { 91a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) printf("%3o:", y); 92b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) for (x = 0; x < 8 * width; x++) 93b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) putchar((bitmap[width * (height - y - 1) + x / 8] & (1 << (7 - (x % 94b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 8)))) 95b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ? '*' : '.'); 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) printf(" "); 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (x = 0; x < width; x++) 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) printf("0x%02x, ", bitmap[width * (height - y - 1) + x]); 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) putchar('\n'); 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif /* DEBUG */ 103b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 104b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 105b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)/* Implementation. */ 106b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 107b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)/* Fill a BITMAP with a character C from thew current font 108b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) in the graphics context GC. WIDTH is the width in bytes 109b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) and HEIGHT is the height in bits. 110b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 111a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) Note that the generated bitmaps must be used with 112a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 113a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE); 114b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE); 115b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); 116b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) glPixelStorei (GL_UNPACK_SKIP_ROWS, 0); 117b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0); 118b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) glPixelStorei (GL_UNPACK_ALIGNMENT, 1); 119b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 120b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) Possible optimizations: 121b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 122b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) * use only one reusable pixmap with the maximum dimensions. 123a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) * draw the entire font into a single pixmap (careful with 124a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) proportional fonts!). 125a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)*/ 126a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 127b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch/* 129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * Generate OpenGL-compatible bitmap. 130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch */ 131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochstatic void 132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochfill_bitmap(Display * dpy, Window win, GC gc, 133b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) unsigned int width, unsigned int height, 1345b892326406927b709cdaf6c384d4ababf456332Ben Murdoch int x0, int y0, unsigned int c, GLubyte * bitmap) 1355b892326406927b709cdaf6c384d4ababf456332Ben Murdoch{ 1365b892326406927b709cdaf6c384d4ababf456332Ben Murdoch XImage *image; 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int x, y; 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Pixmap pixmap; 1395b892326406927b709cdaf6c384d4ababf456332Ben Murdoch XChar2b char2b; 1405b892326406927b709cdaf6c384d4ababf456332Ben Murdoch 1415b892326406927b709cdaf6c384d4ababf456332Ben Murdoch pixmap = XCreatePixmap(dpy, win, 8 * width, height, 1); 1425b892326406927b709cdaf6c384d4ababf456332Ben Murdoch XSetForeground(dpy, gc, 0); 1435b892326406927b709cdaf6c384d4ababf456332Ben Murdoch XFillRectangle(dpy, pixmap, gc, 0, 0, 8 * width, height); 1445b892326406927b709cdaf6c384d4ababf456332Ben Murdoch XSetForeground(dpy, gc, 1); 1455b892326406927b709cdaf6c384d4ababf456332Ben Murdoch 1465b892326406927b709cdaf6c384d4ababf456332Ben Murdoch char2b.byte1 = (c >> 8) & 0xff; 1475b892326406927b709cdaf6c384d4ababf456332Ben Murdoch char2b.byte2 = (c & 0xff); 1485b892326406927b709cdaf6c384d4ababf456332Ben Murdoch 1495b892326406927b709cdaf6c384d4ababf456332Ben Murdoch XDrawString16(dpy, pixmap, gc, x0, y0, &char2b, 1); 1505b892326406927b709cdaf6c384d4ababf456332Ben Murdoch 1515b892326406927b709cdaf6c384d4ababf456332Ben Murdoch image = XGetImage(dpy, pixmap, 0, 0, 8 * width, height, 1, XYPixmap); 1525b892326406927b709cdaf6c384d4ababf456332Ben Murdoch if (image) { 1535b892326406927b709cdaf6c384d4ababf456332Ben Murdoch /* Fill the bitmap (X11 and OpenGL are upside down wrt each other). */ 1545b892326406927b709cdaf6c384d4ababf456332Ben Murdoch for (y = 0; y < height; y++) 1555b892326406927b709cdaf6c384d4ababf456332Ben Murdoch for (x = 0; x < 8 * width; x++) 1565b892326406927b709cdaf6c384d4ababf456332Ben Murdoch if (XGetPixel(image, x, y)) 1575b892326406927b709cdaf6c384d4ababf456332Ben Murdoch bitmap[width * (height - y - 1) + x / 8] |= 1585b892326406927b709cdaf6c384d4ababf456332Ben Murdoch (1 << (7 - (x % 8))); 1595b892326406927b709cdaf6c384d4ababf456332Ben Murdoch XDestroyImage(image); 1605b892326406927b709cdaf6c384d4ababf456332Ben Murdoch } 1615b892326406927b709cdaf6c384d4ababf456332Ben Murdoch 1625b892326406927b709cdaf6c384d4ababf456332Ben Murdoch XFreePixmap(dpy, pixmap); 1635b892326406927b709cdaf6c384d4ababf456332Ben Murdoch} 1645b892326406927b709cdaf6c384d4ababf456332Ben Murdoch 1655b892326406927b709cdaf6c384d4ababf456332Ben Murdoch/* 1665b892326406927b709cdaf6c384d4ababf456332Ben Murdoch * determine if a given glyph is valid and return the 1675b892326406927b709cdaf6c384d4ababf456332Ben Murdoch * corresponding XCharStruct. 1685b892326406927b709cdaf6c384d4ababf456332Ben Murdoch */ 1695b892326406927b709cdaf6c384d4ababf456332Ben Murdochstatic XCharStruct * 1705b892326406927b709cdaf6c384d4ababf456332Ben Murdochisvalid(XFontStruct * fs, int which) 1715b892326406927b709cdaf6c384d4ababf456332Ben Murdoch{ 1725b892326406927b709cdaf6c384d4ababf456332Ben Murdoch unsigned int rows, pages; 1735b892326406927b709cdaf6c384d4ababf456332Ben Murdoch int byte1 = 0, byte2 = 0; 1745b892326406927b709cdaf6c384d4ababf456332Ben Murdoch int i, valid = 1; 1755b892326406927b709cdaf6c384d4ababf456332Ben Murdoch 1765b892326406927b709cdaf6c384d4ababf456332Ben Murdoch rows = fs->max_byte1 - fs->min_byte1 + 1; 1775b892326406927b709cdaf6c384d4ababf456332Ben Murdoch pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1; 1785b892326406927b709cdaf6c384d4ababf456332Ben Murdoch 1795b892326406927b709cdaf6c384d4ababf456332Ben Murdoch if (rows == 1) { 1805b892326406927b709cdaf6c384d4ababf456332Ben Murdoch /* "linear" fonts */ 1815b892326406927b709cdaf6c384d4ababf456332Ben Murdoch if ((fs->min_char_or_byte2 > which) || (fs->max_char_or_byte2 < which)) 1825b892326406927b709cdaf6c384d4ababf456332Ben Murdoch valid = 0; 1835b892326406927b709cdaf6c384d4ababf456332Ben Murdoch } 1845b892326406927b709cdaf6c384d4ababf456332Ben Murdoch else { 1855b892326406927b709cdaf6c384d4ababf456332Ben Murdoch /* "matrix" fonts */ 1865b892326406927b709cdaf6c384d4ababf456332Ben Murdoch byte2 = which & 0xff; 1875b892326406927b709cdaf6c384d4ababf456332Ben Murdoch byte1 = which >> 8; 1885b892326406927b709cdaf6c384d4ababf456332Ben Murdoch if ((fs->min_char_or_byte2 > byte2) || 1895b892326406927b709cdaf6c384d4ababf456332Ben Murdoch (fs->max_char_or_byte2 < byte2) || 1905b892326406927b709cdaf6c384d4ababf456332Ben Murdoch (fs->min_byte1 > byte1) || (fs->max_byte1 < byte1)) 1915b892326406927b709cdaf6c384d4ababf456332Ben Murdoch valid = 0; 1925b892326406927b709cdaf6c384d4ababf456332Ben Murdoch } 1935b892326406927b709cdaf6c384d4ababf456332Ben Murdoch 1945b892326406927b709cdaf6c384d4ababf456332Ben Murdoch if (valid) { 1955b892326406927b709cdaf6c384d4ababf456332Ben Murdoch if (fs->per_char) { 1965b892326406927b709cdaf6c384d4ababf456332Ben Murdoch if (rows == 1) { 1975b892326406927b709cdaf6c384d4ababf456332Ben Murdoch /* "linear" fonts */ 1985b892326406927b709cdaf6c384d4ababf456332Ben Murdoch return (fs->per_char + (which - fs->min_char_or_byte2)); 1995b892326406927b709cdaf6c384d4ababf456332Ben Murdoch } 2005b892326406927b709cdaf6c384d4ababf456332Ben Murdoch else { 2015b892326406927b709cdaf6c384d4ababf456332Ben Murdoch /* "matrix" fonts */ 2025b892326406927b709cdaf6c384d4ababf456332Ben Murdoch i = ((byte1 - fs->min_byte1) * pages) + 2035b892326406927b709cdaf6c384d4ababf456332Ben Murdoch (byte2 - fs->min_char_or_byte2); 2045b892326406927b709cdaf6c384d4ababf456332Ben Murdoch return (fs->per_char + i); 205a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2075b892326406927b709cdaf6c384d4ababf456332Ben Murdoch else { 208a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return (&fs->min_bounds); 209a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 210a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 211a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return (NULL); 2125b892326406927b709cdaf6c384d4ababf456332Ben Murdoch} 213b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 214a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)_X_HIDDEN void 215a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)DRI_glXUseXFont(Font font, int first, int count, int listbase) 216a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles){ 217a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) GLXContext CC; 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Display *dpy; 219c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Window win; 220c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Pixmap pixmap; 221c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GC gc; 222c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch XGCValues values; 223c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch unsigned long valuemask; 224c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch XFontStruct *fs; 225c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 226c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GLint swapbytes, lsbfirst, rowlength; 227c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GLint skiprows, skippixels, alignment; 228c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 229c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch unsigned int max_width, max_height, max_bm_width, max_bm_height; 230a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch GLubyte *bm; 231c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 232c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int i; 233a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 234c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CC = __glXGetCurrentContext(); 235a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch dpy = CC->currentDpy; 236c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch win = CC->currentDrawable; 237c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 238c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch fs = XQueryFont(dpy, font); 239c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!fs) { 240c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch __glXSetError(CC, GL_INVALID_VALUE); 241c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 242c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 243a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 244a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch /* Allocate a bitmap that can fit all characters. */ 245a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing; 246a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch max_height = fs->max_bounds.ascent + fs->max_bounds.descent; 247b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) max_bm_width = (max_width + 7) / 8; 248a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) max_bm_height = max_height; 2495b892326406927b709cdaf6c384d4ababf456332Ben Murdoch 250b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) bm = (GLubyte *) Xmalloc((max_bm_width * max_bm_height) * sizeof(GLubyte)); 251c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!bm) { 2525b892326406927b709cdaf6c384d4ababf456332Ben Murdoch XFreeFontInfo(NULL, fs, 1); 253a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) __glXSetError(CC, GL_OUT_OF_MEMORY); 254a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return; 255a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 256a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if 0 258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* get the page info */ 259a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1; 2605b892326406927b709cdaf6c384d4ababf456332Ben Murdoch firstchar = (fs->min_byte1 << 8) + fs->min_char_or_byte2; 261a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) lastchar = (fs->max_byte1 << 8) + fs->max_char_or_byte2; 262a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) rows = fs->max_byte1 - fs->min_byte1 + 1; 263b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) unsigned int first_char, last_char, pages, rows; 264b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#endif 265a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 266a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) /* Save the current packing mode for bitmaps. */ 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes); 268b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst); 269a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength); 270a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows); 271b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels); 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment); 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 274b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) /* Enforce a standard packing mode which is compatible with 275a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) fill_bitmap() from above. This is actually the default mode, 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except for the (non)alignment. */ 277a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); 278a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); 279a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 2805b892326406927b709cdaf6c384d4ababf456332Ben Murdoch glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); 2815b892326406927b709cdaf6c384d4ababf456332Ben Murdoch glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pixmap = XCreatePixmap(dpy, win, 10, 10, 1); 285 values.foreground = BlackPixel(dpy, DefaultScreen(dpy)); 286 values.background = WhitePixel(dpy, DefaultScreen(dpy)); 287 values.font = fs->fid; 288 valuemask = GCForeground | GCBackground | GCFont; 289 gc = XCreateGC(dpy, pixmap, valuemask, &values); 290 XFreePixmap(dpy, pixmap); 291 292#ifdef DEBUG 293 if (debug_xfonts) 294 dump_font_struct(fs); 295#endif 296 297 for (i = 0; i < count; i++) { 298 unsigned int width, height, bm_width, bm_height; 299 GLfloat x0, y0, dx, dy; 300 XCharStruct *ch; 301 int x, y; 302 unsigned int c = first + i; 303 int list = listbase + i; 304 int valid; 305 306 /* check on index validity and get the bounds */ 307 ch = isvalid(fs, c); 308 if (!ch) { 309 ch = &fs->max_bounds; 310 valid = 0; 311 } 312 else { 313 valid = 1; 314 } 315 316#ifdef DEBUG 317 if (debug_xfonts) { 318 char s[7]; 319 sprintf(s, isprint(c) ? "%c> " : "\\%03o> ", c); 320 dump_char_struct(ch, s); 321 } 322#endif 323 324 /* glBitmap()' parameters: 325 straight from the glXUseXFont(3) manpage. */ 326 width = ch->rbearing - ch->lbearing; 327 height = ch->ascent + ch->descent; 328 x0 = -ch->lbearing; 329 y0 = ch->descent - 1; 330 dx = ch->width; 331 dy = 0; 332 333 /* X11's starting point. */ 334 x = -ch->lbearing; 335 y = ch->ascent; 336 337 /* Round the width to a multiple of eight. We will use this also 338 for the pixmap for capturing the X11 font. This is slightly 339 inefficient, but it makes the OpenGL part real easy. */ 340 bm_width = (width + 7) / 8; 341 bm_height = height; 342 343 glNewList(list, GL_COMPILE); 344 if (valid && (bm_width > 0) && (bm_height > 0)) { 345 346 memset(bm, '\0', bm_width * bm_height); 347 fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm); 348 349 glBitmap(width, height, x0, y0, dx, dy, bm); 350#ifdef DEBUG 351 if (debug_xfonts) { 352 printf("width/height = %u/%u\n", width, height); 353 printf("bm_width/bm_height = %u/%u\n", bm_width, bm_height); 354 dump_bitmap(bm_width, bm_height, bm); 355 } 356#endif 357 } 358 else { 359 glBitmap(0, 0, 0.0, 0.0, dx, dy, NULL); 360 } 361 glEndList(); 362 } 363 364 Xfree(bm); 365 XFreeFontInfo(NULL, fs, 1); 366 XFreeGC(dpy, gc); 367 368 /* Restore saved packing modes. */ 369 glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes); 370 glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst); 371 glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength); 372 glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows); 373 glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels); 374 glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); 375} 376 377#endif 378