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