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