1afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
2afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/*
3afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Mesa 3-D graphics library
4e9bf776711b22ce336cd462adf534ad3e2d61eecKeith Whitwell * Version:  3.5
5afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg *
671dea349d2be623b7819389428b0d6a124e8d184Brian Paul * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
7afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg *
8afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Permission is hereby granted, free of charge, to any person obtaining a
9afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * copy of this software and associated documentation files (the "Software"),
10afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * to deal in the Software without restriction, including without limitation
11afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * and/or sell copies of the Software, and to permit persons to whom the
13afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Software is furnished to do so, subject to the following conditions:
14afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg *
15afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * The above copyright notice and this permission notice shall be included
16afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * in all copies or substantial portions of the Software.
17afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg *
18afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
25afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
26afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
27afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/* xfonts.c -- glXUseXFont() for Mesa written by
28afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de
29afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
30afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
31b5b5c52034840dbfcd3f76a9e7cde8b379e7d517Jouk Jansen#ifdef __VMS
32b5b5c52034840dbfcd3f76a9e7cde8b379e7d517Jouk Jansen#include <GL/vms_x_fix.h>
33b5b5c52034840dbfcd3f76a9e7cde8b379e7d517Jouk Jansen#endif
34afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
353c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "glxheader.h"
36374e7fd6cc95d3d91629a6e1c951d77e8a29c31cBrian Paul#include "main/context.h"
37374e7fd6cc95d3d91629a6e1c951d77e8a29c31cBrian Paul#include "main/imports.h"
3871dea349d2be623b7819389428b0d6a124e8d184Brian Paul#include "xfonts.h"
39afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
4071dea349d2be623b7819389428b0d6a124e8d184Brian Paul
41afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/* Some debugging info.  */
42afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
43afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#ifdef DEBUG
44afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#undef _R
45afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#undef _G
46afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#undef _B
47afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include <ctype.h>
48afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
49afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgint debug_xfonts = 0;
50afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
51afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgstatic void
5249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Pauldump_char_struct(XCharStruct * ch, char *prefix)
53afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
5449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   printf("%slbearing = %d, rbearing = %d, width = %d\n",
5549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	  prefix, ch->lbearing, ch->rbearing, ch->width);
5649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   printf("%sascent = %d, descent = %d, attributes = %u\n",
5749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	  prefix, ch->ascent, ch->descent, (unsigned int) ch->attributes);
58afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
59afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
60afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgstatic void
6149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Pauldump_font_struct(XFontStruct * font)
62afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
6349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   printf("ascent = %d, descent = %d\n", font->ascent, font->descent);
6449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   printf("char_or_byte2 = (%u,%u)\n",
6549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	  font->min_char_or_byte2, font->max_char_or_byte2);
6649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   printf("byte1 = (%u,%u)\n", font->min_byte1, font->max_byte1);
6749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   printf("all_chars_exist = %s\n", font->all_chars_exist ? "True" : "False");
6849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   printf("default_char = %c (\\%03o)\n",
6949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	  (char) (isprint(font->default_char) ? font->default_char : ' '),
7049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	  font->default_char);
7149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   dump_char_struct(&font->min_bounds, "min> ");
7249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   dump_char_struct(&font->max_bounds, "max> ");
73afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#if 0
7449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   for (c = font->min_char_or_byte2; c <= font->max_char_or_byte2; c++) {
75afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      char prefix[8];
7649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      sprintf(prefix, "%d> ", c);
7749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      dump_char_struct(&font->per_char[c], prefix);
7849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   }
79afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#endif
80afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
81afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
82afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgstatic void
8349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Pauldump_bitmap(unsigned int width, unsigned int height, GLubyte * bitmap)
84afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
8549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   unsigned int x, y;
8649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul
8749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   printf("    ");
8849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   for (x = 0; x < 8 * width; x++)
8949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      printf("%o", 7 - (x % 8));
9049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   putchar('\n');
9149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   for (y = 0; y < height; y++) {
9249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      printf("%3o:", y);
9349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      for (x = 0; x < 8 * width; x++)
9449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	 putchar((bitmap[width * (height - y - 1) + x / 8] & (1 << (7 - (x %
9549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul									 8))))
9649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul		 ? '*' : '.');
9749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      printf("   ");
98afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      for (x = 0; x < width; x++)
9949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	 printf("0x%02x, ", bitmap[width * (height - y - 1) + x]);
10049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      putchar('\n');
10149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   }
102afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
103afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#endif /* DEBUG */
104afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
105afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
106afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/* Implementation.  */
107afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
108afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/* Fill a BITMAP with a character C from thew current font
109afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   in the graphics context GC.  WIDTH is the width in bytes
110afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   and HEIGHT is the height in bits.
111afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
112afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   Note that the generated bitmaps must be used with
113afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
114afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg        glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
115afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg        glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
116afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg        glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
117afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg        glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
118afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg        glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
119afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg        glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
120afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
121afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   Possible optimizations:
122afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
123afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg     * use only one reusable pixmap with the maximum dimensions.
124afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg     * draw the entire font into a single pixmap (careful with
125afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg       proportional fonts!).
126afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg*/
127afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
128afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
129afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/*
130afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Generate OpenGL-compatible bitmap.
131afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
132afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgstatic void
13349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paulfill_bitmap(Display * dpy, Window win, GC gc,
13449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	    unsigned int width, unsigned int height,
13549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	    int x0, int y0, unsigned int c, GLubyte * bitmap)
136afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
13749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   XImage *image;
13849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   unsigned int x, y;
13949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   Pixmap pixmap;
14049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   XChar2b char2b;
14149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul
14249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   pixmap = XCreatePixmap(dpy, win, 8 * width, height, 1);
14349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   XSetForeground(dpy, gc, 0);
14449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   XFillRectangle(dpy, pixmap, gc, 0, 0, 8 * width, height);
14549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   XSetForeground(dpy, gc, 1);
14649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul
14749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   char2b.byte1 = (c >> 8) & 0xff;
14849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   char2b.byte2 = (c & 0xff);
14949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul
15049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   XDrawString16(dpy, pixmap, gc, x0, y0, &char2b, 1);
15149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul
15249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   image = XGetImage(dpy, pixmap, 0, 0, 8 * width, height, 1, XYPixmap);
15349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   if (image) {
15449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      /* Fill the bitmap (X11 and OpenGL are upside down wrt each other).  */
15549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      for (y = 0; y < height; y++)
15649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	 for (x = 0; x < 8 * width; x++)
15749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	    if (XGetPixel(image, x, y))
15849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	       bitmap[width * (height - y - 1) + x / 8] |=
15949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul		  (1 << (7 - (x % 8)));
16049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      XDestroyImage(image);
16149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   }
16249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul
16349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   XFreePixmap(dpy, pixmap);
164afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
165afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
166afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/*
167afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * determine if a given glyph is valid and return the
168afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * corresponding XCharStruct.
169afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
17049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paulstatic XCharStruct *
17149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paulisvalid(XFontStruct * fs, unsigned int which)
172afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
17349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   unsigned int rows, pages;
17449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   unsigned int byte1 = 0, byte2 = 0;
17549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   int i, valid = 1;
17649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul
17749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   rows = fs->max_byte1 - fs->min_byte1 + 1;
17849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
17949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul
18049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   if (rows == 1) {
18149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      /* "linear" fonts */
18249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      if ((fs->min_char_or_byte2 > which) || (fs->max_char_or_byte2 < which))
18349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	 valid = 0;
18449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   }
18549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   else {
18649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      /* "matrix" fonts */
18749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      byte2 = which & 0xff;
18849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      byte1 = which >> 8;
18949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      if ((fs->min_char_or_byte2 > byte2) ||
19049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	  (fs->max_char_or_byte2 < byte2) ||
19149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	  (fs->min_byte1 > byte1) || (fs->max_byte1 < byte1))
19249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	 valid = 0;
19349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   }
19449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul
19549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   if (valid) {
19649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      if (fs->per_char) {
19749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	 if (rows == 1) {
19849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	    /* "linear" fonts */
19949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	    return (fs->per_char + (which - fs->min_char_or_byte2));
20049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	 }
20149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	 else {
20249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	    /* "matrix" fonts */
20349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	    i = ((byte1 - fs->min_byte1) * pages) +
20449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	       (byte2 - fs->min_char_or_byte2);
20549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	    return (fs->per_char + i);
20649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	 }
207afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
20849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      else {
20949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	 return (&fs->min_bounds);
21049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      }
21149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   }
21249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   return (NULL);
213afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
214afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
215afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
21649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paulvoid
21749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian PaulFake_glXUseXFont(Font font, int first, int count, int listbase)
218afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
21949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   Display *dpy;
22049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   Window win;
22149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   Pixmap pixmap;
22249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   GC gc;
22349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   XGCValues values;
22449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   unsigned long valuemask;
22549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   XFontStruct *fs;
22649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   GLint swapbytes, lsbfirst, rowlength;
22749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   GLint skiprows, skippixels, alignment;
22849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   unsigned int max_width, max_height, max_bm_width, max_bm_height;
22949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   GLubyte *bm;
23049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   int i;
23149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul
23249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   dpy = glXGetCurrentDisplay();
23349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   if (!dpy)
23449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      return;			/* I guess glXMakeCurrent wasn't called */
23549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   win = RootWindow(dpy, DefaultScreen(dpy));
23649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul
23749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   fs = XQueryFont(dpy, font);
23849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   if (!fs) {
23908836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul      _mesa_error(NULL, GL_INVALID_VALUE,
24049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul		  "Couldn't get font structure information");
241afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      return;
24249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   }
24349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul
24449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   /* Allocate a bitmap that can fit all characters.  */
24549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing;
24649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   max_height = fs->max_bounds.ascent + fs->max_bounds.descent;
24749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   max_bm_width = (max_width + 7) / 8;
24849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   max_bm_height = max_height;
24949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul
25049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   bm = (GLubyte *) MALLOC((max_bm_width * max_bm_height) * sizeof(GLubyte));
25149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   if (!bm) {
25249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      XFreeFontInfo(NULL, fs, 1);
25308836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul      _mesa_error(NULL, GL_OUT_OF_MEMORY,
25449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul		  "Couldn't allocate bitmap in glXUseXFont()");
255afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      return;
25649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   }
257afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
258afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#if 0
25949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   /* get the page info */
26049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
26149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   firstchar = (fs->min_byte1 << 8) + fs->min_char_or_byte2;
26249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   lastchar = (fs->max_byte1 << 8) + fs->max_char_or_byte2;
26349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   rows = fs->max_byte1 - fs->min_byte1 + 1;
26449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   unsigned int first_char, last_char, pages, rows;
265afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#endif
266afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
26749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   /* Save the current packing mode for bitmaps.  */
26849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes);
26949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst);
27049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength);
27149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows);
27249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels);
27349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
27449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul
27549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   /* Enforce a standard packing mode which is compatible with
27649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      fill_bitmap() from above.  This is actually the default mode,
27749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      except for the (non)alignment.  */
27849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
27949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
28049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
28149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
28249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
28349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
28449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul
28549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   pixmap = XCreatePixmap(dpy, win, 10, 10, 1);
28649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   values.foreground = BlackPixel(dpy, DefaultScreen(dpy));
28749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   values.background = WhitePixel(dpy, DefaultScreen(dpy));
28849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   values.font = fs->fid;
28949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   valuemask = GCForeground | GCBackground | GCFont;
29049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   gc = XCreateGC(dpy, pixmap, valuemask, &values);
29149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   XFreePixmap(dpy, pixmap);
292afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
293afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#ifdef DEBUG
29449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   if (debug_xfonts)
29549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      dump_font_struct(fs);
296afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#endif
297afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
29849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   for (i = 0; i < count; i++) {
299afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      unsigned int width, height, bm_width, bm_height;
300afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      GLfloat x0, y0, dx, dy;
301afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      XCharStruct *ch;
302afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      int x, y;
303afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      unsigned int c = first + i;
304afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      int list = listbase + i;
305afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      int valid;
306afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
307afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      /* check on index validity and get the bounds */
308afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      ch = isvalid(fs, c);
309afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      if (!ch) {
31049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	 ch = &fs->max_bounds;
31149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	 valid = 0;
31249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      }
31349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      else {
31449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	 valid = 1;
315afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
316afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
317afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#ifdef DEBUG
318afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      if (debug_xfonts) {
31949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	 char s[7];
32049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	 sprintf(s, isprint(c) ? "%c> " : "\\%03o> ", c);
32149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	 dump_char_struct(ch, s);
322afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
323afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#endif
324afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
325afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      /* glBitmap()' parameters:
326afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         straight from the glXUseXFont(3) manpage.  */
327afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      width = ch->rbearing - ch->lbearing;
328afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      height = ch->ascent + ch->descent;
32949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      x0 = -ch->lbearing;
33049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      y0 = ch->descent - 0;	/* XXX used to subtract 1 here */
33149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      /* but that caused a conformace failure */
332afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      dx = ch->width;
333afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      dy = 0;
334afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
335afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      /* X11's starting point.  */
33649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      x = -ch->lbearing;
337afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      y = ch->ascent;
338afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
339afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      /* Round the width to a multiple of eight.  We will use this also
340afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         for the pixmap for capturing the X11 font.  This is slightly
341afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         inefficient, but it makes the OpenGL part real easy.  */
342afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      bm_width = (width + 7) / 8;
343afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      bm_height = height;
344afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
34549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      glNewList(list, GL_COMPILE);
34649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      if (valid && (bm_width > 0) && (bm_height > 0)) {
347afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
3482240ba10f30315410bcff77e372ee71664ac4453Brian Paul	 memset(bm, '\0', bm_width * bm_height);
34949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	 fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm);
350afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
35149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	 glBitmap(width, height, x0, y0, dx, dy, bm);
352afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#ifdef DEBUG
35349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	 if (debug_xfonts) {
35449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	    printf("width/height = %u/%u\n", width, height);
35549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	    printf("bm_width/bm_height = %u/%u\n", bm_width, bm_height);
35649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	    dump_bitmap(bm_width, bm_height, bm);
35749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	 }
358afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#endif
35949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      }
36049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      else {
36149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul	 glBitmap(0, 0, 0.0, 0.0, dx, dy, NULL);
36249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      }
36349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul      glEndList();
36449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   }
36549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul
36649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   FREE(bm);
36749bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   XFreeFontInfo(NULL, fs, 1);
36849bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   XFreeGC(dpy, gc);
36949bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul
37049bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   /* Restore saved packing modes.  */
37149bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes);
37249bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst);
37349bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength);
37449bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows);
37549bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels);
37649bef526fde084b3ab20e9ff19bb89ecc31d4e55Brian Paul   glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
377afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
378