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