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