1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mesa 3-D graphics library
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Version:  7.6
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions:
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in all copies or substantial portions of the Software.
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fake implementation of glXUseXFont().
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/core.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <GL/glx.h>
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Some debugging info.  */
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <ctype.h>
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint debug_xfonts = 0;
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdump_char_struct(XCharStruct * ch, char *prefix)
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   printf("%slbearing = %d, rbearing = %d, width = %d\n",
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  prefix, ch->lbearing, ch->rbearing, ch->width);
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   printf("%sascent = %d, descent = %d, attributes = %u\n",
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  prefix, ch->ascent, ch->descent, (unsigned int) ch->attributes);
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdump_font_struct(XFontStruct * font)
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   printf("ascent = %d, descent = %d\n", font->ascent, font->descent);
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   printf("char_or_byte2 = (%u,%u)\n",
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  font->min_char_or_byte2, font->max_char_or_byte2);
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   printf("byte1 = (%u,%u)\n", font->min_byte1, font->max_byte1);
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   printf("all_chars_exist = %s\n", font->all_chars_exist ? "True" : "False");
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   printf("default_char = %c (\\%03o)\n",
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  (char) (isprint(font->default_char) ? font->default_char : ' '),
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  font->default_char);
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dump_char_struct(&font->min_bounds, "min> ");
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dump_char_struct(&font->max_bounds, "max> ");
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (c = font->min_char_or_byte2; c <= font->max_char_or_byte2; c++) {
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      char prefix[8];
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sprintf(prefix, "%d> ", c);
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dump_char_struct(&font->per_char[c], prefix);
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdump_bitmap(unsigned int width, unsigned int height, GLubyte * bitmap)
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int x, y;
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   printf("    ");
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (x = 0; x < 8 * width; x++)
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("%o", 7 - (x % 8));
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   putchar('\n');
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (y = 0; y < height; y++) {
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("%3o:", y);
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (x = 0; x < 8 * width; x++)
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 putchar((bitmap[width * (height - y - 1) + x / 8] & (1 << (7 - (x %
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org									 8))))
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 ? '*' : '.');
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("   ");
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (x = 0; x < width; x++)
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 printf("0x%02x, ", bitmap[width * (height - y - 1) + x]);
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      putchar('\n');
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* DEBUG */
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Implementation.  */
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Fill a BITMAP with a character C from thew current font
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   in the graphics context GC.  WIDTH is the width in bytes
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   and HEIGHT is the height in bits.
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Note that the generated bitmaps must be used with
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Possible optimizations:
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * use only one reusable pixmap with the maximum dimensions.
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * draw the entire font into a single pixmap (careful with
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       proportional fonts!).
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org*/
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Generate OpenGL-compatible bitmap.
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfill_bitmap(Display * dpy, Window win, GC gc,
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    unsigned int width, unsigned int height,
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    int x0, int y0, unsigned int c, GLubyte * bitmap)
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XImage *image;
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int x, y;
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Pixmap pixmap;
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XChar2b char2b;
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pixmap = XCreatePixmap(dpy, win, 8 * width, height, 1);
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XSetForeground(dpy, gc, 0);
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XFillRectangle(dpy, pixmap, gc, 0, 0, 8 * width, height);
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XSetForeground(dpy, gc, 1);
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   char2b.byte1 = (c >> 8) & 0xff;
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   char2b.byte2 = (c & 0xff);
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XDrawString16(dpy, pixmap, gc, x0, y0, &char2b, 1);
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   image = XGetImage(dpy, pixmap, 0, 0, 8 * width, height, 1, XYPixmap);
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (image) {
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Fill the bitmap (X11 and OpenGL are upside down wrt each other).  */
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (y = 0; y < height; y++)
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 for (x = 0; x < 8 * width; x++)
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (XGetPixel(image, x, y))
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       bitmap[width * (height - y - 1) + x / 8] |=
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  (1 << (7 - (x % 8)));
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XDestroyImage(image);
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XFreePixmap(dpy, pixmap);
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * determine if a given glyph is valid and return the
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * corresponding XCharStruct.
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic XCharStruct *
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgisvalid(XFontStruct * fs, unsigned int which)
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int rows, pages;
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int byte1 = 0, byte2 = 0;
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i, valid = 1;
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rows = fs->max_byte1 - fs->min_byte1 + 1;
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (rows == 1) {
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* "linear" fonts */
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((fs->min_char_or_byte2 > which) || (fs->max_char_or_byte2 < which))
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 valid = 0;
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* "matrix" fonts */
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      byte2 = which & 0xff;
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      byte1 = which >> 8;
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((fs->min_char_or_byte2 > byte2) ||
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  (fs->max_char_or_byte2 < byte2) ||
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  (fs->min_byte1 > byte1) || (fs->max_byte1 < byte1))
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 valid = 0;
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (valid) {
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (fs->per_char) {
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (rows == 1) {
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    /* "linear" fonts */
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    return (fs->per_char + (which - fs->min_char_or_byte2));
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 else {
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    /* "matrix" fonts */
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    i = ((byte1 - fs->min_byte1) * pages) +
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       (byte2 - fs->min_char_or_byte2);
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    return (fs->per_char + i);
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return (&fs->min_bounds);
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (NULL);
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgPUBLIC void
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglXUseXFont(Font font, int first, int count, int listbase)
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Display *dpy;
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Window win;
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Pixmap pixmap;
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GC gc;
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XGCValues values;
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned long valuemask;
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XFontStruct *fs;
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint swapbytes, lsbfirst, rowlength;
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint skiprows, skippixels, alignment;
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int max_width, max_height, max_bm_width, max_bm_height;
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLubyte *bm;
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dpy = glXGetCurrentDisplay();
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!dpy)
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;			/* I guess glXMakeCurrent wasn't called */
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i = DefaultScreen(dpy);
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   win = RootWindow(dpy, i);
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fs = XQueryFont(dpy, font);
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!fs) {
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_error(NULL, GL_INVALID_VALUE,
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  "Couldn't get font structure information");
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Allocate a bitmap that can fit all characters.  */
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing;
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   max_height = fs->max_bounds.ascent + fs->max_bounds.descent;
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   max_bm_width = (max_width + 7) / 8;
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   max_bm_height = max_height;
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bm = (GLubyte *) MALLOC((max_bm_width * max_bm_height) * sizeof(GLubyte));
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!bm) {
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XFreeFontInfo(NULL, fs, 1);
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_error(NULL, GL_OUT_OF_MEMORY,
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  "Couldn't allocate bitmap in glXUseXFont()");
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* get the page info */
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   firstchar = (fs->min_byte1 << 8) + fs->min_char_or_byte2;
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lastchar = (fs->max_byte1 << 8) + fs->max_char_or_byte2;
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rows = fs->max_byte1 - fs->min_byte1 + 1;
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int first_char, last_char, pages, rows;
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Save the current packing mode for bitmaps.  */
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes);
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst);
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength);
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows);
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels);
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Enforce a standard packing mode which is compatible with
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fill_bitmap() from above.  This is actually the default mode,
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      except for the (non)alignment.  */
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pixmap = XCreatePixmap(dpy, win, 10, 10, 1);
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   values.foreground = BlackPixel(dpy, DefaultScreen(dpy));
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   values.background = WhitePixel(dpy, DefaultScreen(dpy));
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   values.font = fs->fid;
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   valuemask = GCForeground | GCBackground | GCFont;
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gc = XCreateGC(dpy, pixmap, valuemask, &values);
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XFreePixmap(dpy, pixmap);
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (debug_xfonts)
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dump_font_struct(fs);
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < count; i++) {
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned int width, height, bm_width, bm_height;
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat x0, y0, dx, dy;
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XCharStruct *ch;
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int x, y;
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned int c = first + i;
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int list = listbase + i;
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int valid;
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* check on index validity and get the bounds */
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ch = isvalid(fs, c);
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!ch) {
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ch = &fs->max_bounds;
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 valid = 0;
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 valid = 1;
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (debug_xfonts) {
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 char s[7];
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 sprintf(s, isprint(c) ? "%c> " : "\\%03o> ", c);
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 dump_char_struct(ch, s);
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* glBitmap()' parameters:
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         straight from the glXUseXFont(3) manpage.  */
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      width = ch->rbearing - ch->lbearing;
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      height = ch->ascent + ch->descent;
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      x0 = -ch->lbearing;
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      y0 = ch->descent - 0;	/* XXX used to subtract 1 here */
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* but that caused a conformace failure */
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dx = ch->width;
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dy = 0;
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* X11's starting point.  */
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      x = -ch->lbearing;
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      y = ch->ascent;
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Round the width to a multiple of eight.  We will use this also
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for the pixmap for capturing the X11 font.  This is slightly
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         inefficient, but it makes the OpenGL part real easy.  */
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bm_width = (width + 7) / 8;
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bm_height = height;
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glNewList(list, GL_COMPILE);
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (valid && (bm_width > 0) && (bm_height > 0)) {
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 memset(bm, '\0', bm_width * bm_height);
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm);
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 glBitmap(width, height, x0, y0, dx, dy, bm);
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (debug_xfonts) {
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    printf("width/height = %u/%u\n", width, height);
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    printf("bm_width/bm_height = %u/%u\n", bm_width, bm_height);
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    dump_bitmap(bm_width, bm_height, bm);
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 glBitmap(0, 0, 0.0, 0.0, dx, dy, NULL);
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glEndList();
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(bm);
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XFreeFontInfo(NULL, fs, 1);
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XFreeGC(dpy, gc);
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Restore saved packing modes.  */
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes);
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst);
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength);
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows);
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels);
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
372