13a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/*
23a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Mesa 3-D graphics library
33a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Version:  3.1
43a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *
53a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Copyright (C) 1999  Brian Paul   All Rights Reserved.
63a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *
73a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
83a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * copy of this software and associated documentation files (the "Software"),
93a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * to deal in the Software without restriction, including without limitation
103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Software is furnished to do so, subject to the following conditions:
133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *
143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * The above copyright notice and this permission notice shall be included
153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * in all copies or substantial portions of the Software.
163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *
173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/* xfonts.c -- glXUseXFont() for Mesa written by
273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de
283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/*
313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org  This was take from Mesa and modified to work in the real GLX structure.
323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org  It provides a fully client side implementation of glXUseXFont and is
333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org  called by that routine when direct rendering is enabled.
343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org*/
353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#ifdef GLX_DIRECT_RENDERING
373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "glxclient.h"
393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/* Some debugging info.  */
413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#ifdef DEBUG
433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#undef _R
443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#undef _G
453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#undef _B
463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include <ctype.h>
473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgint debug_xfonts = 0;
493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void
513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgdump_char_struct(XCharStruct * ch, char *prefix)
523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   printf("%slbearing = %d, rbearing = %d, width = %d\n",
543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org          prefix, ch->lbearing, ch->rbearing, ch->width);
553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   printf("%sascent = %d, descent = %d, attributes = %u\n",
563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org          prefix, ch->ascent, ch->descent, (unsigned int) ch->attributes);
573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void
603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgdump_font_struct(XFontStruct * font)
613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   printf("ascent = %d, descent = %d\n", font->ascent, font->descent);
633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   printf("char_or_byte2 = (%u,%u)\n",
643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org          font->min_char_or_byte2, font->max_char_or_byte2);
653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   printf("byte1 = (%u,%u)\n", font->min_byte1, font->max_byte1);
663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   printf("all_chars_exist = %s\n", font->all_chars_exist ? "True" : "False");
673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   printf("default_char = %c (\\%03o)\n",
683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org          (char) (isprint(font->default_char) ? font->default_char : ' '),
693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org          font->default_char);
703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   dump_char_struct(&font->min_bounds, "min> ");
713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   dump_char_struct(&font->max_bounds, "max> ");
723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#if 0
733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   for (c = font->min_char_or_byte2; c <= font->max_char_or_byte2; c++) {
743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      char prefix[8];
753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      sprintf(prefix, "%d> ", c);
763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      dump_char_struct(&font->per_char[c], prefix);
773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#endif
793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void
823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgdump_bitmap(unsigned int width, unsigned int height, GLubyte * bitmap)
833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   unsigned int x, y;
853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   printf("    ");
873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   for (x = 0; x < 8 * width; x++)
883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      printf("%o", 7 - (x % 8));
893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   putchar('\n');
903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   for (y = 0; y < height; y++) {
913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      printf("%3o:", y);
923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      for (x = 0; x < 8 * width; x++)
933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         putchar((bitmap[width * (height - y - 1) + x / 8] & (1 << (7 - (x %
943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org                                                                         8))))
953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org                 ? '*' : '.');
963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      printf("   ");
973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      for (x = 0; x < width; x++)
983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         printf("0x%02x, ", bitmap[width * (height - y - 1) + x]);
993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      putchar('\n');
1003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
1013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
1023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#endif /* DEBUG */
1033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/* Implementation.  */
1063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/* Fill a BITMAP with a character C from thew current font
1083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   in the graphics context GC.  WIDTH is the width in bytes
1093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   and HEIGHT is the height in bits.
1103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   Note that the generated bitmaps must be used with
1123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org        glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
1143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org        glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
1153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org        glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
1163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org        glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
1173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org        glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
1183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org        glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
1193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   Possible optimizations:
1213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org     * use only one reusable pixmap with the maximum dimensions.
1233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org     * draw the entire font into a single pixmap (careful with
1243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org       proportional fonts!).
1253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org*/
1263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/*
1293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Generate OpenGL-compatible bitmap.
1303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
1313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void
1323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgfill_bitmap(Display * dpy, Window win, GC gc,
1333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org            unsigned int width, unsigned int height,
1343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org            int x0, int y0, unsigned int c, GLubyte * bitmap)
1353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
1363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   XImage *image;
1373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   unsigned int x, y;
1383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   Pixmap pixmap;
1393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   XChar2b char2b;
1403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   pixmap = XCreatePixmap(dpy, win, 8 * width, height, 1);
1423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   XSetForeground(dpy, gc, 0);
1433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   XFillRectangle(dpy, pixmap, gc, 0, 0, 8 * width, height);
1443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   XSetForeground(dpy, gc, 1);
1453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   char2b.byte1 = (c >> 8) & 0xff;
1473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   char2b.byte2 = (c & 0xff);
1483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   XDrawString16(dpy, pixmap, gc, x0, y0, &char2b, 1);
1503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   image = XGetImage(dpy, pixmap, 0, 0, 8 * width, height, 1, XYPixmap);
1523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if (image) {
1533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      /* Fill the bitmap (X11 and OpenGL are upside down wrt each other).  */
1543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      for (y = 0; y < height; y++)
1553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         for (x = 0; x < 8 * width; x++)
1563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org            if (XGetPixel(image, x, y))
1573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org               bitmap[width * (height - y - 1) + x / 8] |=
1583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org                  (1 << (7 - (x % 8)));
1593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      XDestroyImage(image);
1603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
1613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   XFreePixmap(dpy, pixmap);
1633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
1643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/*
1663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * determine if a given glyph is valid and return the
1673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * corresponding XCharStruct.
1683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
1693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic XCharStruct *
1703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgisvalid(XFontStruct * fs, int which)
1713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
1723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   unsigned int rows, pages;
1733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   int byte1 = 0, byte2 = 0;
1743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   int i, valid = 1;
1753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   rows = fs->max_byte1 - fs->min_byte1 + 1;
1773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
1783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if (rows == 1) {
1803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      /* "linear" fonts */
1813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      if ((fs->min_char_or_byte2 > which) || (fs->max_char_or_byte2 < which))
1823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         valid = 0;
1833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
1843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   else {
1853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      /* "matrix" fonts */
1863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      byte2 = which & 0xff;
1873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      byte1 = which >> 8;
1883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      if ((fs->min_char_or_byte2 > byte2) ||
1893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org          (fs->max_char_or_byte2 < byte2) ||
1903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org          (fs->min_byte1 > byte1) || (fs->max_byte1 < byte1))
1913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         valid = 0;
1923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
1933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if (valid) {
1953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      if (fs->per_char) {
1963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         if (rows == 1) {
1973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org            /* "linear" fonts */
1983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org            return (fs->per_char + (which - fs->min_char_or_byte2));
1993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         }
2003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         else {
2013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org            /* "matrix" fonts */
2023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org            i = ((byte1 - fs->min_byte1) * pages) +
2033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org               (byte2 - fs->min_char_or_byte2);
2043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org            return (fs->per_char + i);
2053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         }
2063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      }
2073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      else {
2083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         return (&fs->min_bounds);
2093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      }
2103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
2113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   return (NULL);
2123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
2133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org_X_HIDDEN void
215760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.orgDRI_glXUseXFont(struct glx_context *CC, Font font, int first, int count, int listbase)
2163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
2173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   Display *dpy;
2183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   Window win;
2193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   Pixmap pixmap;
2203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   GC gc;
2213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   XGCValues values;
2223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   unsigned long valuemask;
2233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   XFontStruct *fs;
2243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   GLint swapbytes, lsbfirst, rowlength;
2263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   GLint skiprows, skippixels, alignment;
2273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   unsigned int max_width, max_height, max_bm_width, max_bm_height;
2293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   GLubyte *bm;
2303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   int i;
2323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   dpy = CC->currentDpy;
2343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   win = CC->currentDrawable;
2353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   fs = XQueryFont(dpy, font);
2373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if (!fs) {
2383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      __glXSetError(CC, GL_INVALID_VALUE);
2393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      return;
2403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
2413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   /* Allocate a bitmap that can fit all characters.  */
2433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing;
2443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   max_height = fs->max_bounds.ascent + fs->max_bounds.descent;
2453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   max_bm_width = (max_width + 7) / 8;
2463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   max_bm_height = max_height;
2473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   bm = (GLubyte *) Xmalloc((max_bm_width * max_bm_height) * sizeof(GLubyte));
2493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if (!bm) {
2503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      XFreeFontInfo(NULL, fs, 1);
2513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      __glXSetError(CC, GL_OUT_OF_MEMORY);
2523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      return;
2533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
2543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#if 0
2563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   /* get the page info */
2573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
2583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   firstchar = (fs->min_byte1 << 8) + fs->min_char_or_byte2;
2593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   lastchar = (fs->max_byte1 << 8) + fs->max_char_or_byte2;
2603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   rows = fs->max_byte1 - fs->min_byte1 + 1;
2613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   unsigned int first_char, last_char, pages, rows;
2623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#endif
2633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   /* Save the current packing mode for bitmaps.  */
2653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes);
2663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst);
2673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength);
2683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows);
2693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels);
2703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
2713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   /* Enforce a standard packing mode which is compatible with
2733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      fill_bitmap() from above.  This is actually the default mode,
2743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      except for the (non)alignment.  */
2753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
2763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
2773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
2793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
2803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   pixmap = XCreatePixmap(dpy, win, 10, 10, 1);
2833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   values.foreground = BlackPixel(dpy, DefaultScreen(dpy));
2843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   values.background = WhitePixel(dpy, DefaultScreen(dpy));
2853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   values.font = fs->fid;
2863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   valuemask = GCForeground | GCBackground | GCFont;
2873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   gc = XCreateGC(dpy, pixmap, valuemask, &values);
2883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   XFreePixmap(dpy, pixmap);
2893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#ifdef DEBUG
2913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if (debug_xfonts)
2923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      dump_font_struct(fs);
2933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#endif
2943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   for (i = 0; i < count; i++) {
2963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      unsigned int width, height, bm_width, bm_height;
2973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      GLfloat x0, y0, dx, dy;
2983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      XCharStruct *ch;
2993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      int x, y;
3003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      unsigned int c = first + i;
3013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      int list = listbase + i;
3023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      int valid;
3033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
3043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      /* check on index validity and get the bounds */
3053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      ch = isvalid(fs, c);
3063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      if (!ch) {
3073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         ch = &fs->max_bounds;
3083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         valid = 0;
3093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      }
3103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      else {
3113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         valid = 1;
3123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      }
3133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
3143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#ifdef DEBUG
3153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      if (debug_xfonts) {
3163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         char s[7];
3173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         sprintf(s, isprint(c) ? "%c> " : "\\%03o> ", c);
3183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         dump_char_struct(ch, s);
3193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      }
3203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#endif
3213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
3223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      /* glBitmap()' parameters:
3233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         straight from the glXUseXFont(3) manpage.  */
3243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      width = ch->rbearing - ch->lbearing;
3253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      height = ch->ascent + ch->descent;
3263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      x0 = -ch->lbearing;
3273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      y0 = ch->descent - 1;
3283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      dx = ch->width;
3293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      dy = 0;
3303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
3313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      /* X11's starting point.  */
3323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      x = -ch->lbearing;
3333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      y = ch->ascent;
3343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
3353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      /* Round the width to a multiple of eight.  We will use this also
3363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         for the pixmap for capturing the X11 font.  This is slightly
3373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         inefficient, but it makes the OpenGL part real easy.  */
3383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      bm_width = (width + 7) / 8;
3393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      bm_height = height;
3403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
3413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      glNewList(list, GL_COMPILE);
3423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      if (valid && (bm_width > 0) && (bm_height > 0)) {
3433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
3443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         memset(bm, '\0', bm_width * bm_height);
3453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm);
3463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
3473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         glBitmap(width, height, x0, y0, dx, dy, bm);
3483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#ifdef DEBUG
3493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         if (debug_xfonts) {
3503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org            printf("width/height = %u/%u\n", width, height);
3513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org            printf("bm_width/bm_height = %u/%u\n", bm_width, bm_height);
3523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org            dump_bitmap(bm_width, bm_height, bm);
3533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         }
3543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#endif
3553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      }
3563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      else {
3573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         glBitmap(0, 0, 0.0, 0.0, dx, dy, NULL);
3583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      }
3593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      glEndList();
3603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
3613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
3623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   Xfree(bm);
3633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   XFreeFontInfo(NULL, fs, 1);
3643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   XFreeGC(dpy, gc);
3653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
3663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   /* Restore saved packing modes.  */
3673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes);
3683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst);
3693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength);
3703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows);
3713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels);
3723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
3733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
3743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
3753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#endif
376